417561 Refactor annotation related code

Rename and refactor ServletContainerInitializerListener
This commit is contained in:
Jan Bartel 2013-09-19 22:30:23 +10:00
parent ad5624f000
commit 73d0ed8d71
6 changed files with 184 additions and 169 deletions

View File

@ -43,7 +43,8 @@ public class ServerWithAnnotations
//Create a WebApp
WebAppContext webapp = new WebAppContext();
webapp.setContextPath("/");
webapp.setWar("../../tests/test-webapps/test-servlet-spec/test-spec-webapp/target/test-spec-webapp-9.0.4-SNAPSHOT.war");
webapp.setWar("../../tests/test-webapps/test-servlet-spec/test-spec-webapp/target/test-spec-webapp-9.1.0-SNAPSHOT.war");
webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",".*/javax.servlet-[^/]*\\.jar$|.*/servlet-api-[^/]*\\.jar$");
server.setHandler(webapp);
//Register new transaction manager in JNDI

View File

@ -48,7 +48,7 @@ public class AnnotationConfiguration extends AbstractConfiguration
private static final Logger LOG = Log.getLogger(AnnotationConfiguration.class);
public static final String CLASS_INHERITANCE_MAP = "org.eclipse.jetty.classInheritanceMap";
public static final String CONTAINER_INITIALIZERS = "org.eclipse.jetty.containerInitializers";
public static final String CONTAINER_INITIALIZER_LISTENER = "org.eclipse.jetty.containerInitializerListener";
public static final String CONTAINER_INITIALIZER_STARTER = "org.eclipse.jetty.containerInitializerStarter";
protected List<AbstractDiscoverableAnnotationHandler> _discoverableAnnotationHandlers = new ArrayList<AbstractDiscoverableAnnotationHandler>();
@ -147,11 +147,11 @@ public class AnnotationConfiguration extends AbstractConfiguration
{
context.removeAttribute(CLASS_INHERITANCE_MAP);
context.removeAttribute(CONTAINER_INITIALIZERS);
ServletContainerInitializerListener listener = (ServletContainerInitializerListener)context.getAttribute(CONTAINER_INITIALIZER_LISTENER);
if (listener != null)
ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(CONTAINER_INITIALIZER_STARTER);
if (starter != null)
{
context.removeBean(listener);
context.removeAttribute(CONTAINER_INITIALIZER_LISTENER);
context.removeBean(starter);
context.removeAttribute(CONTAINER_INITIALIZER_STARTER);
}
}
@ -209,15 +209,17 @@ public class AnnotationConfiguration extends AbstractConfiguration
@Override
public void postConfigure(WebAppContext context) throws Exception
{
MultiMap<String> map = (MultiMap<String>)context.getAttribute(CLASS_INHERITANCE_MAP);
if (map != null)
map.clear();
MultiMap<String> classMap = (MultiMap<String>)context.getAttribute(CLASS_INHERITANCE_MAP);
List<ContainerInitializer> initializers = (List<ContainerInitializer>)context.getAttribute(CONTAINER_INITIALIZERS);
context.removeAttribute(CLASS_INHERITANCE_MAP);
if (classMap != null)
classMap.clear();
List<ContainerInitializer> initializers = (List<ContainerInitializer>)context.getAttribute(CONTAINER_INITIALIZERS);
context.removeAttribute(CONTAINER_INITIALIZERS);
if (initializers != null)
initializers.clear();
if (_discoverableAnnotationHandlers != null)
_discoverableAnnotationHandlers.clear();
@ -303,17 +305,14 @@ public class AnnotationConfiguration extends AbstractConfiguration
else
if (LOG.isDebugEnabled()) LOG.debug("No annotation on initializer "+service.getClass());
}
//add a bean which will call the servletcontainerinitializers when appropriate
ServletContainerInitializerListener listener = (ServletContainerInitializerListener)context.getAttribute(CONTAINER_INITIALIZER_LISTENER);
if (listener != null)
throw new IllegalStateException("ServletContainerInitializerListener already exists");
listener = new ServletContainerInitializerListener();
listener.setWebAppContext(context);
context.setAttribute(CONTAINER_INITIALIZER_LISTENER, listener);
context.addBean(listener, true);
//add a bean to the context which will call the servletcontainerinitializers when appropriate
ServletContainerInitializersStarter starter = (ServletContainerInitializersStarter)context.getAttribute(CONTAINER_INITIALIZER_STARTER);
if (starter != null)
throw new IllegalStateException("ServletContainerInitializersStarter already exists");
starter = new ServletContainerInitializersStarter(context);
context.setAttribute(CONTAINER_INITIALIZER_STARTER, starter);
context.addBean(starter, true);
}

View File

@ -1,145 +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.annotations;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* ServletContainerInitializerListener
*
*
*/
public class ServletContainerInitializerListener extends AbstractLifeCycle
{
private static final Logger LOG = Log.getLogger(ServletContainerInitializerListener.class);
protected WebAppContext _context = null;
public void setWebAppContext (WebAppContext context)
{
_context = context;
}
/**
* Call the doStart method of the ServletContainerInitializers
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
public void doStart()
{
List<ContainerInitializer> initializers = (List<ContainerInitializer>)_context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
MultiMap classMap = (MultiMap)_context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
if (initializers != null)
{
for (ContainerInitializer i : initializers)
{
//We have already found the classes that directly have an annotation that was in the HandlesTypes
//annotation of the ServletContainerInitializer. For each of those classes, walk the inheritance
//hierarchy to find classes that extend or implement them.
if (i.getAnnotatedTypeNames() != null)
{
Set<String> annotatedClassNames = new HashSet<String>(i.getAnnotatedTypeNames());
for (String name : annotatedClassNames)
{
//add the class with the annotation
i.addApplicableTypeName(name);
//add the classes that inherit the annotation
if (classMap != null)
{
List<String> implementsOrExtends = (List<String>)classMap.getValues(name);
if (implementsOrExtends != null && !implementsOrExtends.isEmpty())
addInheritedTypes(classMap, i, implementsOrExtends);
}
}
}
//Now we need to look at the HandlesTypes classes that were not annotations. We need to
//find all classes that extend or implement them.
if (i.getInterestedTypes() != null)
{
for (Class c : i.getInterestedTypes())
{
if (!c.isAnnotation())
{
//add the classes that implement or extend the class.
//TODO but not including the class itself?
if (classMap != null)
{
List<String> implementsOrExtends = (List<String>)classMap.getValues(c.getName());
if (implementsOrExtends != null && !implementsOrExtends.isEmpty())
addInheritedTypes(classMap, i, implementsOrExtends);
}
}
}
}
//instantiate ServletContainerInitializers, call doStart
try
{
i.callStartup(_context);
}
catch (Exception e)
{
LOG.warn(e);
throw new RuntimeException(e);
}
}
}
}
void addInheritedTypes (MultiMap classMap, ContainerInitializer initializer, List<String> applicableTypes)
{
for (String s : applicableTypes)
{
//add the name of the class that extends or implements
initializer.addApplicableTypeName(s);
//walk the hierarchy and find all types that extend or implement it
List<String> implementsOrExtends = (List<String>)classMap.getValues(s);
if (implementsOrExtends != null && !implementsOrExtends.isEmpty())
addInheritedTypes (classMap, initializer, implementsOrExtends);
}
}
/**
* Nothing to do for ServletContainerInitializers on stop
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
*/
public void doStop()
{
}
}

View File

@ -0,0 +1,159 @@
//
// ========================================================================
// 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.annotations;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jetty.plus.annotation.ContainerInitializer;
import org.eclipse.jetty.util.MultiMap;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.webapp.WebAppContext;
/**
* ServletContainerInitializersStarter
*
* Call the onStartup() method on all ServletContainerInitializers, after having
* found all applicable classes (if any) to pass in as args.
*/
public class ServletContainerInitializersStarter extends AbstractLifeCycle
{
private static final Logger LOG = Log.getLogger(ServletContainerInitializersStarter.class);
WebAppContext _context;
/**
* @param context
*/
public ServletContainerInitializersStarter(WebAppContext context)
{
_context = context;
}
/**
* Call the doStart method of the ServletContainerInitializers
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
public void doStart()
{
List<ContainerInitializer> initializers = (List<ContainerInitializer>)_context.getAttribute(AnnotationConfiguration.CONTAINER_INITIALIZERS);
if (initializers == null)
return;
MultiMap classMap = (MultiMap)_context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
for (ContainerInitializer i : initializers)
{
configureHandlesTypes(_context, i, classMap);
//instantiate ServletContainerInitializers, call doStart
try
{
i.callStartup(_context);
}
catch (Exception e)
{
LOG.warn(e);
throw new RuntimeException(e);
}
}
}
private void configureHandlesTypes (WebAppContext context, ContainerInitializer initializer, MultiMap<String> classMap)
{
doHandlesTypesAnnotations(context, initializer, classMap);
doHandlesTypesClasses(context, initializer, classMap);
}
private void doHandlesTypesAnnotations(WebAppContext context, ContainerInitializer initializer, MultiMap<String> classMap)
{
if (initializer == null)
return;
if (context == null)
throw new IllegalArgumentException("WebAppContext null");
//We have already found the classes that directly have an annotation that was in the HandlesTypes
//annotation of the ServletContainerInitializer. For each of those classes, walk the inheritance
//hierarchy to find classes that extend or implement them.
if (initializer.getAnnotatedTypeNames() != null)
{
if (classMap == null)
throw new IllegalStateException ("No class hierarchy");
Set<String> annotatedClassNames = new HashSet<String>(initializer.getAnnotatedTypeNames());
for (String name : annotatedClassNames)
{
//add the class that has the annotation
initializer.addApplicableTypeName(name);
//find and add the classes that inherit the annotation
addInheritedTypes(classMap, initializer, (List<String>)classMap.getValues(name));
}
}
}
private void doHandlesTypesClasses (WebAppContext context, ContainerInitializer initializer, MultiMap<String> classMap)
{
if (initializer == null)
return;
if (context == null)
throw new IllegalArgumentException("WebAppContext null");
//Now we need to look at the HandlesTypes classes that were not annotations. We need to
//find all classes that extend or implement them.
if (initializer.getInterestedTypes() != null)
{
if (classMap == null)
throw new IllegalStateException ("No class hierarchy");
for (Class c : initializer.getInterestedTypes())
{
if (!c.isAnnotation())
{
//find and add the classes that implement or extend the class.
//but not including the class itself
addInheritedTypes(classMap, initializer, (List<String>)classMap.getValues(c.getName()));
}
}
}
}
private void addInheritedTypes (MultiMap classMap, ContainerInitializer initializer, List<String> names)
{
if (names == null || names.isEmpty())
return;
for (String s : names)
{
//add the name of the class
initializer.addApplicableTypeName(s);
//walk the hierarchy and find all types that extend or implement the class
addInheritedTypes(classMap, initializer, (List<String>)classMap.getValues(s));
}
}
}

View File

@ -19,6 +19,7 @@
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;
@ -70,7 +71,7 @@ public class WebSocketConfiguration extends AbstractConfiguration
return jettyContainer;
}
public static boolean isJSR356Context(WebAppContext context)
public static boolean isJSR356Context(ContextHandler context)
{
Object enable = context.getAttribute(ENABLE);
if (enable instanceof Boolean)

View File

@ -33,9 +33,9 @@ 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.webapp.WebAppContext;
import org.eclipse.jetty.websocket.jsr356.server.ServerContainer;
import org.eclipse.jetty.websocket.jsr356.server.WebSocketConfiguration;
import org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter;
@ -49,7 +49,7 @@ public class ServerApplicationConfigListener implements ServletContainerInitiali
@Override
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException
{
if (!WebSocketConfiguration.isJSR356Context(WebAppContext.getCurrentWebAppContext()))
if (!WebSocketConfiguration.isJSR356Context(((ContextHandler.Context)ctx).getContextHandler()))
return;
WebSocketUpgradeFilter filter = (WebSocketUpgradeFilter)ctx.getAttribute(WebSocketUpgradeFilter.class.getName());