417152 - WebSocket / Do all setup in websocket specific ServletContainerInitializer

+ Removed WebSocketConfiguration class entirely + annotation handlers
+ Renamed ServerAppliationConfigListener to
  WebSocketServerContainerInitializer
+ Embedded jetty code that used to use:
  WebSocketContainer.configureContext(context) now uses
  WebSocketServerContainerInitializer.configureContext(context)
This commit is contained in:
Joakim Erdfelt 2013-09-23 13:30:14 -07:00
parent cc9c19fd9d
commit cd236bc016
14 changed files with 220 additions and 639 deletions

View File

@ -25,7 +25,7 @@ import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.jsr356.server.WebSocketConfiguration;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
/**
* Example of setting up a javax.websocket server with Jetty embedded
@ -54,7 +54,7 @@ public class WebSocketJsrServer
server.setHandler(context);
// Enable javax.websocket configuration for the context
ServerContainer wsContainer = WebSocketConfiguration.configureContext(context);
ServerContainer wsContainer = WebSocketServerContainerInitializer.configureContext(context);
// Add your websockets to the container
wsContainer.addEndpoint(EchoJsrSocket.class);

View File

@ -19,6 +19,7 @@
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>

View File

@ -1,123 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.websocket.jsr356.server.deploy.DiscoveredEndpoints;
import org.eclipse.jetty.websocket.jsr356.server.deploy.ServerEndpointAnnotationHandler;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
/**
* WebSocket Server Configuration component.
* <p>
* This configuration will configure a context for JSR356 Websockets.
* <p>
* It is possible to disable specific contexts with an attribute <code>"org.eclipse.jetty.websocket.jsr356"</code> (set to <code>"false"</code>)
* <p>
* This attribute may be set on an individual context, or on the server to affect all deployed contexts.
*/
public class WebSocketConfiguration extends AbstractConfiguration
{
public static final String ENABLE = "org.eclipse.jetty.websocket.jsr356";
private static final Logger LOG = Log.getLogger(WebSocketConfiguration.class);
/**
* Create a ServerContainer properly, useful for embedded application use.
* <p>
* Notably, the cometd3 project uses this.
*
* @param context
* the context to enable javax.websocket support filters on
* @return the ServerContainer that was created
*/
public static ServerContainer configureContext(ServletContextHandler context)
{
LOG.debug("Configure javax.websocket for WebApp {}",context);
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
// Create the Jetty ServerContainer implementation
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory());
context.addBean(jettyContainer);
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
// Store reference to DiscoveredEndpoints
context.setAttribute(DiscoveredEndpoints.class.getName(),new DiscoveredEndpoints());
return jettyContainer;
}
public static boolean isJSR356Context(ContextHandler context)
{
Object enable = context.getAttribute(ENABLE);
if (enable instanceof Boolean)
{
return ((Boolean)enable).booleanValue();
}
enable = context.getServer().getAttribute(ENABLE);
if (enable instanceof Boolean)
{
return ((Boolean)enable).booleanValue();
}
return true;
}
@Override
public void configure(WebAppContext context) throws Exception
{
if (isJSR356Context(context))
{
WebSocketConfiguration.configureContext(context);
}
else
{
LOG.debug("JSR-356 support disabled for WebApp {}",context);
}
}
@Override
public void preConfigure(WebAppContext context) throws Exception
{
if (isJSR356Context(context))
{
boolean scanningAdded = false;
// Add the annotation scanning handlers (if annotation scanning enabled)
for (Configuration config : context.getConfigurations())
{
if (config instanceof AnnotationConfiguration)
{
AnnotationConfiguration annocfg = (AnnotationConfiguration)config;
annocfg.addDiscoverableAnnotationHandler(new ServerEndpointAnnotationHandler(context));
scanningAdded = true;
}
}
LOG.debug("@ServerEndpoint scanning added: {}",scanningAdded);
}
}
}

View File

@ -1,158 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server.deploy;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
import javax.websocket.Endpoint;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* Tracking for Discovered Endpoints.
* <p>
* This is a collection of endpoints, grouped by type (by Annotation or by extending Endpoint). Along with some better error messages for conflicting endpoints.
*/
public class DiscoveredEndpoints
{
private static class LocatedClass
{
private Class<?> clazz;
private URI location;
public LocatedClass(Class<?> clazz)
{
this.clazz = clazz;
this.location = getArchiveURI(clazz);
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("LocatedClass[");
builder.append(clazz.getName());
builder.append("]");
return builder.toString();
}
}
private static final Logger LOG = Log.getLogger(DiscoveredEndpoints.class);
public static URI getArchiveURI(Class<?> clazz)
{
String resourceName = clazz.getName().replace('.','/') + ".class";
URL classUrl = clazz.getClassLoader().getResource(resourceName);
if (classUrl == null)
{
// is this even possible at this point?
return null;
}
try
{
URI uri = classUrl.toURI();
String scheme = uri.getScheme();
if (scheme.equalsIgnoreCase("jar"))
{
String ssp = uri.getSchemeSpecificPart();
int idx = ssp.indexOf("!/");
if (idx >= 0)
{
ssp = ssp.substring(0,idx);
}
return URI.create(ssp);
}
}
catch (URISyntaxException e)
{
LOG.warn("Class reference not a valid URI? " + classUrl,e);
}
return null;
}
private Set<LocatedClass> extendedEndpoints;
private Set<LocatedClass> annotatedEndpoints;
public DiscoveredEndpoints()
{
extendedEndpoints = new HashSet<>();
annotatedEndpoints = new HashSet<>();
}
public void addAnnotatedEndpoint(Class<?> endpoint)
{
this.annotatedEndpoints.add(new LocatedClass(endpoint));
}
public void addExtendedEndpoint(Class<? extends Endpoint> endpoint)
{
this.extendedEndpoints.add(new LocatedClass(endpoint));
}
public Set<Class<?>> getAnnotatedEndpoints()
{
Set<Class<?>> endpoints = new HashSet<>();
for (LocatedClass lc : annotatedEndpoints)
{
endpoints.add(lc.clazz);
}
return endpoints;
}
public void getArchiveSpecificAnnnotatedEndpoints(URI archiveURI, Set<Class<?>> archiveSpecificEndpoints)
{
for (LocatedClass lc : annotatedEndpoints)
{
if ((archiveURI == null) || lc.location.getPath().equals(archiveURI.getPath()))
{
archiveSpecificEndpoints.add(lc.clazz);
}
}
}
@SuppressWarnings("unchecked")
public void getArchiveSpecificExtendedEndpoints(URI archiveURI, Set<Class<? extends Endpoint>> archiveSpecificEndpoints)
{
for (LocatedClass lc : extendedEndpoints)
{
if ((archiveURI == null) || (lc.location.getPath().equals(archiveURI.getPath()) && Endpoint.class.isAssignableFrom(lc.clazz)))
{
archiveSpecificEndpoints.add((Class<? extends Endpoint>)lc.clazz);
}
}
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("DiscoveredEndpoints [extendedEndpoints=");
builder.append(extendedEndpoints);
builder.append(", annotatedEndpoints=");
builder.append(annotatedEndpoints);
builder.append("]");
return builder.toString();
}
}

View File

@ -1,162 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server.deploy;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.jsr356.server.WebSocketConfiguration;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
@HandlesTypes(
{ ServerApplicationConfig.class, Endpoint.class })
public class ServerApplicationConfigListener implements ServletContainerInitializer
{
private static final Logger LOG = Log.getLogger(ServerApplicationConfigListener.class);
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
{
if (!WebSocketConfiguration.isJSR356Context(((ContextHandler.Context)ctx).getContextHandler()))
return;
WebSocketUpgradeFilter filter = (WebSocketUpgradeFilter)ctx.getAttribute(WebSocketUpgradeFilter.class.getName());
if (filter == null)
{
LOG.warn("Required attribute not available: " + WebSocketUpgradeFilter.class.getName());
return;
}
DiscoveredEndpoints discovered = (DiscoveredEndpoints)ctx.getAttribute(DiscoveredEndpoints.class.getName());
if (discovered == null)
{
LOG.warn("Required attribute not available: " + DiscoveredEndpoints.class.getName());
return;
}
LOG.debug("Found {} classes",c.size());
LOG.debug("Discovered: {}",discovered);
// First add all of the Endpoints
addEndpoints(c,discovered);
// Now process the ServerApplicationConfig entries
ServerContainer container = (ServerContainer)ctx.getAttribute(javax.websocket.server.ServerContainer.class.getName());
Set<Class<? extends Endpoint>> archiveSpecificExtendEndpoints = new HashSet<>();
Set<Class<?>> archiveSpecificAnnotatedEndpoints = new HashSet<>();
List<Class<? extends ServerApplicationConfig>> serverAppConfigs = filterServerApplicationConfigs(c);
if(serverAppConfigs.size() >= 1) {
for (Class<? extends ServerApplicationConfig> clazz : filterServerApplicationConfigs(c))
{
LOG.debug("Found ServerApplicationConfig: {}",clazz);
try
{
ServerApplicationConfig config = (ServerApplicationConfig)clazz.newInstance();
URI archiveURI = DiscoveredEndpoints.getArchiveURI(clazz);
archiveSpecificExtendEndpoints.clear();
archiveSpecificAnnotatedEndpoints.clear();
discovered.getArchiveSpecificExtendedEndpoints(archiveURI,archiveSpecificExtendEndpoints);
discovered.getArchiveSpecificAnnnotatedEndpoints(archiveURI,archiveSpecificAnnotatedEndpoints);
Set<ServerEndpointConfig> seconfigs = config.getEndpointConfigs(archiveSpecificExtendEndpoints);
if (seconfigs != null)
{
for (ServerEndpointConfig sec : seconfigs)
{
container.addEndpoint(sec);
}
}
Set<Class<?>> annotatedClasses = config.getAnnotatedEndpointClasses(archiveSpecificAnnotatedEndpoints);
if (annotatedClasses != null)
{
for (Class<?> annotatedClass : annotatedClasses)
{
container.addEndpoint(annotatedClass);
}
}
}
catch (InstantiationException | IllegalAccessException e)
{
throw new ServletException("Unable to instantiate: " + clazz.getName(),e);
}
catch (DeploymentException e)
{
throw new ServletException(e);
}
}
} else {
// Default behavior (no ServerApplicationConfigs found)
// Note: it is impossible to determine path of "extends Endpoint" discovered classes
for(Class<?> annotatedClass: discovered.getAnnotatedEndpoints())
{
try
{
container.addEndpoint(annotatedClass);
}
catch (DeploymentException e)
{
throw new ServletException(e);
}
}
}
}
@SuppressWarnings("unchecked")
private List<Class<? extends ServerApplicationConfig>> filterServerApplicationConfigs(Set<Class<?>> c)
{
List<Class<? extends ServerApplicationConfig>> configs = new ArrayList<>();
for (Class<?> clazz : c)
{
if (ServerApplicationConfig.class.isAssignableFrom(clazz))
{
configs.add((Class<? extends ServerApplicationConfig>)clazz);
}
}
return configs;
}
@SuppressWarnings("unchecked")
private void addEndpoints(Set<Class<?>> c, DiscoveredEndpoints discovered)
{
for (Class<?> clazz : c)
{
if (Endpoint.class.isAssignableFrom(clazz))
{
discovered.addExtendedEndpoint((Class<? extends Endpoint>)clazz);
}
}
}
}

View File

@ -1,64 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server.deploy;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.webapp.DiscoveredAnnotation;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* Once an Annotated Server Endpoint is discovered, add it to the list of
* discovered Annotated Endpoints.
*/
public class ServerEndpointAnnotation extends DiscoveredAnnotation
{
private static final Logger LOG = Log.getLogger(ServerEndpointAnnotation.class);
public ServerEndpointAnnotation(WebAppContext context, String className)
{
super(context,className);
}
public ServerEndpointAnnotation(WebAppContext context, String className, Resource resource)
{
super(context,className,resource);
}
@Override
public void apply()
{
Class<?> clazz = getTargetClass();
if (clazz == null)
{
LOG.warn(_className + " cannot be loaded");
return;
}
DiscoveredEndpoints discovered = (DiscoveredEndpoints)_context.getAttribute(DiscoveredEndpoints.class.getName());
if(discovered == null) {
LOG.warn("Context attribute not found: " + DiscoveredEndpoints.class.getName());
return;
}
discovered.addAnnotatedEndpoint(clazz);
}
}

View File

@ -1,68 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server.deploy;
import java.util.List;
import javax.websocket.server.ServerEndpoint;
import org.eclipse.jetty.annotations.AbstractDiscoverableAnnotationHandler;
import org.eclipse.jetty.annotations.AnnotationParser.ClassInfo;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.DiscoveredAnnotation;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* Processing for &#64;{@link ServerEndpoint} annotations during Web App Annotation Scanning
*/
public class ServerEndpointAnnotationHandler extends AbstractDiscoverableAnnotationHandler
{
private static final String ANNOTATION_NAME = "javax.websocket.server.ServerEndpoint";
private static final Logger LOG = Log.getLogger(ServerEndpointAnnotationHandler.class);
public ServerEndpointAnnotationHandler(WebAppContext context)
{
super(context);
}
public ServerEndpointAnnotationHandler(WebAppContext context, List<DiscoveredAnnotation> list)
{
super(context,list);
}
@Override
public void handle(ClassInfo info, String annotationName)
{
if (LOG.isDebugEnabled())
{
LOG.debug("handleClass: {}, {}, {}",info.getClassName(),annotationName);
}
if (!ANNOTATION_NAME.equals(annotationName))
{
// Not the one we are interested in
return;
}
ServerEndpointAnnotation annotation = new ServerEndpointAnnotation(_context,info.getClassName(),info.getContainingResource());
addAnnotation(annotation);
}
}

View File

@ -0,0 +1,211 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server.deploy;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import javax.websocket.DeploymentException;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
@HandlesTypes(
{ ServerApplicationConfig.class, ServerEndpoint.class, Endpoint.class })
public class WebSocketServerContainerInitializer implements ServletContainerInitializer
{
public static final String ENABLE_KEY = "org.eclipse.jetty.websocket.jsr356";
private static final Logger LOG = Log.getLogger(WebSocketServerContainerInitializer.class);
public static boolean isJSR356EnabledOnContext(ServletContext context)
{
Object enable = context.getAttribute(ENABLE_KEY);
if (enable instanceof Boolean)
{
return ((Boolean)enable).booleanValue();
}
return true;
}
public static ServerContainer configureContext(ServletContextHandler context)
{
// Create Filter
WebSocketUpgradeFilter filter = WebSocketUpgradeFilter.configureContext(context);
// Store reference to the WebSocketUpgradeFilter
context.setAttribute(WebSocketUpgradeFilter.class.getName(),filter);
// Create the Jetty ServerContainer implementation
ServerContainer jettyContainer = new ServerContainer(filter,filter.getFactory());
context.addBean(jettyContainer);
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
return jettyContainer;
}
@Override
public void onStartup(Set<Class<?>> c, ServletContext context) throws ServletException
{
if (!isJSR356EnabledOnContext(context))
{
LOG.info("JSR-356 support disabled via attribute on context {} - {}",context.getContextPath(),context);
return;
}
ContextHandler handler = ContextHandler.getContextHandler(context);
if (handler == null)
{
throw new ServletException("Not running on Jetty, JSR support disabled");
}
if (!(handler instanceof ServletContextHandler))
{
throw new ServletException("Not running in Jetty ServletContextHandler, JSR support disabled");
}
ServletContextHandler jettyContext = (ServletContextHandler)handler;
// Create the Jetty ServerContainer implementation
ServerContainer jettyContainer = configureContext(jettyContext);
// Store a reference to the ServerContainer per javax.websocket spec 1.0 final section 6.4 Programmatic Server Deployment
context.setAttribute(javax.websocket.server.ServerContainer.class.getName(),jettyContainer);
LOG.debug("Found {} classes",c.size());
// Now process the incoming classes
Set<Class<? extends Endpoint>> discoveredExtendedEndpoints = new HashSet<>();
Set<Class<?>> discoveredAnnotatedEndpoints = new HashSet<>();
Set<Class<? extends ServerApplicationConfig>> serverAppConfigs = new HashSet<>();
filterClasses(c,discoveredExtendedEndpoints,discoveredAnnotatedEndpoints,serverAppConfigs);
LOG.debug("Discovered {} extends Endpoint classes",discoveredExtendedEndpoints.size());
LOG.debug("Discovered {} @ServerEndpoint classes",discoveredAnnotatedEndpoints.size());
LOG.debug("Discovered {} ServerApplicationConfig classes",serverAppConfigs.size());
// Process the server app configs to determine endpoint filtering
boolean wasFiltered = false;
Set<ServerEndpointConfig> deployableExtendedEndpointConfigs = new HashSet<>();
Set<Class<?>> deployableAnnotatedEndpoints = new HashSet<>();
for (Class<? extends ServerApplicationConfig> clazz : serverAppConfigs)
{
LOG.debug("Found ServerApplicationConfig: {}",clazz);
try
{
ServerApplicationConfig config = (ServerApplicationConfig)clazz.newInstance();
Set<ServerEndpointConfig> seconfigs = config.getEndpointConfigs(discoveredExtendedEndpoints);
if (seconfigs != null)
{
wasFiltered = true;
deployableExtendedEndpointConfigs.addAll(seconfigs);
}
Set<Class<?>> annotatedClasses = config.getAnnotatedEndpointClasses(discoveredAnnotatedEndpoints);
if (annotatedClasses != null)
{
wasFiltered = true;
deployableAnnotatedEndpoints.addAll(annotatedClasses);
}
}
catch (InstantiationException | IllegalAccessException e)
{
throw new ServletException("Unable to instantiate: " + clazz.getName(),e);
}
}
// Default behavior if nothing filtered
if (!wasFiltered)
{
deployableAnnotatedEndpoints.addAll(discoveredAnnotatedEndpoints);
// Note: it is impossible to determine path of "extends Endpoint" discovered classes
deployableExtendedEndpointConfigs = new HashSet<>();
}
// Deploy what should be deployed.
LOG.debug("Deploying {} ServerEndpointConfig(s)",deployableExtendedEndpointConfigs.size());
for (ServerEndpointConfig config : deployableExtendedEndpointConfigs)
{
try
{
jettyContainer.addEndpoint(config);
}
catch (DeploymentException e)
{
throw new ServletException(e);
}
}
LOG.debug("Deploying {} @ServerEndpoint(s)",deployableAnnotatedEndpoints.size());
for (Class<?> annotatedClass : deployableAnnotatedEndpoints)
{
try
{
jettyContainer.addEndpoint(annotatedClass);
}
catch (DeploymentException e)
{
throw new ServletException(e);
}
}
}
@SuppressWarnings("unchecked")
private void filterClasses(Set<Class<?>> c, Set<Class<? extends Endpoint>> discoveredExtendedEndpoints, Set<Class<?>> discoveredAnnotatedEndpoints,
Set<Class<? extends ServerApplicationConfig>> serverAppConfigs)
{
for (Class<?> clazz : c)
{
if (ServerApplicationConfig.class.isAssignableFrom(clazz))
{
serverAppConfigs.add((Class<? extends ServerApplicationConfig>)clazz);
}
if (Endpoint.class.isAssignableFrom(clazz))
{
discoveredExtendedEndpoints.add((Class<? extends Endpoint>)clazz);
}
ServerEndpoint endpoint = clazz.getAnnotation(ServerEndpoint.class);
if (endpoint != null)
{
discoveredAnnotatedEndpoints.add(clazz);
}
}
}
}

View File

@ -1 +1 @@
org.eclipse.jetty.websocket.jsr356.server.deploy.ServerApplicationConfigListener
org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer

View File

@ -45,6 +45,7 @@ import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.jsr356.server.blockhead.BlockheadClient;
import org.eclipse.jetty.websocket.jsr356.server.blockhead.HttpResponse;
import org.eclipse.jetty.websocket.jsr356.server.blockhead.IncomingFramesCapture;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@ -144,7 +145,7 @@ public class ConfiguratorTest
context.setContextPath("/");
server.setHandler(context);
ServerContainer container = WebSocketConfiguration.configureContext(context);
ServerContainer container = WebSocketServerContainerInitializer.configureContext(context);
container.addEndpoint(CaptureHeadersSocket.class);
container.addEndpoint(EmptySocket.class);
container.addEndpoint(NoExtensionsSocket.class);

View File

@ -113,7 +113,6 @@ public class WSServer
// @formatter:off
context.setConfigurations(new Configuration[] {
new WebSocketConfiguration(),
new AnnotationConfiguration(),
new WebXmlConfiguration(),
new WebInfConfiguration(),

View File

@ -60,6 +60,7 @@ public class BlockheadClientConstructionTest
this.expectedHttpUri = URI.create(httpuri);
}
@SuppressWarnings("resource")
@Test
public void testURIs() throws URISyntaxException
{

View File

@ -28,7 +28,7 @@ import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.jsr356.server.WebSocketConfiguration;
import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
/**
* Tool to help debug JSR based websocket circumstances reported around browsers.
@ -89,7 +89,7 @@ public class JsrBrowserDebugTool
holder.setInitParameter("dirAllowed","true");
server.setHandler(context);
ServerContainer container = WebSocketConfiguration.configureContext(context);
ServerContainer container = WebSocketServerContainerInitializer.configureContext(context);
container.addEndpoint(JsrBrowserSocket.class);
LOG.info("{} setup on port {}",this.getClass().getName(),port);

View File

@ -1,57 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.websocket.jsr356.server.deploy;
import static org.hamcrest.Matchers.*;
import java.net.URI;
import org.junit.Assert;
import org.junit.Test;
public class DiscoveredEndpointsTest
{
/**
* Attempt to get an Archive URI, to a class known to be in an archive.
*/
@Test
public void testGetArchiveURI_InJar()
{
Class<?> clazz = javax.websocket.server.ServerContainer.class;
URI archiveURI = DiscoveredEndpoints.getArchiveURI(clazz);
// should point to a JAR file
Assert.assertThat("Archive URI for: " + clazz.getName(),
archiveURI.toASCIIString(),
endsWith("javax.websocket-api-1.0.jar"));
}
/**
* Get an Archive URI for a class reference that is known to not be in an archive.
*/
@Test
public void testGetArchiveURI_InClassDirectory()
{
Class<?> clazz = DiscoveredEndpointsTest.class;
URI archivePath = DiscoveredEndpoints.getArchiveURI(clazz);
// Should be null, as it does not point to an archive
Assert.assertThat("Archive URI for: " + clazz,
archivePath,
nullValue());
}
}