You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/11/12 14:50:19 UTC
svn commit: r1408286 - in /openejb/trunk/openejb:
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
container/openejb-core/src/main/java/org/apache/openejb/config/
container/openejb-core/src/main/java/org/apache/openejb/web/ co...
Author: rmannibucau
Date: Mon Nov 12 13:50:17 2012
New Revision: 1408286
URL: http://svn.apache.org/viewvc?rev=1408286&view=rev
Log:
OPENEJB-1932 basic filter + servletcontextinitializer for applicationcomposer
Added:
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/FilterInfo.java
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ListenerInfo.java
openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/FilterListener.java
openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java
- copied, changed from r1408118, openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.java
openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletContextListenerRegistrationTest.java
Modified:
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java
openejb/trunk/openejb/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java
openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletListener.java
openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletRequestAdapter.java
openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java
Added: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/FilterInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/FilterInfo.java?rev=1408286&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/FilterInfo.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/FilterInfo.java Mon Nov 12 13:50:17 2012
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.assembler.classic;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class FilterInfo {
+ public String classname;
+ public List<String> mappings;
+ public Map<String, String> initParams = new HashMap<String, String>();
+ public String name;
+}
Added: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ListenerInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ListenerInfo.java?rev=1408286&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ListenerInfo.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ListenerInfo.java Mon Nov 12 13:50:17 2012
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.assembler.classic;
+
+public class ListenerInfo {
+ public String classname;
+}
Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/WebAppInfo.java Mon Nov 12 13:50:17 2012
@@ -42,4 +42,6 @@ public class WebAppInfo extends CommonIn
public final List<ServletInfo> servlets = new ArrayList<ServletInfo>();
public final List<ClassListInfo> jsfAnnotatedClasses = new ArrayList<ClassListInfo>();
public final Set<String> jaxRsProviders = new TreeSet<String>();
+ public final List<ListenerInfo> listeners = new ArrayList<ListenerInfo>();
+ public final List<FilterInfo> filters = new ArrayList<FilterInfo>();
}
Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java Mon Nov 12 13:50:17 2012
@@ -26,9 +26,11 @@ import org.apache.openejb.assembler.clas
import org.apache.openejb.assembler.classic.EjbJarInfo;
import org.apache.openejb.assembler.classic.EnterpriseBeanInfo;
import org.apache.openejb.assembler.classic.EntityManagerFactoryCallable;
+import org.apache.openejb.assembler.classic.FilterInfo;
import org.apache.openejb.assembler.classic.HandlerChainInfo;
import org.apache.openejb.assembler.classic.IdPropertiesInfo;
import org.apache.openejb.assembler.classic.JndiEncInfo;
+import org.apache.openejb.assembler.classic.ListenerInfo;
import org.apache.openejb.assembler.classic.MdbContainerInfo;
import org.apache.openejb.assembler.classic.MessageDrivenBeanInfo;
import org.apache.openejb.assembler.classic.PersistenceUnitInfo;
@@ -47,9 +49,12 @@ import org.apache.openejb.jee.ConfigProp
import org.apache.openejb.jee.ConnectionDefinition;
import org.apache.openejb.jee.Connector;
import org.apache.openejb.jee.EnterpriseBean;
+import org.apache.openejb.jee.Filter;
import org.apache.openejb.jee.InboundResourceadapter;
+import org.apache.openejb.jee.Listener;
import org.apache.openejb.jee.MessageListener;
import org.apache.openejb.jee.OutboundResourceAdapter;
+import org.apache.openejb.jee.ParamValue;
import org.apache.openejb.jee.PortComponent;
import org.apache.openejb.jee.ResourceAdapter;
import org.apache.openejb.jee.ServiceImplBean;
@@ -399,6 +404,23 @@ class AppInfoBuilder {
webAppInfo.servlets.add(servletInfo);
}
+ for (Listener listener : webModule.getWebApp().getListener()) {
+ final ListenerInfo listenerInfo = new ListenerInfo();
+ listenerInfo.classname = listener.getListenerClass();
+ webAppInfo.listeners.add(listenerInfo);
+ }
+
+ for (Filter filter : webModule.getWebApp().getFilter()) {
+ final FilterInfo filterInfo = new FilterInfo();
+ filterInfo.name = filter.getFilterName();
+ filterInfo.classname = filter.getFilterClass();
+ filterInfo.mappings = webModule.getWebApp().getFilterMappings(filter.getFilterName());
+ for (ParamValue pv : filter.getInitParam()) {
+ filterInfo.initParams.put(pv.getParamName(), pv.getParamValue());
+ }
+ webAppInfo.filters.add(filterInfo);
+ }
+
appInfo.webApps.add(webAppInfo);
}
}
Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/web/LightweightWebAppBuilder.java Mon Nov 12 13:50:17 2012
@@ -21,8 +21,10 @@ import org.apache.openejb.Injection;
import org.apache.openejb.OpenEJBRuntimeException;
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.ClassListInfo;
+import org.apache.openejb.assembler.classic.FilterInfo;
import org.apache.openejb.assembler.classic.InjectionBuilder;
import org.apache.openejb.assembler.classic.JndiEncBuilder;
+import org.apache.openejb.assembler.classic.ListenerInfo;
import org.apache.openejb.assembler.classic.ServletInfo;
import org.apache.openejb.assembler.classic.WebAppBuilder;
import org.apache.openejb.assembler.classic.WebAppInfo;
@@ -30,8 +32,10 @@ import org.apache.openejb.core.CoreConta
import org.apache.openejb.core.WebContext;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.ContainerSystem;
+import org.apache.openejb.util.ArrayEnumeration;
import org.apache.openejb.util.LogCategory;
import org.apache.openejb.util.Logger;
+import org.apache.webbeans.web.lifecycle.test.MockServletContextEvent;
import javax.naming.Binding;
import javax.naming.Context;
@@ -41,12 +45,19 @@ import javax.naming.NameNotFoundExceptio
import javax.naming.NameParser;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
@@ -56,23 +67,33 @@ import java.util.Set;
public class LightweightWebAppBuilder implements WebAppBuilder {
private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, LightweightWebAppBuilder.class);
- private static final Method addServletMethod;
- private static final Method removeServletMethod;
+ private static Method addServletMethod = null;
+ private static Method removeServletMethod = null;
+ private static Method addFilterMethod = null;
+ private static Method removeFilterMethod = null;
static {
try {
final Class<?> utilClass = LightweightWebAppBuilder.class.getClassLoader().loadClass("org.apache.openejb.server.httpd.util.HttpUtil");
addServletMethod = utilClass.getMethod("addServlet", String.class, WebContext.class, String.class);
removeServletMethod = utilClass.getMethod("removeServlet", String.class, WebContext.class);
+ addFilterMethod = utilClass.getMethod("addFilter", String.class, WebContext.class, String.class, FilterConfig.class);
+ removeFilterMethod = utilClass.getMethod("removeFilter", String.class, WebContext.class);
} catch (Exception e) {
- throw new OpenEJBRuntimeException(e);
+ LOGGER.info("Web features will not be available, add openejb-http if you need them");
}
}
- private final Map<WebAppInfo, DeployedServlet> deploymentInfo = new HashMap<WebAppInfo, DeployedServlet>();
+ private final Map<WebAppInfo, DeployedWebObjects> servletDeploymentInfo = new HashMap<WebAppInfo, DeployedWebObjects>();
+ private final Map<WebAppInfo, List<Object>> listeners = new HashMap<WebAppInfo, List<Object>>();
+ private final Map<WebAppInfo, ServletContextEvent> servletContextEvents = new HashMap<WebAppInfo, ServletContextEvent>();
@Override
public void deployWebApps(final AppInfo appInfo, final ClassLoader classLoader) throws Exception {
+ if (addServletMethod == null) {
+ return;
+ }
+
final CoreContainerSystem cs = (CoreContainerSystem) SystemInstance.get().getComponent(ContainerSystem.class);
final AppContext appContext = cs.getAppContext(appInfo.appId);
if (appContext == null) {
@@ -100,15 +121,75 @@ public class LightweightWebAppBuilder im
appContext.getWebContexts().add(webContext);
cs.addWebContext(webContext);
- final DeployedServlet deployedServlet = new DeployedServlet();
- deployedServlet.webContext = webContext;
+ final ServletContextEvent sce = new MockServletContextEvent();
+ servletContextEvents.put(webAppInfo, sce);
+
+ // otherwise myfaces can't start at all with our light http layer
+ sce.getServletContext().setAttribute("org.apache.myfaces.DYNAMICALLY_ADDED_FACES_SERVLET", true);
+
+ // listeners
+ for (ListenerInfo listener : webAppInfo.listeners) {
+ final Class<?> clazz = webContext.getClassLoader().loadClass(listener.classname);
+ final Object instance = webContext.newInstance(clazz);
+ if (ServletContextListener.class.isInstance(instance)) {
+ ((ServletContextListener) instance).contextInitialized(sce);
+ }
+
+ List<Object> list = listeners.get(webAppInfo);
+ if (list == null) {
+ list = new ArrayList<Object>();
+ listeners.put(webAppInfo, list);
+ }
+ list.add(instance);
+ }
+
+ final DeployedWebObjects deployedWebObjects = new DeployedWebObjects();
+ deployedWebObjects.webContext = webContext;
+
+ // register filters
+ for (FilterInfo info : webAppInfo.filters) {
+ for (String mapping : info.mappings) {
+ final FilterConfig config = new SimpleFilterConfig(sce.getServletContext(), info.name, info.initParams);
+ try {
+ addFilterMethod.invoke(null, info.classname, webContext, mapping, config);
+ deployedWebObjects.filterMappings.add(mapping);
+ } catch (Exception e) {
+ LOGGER.warning(e.getMessage(), e);
+ }
+ }
+ }
+ for (ClassListInfo info : webAppInfo.webAnnotatedClasses) {
+ final String url = info.name;
+ for (String filterPath : info.list) {
+ String classname = nameFromUrls(url, filterPath);
+
+ final Class<?> clazz = webContext.getClassLoader().loadClass(classname);
+ final WebFilter annotation = clazz.getAnnotation(WebFilter.class);
+ if (annotation != null) {
+ final Map<String, String> initParams = new HashMap<String, String>();
+ for (WebInitParam param : annotation.initParams()) {
+ initParams.put(param.name(), param.value());
+ }
+
+ final FilterConfig config = new SimpleFilterConfig(sce.getServletContext(), info.name, initParams);
+ for (String mapping: annotation.urlPatterns()) {
+ try {
+ addFilterMethod.invoke(null, classname, webContext, mapping, config);
+ deployedWebObjects.filterMappings.add(mapping);
+ } catch (Exception e) {
+ LOGGER.warning(e.getMessage(), e);
+ }
+ }
+ }
+ }
+ }
// register servlets
for (ServletInfo info : webAppInfo.servlets) {
for (String mapping : info.mappings) {
try {
addServletMethod.invoke(null, info.servletClass, webContext, mapping);
- deployedServlet.mappings.add(mapping);
+ deployedWebObjects.mappings.add(mapping);
} catch (Exception e) {
LOGGER.warning(e.getMessage(), e);
}
@@ -117,8 +198,7 @@ public class LightweightWebAppBuilder im
for (ClassListInfo info : webAppInfo.webAnnotatedClasses) {
final String url = info.name;
for (String servletPath : info.list) {
- String classname = servletPath.substring(url.length()).replace(File.separatorChar, '/').replace('/', '.');
- classname = classname.substring(0, classname.length() - ".class".length());
+ String classname = nameFromUrls(url, servletPath);
final Class<?> clazz = webContext.getClassLoader().loadClass(classname);
final WebServlet annotation = clazz.getAnnotation(WebServlet.class);
@@ -126,7 +206,7 @@ public class LightweightWebAppBuilder im
for (String mapping: annotation.urlPatterns()) {
try {
addServletMethod.invoke(null, classname, webContext, mapping);
- deployedServlet.mappings.add(mapping);
+ deployedWebObjects.mappings.add(mapping);
} catch (Exception e) {
LOGGER.warning(e.getMessage(), e);
}
@@ -135,14 +215,25 @@ public class LightweightWebAppBuilder im
}
}
- deploymentInfo.put(webAppInfo, deployedServlet);
+ servletDeploymentInfo.put(webAppInfo, deployedWebObjects);
}
}
+ private static String nameFromUrls(final String url, final String path) {
+ final String value = path.substring(url.length()).replace(File.separatorChar, '/').replace('/', '.');
+ return value.substring(0, value.length() - ".class".length());
+ }
+
@Override
public void undeployWebApps(final AppInfo appInfo) throws Exception {
+ if (addServletMethod == null) {
+ return;
+ }
+
for (WebAppInfo webAppInfo : appInfo.webApps) {
- final DeployedServlet context = deploymentInfo.remove(webAppInfo);
+ final DeployedWebObjects context = servletDeploymentInfo.remove(webAppInfo);
+ final ServletContextEvent sce = servletContextEvents.remove(webAppInfo);
+ final List<Object> listenerInstances = listeners.remove(webAppInfo);
for (String mapping : context.mappings) {
try {
@@ -151,6 +242,22 @@ public class LightweightWebAppBuilder im
// no-op
}
}
+
+ for (String mapping : context.filterMappings) {
+ try {
+ removeFilterMethod.invoke(null, mapping, context.webContext);
+ } catch (Exception e) {
+ // no-op
+ }
+ }
+
+ if (listenerInstances != null) {
+ for (Object instance : listenerInstances) {
+ if (ServletContextListener.class.isInstance(instance)) {
+ ((ServletContextListener) instance).contextDestroyed(sce);
+ }
+ }
+ }
}
}
@@ -159,8 +266,9 @@ public class LightweightWebAppBuilder im
return Collections.emptyMap(); // while we don't manage servlet in embedded mode we don't need it
}
- private static class DeployedServlet {
+ private static class DeployedWebObjects {
public List<String> mappings = new ArrayList<String>();
+ public List<String> filterMappings = new ArrayList<String>();
public WebContext webContext;
}
@@ -322,4 +430,36 @@ public class LightweightWebAppBuilder im
return null;
}
}
+
+ private static class SimpleFilterConfig implements FilterConfig {
+ private final Map<String, String> params;
+ private final String name;
+ private final ServletContext servletContext;
+
+ public SimpleFilterConfig(final ServletContext sc, final String name, final Map<String, String> initParams) {
+ this.name = name;
+ params = initParams;
+ servletContext = sc;
+ }
+
+ @Override
+ public String getFilterName() {
+ return name;
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ @Override
+ public String getInitParameter(final String name) {
+ return params.get(name);
+ }
+
+ @Override
+ public Enumeration<String> getInitParameterNames() {
+ return new ArrayEnumeration(params.keySet());
+ }
+ }
}
Modified: openejb/trunk/openejb/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java (original)
+++ openejb/trunk/openejb/container/openejb-jee/src/main/java/org/apache/openejb/jee/WebApp.java Mon Nov 12 13:50:17 2012
@@ -637,6 +637,18 @@ public class WebApp implements WebCommon
return Collections.emptyList();
}
+ public List<String> getFilterMappings(final String filterName) {
+ if (filterMapping == null || filterName == null) {
+ return Collections.emptyList();
+ }
+ for (FilterMapping mapping : filterMapping) {
+ if (filterName.equals(mapping.getFilterName())) {
+ return mapping.getUrlPattern();
+ }
+ }
+ return Collections.emptyList();
+ }
+
private Servlet findServlet(final String name) {
for (Servlet s : getServlet()) {
if (name.equals(s.getServletName())) {
@@ -680,8 +692,58 @@ public class WebApp implements WebCommon
return this;
}
+ public WebApp addFilter(final String name, final String clazz, final String... mappings) {
+ final Filter newFilter = new Filter();
+ newFilter.setFilterName(name);
+ newFilter.setFilterClass(clazz);
+
+ if (mappings != null && mappings.length > 0) {
+ final FilterMapping sm = new FilterMapping();
+ sm.setFilterName(name);
+
+ for (String mapping : mappings) {
+ if (filterMapping == null) {
+ filterMapping = new ArrayList<FilterMapping>();
+ }
+
+ sm.getUrlPattern().add(mapping);
+ }
+ filterMapping.add(sm);
+ }
+
+ getFilter().add(newFilter);
+
+ return this;
+ }
+
+ public WebApp addFilterInitParam(final String filterName, final String name, final String value) {
+ final ParamValue paramValue = new ParamValue();
+ paramValue.setParamName(name);
+ paramValue.setParamValue(value);
+
+ findFilter(filterName).getInitParam().add(paramValue);
+
+ return this;
+ }
+
+ private Filter findFilter(final String filterName) {
+ for (Filter s : getFilter()) {
+ if (filterName.equals(s.getFilterName())) {
+ return s;
+ }
+ }
+ return null;
+ }
+
public WebApp contextRoot(final String root) {
setContextRoot(root);
return this;
}
+
+ public WebApp addListener(final String classname) {
+ final Listener l = new Listener();
+ l.setListenerClass(classname);
+ getListener().add(l);
+ return this;
+ }
}
Added: openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/FilterListener.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/FilterListener.java?rev=1408286&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/FilterListener.java (added)
+++ openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/FilterListener.java Mon Nov 12 13:50:17 2012
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.server.httpd;
+
+import org.apache.openejb.loader.SystemInstance;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+public class FilterListener implements HttpListener {
+ private final String context;
+ private final Filter delegate;
+
+ public FilterListener(final Filter filter, final String contextRoot) {
+ delegate = filter;
+ context = contextRoot;
+ }
+
+ @Override
+ public void onMessage(final HttpRequest request, final HttpResponse response) throws Exception {
+ HttpRequestImpl req = null;
+ if (request instanceof HttpRequestImpl) {
+ req = (HttpRequestImpl) request;
+ } else if (request instanceof ServletRequestAdapter) {
+ final HttpServletRequest delegate = ((ServletRequestAdapter) request).getRequest();
+ if (delegate instanceof HttpRequestImpl) {
+ req = (HttpRequestImpl) delegate;
+ }
+ }
+ if (req != null) {
+ req.initPathFromContext(context);
+ }
+ delegate.doFilter(request, response, new SimpleFilterChain(this));
+ }
+
+ public Filter getDelegate() {
+ return delegate;
+ }
+
+ private static class SimpleFilterChain implements FilterChain {
+ private final FilterListener origin;
+
+ private SimpleFilterChain(final FilterListener origin) {
+ this.origin = origin;
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
+ final HttpListenerRegistry registry = SystemInstance.get().getComponent(HttpListenerRegistry.class);
+ registry.setOrigin(origin);
+ try {
+ registry.onMessage((HttpRequest) request, (HttpResponse) response);
+ } catch (Exception e) {
+ throw new ServletException(e);
+ } finally {
+ registry.setOrigin(origin);
+ }
+ }
+ }
+}
Modified: openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java (original)
+++ openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpListenerRegistry.java Mon Nov 12 13:50:17 2012
@@ -16,6 +16,8 @@
*/
package org.apache.openejb.server.httpd;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -25,22 +27,52 @@ import java.util.Map;
*/
public class HttpListenerRegistry implements HttpListener {
private final Map<String, HttpListener> registry = new LinkedHashMap<String, HttpListener>();
+ private final Map<String, Collection<HttpListener>> filterRegistry = new LinkedHashMap<String, Collection<HttpListener>>();
+ private final ThreadLocal<FilterListener> currentFilterListener = new ThreadLocal<FilterListener>();
public HttpListenerRegistry() {
}
public void onMessage(HttpRequest request, HttpResponse response) throws Exception {
- Map<String, HttpListener> listeners;
- synchronized (registry) {
- listeners = new HashMap<String, HttpListener>(registry);
+ final String path = request.getURI().getPath();
+ final FilterListener currentFL = currentFilterListener.get();
+
+ // first look filters
+ Map<String, Collection<HttpListener>> filters;
+ synchronized (filterRegistry) {
+ filters = new HashMap<String, Collection<HttpListener>>(filterRegistry);
}
- String path = request.getURI().getPath();
- for (Map.Entry<String, HttpListener> entry : listeners.entrySet()) {
- String pattern = entry.getKey();
- if (path.matches(pattern)) {
- entry.getValue().onMessage(request, response);
- break;
+ try {
+ boolean lastWasCurrent = false;
+ for (Map.Entry<String, Collection<HttpListener>> entry : filters.entrySet()) {
+ String pattern = entry.getKey();
+ for (HttpListener listener : entry.getValue()) {
+ if ((lastWasCurrent || currentFL == null) && path.matches(pattern)) {
+ listener.onMessage(request, response);
+ return;
+ }
+ lastWasCurrent = listener == currentFL;
+ }
+ }
+
+
+ // then others
+ Map<String, HttpListener> listeners;
+ synchronized (registry) {
+ listeners = new HashMap<String, HttpListener>(registry);
+ }
+
+ for (Map.Entry<String, HttpListener> entry : listeners.entrySet()) {
+ String pattern = entry.getKey();
+ if (path.matches(pattern)) {
+ entry.getValue().onMessage(request, response);
+ break;
+ }
+ }
+ } finally {
+ if (currentFL == null) {
+ currentFilterListener.remove();
}
}
}
@@ -58,4 +90,27 @@ public class HttpListenerRegistry implem
}
return listener;
}
+
+ public void addHttpFilter(HttpListener listener, String regex) {
+ synchronized (filterRegistry) {
+ if (!filterRegistry.containsKey(regex)) {
+ filterRegistry.put(regex, new ArrayList<HttpListener>());
+ }
+ filterRegistry.get(regex).add(listener);
+ }
+ }
+
+ public Collection<HttpListener> removeHttpFilter(String regex) {
+ synchronized (filterRegistry) {
+ return filterRegistry.remove(regex);
+ }
+ }
+
+ public void setOrigin(final FilterListener origin) {
+ if (origin == null) {
+ currentFilterListener.remove();
+ } else {
+ currentFilterListener.set(origin);
+ }
+ }
}
Modified: openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java (original)
+++ openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/HttpRequestImpl.java Mon Nov 12 13:50:17 2012
@@ -962,4 +962,15 @@ public class HttpRequestImpl implements
return getRequestURI();
}
}
+
+ public void initPathFromContext(final String context) {
+ if (!"/".equals(path)) { // already done
+ return;
+ }
+
+ final String rawPath = requestRawPath();
+ if (context != null) {
+ setPath(rawPath.substring(1 + context.length(), rawPath.length())); // 1 because of the first /
+ }
+ }
}
\ No newline at end of file
Modified: openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletListener.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletListener.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletListener.java (original)
+++ openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletListener.java Mon Nov 12 13:50:17 2012
@@ -31,10 +31,7 @@ public class ServletListener implements
public void onMessage(final HttpRequest request, final HttpResponse response) throws Exception {
if (request instanceof HttpRequestImpl) {
final HttpRequestImpl req = (HttpRequestImpl) request;
- final String rawPath = req.requestRawPath();
- if (context != null) {
- req.setPath(rawPath.substring(1 + context.length(), rawPath.length())); // 1 because of the first /
- }
+ req.initPathFromContext(context);
}
delegate.service(request, response);
}
Modified: openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletRequestAdapter.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletRequestAdapter.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletRequestAdapter.java (original)
+++ openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/ServletRequestAdapter.java Mon Nov 12 13:50:17 2012
@@ -397,4 +397,7 @@ public class ServletRequestAdapter imple
request.removeAttribute(s);
}
+ public HttpServletRequest getRequest() {
+ return request;
+ }
}
Modified: openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java?rev=1408286&r1=1408285&r2=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java (original)
+++ openejb/trunk/openejb/server/openejb-http/src/main/java/org/apache/openejb/server/httpd/util/HttpUtil.java Mon Nov 12 13:50:17 2012
@@ -19,10 +19,15 @@ package org.apache.openejb.server.httpd.
import org.apache.openejb.OpenEJBRuntimeException;
import org.apache.openejb.core.WebContext;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.server.httpd.FilterListener;
+import org.apache.openejb.server.httpd.HttpListener;
import org.apache.openejb.server.httpd.HttpListenerRegistry;
import org.apache.openejb.server.httpd.ServletListener;
+import javax.servlet.Filter;
+import javax.servlet.FilterConfig;
import javax.servlet.Servlet;
+import java.util.Collection;
import java.util.List;
public final class HttpUtil {
@@ -83,6 +88,39 @@ public final class HttpUtil {
wc.destroy(servlet);
}
+ public static boolean addFilter(final String classname, final WebContext wc, final String mapping, final FilterConfig config) {
+ final HttpListenerRegistry registry = SystemInstance.get().getComponent(HttpListenerRegistry.class);
+ if (registry == null || mapping == null) {
+ return false;
+ }
+
+ final FilterListener listener;
+ try {
+ listener = new FilterListener((Filter) wc.newInstance(wc.getClassLoader().loadClass(classname)), wc.getContextRoot());
+ listener.getDelegate().init(config);
+ } catch (Exception e) {
+ throw new OpenEJBRuntimeException(e);
+ }
+
+ registry.addHttpFilter(listener, pattern(wc.getContextRoot(), mapping));
+ return true;
+ }
+
+ public static void removeFilter(final String mapping, final WebContext wc) {
+ final HttpListenerRegistry registry = SystemInstance.get().getComponent(HttpListenerRegistry.class);
+ if (registry == null || mapping == null) {
+ return;
+ }
+
+ final Collection<HttpListener> filters = registry.removeHttpFilter(pattern(wc.getContextRoot(), mapping));
+ for (HttpListener listener : filters) {
+ final Filter filter = ((FilterListener) listener).getDelegate();
+ filter.destroy();
+ wc.destroy(filter);
+ }
+ filters.clear();
+ }
+
private static String pattern(final String contextRoot, final String mapping) {
String path = "";
if (contextRoot != null) {
Copied: openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java (from r1408118, openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.java)
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java?p2=openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java&p1=openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.java&r1=1408118&r2=1408286&rev=1408286&view=diff
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletRegistrationTest.java (original)
+++ openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/FilterRegistrationTest.java Mon Nov 12 13:50:17 2012
@@ -25,85 +25,103 @@ import org.apache.openejb.loader.IO;
import org.junit.Test;
import org.junit.runner.RunWith;
-import javax.ejb.EJB;
-import javax.ejb.Singleton;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
-import javax.servlet.annotation.WebServlet;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
@EnableServices({ "httpejbd" })
@RunWith(ApplicationComposer.class)
-public class ServletRegistrationTest {
+public class FilterRegistrationTest {
@Module
- @Classes({ TestServlet.class, TestServlet2.class, TestServlet3.class, TestServlet4.class, SomeEjb.class })
public WebApp app() {
return new WebApp()
- .contextRoot("servlet")
- .addServlet("test", TestServlet.class.getName(), "/touch");
+ .contextRoot("filter")
+ .addServlet("test", TestServlet.class.getName(), "/touch")
+ .addFilter("filter", TestFilter.class.getName(), "/touch")
+ .addFilter("filter2", TestFilter2.class.getName(), "/touch");
}
@Test
public void touch() throws IOException {
- assertEquals("touched", IO.slurp(new URL("http://localhost:4204/servlet/touch")));
- }
-
- @Test
- public void discover() throws IOException {
- assertEquals("discovered", IO.slurp(new URL("http://localhost:4204/servlet/discover")));
- }
-
- @Test
- public void wildcard() throws IOException {
- assertEquals("wildcard", IO.slurp(new URL("http://localhost:4204/servlet/bar/openejb")));
- }
-
- @Test
- public void injections() throws IOException {
- assertEquals("true", IO.slurp(new URL("http://localhost:4204/servlet/injection")));
+ assertEquals("http://ok/filter/touch", IO.slurp(new URL("http://localhost:4204/filter/touch")));
+ assertTrue(TestFilter.init);
+ assertTrue(TestFilter.ok);
+ assertTrue(TestFilter2.ok);
}
private static class TestServlet extends HttpServlet {
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
- resp.getWriter().write("touched");
+ resp.getWriter().write(req.getRequestURI());
}
}
- @WebServlet(urlPatterns = "/discover")
- private static class TestServlet2 extends HttpServlet {
+ private static class TestFilter implements Filter {
+ public static boolean ok = false;
+ private static boolean init = false;
+
@Override
- protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
- resp.getWriter().write("discovered");
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ init = true;
}
- }
- @WebServlet(urlPatterns = "/bar/*")
- private static class TestServlet3 extends HttpServlet {
@Override
- protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
- resp.getWriter().write("wildcard");
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+ ok = true;
+ try {
+ chain.doFilter(new HttpRequestImpl(new URI("http://ok/filter/touch")) {
+ @Override
+ public java.net.URI getURI() {
+ return super.getSocketURI();
+ }
+
+ @Override
+ public String getMethod() {
+ return "GET";
+ }
+
+ }, response);
+ } catch (URISyntaxException e) {
+ throw new ServletException(e);
+ }
+ }
+
+ @Override
+ public void destroy() {
+ System.out.println("destroyed");
}
}
- @WebServlet(urlPatterns = "/injection")
- private static class TestServlet4 extends HttpServlet {
- @EJB
- private SomeEjb ejb;
+ private static class TestFilter2 implements Filter {
+ public static boolean ok = false;
@Override
- protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
- resp.getWriter().write(Boolean.toString(ejb != null));
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ // no-op
}
- }
- @Singleton
- public static class SomeEjb {
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+ ok = true;
+ chain.doFilter(request, response);
+ }
+ @Override
+ public void destroy() {
+ // no-op
+ }
}
}
Added: openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletContextListenerRegistrationTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletContextListenerRegistrationTest.java?rev=1408286&view=auto
==============================================================================
--- openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletContextListenerRegistrationTest.java (added)
+++ openejb/trunk/openejb/server/openejb-http/src/test/java/org/apache/openejb/server/httpd/ServletContextListenerRegistrationTest.java Mon Nov 12 13:50:17 2012
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.server.httpd;
+
+import org.apache.openejb.jee.WebApp;
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.EnableServices;
+import org.apache.openejb.junit.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import java.io.IOException;
+
+import static org.junit.Assert.assertTrue;
+
+@EnableServices({ "httpejbd" })
+@RunWith(ApplicationComposer.class)
+public class ServletContextListenerRegistrationTest {
+ @Module
+ public WebApp app() {
+ return new WebApp()
+ .contextRoot("init")
+ .addListener(Initializer.class.getName());
+ }
+
+ @Test
+ public void check() throws IOException {
+ assertTrue(Initializer.init);
+ }
+
+ private static class Initializer implements ServletContextListener {
+ private static boolean init = false;
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ init = sce != null;
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent sce) {
+ System.out.println("destroyed");
+ }
+ }
+}