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.jsr356.server;
20  
21  import java.util.concurrent.Executor;
22  
23  import javax.websocket.DeploymentException;
24  import javax.websocket.Endpoint;
25  import javax.websocket.server.ServerEndpoint;
26  import javax.websocket.server.ServerEndpointConfig;
27  
28  import org.eclipse.jetty.util.log.Log;
29  import org.eclipse.jetty.util.log.Logger;
30  import org.eclipse.jetty.websocket.common.events.EventDriverFactory;
31  import org.eclipse.jetty.websocket.jsr356.ClientContainer;
32  import org.eclipse.jetty.websocket.jsr356.JsrSessionFactory;
33  import org.eclipse.jetty.websocket.jsr356.annotations.AnnotatedEndpointScanner;
34  import org.eclipse.jetty.websocket.jsr356.endpoints.EndpointInstance;
35  import org.eclipse.jetty.websocket.jsr356.metadata.EndpointMetadata;
36  import org.eclipse.jetty.websocket.jsr356.server.pathmap.WebSocketPathSpec;
37  import org.eclipse.jetty.websocket.server.MappedWebSocketCreator;
38  import org.eclipse.jetty.websocket.server.WebSocketServerFactory;
39  
40  public class ServerContainer extends ClientContainer implements javax.websocket.server.ServerContainer
41  {
42      private static final Logger LOG = Log.getLogger(ServerContainer.class);
43  
44      private final MappedWebSocketCreator mappedCreator;
45      private final WebSocketServerFactory webSocketServerFactory;
46  
47      public ServerContainer(MappedWebSocketCreator creator, WebSocketServerFactory factory, Executor executor)
48      {
49          super(executor);
50          this.mappedCreator = creator;
51          this.webSocketServerFactory = factory;
52          EventDriverFactory eventDriverFactory = this.webSocketServerFactory.getEventDriverFactory();
53          eventDriverFactory.addImplementation(new JsrServerEndpointImpl());
54          eventDriverFactory.addImplementation(new JsrServerExtendsEndpointImpl());
55          this.webSocketServerFactory.addSessionFactory(new JsrSessionFactory(this));
56      }
57      
58      public EndpointInstance newClientEndpointInstance(Object endpoint, ServerEndpointConfig config, String path)
59      {
60          EndpointMetadata metadata = getClientEndpointMetadata(endpoint.getClass());
61          ServerEndpointConfig cec = config;
62          if (config == null)
63          {
64              if (metadata instanceof AnnotatedServerEndpointMetadata)
65              {
66                  cec = ((AnnotatedServerEndpointMetadata)metadata).getConfig();
67              }
68              else
69              {
70                  cec = new BasicServerEndpointConfig(endpoint.getClass(),path);
71              }
72          }
73          return new EndpointInstance(endpoint,cec,metadata);
74      }
75  
76      @Override
77      public void addEndpoint(Class<?> endpointClass) throws DeploymentException
78      {
79          ServerEndpointMetadata metadata = getServerEndpointMetadata(endpointClass,null);
80          addEndpoint(metadata);
81      }
82  
83      public void addEndpoint(ServerEndpointMetadata metadata) throws DeploymentException
84      {
85          JsrCreator creator = new JsrCreator(metadata,webSocketServerFactory.getExtensionFactory());
86          mappedCreator.addMapping(new WebSocketPathSpec(metadata.getPath()),creator);
87      }
88  
89      @Override
90      public void addEndpoint(ServerEndpointConfig config) throws DeploymentException
91      {
92          if (LOG.isDebugEnabled())
93          {
94              LOG.debug("addEndpoint({}) path={} endpoint={}",config,config.getPath(),config.getEndpointClass());
95          }
96          ServerEndpointMetadata metadata = getServerEndpointMetadata(config.getEndpointClass(),config);
97          addEndpoint(metadata);
98      }
99  
100     public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
101     {
102         ServerEndpointMetadata metadata = null;
103 
104         ServerEndpoint anno = endpoint.getAnnotation(ServerEndpoint.class);
105         if (anno != null)
106         {
107             // Annotated takes precedence here
108             AnnotatedServerEndpointMetadata ametadata = new AnnotatedServerEndpointMetadata(endpoint,config);
109             AnnotatedEndpointScanner<ServerEndpoint, ServerEndpointConfig> scanner = new AnnotatedEndpointScanner<>(ametadata);
110             metadata = ametadata;
111             scanner.scan();
112         }
113         else if (Endpoint.class.isAssignableFrom(endpoint))
114         {
115             // extends Endpoint
116             @SuppressWarnings("unchecked")
117             Class<? extends Endpoint> eendpoint = (Class<? extends Endpoint>)endpoint;
118             metadata = new SimpleServerEndpointMetadata(eendpoint,config);
119         }
120         else
121         {
122             StringBuilder err = new StringBuilder();
123             err.append("Not a recognized websocket [");
124             err.append(endpoint.getName());
125             err.append("] does not extend @").append(ServerEndpoint.class.getName());
126             err.append(" or extend from ").append(Endpoint.class.getName());
127             throw new DeploymentException("Unable to identify as valid Endpoint: " + endpoint);
128         }
129 
130         return metadata;
131     }
132 
133     @Override
134     public long getDefaultAsyncSendTimeout()
135     {
136         return webSocketServerFactory.getPolicy().getAsyncWriteTimeout();
137     }
138 
139     @Override
140     public int getDefaultMaxBinaryMessageBufferSize()
141     {
142         return webSocketServerFactory.getPolicy().getMaxBinaryMessageSize();
143     }
144 
145     @Override
146     public long getDefaultMaxSessionIdleTimeout()
147     {
148         return webSocketServerFactory.getPolicy().getIdleTimeout();
149     }
150 
151     @Override
152     public int getDefaultMaxTextMessageBufferSize()
153     {
154         return webSocketServerFactory.getPolicy().getMaxTextMessageSize();
155     }
156 
157     @Override
158     public void setAsyncSendTimeout(long ms)
159     {
160         super.setAsyncSendTimeout(ms);
161         webSocketServerFactory.getPolicy().setAsyncWriteTimeout(ms);
162     }
163 
164     @Override
165     public void setDefaultMaxBinaryMessageBufferSize(int max)
166     {
167         super.setDefaultMaxBinaryMessageBufferSize(max);
168         // overall message limit (used in non-streaming)
169         webSocketServerFactory.getPolicy().setMaxBinaryMessageSize(max);
170         // incoming streaming buffer size
171         webSocketServerFactory.getPolicy().setMaxBinaryMessageBufferSize(max);
172     }
173 
174     @Override
175     public void setDefaultMaxSessionIdleTimeout(long ms)
176     {
177         super.setDefaultMaxSessionIdleTimeout(ms);
178         webSocketServerFactory.getPolicy().setIdleTimeout(ms);
179     }
180 
181     @Override
182     public void setDefaultMaxTextMessageBufferSize(int max)
183     {
184         super.setDefaultMaxTextMessageBufferSize(max);
185         // overall message limit (used in non-streaming)
186         webSocketServerFactory.getPolicy().setMaxTextMessageSize(max);
187         // incoming streaming buffer size
188         webSocketServerFactory.getPolicy().setMaxTextMessageBufferSize(max);
189     }
190 }