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.server;
20  
21  import javax.websocket.OnMessage;
22  import javax.websocket.server.ServerEndpoint;
23  import javax.websocket.server.ServerEndpointConfig;
24  
25  import org.eclipse.jetty.websocket.api.WebSocketPolicy;
26  import org.eclipse.jetty.websocket.common.events.EventDriver;
27  import org.eclipse.jetty.websocket.common.events.EventDriverImpl;
28  import org.eclipse.jetty.websocket.jsr356.annotations.JsrEvents;
29  import org.eclipse.jetty.websocket.jsr356.annotations.OnMessageCallable;
30  import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
31  import org.eclipse.jetty.websocket.jsr356.endpoints.JsrAnnotatedEventDriver;
32  
33  /**
34   * Event Driver for classes annotated with @{@link ServerEndpoint}
35   */
36  public class JsrServerEndpointImpl implements EventDriverImpl
37  {
38      @Override
39      public EventDriver create(Object websocket, WebSocketPolicy policy) throws Throwable
40      {
41          if (!(websocket instanceof EndpointInstance))
42          {
43              throw new IllegalStateException(String.format("Websocket %s must be an %s",websocket.getClass().getName(),EndpointInstance.class.getName()));
44          }
45  
46          EndpointInstance ei = (EndpointInstance)websocket;
47          AnnotatedServerEndpointMetadata metadata = (AnnotatedServerEndpointMetadata)ei.getMetadata();
48          JsrEvents<ServerEndpoint, ServerEndpointConfig> events = new JsrEvents<>(metadata);
49  
50          // Handle @OnMessage maxMessageSizes
51          int maxBinaryMessage = getMaxMessageSize(policy.getMaxBinaryMessageSize(),metadata.onBinary,metadata.onBinaryStream);
52          int maxTextMessage = getMaxMessageSize(policy.getMaxTextMessageSize(),metadata.onText,metadata.onTextStream);
53  
54          policy.setMaxBinaryMessageSize(maxBinaryMessage);
55          policy.setMaxTextMessageSize(maxTextMessage);
56  
57          JsrAnnotatedEventDriver driver = new JsrAnnotatedEventDriver(policy,ei,events);
58          // Handle @PathParam values
59          ServerEndpointConfig config = (ServerEndpointConfig)ei.getConfig();
60          if (config instanceof PathParamServerEndpointConfig)
61          {
62              PathParamServerEndpointConfig ppconfig = (PathParamServerEndpointConfig)config;
63              driver.setPathParameters(ppconfig.getPathParamMap());
64          }
65  
66          return driver;
67      }
68  
69      @Override
70      public String describeRule()
71      {
72          return "class is annotated with @" + ServerEndpoint.class.getName();
73      }
74  
75      private int getMaxMessageSize(int defaultMaxMessageSize, OnMessageCallable... onMessages)
76      {
77          for (OnMessageCallable callable : onMessages)
78          {
79              if (callable == null)
80              {
81                  continue;
82              }
83              OnMessage onMsg = callable.getMethod().getAnnotation(OnMessage.class);
84              if (onMsg == null)
85              {
86                  continue;
87              }
88              if (onMsg.maxMessageSize() > 0)
89              {
90                  return (int)onMsg.maxMessageSize();
91              }
92          }
93          return defaultMaxMessageSize;
94      }
95  
96      @Override
97      public boolean supports(Object websocket)
98      {
99          if (!(websocket instanceof EndpointInstance))
100         {
101             return false;
102         }
103 
104         EndpointInstance ei = (EndpointInstance)websocket;
105         Object endpoint = ei.getEndpoint();
106 
107         ServerEndpoint anno = endpoint.getClass().getAnnotation(ServerEndpoint.class);
108         return (anno != null);
109     }
110 }