View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.common.events;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.Reader;
24  import java.nio.ByteBuffer;
25  
26  import org.eclipse.jetty.websocket.api.WebSocketPolicy;
27  import org.eclipse.jetty.websocket.api.annotations.WebSocket;
28  import org.eclipse.jetty.websocket.api.extensions.Frame;
29  import org.eclipse.jetty.websocket.common.CloseInfo;
30  import org.eclipse.jetty.websocket.common.message.MessageAppender;
31  import org.eclipse.jetty.websocket.common.message.MessageInputStream;
32  import org.eclipse.jetty.websocket.common.message.MessageReader;
33  import org.eclipse.jetty.websocket.common.message.SimpleBinaryMessage;
34  import org.eclipse.jetty.websocket.common.message.SimpleTextMessage;
35  
36  /**
37   * Handler for Annotated User WebSocket objects.
38   */
39  public class AnnotatedEventDriver extends EventDriver
40  {
41      private final EventMethods events;
42      private MessageAppender activeMessage;
43      private boolean hasCloseBeenCalled = false;
44  
45      public AnnotatedEventDriver(WebSocketPolicy policy, Object websocket, EventMethods events)
46      {
47          super(policy,websocket);
48          this.events = events;
49  
50          WebSocket anno = websocket.getClass().getAnnotation(WebSocket.class);
51          // Setup the policy
52          if (anno.maxMessageSize() > 0)
53          {
54              this.policy.setMaxMessageSize(anno.maxMessageSize());
55          }
56          if (anno.inputBufferSize() > 0)
57          {
58              this.policy.setInputBufferSize(anno.inputBufferSize());
59          }
60          if (anno.maxIdleTime() > 0)
61          {
62              this.policy.setIdleTimeout(anno.maxIdleTime());
63          }
64      }
65  
66      @Override
67      public void onBinaryFrame(ByteBuffer buffer, boolean fin) throws IOException
68      {
69          if (events.onBinary == null)
70          {
71              // not interested in binary events
72              return;
73          }
74  
75          if (activeMessage == null)
76          {
77              if (events.onBinary.isStreaming())
78              {
79                  activeMessage = new MessageInputStream(this);
80              }
81              else
82              {
83                  activeMessage = new SimpleBinaryMessage(this);
84              }
85          }
86  
87          activeMessage.appendMessage(buffer);
88  
89          if (fin)
90          {
91              activeMessage.messageComplete();
92              activeMessage = null;
93          }
94      }
95  
96      @Override
97      public void onBinaryMessage(byte[] data)
98      {
99          if (events.onBinary != null)
100         {
101             events.onBinary.call(websocket,session,data,0,data.length);
102         }
103     }
104 
105     @Override
106     public void onClose(CloseInfo close)
107     {
108         if (hasCloseBeenCalled)
109         {
110             // avoid duplicate close events (possible when using harsh Session.disconnect())
111             return;
112         }
113         hasCloseBeenCalled = true;
114         if (events.onClose != null)
115         {
116             events.onClose.call(websocket,session,close.getStatusCode(),close.getReason());
117         }
118     }
119 
120     @Override
121     public void onConnect()
122     {
123         if (events.onConnect != null)
124         {
125             events.onConnect.call(websocket,session);
126         }
127     }
128 
129     @Override
130     public void onError(Throwable cause)
131     {
132         if (events.onError != null)
133         {
134             events.onError.call(websocket,session,cause);
135         }
136     }
137 
138     @Override
139     public void onFrame(Frame frame)
140     {
141         if (events.onFrame != null)
142         {
143             events.onFrame.call(websocket,session,frame);
144         }
145     }
146 
147     public void onInputStream(InputStream stream)
148     {
149         if (events.onBinary != null)
150         {
151             events.onBinary.call(websocket,session,stream);
152         }
153     }
154 
155     public void onReader(Reader reader)
156     {
157         if (events.onText != null)
158         {
159             events.onText.call(websocket,session,reader);
160         }
161     }
162 
163     @Override
164     public void onTextFrame(ByteBuffer buffer, boolean fin) throws IOException
165     {
166         if (events.onText == null)
167         {
168             // not interested in text events
169             return;
170         }
171 
172         if (activeMessage == null)
173         {
174             if (events.onText.isStreaming())
175             {
176                 activeMessage = new MessageReader(this);
177             }
178             else
179             {
180                 activeMessage = new SimpleTextMessage(this);
181             }
182         }
183 
184         activeMessage.appendMessage(buffer);
185 
186         if (fin)
187         {
188             activeMessage.messageComplete();
189             activeMessage = null;
190         }
191     }
192 
193     @Override
194     public void onTextMessage(String message)
195     {
196         if (events.onText != null)
197         {
198             events.onText.call(websocket,session,message);
199         }
200     }
201 
202     @Override
203     public String toString()
204     {
205         return String.format("%s[%s]", this.getClass().getSimpleName(), websocket);
206     }
207 }