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 */ BOSHClientConnEvent( final BOSHClient source, final boolean cConnected, final List<ComposableBody> cRequests, final Throwable cCause)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 */ createConnectionEstablishedEvent( final BOSHClient source)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 */ createConnectionClosedEvent( final BOSHClient source)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 */ createConnectionClosedOnErrorEvent( final BOSHClient source, final List<ComposableBody> outstanding, final Throwable cause)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 */ getBOSHClient()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 */ isConnected()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 */ isError()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 */ getCause()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 */ getOutstandingRequests()185 public List<ComposableBody> getOutstandingRequests() { 186 return requests; 187 } 188 189 } 190