View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.websocket.jsr356.annotations;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.Reader;
24  import java.lang.annotation.Annotation;
25  import java.nio.ByteBuffer;
26  import java.util.Map;
27  
28  import javax.websocket.CloseReason;
29  import javax.websocket.DecodeException;
30  import javax.websocket.EndpointConfig;
31  import javax.websocket.OnClose;
32  import javax.websocket.OnError;
33  import javax.websocket.OnMessage;
34  import javax.websocket.OnOpen;
35  import javax.websocket.RemoteEndpoint;
36  
37  import org.eclipse.jetty.util.log.Log;
38  import org.eclipse.jetty.util.log.Logger;
39  import org.eclipse.jetty.websocket.jsr356.JsrSession;
40  
41  /**
42   * The live event methods found for a specific Annotated Endpoint
43   * @param <T> the annotation type
44   * @param <C> the endpoint config type
45   */
46  public class JsrEvents<T extends Annotation, C extends EndpointConfig>
47  {
48      private static final Logger LOG = Log.getLogger(JsrEvents.class);
49      private final AnnotatedEndpointMetadata<T, C> metadata;
50  
51      /**
52       * Callable for &#064;{@link OnOpen} annotation.
53       */
54      private final OnOpenCallable onOpen;
55  
56      /**
57       * Callable for &#064;{@link OnClose} annotation
58       */
59      private final OnCloseCallable onClose;
60  
61      /**
62       * Callable for &#064;{@link OnError} annotation
63       */
64      private final OnErrorCallable onError;
65  
66      /**
67       * Callable for &#064;{@link OnMessage} annotation dealing with Text Message Format
68       */
69      private final OnMessageTextCallable onText;
70  
71      /**
72       * Callable for &#064;{@link OnMessage} annotation dealing with Text Streaming Message Format
73       */
74      private final OnMessageTextStreamCallable onTextStream;
75  
76      /**
77       * Callable for &#064;{@link OnMessage} annotation dealing with Binary Message Format
78       */
79      private final OnMessageBinaryCallable onBinary;
80  
81      /**
82       * Callable for &#064;{@link OnMessage} annotation dealing with Binary Streaming Message Format
83       */
84      private final OnMessageBinaryStreamCallable onBinaryStream;
85  
86      /**
87       * Callable for &#064;{@link OnMessage} annotation dealing with Pong Message Format
88       */
89      private OnMessagePongCallable onPong;
90  
91      /**
92       * The Request Parameters (from resolved javax.websocket.server.PathParam entries)
93       */
94      private Map<String, String> pathParameters;
95  
96      public JsrEvents(AnnotatedEndpointMetadata<T, C> metadata)
97      {
98          this.metadata = metadata;
99          this.onOpen = (metadata.onOpen == null)?null:new OnOpenCallable(metadata.onOpen);
100         this.onClose = (metadata.onClose == null)?null:new OnCloseCallable(metadata.onClose);
101         this.onError = (metadata.onError == null)?null:new OnErrorCallable(metadata.onError);
102         this.onBinary = (metadata.onBinary == null)?null:new OnMessageBinaryCallable(metadata.onBinary);
103         this.onBinaryStream = (metadata.onBinaryStream == null)?null:new OnMessageBinaryStreamCallable(metadata.onBinaryStream);
104         this.onText = (metadata.onText == null)?null:new OnMessageTextCallable(metadata.onText);
105         this.onTextStream = (metadata.onTextStream == null)?null:new OnMessageTextStreamCallable(metadata.onTextStream);
106         this.onPong = (metadata.onPong == null)?null:new OnMessagePongCallable(metadata.onPong);
107     }
108 
109     public void callBinary(RemoteEndpoint.Async endpoint, Object websocket, ByteBuffer buf, boolean fin) throws DecodeException
110     {
111         if (onBinary == null)
112         {
113             return;
114         }
115 
116         Object ret = onBinary.call(websocket,buf,fin);
117         if (ret != null)
118         {
119             if (LOG.isDebugEnabled())
120             {
121                 LOG.debug("returning: {}",ret);
122             }
123             endpoint.sendObject(ret);
124         }
125     }
126 
127     public void callBinaryStream(RemoteEndpoint.Async endpoint, Object websocket, InputStream stream) throws DecodeException, IOException
128     {
129         if (onBinaryStream == null)
130         {
131             return;
132         }
133 
134         Object ret = onBinaryStream.call(websocket,stream);
135         if (ret != null)
136         {
137             if (LOG.isDebugEnabled())
138             {
139                 LOG.debug("returning: {}",ret);
140             }
141             endpoint.sendObject(ret);
142         }
143     }
144 
145     public void callClose(Object websocket, CloseReason close)
146     {
147         if (onClose == null)
148         {
149             return;
150         }
151         onClose.call(websocket,close);
152     }
153 
154     public void callError(Object websocket, Throwable cause)
155     {
156         if (onError == null)
157         {
158             LOG.warn("Unable to report throwable to websocket (no @OnError handler declared): " + websocket.getClass().getName(), cause);
159             return;
160         }
161         onError.call(websocket,cause);
162     }
163 
164     public void callOpen(Object websocket, EndpointConfig config)
165     {
166         if (onOpen == null)
167         {
168             return;
169         }
170         onOpen.call(websocket,config);
171     }
172 
173     public void callPong(RemoteEndpoint.Async endpoint, Object websocket, ByteBuffer pong)
174     {
175         if (onPong == null)
176         {
177             return;
178         }
179 
180         Object ret = onPong.call(websocket,pong);
181         if (ret != null)
182         {
183             if (LOG.isDebugEnabled())
184             {
185                 LOG.debug("returning: {}",ret);
186             }
187             endpoint.sendObject(ret);
188         }
189     }
190 
191     public void callText(RemoteEndpoint.Async endpoint, Object websocket, String text, boolean fin) throws DecodeException
192     {
193         if (onText == null)
194         {
195             return;
196         }
197         Object ret = onText.call(websocket,text,fin);
198         if (ret != null)
199         {
200             if (LOG.isDebugEnabled())
201             {
202                 LOG.debug("returning: {}",ret);
203             }
204             endpoint.sendObject(ret);
205         }
206     }
207 
208     public void callTextStream(RemoteEndpoint.Async endpoint, Object websocket, Reader reader) throws DecodeException, IOException
209     {
210         if (onTextStream == null)
211         {
212             return;
213         }
214         Object ret = onTextStream.call(websocket,reader);
215         if (ret != null)
216         {
217             if (LOG.isDebugEnabled())
218             {
219                 LOG.debug("returning: {}",ret);
220             }
221             endpoint.sendObject(ret);
222         }
223     }
224 
225     public AnnotatedEndpointMetadata<T, C> getMetadata()
226     {
227         return metadata;
228     }
229 
230     public boolean hasBinary()
231     {
232         return (onBinary != null);
233     }
234 
235     public boolean hasBinaryStream()
236     {
237         return (onBinaryStream != null);
238     }
239 
240     public boolean hasText()
241     {
242         return (onText != null);
243     }
244 
245     public boolean hasTextStream()
246     {
247         return (onTextStream != null);
248     }
249 
250     public void init(JsrSession session)
251     {
252         session.setPathParameters(pathParameters);
253 
254         if (onOpen != null)
255         {
256             onOpen.init(session);
257         }
258         if (onClose != null)
259         {
260             onClose.init(session);
261         }
262         if (onError != null)
263         {
264             onError.init(session);
265         }
266         if (onText != null)
267         {
268             onText.init(session);
269         }
270         if (onTextStream != null)
271         {
272             onTextStream.init(session);
273         }
274         if (onBinary != null)
275         {
276             onBinary.init(session);
277         }
278         if (onBinaryStream != null)
279         {
280             onBinaryStream.init(session);
281         }
282         if (onPong != null)
283         {
284             onPong.init(session);
285         }
286     }
287 
288     public boolean isBinaryPartialSupported()
289     {
290         if (onBinary == null)
291         {
292             return false;
293         }
294         return onBinary.isPartialMessageSupported();
295     }
296 
297     public boolean isTextPartialSupported()
298     {
299         if (onText == null)
300         {
301             return false;
302         }
303         return onText.isPartialMessageSupported();
304     }
305 
306     public void setPathParameters(Map<String, String> pathParameters)
307     {
308         this.pathParameters = pathParameters;
309     }
310 }