/* * Copyright 2009 Mike Cumings * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.kenai.jbosh; import java.util.ArrayList; import java.util.Collections; import java.util.EventObject; import java.util.List; /** * Client connection event, notifying of changes in connection state. * <p/> * This class is immutable and thread-safe. */ public final class BOSHClientConnEvent extends EventObject { /** * Serialized version. */ private static final long serialVersionUID = 1L; /** * Boolean flag indicating whether or not a session has been established * and is currently active. */ private final boolean connected; /** * List of outstanding requests which may not have been sent and/or * acknowledged by the remote CM. */ private final List<ComposableBody> requests; /** * Cause of the session termination, or {@code null}. */ private final Throwable cause; /** * Creates a new connection event instance. * * @param source event source * @param cConnected flag indicating whether or not the session is * currently active * @param cRequests outstanding requests when an error condition is * detected, or {@code null} when not an error condition * @param cCause cause of the error condition, or {@code null} when no * error condition is present */ private BOSHClientConnEvent( final BOSHClient source, final boolean cConnected, final List<ComposableBody> cRequests, final Throwable cCause) { super(source); connected = cConnected; cause = cCause; if (connected) { if (cCause != null) { throw(new IllegalStateException( "Cannot be connected and have a cause")); } if (cRequests != null && cRequests.size() > 0) { throw(new IllegalStateException( "Cannot be connected and have outstanding requests")); } } if (cRequests == null) { requests = Collections.emptyList(); } else { // Defensive copy: requests = Collections.unmodifiableList( new ArrayList<ComposableBody>(cRequests)); } } /** * Creates a new connection establishment event. * * @param source client which has become connected * @return event instance */ static BOSHClientConnEvent createConnectionEstablishedEvent( final BOSHClient source) { return new BOSHClientConnEvent(source, true, null, null); } /** * Creates a new successful connection closed event. This represents * a clean termination of the client session. * * @param source client which has been disconnected * @return event instance */ static BOSHClientConnEvent createConnectionClosedEvent( final BOSHClient source) { return new BOSHClientConnEvent(source, false, null, null); } /** * Creates a connection closed on error event. This represents * an unexpected termination of the client session. * * @param source client which has been disconnected * @param outstanding list of requests which may not have been received * by the remote connection manager * @param cause cause of termination * @return event instance */ static BOSHClientConnEvent createConnectionClosedOnErrorEvent( final BOSHClient source, final List<ComposableBody> outstanding, final Throwable cause) { return new BOSHClientConnEvent(source, false, outstanding, cause); } /** * Gets the client from which this event originated. * * @return client instance */ public BOSHClient getBOSHClient() { return (BOSHClient) getSource(); } /** * Returns whether or not the session has been successfully established * and is currently active. * * @return {@code true} if a session is active, {@code false} otherwise */ public boolean isConnected() { return connected; } /** * Returns whether or not this event indicates an error condition. This * will never return {@code true} when {@code isConnected()} returns * {@code true}. * * @return {@code true} if the event indicates a terminal error has * occurred, {@code false} otherwise. */ public boolean isError() { return cause != null; } /** * Returns the underlying cause of the error condition. This method is * guaranteed to return {@code null} when @{code isError()} returns * {@code false}. Similarly, this method is guaranteed to return * non-@{code null} if {@code isError()} returns {@code true}. * * @return underlying cause of the error condition, or {@code null} if * this event does not represent an error condition */ public Throwable getCause() { return cause; } /** * Get the list of requests which may not have been sent or were not * acknowledged by the remote connection manager prior to session * termination. * * @return list of messages which may not have been received by the remote * connection manager, or an empty list if the session is still connected */ public List<ComposableBody> getOutstandingRequests() { return requests; } }