summaryrefslogtreecommitdiffstats
path: root/sandbox/old/contrib/runtime-webapp/webapp-api/src
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/old/contrib/runtime-webapp/webapp-api/src')
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java116
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java31
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java33
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java114
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java63
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java48
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java76
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java58
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java53
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java93
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java35
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java67
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java56
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java124
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyContextListenerTestCase.java113
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyFilterTestCase.java112
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyServletTestCase.java80
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanySessionListenerTestCase.java78
-rw-r--r--sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/WebappUtilTestCase.java131
19 files changed, 1481 insertions, 0 deletions
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java
new file mode 100644
index 0000000000..ef209c05ee
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java
@@ -0,0 +1,116 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+/**
+ * Constants used by the web application booter
+ *
+ * @version $Rev$ $Date$
+ */
+public final class Constants {
+
+ /**
+ * Name of the servlet context-param that should contain the component id for the webapp.
+ */
+ public static final String COMPOSITE_PARAM = "tuscany.composite";
+
+ /**
+ * Name of the servlet context-param that should contain the component id for the webapp.
+ */
+ public static final String COMPONENT_PARAM = "tuscany.component";
+
+ /**
+ * Servlet context-param name for user-specified application SCDL path.
+ */
+ static final String APPLICATION_SCDL_PATH_PARAM = "tuscany.applicationScdlPath";
+
+ /**
+ * Default application SCDL path.
+ */
+ public static final String APPLICATION_SCDL_PATH_DEFAULT = "/WEB-INF/default.scdl";
+
+ /**
+ * Servlet context-param name for setting if the runtime is online.
+ */
+ public static final String ONLINE_PARAM = "tuscany.online";
+
+ /**
+ * Name of the context attribute that contains the ComponentContext.
+ */
+ public static final String CONTEXT_ATTRIBUTE = "tuscany.context";
+
+ /**
+ * Name of the parameter that defines the name of webapp resource containing bootstrap jars.
+ */
+ static final String BOOTDIR_PARAM = "tuscany.bootDir";
+
+ /**
+ * Default value for BOOTDIR_PARAM.
+ */
+ static final String BOOTDIR_DEFAULT = "/WEB-INF/tuscany/boot";
+
+ /**
+ * Name of the parameter that defines the class to load to launch the runtime.
+ */
+ static final String RUNTIME_PARAM = "tuscany.runtimeImpl";
+
+ /**
+ * Name of the default webapp runtime implementation.
+ */
+ static final String RUNTIME_DEFAULT = "org.apache.tuscany.runtime.webapp.WebappRuntimeImpl";
+
+ /**
+ * Servlet context-param name for user-specified system SCDL path.
+ */
+ static final String SYSTEM_SCDL_PATH_PARAM = "tuscany.systemScdlPath";
+
+ /**
+ * Default webapp system SCDL path.
+ */
+ static final String SYSTEM_SCDL_PATH_DEFAULT = "META-INF/tuscany/webapp.scdl";
+
+ /**
+ * Context attribute to which the Tuscany runtime for this servlet context is stored.
+ */
+ static final String RUNTIME_ATTRIBUTE = "tuscany.runtime";
+
+ /**
+ * Servlet context-param name for the path to the composite to set as the webb app composite
+ */
+ static final String CURRENT_COMPOSITE_PATH_PARAM = "tuscany.currentCompositePath";
+
+ /**
+ * Servlet context-param name for user-specified system SCDL path.
+ */
+ static final String EXTENSION_SCDL_PATH_PARAM = "tuscany.extensionScdlPath";
+
+ /**
+ * Default path for extensions if no "extensionScdlPath param is specified
+ */
+ static final String DEFAULT_EXTENSION_PATH_PARAM = "/WEB-INF/tuscany/extensions";
+
+ /**
+ * Servlet context-param name for system monitoring level. Supported values are the names of statics defined in
+ * java.util.logging.Level. If absent, no monitoring will take place.
+ */
+ static final String SYSTEM_MONITORING_PARAM = "tuscany.monitoringLevel";
+
+ private Constants() {
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java
new file mode 100644
index 0000000000..3d1353de25
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java
@@ -0,0 +1,31 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+/**
+ * Denotes an invalid or non-existing path for a resource required by the runtime bootstrap
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidResourcePath extends TuscanyInitException {
+
+ public InvalidResourcePath(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java
new file mode 100644
index 0000000000..5936240481
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import org.apache.tuscany.api.annotation.LogLevel;
+
+/**
+ * A monitor interface used during runtime bootstrap
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ServletLauncherMonitor {
+
+ @LogLevel("DEBUG")
+ void deployExtension(String path);
+
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java
new file mode 100644
index 0000000000..dce4fa7393
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java
@@ -0,0 +1,114 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.net.URL;
+import java.net.URI;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+import org.apache.tuscany.host.runtime.ShutdownException;
+import static org.apache.tuscany.runtime.webapp.Constants.COMPOSITE_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.COMPONENT_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.ONLINE_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+import static org.apache.tuscany.runtime.webapp.Constants.APPLICATION_SCDL_PATH_DEFAULT;
+import static org.apache.tuscany.runtime.webapp.Constants.APPLICATION_SCDL_PATH_PARAM;
+
+/**
+ * Launches a Tuscany runtime in a web application, loading information from servlet context parameters. This listener
+ * manages one runtime per servlet context; the lifecycle of that runtime corresponds to the the lifecycle of the
+ * associated servlet context.
+ * <p/>
+ * The runtime is launched in a child classloader of the web application, thereby providing isolation between
+ * application and system artifacts. Application code only has access to the SCA API and may not reference Tuscany
+ * system artifacts directly.
+ * <p/>
+ * The <code>web.xml</code> of a web application embedding Tuscany must have entries for this listener and {@link
+ * TuscanySessionListener}. The latter notifies the runtime of session creation and expiration events through a
+ * "bridging" contract, {@link WebappRuntime}. The <code>web.xml</code> may also optionally be configured with entries
+ * for {@link TuscanyFilter} and {@link TuscanyServlet}. The former must be mapped to all urls that execute "unmanaged"
+ * code which accesses the Tuscany runtime though the SCA API, for example, JSPs and Servlets. The latter forwards
+ * service requests into the runtime, by default requests sent to URLs relative to the context path beginning with
+ * <code>/services</code>.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyContextListener implements ServletContextListener {
+
+ public void contextInitialized(ServletContextEvent event) {
+ ClassLoader webappClassLoader = Thread.currentThread().getContextClassLoader();
+ ServletContext servletContext = event.getServletContext();
+ WebappUtil utils = getUtils(servletContext);
+ try {
+ // FIXME work this out from the servlet context
+ String defaultComposite = "http://locahost/sca";
+ URI compositeId = new URI(utils.getInitParameter(COMPOSITE_PARAM, defaultComposite));
+ URI componentId = new URI(utils.getInitParameter(COMPONENT_PARAM, "webapp"));
+ String scdlPath = utils.getInitParameter(APPLICATION_SCDL_PATH_PARAM, APPLICATION_SCDL_PATH_DEFAULT);
+ URL scdl = servletContext.getResource(scdlPath);
+
+ boolean online = Boolean.valueOf(utils.getInitParameter(ONLINE_PARAM, "true"));
+ WebappRuntimeInfo info = new WebappRuntimeInfoImpl(servletContext,
+ servletContext.getResource("/WEB-INF/tuscany/"),
+ online);
+ ClassLoader bootClassLoader = utils.getBootClassLoader(webappClassLoader);
+ URL systemScdl = utils.getSystemScdl(bootClassLoader);
+
+ WebappRuntime runtime = utils.getRuntime(bootClassLoader);
+ runtime.setServletContext(servletContext);
+ runtime.setRuntimeInfo(info);
+ runtime.setHostClassLoader(webappClassLoader);
+ runtime.setSystemScdl(systemScdl);
+ runtime.initialize();
+ servletContext.setAttribute(RUNTIME_ATTRIBUTE, runtime);
+
+ runtime.deploy(compositeId, scdl, componentId);
+ } catch (TuscanyRuntimeException e) {
+ servletContext.log(e.getMessage(), e);
+ e.printStackTrace();
+ throw e;
+ } catch (Throwable e) {
+ servletContext.log(e.getMessage(), e);
+ e.printStackTrace();
+ throw new TuscanyInitException(e);
+ }
+ }
+
+ protected WebappUtil getUtils(ServletContext servletContext) {
+ return new WebappUtilImpl(servletContext);
+ }
+
+ public void contextDestroyed(ServletContextEvent event) {
+ ServletContext servletContext = event.getServletContext();
+ WebappRuntime runtime = (WebappRuntime) servletContext.getAttribute(RUNTIME_ATTRIBUTE);
+ if (runtime == null) {
+ return;
+ }
+ servletContext.removeAttribute(RUNTIME_ATTRIBUTE);
+ try {
+ runtime.destroy();
+ } catch (ShutdownException e) {
+ servletContext.log("Error destroying runtume", e);
+ }
+ }
+
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java
new file mode 100644
index 0000000000..e1433014b2
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java
@@ -0,0 +1,63 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.ServletContext;
+
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+
+/**
+ * Maps an incoming request and the current composite context to the composite component for the web application. This
+ * filter must be applied to all web application urls that execute unmanaged code (e.g. JSPs and Servlets) which
+ * accesses the Tuscany runtime.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyFilter implements Filter {
+ private WebappRuntime runtime;
+
+ public void init(FilterConfig config) throws ServletException {
+ ServletContext servletContext = config.getServletContext();
+ runtime = (WebappRuntime) servletContext.getAttribute(RUNTIME_ATTRIBUTE);
+ if (runtime == null) {
+ throw new ServletException("Tuscany is not configured for the web application");
+ }
+ }
+
+ public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
+ throws IOException, ServletException {
+ try {
+ runtime.startRequest();
+ filterChain.doFilter(req, resp);
+ } finally {
+ runtime.stopRequest();
+ }
+ }
+
+ public void destroy() {
+ runtime = null;
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java
new file mode 100644
index 0000000000..a929dd6307
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import org.apache.tuscany.api.TuscanyRuntimeException;
+
+/**
+ * Exception indicating that there was a problem starting the Tuscany runtime.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyInitException extends TuscanyRuntimeException {
+ public TuscanyInitException(String string) {
+ super(string);
+ }
+
+ public TuscanyInitException(String message, String identifier) {
+ super(message, identifier);
+ }
+
+ public TuscanyInitException(String string, Throwable throwable) {
+ super(string, throwable);
+ }
+
+ public TuscanyInitException(String message, String identifier, Throwable cause) {
+ super(message, identifier, cause);
+ }
+
+ public TuscanyInitException(Throwable throwable) {
+ super(throwable);
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java
new file mode 100644
index 0000000000..325532aef6
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java
@@ -0,0 +1,76 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+/**
+ * Notifies the Tuscany runtime of session creation and expiration events.
+ *
+ * @version $Rev: 441961 $ $Date: 2006-09-10 11:48:29 -0400 (Sun, 10 Sep 2006) $
+ */
+public class TuscanyRequestListener implements ServletRequestListener {
+ private WebappRuntime runtime;
+
+ public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
+
+ final ServletContext context = servletRequestEvent.getServletContext();
+ getRuntime(context);
+ ServletRequest servletRequest = servletRequestEvent.getServletRequest();
+ if (servletRequest instanceof HttpServletRequest) {
+ HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
+ HttpSession session = httpServletRequest.getSession(false);
+ runtime.httpRequestEnded(session == null ? null : session.getId());
+
+ }
+
+ }
+
+ public void requestInitialized(ServletRequestEvent servletRequestEvent) {
+
+ final ServletContext context = servletRequestEvent.getServletContext();
+ getRuntime(context);
+ ServletRequest servletRequest = servletRequestEvent.getServletRequest();
+ if (servletRequest instanceof HttpServletRequest) {
+ runtime.httpRequestStarted((HttpServletRequest) servletRequest);
+
+ }
+
+ }
+
+ protected WebappRuntime getRuntime(final ServletContext context) {
+ if (runtime == null) {
+
+ runtime = (WebappRuntime) context.getAttribute(RUNTIME_ATTRIBUTE);
+ if (runtime == null) {
+ context.log("requestInitialized", new ServletException("Tuscany runtime not configured"));
+ return null;
+ }
+ }
+ return runtime;
+ }
+} \ No newline at end of file
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java
new file mode 100644
index 0000000000..3132559fdd
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java
@@ -0,0 +1,58 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.io.IOException;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.tuscany.host.servlet.ServletRequestInjector;
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+
+/**
+ * A servlet that forwards requests intended for SCA services into the Tuscany runtime via a ServletRequestInjector.
+ * This servlet is typically mapped to relative paths beginning with <code>/services</code> in the <code>web.xml</code>
+ * <p/>
+ * TODO a better URL mapping scheme out to be implemented that corresponds to the SCA specification
+ */
+public class TuscanyServlet extends HttpServlet {
+ private static final long serialVersionUID = 1L;
+
+ private ServletRequestInjector requestInjector;
+
+ @Override
+ public void init(ServletConfig config) throws ServletException {
+ ServletContext servletContext = config.getServletContext();
+ WebappRuntime runtime = (WebappRuntime) servletContext.getAttribute(RUNTIME_ATTRIBUTE);
+ if (runtime == null) {
+ throw new ServletException("Tuscany runtime not configured for web application");
+ }
+ requestInjector = runtime.getRequestInjector();
+ }
+
+ @Override
+ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
+ requestInjector.service(req, res);
+ }
+
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java
new file mode 100644
index 0000000000..0335c7bc6a
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java
@@ -0,0 +1,53 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSessionEvent;
+import javax.servlet.http.HttpSessionListener;
+
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+
+/**
+ * Notifies the Tuscany runtime of session creation and expiration events.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanySessionListener implements HttpSessionListener {
+ private WebappRuntime runtime;
+
+ public void sessionCreated(HttpSessionEvent event) {
+ if (runtime == null) {
+ ServletContext context = event.getSession().getServletContext();
+ runtime = (WebappRuntime) context.getAttribute(RUNTIME_ATTRIBUTE);
+ if (runtime == null) {
+ context.log("Error on session creation", new ServletException("Tuscany runtime not configured"));
+ return;
+ }
+ }
+ runtime.sessionCreated(event);
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ if (runtime != null) {
+ runtime.sessionDestroyed(event);
+ }
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java
new file mode 100644
index 0000000000..b74cc6e67e
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java
@@ -0,0 +1,93 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.net.URI;
+import java.net.URL;
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.tuscany.host.runtime.TuscanyRuntime;
+import org.apache.tuscany.host.runtime.InitializationException;
+import org.apache.tuscany.host.servlet.ServletRequestInjector;
+
+/**
+ * The contract for artifacts loaded in the web application classloader to comminicate with the Tuscany runtime loaded
+ * in a child classloader. For example, filters and listeners may use this interface to notify the runtime of the web
+ * container events.
+ *
+ * @version $Rev$ $Date$
+ * @see TuscanyFilter
+ * @see TuscanySessionListener
+ */
+public interface WebappRuntime extends HttpSessionListener, TuscanyRuntime<WebappRuntimeInfo> {
+ /**
+ * Returns the ServletContext associated with this runtime.
+ *
+ * @return the ServletContext associated with this runtime
+ */
+ ServletContext getServletContext();
+
+ /**
+ * Sets the ServletContext associated with this runtime.
+ *
+ * @param servletContext the ServletContext associated with this runtime
+ */
+ void setServletContext(ServletContext servletContext);
+
+ /**
+ * Returns the request injector for the runtime
+ * @return the runtime's request injector
+ */
+ ServletRequestInjector getRequestInjector();
+
+ /**
+ * Notification that the web application has begun servicing a request
+ */
+ void startRequest();
+
+ /**
+ * Notification that the web application has stopped servicing a request
+ */
+ void stopRequest();
+
+ /**
+ * Request has been started for the given request.
+ * @param request the servlet request
+ */
+ void httpRequestStarted(HttpServletRequest request);
+
+ /**
+ * Request has been ended with the given session id.
+ * @param id the session id
+ */
+ void httpRequestEnded(Object id);
+
+ /**
+ * Temporary method for deploying SCDL supplied with an application to the runtime.
+ *
+ * @param compositeId the id of the component that the supplied SCDL should implement
+ * @param applicationScdl the location of an application composite
+ * @param componentId the id of the component that should be bound to the webapp
+ * @throws InitializationException if there was a problem initializing the composite
+ */
+ @Deprecated
+ void deploy(URI compositeId, URL applicationScdl, URI componentId) throws InitializationException;
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java
new file mode 100644
index 0000000000..3047a30bb0
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java
@@ -0,0 +1,35 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tuscany.host.RuntimeInfo;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface WebappRuntimeInfo extends RuntimeInfo {
+ /**
+ * Returns the ServletContext associated with this webapp runtime.
+ *
+ * @return the ServletContext associated with this webapp runtime.
+ */
+ ServletContext getServletContext();
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java
new file mode 100644
index 0000000000..1f08fa2790
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.io.File;
+import java.net.URL;
+import java.net.URI;
+import javax.servlet.ServletContext;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebappRuntimeInfoImpl implements WebappRuntimeInfo {
+ private final ServletContext servletContext;
+ private final URL baseURL;
+ private final boolean online;
+
+ public WebappRuntimeInfoImpl(ServletContext servletContext, URL baseURL, boolean online) {
+ this.servletContext = servletContext;
+ this.baseURL = baseURL;
+ this.online = online;
+ }
+
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ public URL getBaseURL() {
+ return baseURL;
+ }
+
+ public File getInstallDirectory() {
+ return new File("");
+ }
+
+ public File getApplicationRootDirectory() {
+ return new File("");
+ }
+
+ public boolean isOnline() {
+ return online;
+ }
+
+ public URI getDomain() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getRuntimeId() {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java
new file mode 100644
index 0000000000..263436bd96
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java
@@ -0,0 +1,56 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface WebappUtil {
+
+ String getApplicationName();
+
+ WebappRuntime getRuntime(ClassLoader bootClassLoader) throws TuscanyInitException;
+
+ /**
+ * Return the classloader that should be used to boot the Tuscany runtime. This will be a child of the web
+ * application's ClassLoader.
+ *
+ * @param webappClassLoader the web application's classloader
+ * @return a classloader that can be used to load the Tuscany runtime classes
+ */
+ ClassLoader getBootClassLoader(ClassLoader webappClassLoader) throws InvalidResourcePath;
+
+ URL getSystemScdl(ClassLoader bootClassLoader) throws InvalidResourcePath;
+
+ URL getApplicationScdl(ClassLoader bootClassLoader) throws InvalidResourcePath;
+
+ URL getScdlURL(String path, ClassLoader classLoader) throws MalformedURLException;
+
+ /**
+ * Return a init parameter from the servlet context or provide a default.
+ *
+ * @param name the name of the parameter
+ * @param value the default value
+ * @return the value of the specified parameter, or the default if not defined
+ */
+ String getInitParameter(String name, String value);
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java
new file mode 100644
index 0000000000..fcaec7f8ac
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java
@@ -0,0 +1,124 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Set;
+import javax.servlet.ServletContext;
+
+import static org.apache.tuscany.runtime.webapp.Constants.APPLICATION_SCDL_PATH_DEFAULT;
+import static org.apache.tuscany.runtime.webapp.Constants.APPLICATION_SCDL_PATH_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.BOOTDIR_DEFAULT;
+import static org.apache.tuscany.runtime.webapp.Constants.BOOTDIR_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_DEFAULT;
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.SYSTEM_SCDL_PATH_DEFAULT;
+import static org.apache.tuscany.runtime.webapp.Constants.SYSTEM_SCDL_PATH_PARAM;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebappUtilImpl implements WebappUtil {
+ private final ServletContext servletContext;
+
+ public WebappUtilImpl(ServletContext servletContext) {
+ this.servletContext = servletContext;
+ }
+
+ public WebappRuntime getRuntime(ClassLoader bootClassLoader) throws TuscanyInitException {
+ try {
+ String className = getInitParameter(RUNTIME_PARAM, RUNTIME_DEFAULT);
+ return (WebappRuntime) bootClassLoader.loadClass(className).newInstance();
+ } catch (InstantiationException e) {
+ throw new TuscanyInitException(e);
+ } catch (IllegalAccessException e) {
+ throw new TuscanyInitException(e);
+ } catch (ClassNotFoundException e) {
+ throw new TuscanyInitException("Runtime Implementation not found", e);
+ }
+ }
+
+ public ClassLoader getBootClassLoader(ClassLoader webappClassLoader) throws InvalidResourcePath {
+ String bootDirName = getInitParameter(BOOTDIR_PARAM, BOOTDIR_DEFAULT);
+ Set paths = servletContext.getResourcePaths(bootDirName);
+ if (paths == null) {
+ // nothing in boot directory, assume everything is in the webapp classloader
+ return webappClassLoader;
+ }
+ URL[] urls = new URL[paths.size()];
+ int i = 0;
+ for (Object path : paths) {
+ try {
+ urls[i++] = servletContext.getResource((String) path);
+ } catch (MalformedURLException e) {
+ throw new InvalidResourcePath(APPLICATION_SCDL_PATH_PARAM, path.toString(), e);
+ }
+ }
+ return new URLClassLoader(urls, webappClassLoader);
+ }
+
+ public URL getSystemScdl(ClassLoader bootClassLoader) throws InvalidResourcePath {
+ String path = getInitParameter(SYSTEM_SCDL_PATH_PARAM, SYSTEM_SCDL_PATH_DEFAULT);
+ try {
+ return getScdlURL(path, bootClassLoader);
+ } catch (MalformedURLException e) {
+ throw new InvalidResourcePath(SYSTEM_SCDL_PATH_PARAM, path, e);
+ }
+ }
+
+ public String getApplicationName() {
+ String name = servletContext.getServletContextName();
+ if (name == null) {
+ name = "application";
+ }
+ return name;
+ }
+
+ public URL getApplicationScdl(ClassLoader bootClassLoader) throws InvalidResourcePath {
+ String path = getInitParameter(APPLICATION_SCDL_PATH_PARAM, APPLICATION_SCDL_PATH_DEFAULT);
+ try {
+ return getScdlURL(path, bootClassLoader);
+ } catch (MalformedURLException e) {
+ throw new InvalidResourcePath(APPLICATION_SCDL_PATH_PARAM, path, e);
+ }
+ }
+
+ public URL getScdlURL(String path, ClassLoader classLoader) throws MalformedURLException {
+ URL ret = null;
+ if (path.charAt(0) == '/') {
+ // user supplied an absolute path - look up as a webapp resource
+ ret = servletContext.getResource(path);
+ }
+ if (ret == null) {
+ // user supplied a relative path - look up as a boot classpath resource
+ ret = classLoader.getResource(path);
+ }
+ return ret;
+ }
+
+ public String getInitParameter(String name, String value) {
+ String result = servletContext.getInitParameter(name);
+ if (result != null && result.length() != 0) {
+ return result;
+ }
+ return value;
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyContextListenerTestCase.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyContextListenerTestCase.java
new file mode 100644
index 0000000000..aa237da01c
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyContextListenerTestCase.java
@@ -0,0 +1,113 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URI;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+import junit.framework.TestCase;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.eq;
+import static org.easymock.classextension.EasyMock.expect;
+import static org.easymock.classextension.EasyMock.isA;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+
+import static org.apache.tuscany.runtime.webapp.Constants.APPLICATION_SCDL_PATH_PARAM;
+import static org.apache.tuscany.runtime.webapp.Constants.APPLICATION_SCDL_PATH_DEFAULT;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TuscanyContextListenerTestCase extends TestCase {
+ private String contextName;
+ private ServletContext context;
+ private TuscanyContextListener listener;
+ private ClassLoader cl;
+ private ClassLoader bootClassLoader;
+ private URL systemUrl;
+ private URL scdl;
+ private WebappUtil utils;
+ private String compositeId;
+
+ public void testInitializationUsingDefaults() throws Exception {
+ ServletContextEvent event = createMock(ServletContextEvent.class);
+ expect(event.getServletContext()).andReturn(context);
+ replay(event);
+
+ WebappRuntime runtime = createMock(WebappRuntime.class);
+ expect(utils.getBootClassLoader(cl)).andReturn(bootClassLoader);
+ expect(utils.getInitParameter("tuscany.composite", compositeId)).andReturn(compositeId);
+ expect(utils.getInitParameter("tuscany.component", contextName)).andReturn(contextName);
+ expect(utils.getInitParameter("tuscany.online", "true")).andReturn("true");
+ expect(utils.getInitParameter(APPLICATION_SCDL_PATH_PARAM, APPLICATION_SCDL_PATH_DEFAULT))
+ .andReturn(APPLICATION_SCDL_PATH_DEFAULT);
+ expect(utils.getRuntime(bootClassLoader)).andReturn(runtime);
+ expect(utils.getSystemScdl(bootClassLoader)).andReturn(systemUrl);
+ replay(utils);
+
+ expect(context.getResource("/WEB-INF/tuscany/")).andReturn(null);
+ expect(context.getResource(APPLICATION_SCDL_PATH_DEFAULT)).andReturn(scdl);
+ context.setAttribute(eq(Constants.RUNTIME_ATTRIBUTE), isA(WebappRuntime.class));
+ replay(context);
+ replay(cl);
+ replay(bootClassLoader);
+ expect(listener.getUtils(context)).andReturn(utils);
+ replay(listener);
+ runtime.setServletContext(context);
+ runtime.setRuntimeInfo(isA(WebappRuntimeInfo.class));
+ runtime.setHostClassLoader(cl);
+ runtime.setSystemScdl(systemUrl);
+ runtime.initialize();
+ runtime.deploy(URI.create(compositeId), scdl, URI.create(contextName));
+ replay(runtime);
+
+ ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(cl);
+ listener.contextInitialized(event);
+ } finally {
+ Thread.currentThread().setContextClassLoader(oldCl);
+ }
+ verify(event);
+ verify(utils);
+ verify(context);
+ verify(listener);
+ verify(cl);
+ verify(bootClassLoader);
+ verify(runtime);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ Method getUtilsMethod = TuscanyContextListener.class.getDeclaredMethod("getUtils", ServletContext.class);
+ utils = createMock(WebappUtil.class);
+ listener = createMock(TuscanyContextListener.class, new Method[]{getUtilsMethod});
+ context = createMock(ServletContext.class);
+ cl = createMock(ClassLoader.class);
+ bootClassLoader = createMock(ClassLoader.class);
+ systemUrl = new URL("file:/system.scdl");
+ scdl = new URL("file:/app.scdl");
+ contextName = "webapp";
+ compositeId = "http://locahost/sca";
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyFilterTestCase.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyFilterTestCase.java
new file mode 100644
index 0000000000..9d811df46c
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyFilterTestCase.java
@@ -0,0 +1,112 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.io.IOException;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class TuscanyFilterTestCase extends TestCase {
+ private TuscanyFilter filter;
+ private FilterConfig config;
+ private ServletContext servletContext;
+ private WebappRuntime runtime;
+ private ServletRequest request;
+ private ServletResponse response;
+ private FilterChain chain;
+
+ public void testFilterInit() {
+ EasyMock.expect(config.getServletContext()).andReturn(servletContext);
+ EasyMock.expect(servletContext.getAttribute(RUNTIME_ATTRIBUTE)).andReturn(runtime);
+
+ EasyMock.replay(servletContext);
+ EasyMock.replay(config);
+ EasyMock.replay(runtime);
+ try {
+ filter.init(config);
+ } catch (ServletException e) {
+ fail(e.getMessage());
+ }
+ EasyMock.verify(servletContext);
+ EasyMock.verify(config);
+ EasyMock.verify(runtime);
+ }
+
+ public void testFilterInitWithNoRuntimeConfigured() {
+ EasyMock.expect(config.getServletContext()).andReturn(servletContext);
+ EasyMock.expect(servletContext.getAttribute(RUNTIME_ATTRIBUTE)).andReturn(null);
+
+ EasyMock.replay(servletContext);
+ EasyMock.replay(config);
+ EasyMock.replay(runtime);
+ try {
+ filter.init(config);
+ fail("Expected a ServletException");
+ } catch (ServletException e) {
+ // OK
+ }
+ EasyMock.verify(servletContext);
+ EasyMock.verify(config);
+ EasyMock.verify(runtime);
+ }
+
+ public void testContextIsAssociatedWithThread() throws ServletException, IOException {
+ EasyMock.expect(config.getServletContext()).andReturn(servletContext);
+ EasyMock.expect(servletContext.getAttribute(RUNTIME_ATTRIBUTE)).andReturn(runtime);
+ EasyMock.replay(servletContext);
+ EasyMock.replay(config);
+ filter.init(config);
+
+ chain.doFilter(EasyMock.same(request), EasyMock.same(response));
+ EasyMock.replay(chain);
+ runtime.startRequest();
+ runtime.stopRequest();
+ EasyMock.replay(runtime);
+ try {
+ filter.doFilter(request, response, chain);
+ } catch (IOException e) {
+ fail(e.getMessage());
+ }
+ EasyMock.verify(chain);
+ EasyMock.verify(runtime);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ filter = new TuscanyFilter();
+ config = EasyMock.createMock(FilterConfig.class);
+ servletContext = EasyMock.createMock(ServletContext.class);
+ runtime = EasyMock.createMock(WebappRuntime.class);
+ request = EasyMock.createMock(ServletRequest.class);
+ response = EasyMock.createMock(ServletResponse.class);
+ chain = EasyMock.createMock(FilterChain.class);
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyServletTestCase.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyServletTestCase.java
new file mode 100644
index 0000000000..5213ae9cb1
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanyServletTestCase.java
@@ -0,0 +1,80 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+
+import junit.framework.TestCase;
+import org.apache.tuscany.host.servlet.ServletRequestInjector;
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+import org.easymock.EasyMock;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+/**
+ * Verifies {@link TuscanyServlet} properly services a request
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanyServletTestCase extends TestCase {
+
+ public void testRequestInjection() throws Exception {
+ ServletRequest req = createNiceMock(ServletRequest.class);
+ ServletResponse resp = createNiceMock(ServletResponse.class);
+ ServletRequestInjector injector = createMock(ServletRequestInjector.class);
+ injector.service(eq(req), eq(resp));
+ EasyMock.replay(injector);
+ WebappRuntime runtime = createMock(WebappRuntime.class);
+ expect(runtime.getRequestInjector()).andReturn(injector);
+ replay(runtime);
+ ServletContext context = createNiceMock(ServletContext.class);
+ EasyMock.expect(context.getAttribute(RUNTIME_ATTRIBUTE)).andReturn(runtime);
+ EasyMock.replay(context);
+ TuscanyServlet servlet = new TuscanyServlet();
+ ServletConfig config = createMock(ServletConfig.class);
+ expect(config.getServletContext()).andReturn(context);
+ replay(config);
+ servlet.init(config);
+ servlet.service(req, resp);
+ verify(context);
+ verify(injector);
+ }
+
+ public void testRuntimeNotConfigured() throws Exception {
+ ServletContext context = createNiceMock(ServletContext.class);
+ TuscanyServlet servlet = new TuscanyServlet();
+ ServletConfig config = createMock(ServletConfig.class);
+ expect(config.getServletContext()).andReturn(context);
+ replay(config);
+ try {
+ servlet.init(config);
+ fail();
+ } catch (ServletException e) {
+ //expected
+ }
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanySessionListenerTestCase.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanySessionListenerTestCase.java
new file mode 100644
index 0000000000..cdce50cc2b
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/TuscanySessionListenerTestCase.java
@@ -0,0 +1,78 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionEvent;
+
+import junit.framework.TestCase;
+import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE;
+import org.easymock.EasyMock;
+
+/**
+ * Verifies {@link org.apache.tuscany.runtime.webapp.TuscanySessionListener} notifies the runtime of session events
+ *
+ * @version $Rev$ $Date$
+ */
+public class TuscanySessionListenerTestCase extends TestCase {
+
+ public void testSessionPropagated() throws Exception {
+ WebappRuntime runtime = EasyMock.createNiceMock(WebappRuntime.class);
+ runtime.sessionCreated(EasyMock.isA(HttpSessionEvent.class));
+ runtime.sessionDestroyed(EasyMock.isA(HttpSessionEvent.class));
+ EasyMock.replay(runtime);
+ ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+ EasyMock.expect(context.getAttribute(RUNTIME_ATTRIBUTE)).andReturn(runtime);
+ EasyMock.replay(context);
+ HttpSession session = EasyMock.createNiceMock(HttpSession.class);
+ EasyMock.expect(session.getServletContext()).andReturn(context);
+ EasyMock.replay(session);
+ HttpSessionEvent event = new HttpSessionEvent(session);
+ TuscanySessionListener listener = new TuscanySessionListener();
+ listener.sessionCreated(event);
+ listener.sessionDestroyed(event);
+ EasyMock.verify(context);
+ EasyMock.verify(runtime);
+ }
+
+ /**
+ * Verifies an error is logged when no runtime is configured
+ *
+ * @throws Exception
+ */
+ public void testRuntimeNotConfigured() throws Exception {
+ ServletContext context = EasyMock.createNiceMock(ServletContext.class);
+ context.log(EasyMock.isA(String.class), EasyMock.isA(ServletException.class));
+ EasyMock.replay(context);
+ TuscanySessionListener listener = new TuscanySessionListener();
+ HttpSession session = EasyMock.createNiceMock(HttpSession.class);
+ EasyMock.expect(session.getServletContext()).andReturn(context);
+ EasyMock.replay(session);
+ HttpSessionEvent event = new HttpSessionEvent(session);
+ listener.sessionCreated(event);
+ EasyMock.verify(context);
+ }
+
+ public void testSessionDestroyedBeforeCreated() throws Exception {
+ TuscanySessionListener listener = new TuscanySessionListener();
+ listener.sessionDestroyed(null);
+ }
+}
diff --git a/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/WebappUtilTestCase.java b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/WebappUtilTestCase.java
new file mode 100644
index 0000000000..f865a4e740
--- /dev/null
+++ b/sandbox/old/contrib/runtime-webapp/webapp-api/src/test/java/org/apache/tuscany/runtime/webapp/WebappUtilTestCase.java
@@ -0,0 +1,131 @@
+/*
+ * 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.tuscany.runtime.webapp;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.servlet.ServletContext;
+
+import junit.framework.TestCase;
+import static org.easymock.classextension.EasyMock.*;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebappUtilTestCase extends TestCase {
+ private ServletContext context;
+ private WebappUtilImpl listener;
+ private ClassLoader cl;
+ private URL systemUrl;
+
+
+ public void testGetInitParameterWhenSpecified() {
+ String name = "name";
+ String value = "default";
+ expect(context.getInitParameter(name)).andReturn(value);
+ replay(context);
+
+ assertEquals(value, listener.getInitParameter(name, "default"));
+ verify(context);
+ }
+
+ public void testGetInitParameterUsingDefault() {
+ String name = "name";
+ String value = "default";
+ expect(context.getInitParameter(name)).andReturn(null);
+ replay(context);
+
+ assertEquals(value, listener.getInitParameter(name, value));
+ verify(context);
+ }
+
+ public void testGetInitParameterWithZeroLength() {
+ String name = "name";
+ String value = "default";
+ expect(context.getInitParameter(name)).andReturn("");
+ replay(context);
+
+ assertEquals(value, listener.getInitParameter(name, value));
+ verify(context);
+ }
+
+ public void testGetScdlFromWebapp() throws MalformedURLException {
+ String path = "/WEB-INF/test";
+ expect(context.getResource(path)).andReturn(systemUrl);
+ replay(context);
+ replay(cl);
+ assertSame(systemUrl, listener.getScdlURL(path, cl));
+ verify(context);
+ verify(cl);
+ }
+
+ public void testGetScdlFromWebappMissing() throws MalformedURLException {
+ String path = "/WEB-INF/test";
+ expect(context.getResource(path)).andReturn(null);
+ replay(context);
+ expect(cl.getResource(path)).andReturn(null);
+ replay(cl);
+ assertNull(listener.getScdlURL(path, cl));
+ verify(context);
+ verify(cl);
+ }
+
+ public void testGetScdlFromWebappMalformed() throws MalformedURLException {
+ String path = "/WEB-INF/test";
+ expect(context.getResource(path)).andThrow(new MalformedURLException());
+ replay(context);
+ replay(cl);
+ try {
+ listener.getScdlURL(path, cl);
+ fail();
+ } catch (MalformedURLException e) {
+ // OK
+ }
+ verify(context);
+ verify(cl);
+ }
+
+ public void testGetScdlFromClasspath() throws MalformedURLException {
+ String path = "META-INF/test";
+ replay(context);
+ expect(cl.getResource(path)).andReturn(systemUrl);
+ replay(cl);
+ assertSame(systemUrl, listener.getScdlURL(path, cl));
+ verify(context);
+ verify(cl);
+ }
+
+ public void testGetScdlFromClasspathMissing() throws MalformedURLException {
+ String path = "META-INF/test";
+ replay(context);
+ expect(cl.getResource(path)).andReturn(null);
+ replay(cl);
+ assertNull(listener.getScdlURL(path, cl));
+ verify(context);
+ verify(cl);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ context = createMock(ServletContext.class);
+ listener = new WebappUtilImpl(context);
+ cl = createMock(ClassLoader.class);
+ systemUrl = new URL("file:/system.scdl");
+ }
+}