summaryrefslogtreecommitdiffstats
path: root/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany
diff options
context:
space:
mode:
Diffstat (limited to 'branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany')
-rw-r--r--branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/ContainerLoader.java100
-rw-r--r--branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TomcatHost.java53
-rw-r--r--branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyContextListener.java163
-rw-r--r--branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyHost.java185
-rw-r--r--branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyValve.java130
-rw-r--r--branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyWrapper.java43
6 files changed, 674 insertions, 0 deletions
diff --git a/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/ContainerLoader.java b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/ContainerLoader.java
new file mode 100644
index 0000000000..60c9a7961f
--- /dev/null
+++ b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/ContainerLoader.java
@@ -0,0 +1,100 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.tuscany.tomcat;
+
+import java.beans.PropertyChangeListener;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Loader;
+
+/**
+ * Implementation of a TomcatLoader that allows privileged servlets from the container
+ * classloader to be loaded into an unprivileged application. This allows the Tuscany
+ * integration code to add servlets to the application, for example, to handle web
+ * services requests.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContainerLoader implements Loader {
+ private static final String INFO = ContainerLoader.class.getName() + "/SNAPSHOT";
+ private final ClassLoader cl;
+ private Container container;
+
+ /**
+ * Constructor specifying the classloader to be used.
+ *
+ * @param cl the classloader this Loader wraps, typically the container classloader
+ */
+ public ContainerLoader(ClassLoader cl) {
+ this.cl = cl;
+ }
+
+ public void backgroundProcess() {
+ }
+
+ public ClassLoader getClassLoader() {
+ return cl;
+ }
+
+ public Container getContainer() {
+ return container;
+ }
+
+ public void setContainer(Container container) {
+ this.container = container;
+ }
+
+ public boolean getDelegate() {
+ return false;
+ }
+
+ public void setDelegate(boolean delegate) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getInfo() {
+ return INFO;
+ }
+
+ public boolean getReloadable() {
+ return false;
+ }
+
+ public void setReloadable(boolean reloadable) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void addRepository(String repository) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String[] findRepositories() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean modified() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TomcatHost.java b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TomcatHost.java
new file mode 100644
index 0000000000..8351da8edd
--- /dev/null
+++ b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TomcatHost.java
@@ -0,0 +1,53 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.tuscany.tomcat;
+
+import javax.servlet.Servlet;
+
+import org.osoa.sca.annotations.Scope;
+
+import org.apache.tuscany.core.webapp.ServletHost;
+
+/**
+ * SCA Component that acts as a proxy for the Tomcat Host container that created the runtime.
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("MODULE")
+public class TomcatHost implements ServletHost {
+ private TuscanyHost host;
+
+ public void setHost(TuscanyHost host) {
+ this.host = host;
+ }
+
+ public TuscanyHost getHost() {
+ return host;
+ }
+
+ public void registerMapping(String mapping, Servlet servlet) {
+ host.registerMapping(mapping, servlet);
+ }
+
+ public void unregisterMapping(String mapping) {
+ host.unregisterMapping(mapping);
+ }
+
+ public Servlet getMapping(String mapping) {
+ return host.getMapping(mapping);
+ }
+}
diff --git a/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyContextListener.java b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyContextListener.java
new file mode 100644
index 0000000000..be1efdc20e
--- /dev/null
+++ b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyContextListener.java
@@ -0,0 +1,163 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.tuscany.tomcat;
+
+import javax.servlet.ServletContext;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.util.StringManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.tuscany.common.resource.ResourceLoader;
+import org.apache.tuscany.common.resource.impl.ResourceLoaderImpl;
+import org.apache.tuscany.core.client.BootstrapHelper;
+import org.apache.tuscany.core.config.ConfigurationException;
+import org.apache.tuscany.core.config.ConfigurationLoadException;
+import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader;
+import org.apache.tuscany.core.context.CompositeContext;
+import org.apache.tuscany.core.context.EventException;
+import org.apache.tuscany.core.context.event.ModuleStart;
+import org.apache.tuscany.core.context.event.ModuleStop;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.ModuleComponent;
+import org.apache.tuscany.model.assembly.impl.AssemblyContextImpl;
+import org.apache.tuscany.model.assembly.loader.AssemblyModelLoader;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TuscanyContextListener implements LifecycleListener {
+ private static final Log log = LogFactory.getLog(TuscanyContextListener.class);
+ private static final StringManager sm = StringManager.getManager("org.apache.tuscany.tomcat");
+ private static final String TUSCANY_RUNTIME_NAME = RuntimeContext.class.getName();
+ public static final String MODULE_COMPONENT_NAME = "org.apache.tuscany.core.webapp.ModuleComponentContext";
+
+ private final AssemblyFactory modelFactory;
+ private final AssemblyModelLoader modelLoader;
+ private final RuntimeContext runtime;
+ private CompositeContext moduleContext;
+ private TuscanyValve valve;
+
+ public TuscanyContextListener(RuntimeContext runtimeContext, AssemblyFactory modelFactory, AssemblyModelLoader modelLoader) {
+ this.runtime = runtimeContext;
+ this.modelFactory = modelFactory;
+ this.modelLoader = modelLoader;
+ }
+
+ public void lifecycleEvent(LifecycleEvent event) {
+ String type = event.getType();
+ if (Lifecycle.AFTER_START_EVENT.equals(type)) {
+ startContext((Context) event.getLifecycle());
+ } else if (Lifecycle.STOP_EVENT.equals(type)) {
+ stopContext((Context) event.getLifecycle());
+ }
+ }
+
+ private void startContext(Context ctx) {
+ ClassLoader appLoader = ctx.getLoader().getClassLoader();
+ if (appLoader.getResource("sca.module") == null && (appLoader.getResource("webapp.composite") == null)) {
+ return;
+ }
+
+ log.info(sm.getString("context.configLoad", ctx.getName()));
+ try {
+ loadContext(ctx);
+ } catch (ConfigurationException e) {
+ log.error(sm.getString("context.configError"), e);
+ // todo mark application as unavailable
+ return;
+ }
+
+ try {
+ moduleContext.publish(new ModuleStart(this));
+ } catch (EventException e) {
+ log.error(sm.getString("context.moduleStartError"), e);
+ // todo unload module component from runtime
+ // todo mark application as unavailable
+ return;
+ } catch (RuntimeException e) {
+ log.error(sm.getString("context.unknownRuntimeException"), e);
+ // todo unload module component from runtime
+ throw e;
+ }
+
+ // add a valve to this context's pipeline that will associate the request with the runtime
+ if (valve == null) {
+ valve = new TuscanyValve(moduleContext);
+ } else {
+ valve.setContext(moduleContext);
+ valve.setEnabled(true);
+ }
+ ctx.getPipeline().addValve(valve);
+ // add the RuntimeContext in as a servlet context parameter
+ ServletContext servletContext = ctx.getServletContext();
+ servletContext.setAttribute(TUSCANY_RUNTIME_NAME, runtime);
+ servletContext.setAttribute(MODULE_COMPONENT_NAME, moduleContext);
+ }
+
+ private void loadContext(Context ctx) throws ConfigurationException {
+ ResourceLoader resourceLoader = new ResourceLoaderImpl(ctx.getLoader().getClassLoader());
+ ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+ Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
+ try {
+ AssemblyContextImpl modelContext = new AssemblyContextImpl(modelFactory, modelLoader, resourceLoader, ctx.getName());
+
+ ModuleComponentConfigurationLoader loader = BootstrapHelper.getConfigurationLoader(runtime.getSystemContext(), modelContext);
+
+ // Load the SCDL configuration of the application module
+ ModuleComponent moduleComponent;
+ try {
+ moduleComponent = loader.loadModuleComponent(ctx.getName(), ctx.getPath());
+ } catch (ConfigurationLoadException e) {
+
+ //FIXME This is a temporary tweak to allow both 0.9 sca.module file and new composite files
+ // to be loaded, if an sca.module file could not be found, look for a webapp.composite
+ // In the longer term we'll have to choose a fixed name for the webapp's main composite
+ // file, or define a way to configure that name
+ moduleComponent = loader.loadModuleComponent(ctx.getName(), "webapp");
+ }
+
+ // Register it under the root application context
+ CompositeContext rootContext = runtime.getRootContext();
+ rootContext.registerModelObject(moduleComponent);
+ moduleContext = (CompositeContext) rootContext.getContext(moduleComponent.getName());
+ //TODO remove the hack below
+ moduleContext.setAssemblyContext(modelContext);
+ } finally {
+ Thread.currentThread().setContextClassLoader(oldCl);
+ }
+ }
+
+ private void stopContext(Context ctx) {
+ if (moduleContext != null) {
+ moduleContext.publish(new ModuleStop(this));
+ }
+ CompositeContext rootContext = runtime.getRootContext();
+ rootContext.removeContext(moduleContext.getName());
+ valve.setEnabled(false);
+ //ctx.getPipeline().removeValve(valve);
+ //valve = null;
+ moduleContext.stop();
+ moduleContext = null;
+ // todo unload module component from runtime
+ }
+
+}
diff --git a/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyHost.java b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyHost.java
new file mode 100644
index 0000000000..37984ef40d
--- /dev/null
+++ b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyHost.java
@@ -0,0 +1,185 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.tuscany.tomcat;
+
+import javax.servlet.Servlet;
+
+import org.apache.catalina.Container;
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.util.StringManager;
+import org.apache.tomcat.util.buf.MessageBytes;
+import org.apache.tomcat.util.http.mapper.MappingData;
+
+import org.apache.tuscany.common.monitor.impl.NullMonitorFactory;
+import org.apache.tuscany.core.builder.ContextFactoryBuilderRegistry;
+import org.apache.tuscany.core.builder.impl.DefaultWireBuilder;
+import org.apache.tuscany.core.client.BootstrapHelper;
+import org.apache.tuscany.core.config.ConfigurationLoadException;
+import org.apache.tuscany.core.config.ModuleComponentConfigurationLoader;
+import org.apache.tuscany.core.context.CompositeContext;
+import org.apache.tuscany.core.context.SystemCompositeContext;
+import org.apache.tuscany.core.context.event.ModuleStart;
+import org.apache.tuscany.core.context.event.ModuleStop;
+import org.apache.tuscany.core.runtime.RuntimeContext;
+import org.apache.tuscany.core.runtime.RuntimeContextImpl;
+import org.apache.tuscany.core.webapp.ServletHost;
+import org.apache.tuscany.model.assembly.AssemblyContext;
+import org.apache.tuscany.model.assembly.AssemblyFactory;
+import org.apache.tuscany.model.assembly.ModuleComponent;
+import org.apache.tuscany.model.assembly.loader.AssemblyModelLoader;
+
+/**
+ * A specialied Tomcat Host that extends the Standardhost implementation and adds SCA capabilities.
+ * <p/>
+ * As children are added, they are examined for the presence of SCA configuration
+ * information and if any is found then the web application is treated as an
+ * SCA Module defintion which is used to create a ModuleComponent. The name of the
+ * context is used as the name of the ModuleComponent and its context path is used
+ * as the URI.
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings({"serial"})
+public class TuscanyHost extends StandardHost implements ServletHost {
+ private static final String SYSTEM_MODULE_COMPONENT = "org.apache.tuscany.core.system";
+
+ private static final StringManager sm = StringManager.getManager("org.apache.tuscany.tomcat");
+
+ private RuntimeContext runtime;
+ private AssemblyModelLoader modelLoader;
+ private AssemblyFactory modelFactory;
+
+ public synchronized void start() throws LifecycleException {
+ startRuntime();
+ super.start();
+ }
+
+ public synchronized void stop() throws LifecycleException {
+ super.stop();
+ stopRuntime();
+ }
+
+ private void startRuntime() {
+ // Create an assembly model context
+ AssemblyContext modelContext = BootstrapHelper.getModelContext(getClass().getClassLoader());
+ modelFactory = modelContext.getAssemblyFactory();
+ modelLoader = modelContext.getAssemblyLoader();
+
+ // Create and start the runtime
+ NullMonitorFactory monitorFactory = new NullMonitorFactory();
+ ContextFactoryBuilderRegistry builderRegistry = BootstrapHelper.bootstrapContextFactoryBuilders(monitorFactory);
+ runtime = new RuntimeContextImpl(monitorFactory, builderRegistry, new DefaultWireBuilder());
+ runtime.start();
+
+ // Load and start the system configuration
+ try {
+ SystemCompositeContext systemContext = runtime.getSystemContext();
+ BootstrapHelper.bootstrapStaxLoader(systemContext, modelContext);
+ ModuleComponentConfigurationLoader loader = BootstrapHelper.getConfigurationLoader(systemContext, modelContext);
+ ModuleComponent systemModuleComponent = loader.loadSystemModuleComponent(SYSTEM_MODULE_COMPONENT, SYSTEM_MODULE_COMPONENT);
+ CompositeContext context = BootstrapHelper.registerModule(systemContext, systemModuleComponent);
+ context.publish(new ModuleStart(this));
+
+ TomcatHost host = systemContext.resolveInstance(TomcatHost.class);
+ host.setHost(this);
+ } catch (ConfigurationLoadException e) {
+ getLogger().warn(sm.getString("runtime.loadSystemFailed", e.getResourceURI()), e);
+ return;
+ } catch (Exception e) {
+ getLogger().warn(sm.getString("runtime.registerSystemFailed"), e);
+ runtime.stop();
+ runtime = null;
+ return;
+ }
+
+ getLogger().info(sm.getString("runtime.started"));
+ }
+
+ private void stopRuntime() {
+ if (runtime == null) {
+ return;
+ }
+ runtime.getSystemContext().publish(new ModuleStop(this));
+
+ runtime.stop();
+ runtime = null;
+ getLogger().info(sm.getString("runtime.stopped"));
+ }
+
+ public synchronized void addChild(Container child) {
+ if (!(child instanceof StandardContext)) {
+ throw new IllegalArgumentException(sm.getString("tuscanyHost.notContext"));
+ }
+ StandardContext ctx = (StandardContext) child;
+ ctx.addLifecycleListener(new TuscanyContextListener(runtime, modelFactory, modelLoader));
+ super.addChild(child);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder(132);
+ if (getParent() != null) {
+ sb.append(getParent().toString()).append('.');
+ }
+ sb.append("TuscanyHost[").append(getName()).append(']');
+ return (sb.toString());
+ }
+
+ public void registerMapping(String mapping, Servlet servlet) {
+ Context ctx = map(mapping);
+ if (ctx == null) {
+ throw new UnsupportedOperationException("Cannot find context for mapping " + mapping);
+ }
+ String contextPath = ctx.getPath();
+ assert mapping.startsWith(contextPath);
+ mapping = mapping.substring(contextPath.length());
+ Wrapper wrapper = new TuscanyWrapper(servlet);
+ wrapper.setName(mapping.substring(0,mapping.lastIndexOf('/')));
+ ctx.addChild(wrapper);
+ wrapper.addMapping(mapping);
+ ctx.getMapper().addWrapper(mapping, wrapper, false);
+ }
+
+ public void unregisterMapping(String mapping) {
+ }
+
+ public Servlet getMapping(String mapping) {
+ Context ctx = map(mapping);
+ if (ctx == null) {
+ return null;
+ }
+ String contextPath = ctx.getPath();
+ assert mapping.startsWith(contextPath);
+
+ MappingData mappingData = new MappingData();
+ MessageBytes mb = MessageBytes.newInstance();
+ mb.setString(mapping);
+ try {
+ ctx.getMapper().map(mb, mappingData);
+ } catch (Exception e) {
+ return null;
+ }
+ if (!(mappingData.wrapper instanceof TuscanyWrapper)) {
+ return null;
+ }
+ TuscanyWrapper wrapper = (TuscanyWrapper) mappingData.wrapper;
+ return wrapper.getServlet();
+ }
+}
diff --git a/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyValve.java b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyValve.java
new file mode 100644
index 0000000000..352a04bde0
--- /dev/null
+++ b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyValve.java
@@ -0,0 +1,130 @@
+/**
+ *
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.tuscany.tomcat;
+
+import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.valves.ValveBase;
+import org.osoa.sca.CurrentModuleContext;
+import org.osoa.sca.ModuleContext;
+import org.osoa.sca.SCA;
+
+import org.apache.tuscany.core.context.CompositeContext;
+import org.apache.tuscany.core.context.event.HttpSessionBound;
+import org.apache.tuscany.core.context.event.RequestStart;
+import org.apache.tuscany.core.context.event.RequestEnd;
+import org.apache.tuscany.core.webapp.LazyHTTPSessionId;
+
+/**
+ * Valve that can be added to a pipeline to automatically set the SCA environment as each request is processed.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyValve extends ValveBase {
+ /**
+ * Name of the note that contains the request id
+ */
+ private static final String REQUEST_ID = "org.apache.tuscany.tomcat.REQUEST_ID";
+
+ private static final ContextBinder BINDER = new ContextBinder();
+
+ private CompositeContext moduleComponentContext;
+
+ private boolean enabled = true;
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public void setContext(CompositeContext moduleComponentContext) {
+ this.moduleComponentContext = moduleComponentContext;
+ }
+
+ public TuscanyValve(CompositeContext moduleComponentContext) {
+ this.moduleComponentContext = moduleComponentContext;
+ }
+
+ public void invoke(Request request, Response response) throws IOException, ServletException {
+ if (!enabled){
+ return;
+ }
+ Object oldRequestId = request.getNote(REQUEST_ID);
+ ModuleContext oldContext = CurrentModuleContext.getContext();
+ // bind the current module context to the thread for use by CurrentModuleContext
+ BINDER.setContext((ModuleContext) moduleComponentContext);
+ try {
+ if (oldRequestId != null) {
+ // the request has already been started, just invoke the next valve
+ next.invoke(request, response);
+ } else {
+ // tell the runtime a new request is starting
+ Object requestId = new Object();
+
+ HttpSession session = request.getSession(false);
+ if (session != null) {
+ // A session is already active
+ moduleComponentContext .publish(new HttpSessionBound(this,session));
+ } else {
+ // Create a lazy wrapper since a session is not yet active
+ moduleComponentContext.publish(new HttpSessionBound(this, new LazyHTTPSessionId(request)));
+ }
+
+ try {
+ moduleComponentContext.publish(new RequestStart(this, requestId));
+ } catch (Exception e) {
+ throw new ServletException(e.getMessage(), e);
+ }
+ request.setNote(REQUEST_ID, requestId);
+
+ try {
+ // invoke the next valve in the pipeline
+ next.invoke(request, response);
+ } finally {
+ // notify the runtime the request is ending
+ request.removeNote(REQUEST_ID);
+ try {
+ moduleComponentContext.publish(new RequestEnd(this, requestId));
+ } catch (Exception e) {
+ // the application already did its work, log and ignore
+ // todo log this exception
+ }
+ }
+ }
+ } finally {
+ // restore the previous module context onto the thread
+ BINDER.setContext(oldContext);
+ }
+ }
+
+ private static class ContextBinder extends SCA {
+ public void setContext(ModuleContext context) {
+ setModuleContext(context);
+ }
+
+ public void start() {
+ throw new AssertionError();
+ }
+
+ public void stop() {
+ throw new AssertionError();
+ }
+ }
+}
diff --git a/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyWrapper.java b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyWrapper.java
new file mode 100644
index 0000000000..de53ad4d45
--- /dev/null
+++ b/branches/java-post-M1/sca/tomcat/src/main/java/org/apache/tuscany/tomcat/TuscanyWrapper.java
@@ -0,0 +1,43 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * Licensed 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.tuscany.tomcat;
+
+import javax.servlet.Servlet;
+
+import org.apache.catalina.core.StandardWrapper;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TuscanyWrapper extends StandardWrapper {
+ private static final long serialVersionUID = 1L;
+
+ private final Servlet servlet;
+
+ public TuscanyWrapper(Servlet servlet) {
+ super();
+ this.servlet = servlet;
+ }
+
+ public synchronized Servlet loadServlet() {
+ return servlet;
+ }
+
+ public Servlet getServlet() {
+ return servlet;
+ }
+}