Home | History | Annotate | Download | only in jbosh
      1 /*
      2  * Copyright 2009 Mike Cumings
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.kenai.jbosh;
     18 
     19 import java.util.ArrayList;
     20 import java.util.Collections;
     21 import java.util.EventObject;
     22 import java.util.List;
     23 
     24 /**
     25  * Client connection event, notifying of changes in connection state.
     26  * <p/>
     27  * This class is immutable and thread-safe.
     28  */
     29 public final class BOSHClientConnEvent extends EventObject {
     30 
     31     /**
     32      * Serialized version.
     33      */
     34     private static final long serialVersionUID = 1L;
     35 
     36     /**
     37      * Boolean flag indicating whether or not a session has been established
     38      * and is currently active.
     39      */
     40     private final boolean connected;
     41 
     42     /**
     43      * List of outstanding requests which may not have been sent and/or
     44      * acknowledged by the remote CM.
     45      */
     46     private final List<ComposableBody> requests;
     47 
     48     /**
     49      * Cause of the session termination, or {@code null}.
     50      */
     51     private final Throwable cause;
     52 
     53     /**
     54      * Creates a new connection event instance.
     55      *
     56      * @param source event source
     57      * @param cConnected flag indicating whether or not the session is
     58      *  currently active
     59      * @param cRequests outstanding requests when an error condition is
     60      *  detected, or {@code null} when not an error condition
     61      * @param cCause cause of the error condition, or {@code null} when no
     62      *  error condition is present
     63      */
     64     private BOSHClientConnEvent(
     65             final BOSHClient source,
     66             final boolean cConnected,
     67             final List<ComposableBody> cRequests,
     68             final Throwable cCause) {
     69         super(source);
     70         connected = cConnected;
     71         cause = cCause;
     72 
     73         if (connected) {
     74             if (cCause != null) {
     75                 throw(new IllegalStateException(
     76                         "Cannot be connected and have a cause"));
     77             }
     78             if (cRequests != null && cRequests.size() > 0) {
     79                 throw(new IllegalStateException(
     80                         "Cannot be connected and have outstanding requests"));
     81             }
     82         }
     83 
     84         if (cRequests == null) {
     85             requests = Collections.emptyList();
     86         } else {
     87             // Defensive copy:
     88             requests = Collections.unmodifiableList(
     89                     new ArrayList<ComposableBody>(cRequests));
     90         }
     91     }
     92 
     93     /**
     94      * Creates a new connection establishment event.
     95      *
     96      * @param source client which has become connected
     97      * @return event instance
     98      */
     99     static BOSHClientConnEvent createConnectionEstablishedEvent(
    100             final BOSHClient source) {
    101         return new BOSHClientConnEvent(source, true, null, null);
    102     }
    103 
    104     /**
    105      * Creates a new successful connection closed event.  This represents
    106      * a clean termination of the client session.
    107      *
    108      * @param source client which has been disconnected
    109      * @return event instance
    110      */
    111     static BOSHClientConnEvent createConnectionClosedEvent(
    112             final BOSHClient source) {
    113         return new BOSHClientConnEvent(source, false, null, null);
    114     }
    115 
    116     /**
    117      * Creates a connection closed on error event.  This represents
    118      * an unexpected termination of the client session.
    119      *
    120      * @param source client which has been disconnected
    121      * @param outstanding list of requests which may not have been received
    122      *  by the remote connection manager
    123      * @param cause cause of termination
    124      * @return event instance
    125      */
    126     static BOSHClientConnEvent createConnectionClosedOnErrorEvent(
    127             final BOSHClient source,
    128             final List<ComposableBody> outstanding,
    129             final Throwable cause) {
    130         return new BOSHClientConnEvent(source, false, outstanding, cause);
    131     }
    132 
    133     /**
    134      * Gets the client from which this event originated.
    135      *
    136      * @return client instance
    137      */
    138     public BOSHClient getBOSHClient() {
    139         return (BOSHClient) getSource();
    140     }
    141 
    142     /**
    143      * Returns whether or not the session has been successfully established
    144      * and is currently active.
    145      *
    146      * @return {@code true} if a session is active, {@code false} otherwise
    147      */
    148     public boolean isConnected() {
    149         return connected;
    150     }
    151 
    152     /**
    153      * Returns whether or not this event indicates an error condition.  This
    154      * will never return {@code true} when {@code isConnected()} returns
    155      * {@code true}.
    156      *
    157      * @return {@code true} if the event indicates a terminal error has
    158      *  occurred, {@code false} otherwise.
    159      */
    160     public boolean isError() {
    161         return cause != null;
    162     }
    163 
    164     /**
    165      * Returns the underlying cause of the error condition.  This method is
    166      * guaranteed to return {@code null} when @{code isError()} returns
    167      * {@code false}.  Similarly, this method is guaranteed to return
    168      * non-@{code null} if {@code isError()} returns {@code true}.
    169      *
    170      * @return underlying cause of the error condition, or {@code null} if
    171      *  this event does not represent an error condition
    172      */
    173     public Throwable getCause() {
    174         return cause;
    175     }
    176 
    177     /**
    178      * Get the list of requests which may not have been sent or were not
    179      * acknowledged by the remote connection manager prior to session
    180      * termination.
    181      *
    182      * @return list of messages which may not have been received by the remote
    183      *  connection manager, or an empty list if the session is still connected
    184      */
    185     public List<ComposableBody> getOutstandingRequests() {
    186         return requests;
    187     }
    188 
    189 }
    190