summaryrefslogtreecommitdiffstats
path: root/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src
diff options
context:
space:
mode:
Diffstat (limited to 'tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src')
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/InvalidCompositePath.java43
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletHostImpl.java142
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherInitException.java44
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/UnSupportedRuntimeException.java44
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebResourceScanExtender.java83
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImpl.java235
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/binding.axis2.scdl44
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/databinding.sdo.scdl34
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/tuscany/webapp.scdl139
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/Foo.java25
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/FooImpl.java25
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/ServletHostTestCase.java83
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImplTestCase.java68
-rw-r--r--tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/resources/testapp.scdl26
14 files changed, 1035 insertions, 0 deletions
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/InvalidCompositePath.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/InvalidCompositePath.java
new file mode 100644
index 0000000000..100bfa3560
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/InvalidCompositePath.java
@@ -0,0 +1,43 @@
+/*
+ * 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.TuscanyException;
+
+/**
+ * Denotes an invalid path representing a composite in application hierarchy
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidCompositePath extends TuscanyException {
+ public InvalidCompositePath() {
+ }
+
+ public InvalidCompositePath(String message) {
+ super(message);
+ }
+
+ public InvalidCompositePath(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public InvalidCompositePath(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletHostImpl.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletHostImpl.java
new file mode 100644
index 0000000000..8d556b4c2a
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletHostImpl.java
@@ -0,0 +1,142 @@
+/*
+ * 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.core.component.scope.HttpSessionScopeContainer.HTTP_IDENTIFIER;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.tuscany.core.component.event.HttpRequestEnded;
+import org.apache.tuscany.core.component.event.HttpRequestStart;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.apache.tuscany.host.servlet.ServletRequestInjector;
+import org.apache.tuscany.spi.annotation.Autowire;
+import org.apache.tuscany.spi.component.ScopeContainer;
+import org.apache.tuscany.spi.component.ScopeRegistry;
+import org.apache.tuscany.spi.component.WorkContext;
+import org.apache.tuscany.spi.event.Event;
+import org.apache.tuscany.spi.event.EventFilter;
+import org.apache.tuscany.spi.event.EventPublisher;
+import org.apache.tuscany.spi.event.RuntimeEventListener;
+import org.apache.tuscany.spi.host.ServletHost;
+import org.apache.tuscany.spi.model.Scope;
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Service;
+
+/**
+ * A <code>ServletHost</code> implementation that forwards requests to registered servlets
+ */
+@Service(ServletHost.class)
+public class ServletHostImpl implements ServletHost, ServletRequestInjector, EventPublisher {
+
+ protected Map<String, Servlet> servlets;
+
+ public ServletHostImpl() {
+ this.servlets = new HashMap<String, Servlet>();
+ }
+
+ @Init(eager = true)
+ public void init() {
+ }
+
+ protected ScopeRegistry registry = null;
+
+ @Autowire(required = false)
+ public void setSessionScopeContainer(ScopeRegistry registry) {
+ this.registry = registry;
+ }
+
+ WorkContext workContext = null;
+
+ @Autowire(required = false)
+ public void setWorkContext(WorkContext workContext) {
+ this.workContext = workContext;
+ }
+
+ public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
+ assert req instanceof HttpServletRequest : "implementation only supports HttpServletRequest";
+ String path = ((HttpServletRequest) req).getPathInfo();
+ Servlet servlet = servlets.get(path);
+ if (servlet == null) {
+ throw new IllegalStateException("No servlet registered for path: " + path);
+ }
+ servlet.service(req, resp);
+ }
+
+ public void registerMapping(String path, Servlet servlet) {
+ if (servlets.containsKey(path)) {
+ throw new IllegalStateException("Servlet already registered at path: " + path);
+ }
+ servlets.put(path, servlet);
+ }
+
+ public void unregisterMapping(String path) {
+ servlets.remove(path);
+ }
+
+ public void addListener(RuntimeEventListener listener) {
+ throw new UnSupportedRuntimeException("Not Supported");
+
+ }
+
+ public void addListener(EventFilter filter, RuntimeEventListener listener) {
+ throw new UnSupportedRuntimeException("Not Supported");
+
+ }
+
+ public void publish(Event event) {
+ if (null != registry && (event instanceof HttpSessionStart || event instanceof HttpSessionEnd)) {
+ ScopeContainer sc = registry.getScopeContainer(Scope.SESSION);
+ if (null != sc) {
+ sc.onEvent(event);
+
+ }
+ }
+ if (null != workContext) {
+ if (event instanceof HttpRequestStart) {
+ Object key = ((HttpRequestStart) event).getId();
+ if (null != key) {
+ workContext.setIdentifier(HTTP_IDENTIFIER, ((HttpRequestStart) event).getId());
+ } else { // new request with no session.
+ workContext.clearIdentifier(HTTP_IDENTIFIER);
+ }
+ } else if (event instanceof HttpRequestEnded) {
+ workContext.clearIdentifier(HTTP_IDENTIFIER);
+
+ }
+
+ }
+
+ }
+
+ public void removeListener(RuntimeEventListener listener) {
+ throw new UnSupportedRuntimeException("Not Supported");
+
+ }
+
+} \ No newline at end of file
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherInitException.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherInitException.java
new file mode 100644
index 0000000000..6e0726c801
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherInitException.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Thrown when an error is encountered booting the runtme in a web app environment
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServletLauncherInitException extends TuscanyRuntimeException {
+
+ public ServletLauncherInitException() {
+ }
+
+ public ServletLauncherInitException(String message) {
+ super(message);
+ }
+
+ public ServletLauncherInitException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ServletLauncherInitException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/UnSupportedRuntimeException.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/UnSupportedRuntimeException.java
new file mode 100644
index 0000000000..9cfa7345d6
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/UnSupportedRuntimeException.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Thrown when an error is encountered booting the runtme in a web app environment
+ *
+ * @version $Rev: 439728 $ $Date: 2006-09-03 02:02:44 -0400 (Sun, 03 Sep 2006) $
+ */
+public class UnSupportedRuntimeException extends TuscanyRuntimeException {
+
+ public UnSupportedRuntimeException() {
+ }
+
+ public UnSupportedRuntimeException(String message) {
+ super(message);
+ }
+
+ public UnSupportedRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public UnSupportedRuntimeException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebResourceScanExtender.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebResourceScanExtender.java
new file mode 100644
index 0000000000..23d7b29e55
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebResourceScanExtender.java
@@ -0,0 +1,83 @@
+/*
+ * 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.MalformedURLException;
+import java.util.Set;
+
+import javax.servlet.ServletContext;
+
+import org.osoa.sca.annotations.Init;
+import org.osoa.sca.annotations.Property;
+
+import org.apache.tuscany.core.services.extension.AbstractExtensionDeployer;
+import org.apache.tuscany.runtime.webapp.WebappRuntimeInfo;
+import org.apache.tuscany.spi.annotation.Autowire;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebResourceScanExtender extends AbstractExtensionDeployer {
+ private final WebappRuntimeInfo runtimeInfo;
+ private final String path;
+
+ public WebResourceScanExtender(@Autowire WebappRuntimeInfo runtimeInfo,
+ @Property(name = "path") String path) {
+ this.runtimeInfo = runtimeInfo;
+ this.path = path;
+ }
+
+ @Init
+ public void init() {
+ ServletContext servletContext = runtimeInfo.getServletContext();
+ Set extensions = servletContext.getResourcePaths(path);
+ if (extensions == null || extensions.isEmpty()) {
+ // no extensions in this webapp
+ return;
+ }
+
+ for (Object e : extensions) {
+ String extensionPath = (String) e;
+ URL extension;
+ try {
+ extension = servletContext.getResource(extensionPath);
+ } catch (MalformedURLException e1) {
+ // web container should return an invalid URL for a path it gave us
+ throw new AssertionError();
+ }
+
+ String name = extensionPath.substring(path.length());
+ if (name.charAt(name.length() - 1) == '/') {
+ // TODO support exploded extensions
+ continue;
+ }
+ if (name.charAt(0) == '.') {
+ // hidden file
+ continue;
+ }
+
+ int lastDot = name.lastIndexOf('.');
+ if (lastDot != -1) {
+ name = name.substring(0, lastDot);
+ }
+ deployExtension(name, extension);
+ }
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImpl.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImpl.java
new file mode 100644
index 0000000000..c921b35050
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImpl.java
@@ -0,0 +1,235 @@
+/*
+ * 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.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSessionEvent;
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.core.bootstrap.Bootstrapper;
+import org.apache.tuscany.core.bootstrap.DefaultBootstrapper;
+import org.apache.tuscany.core.component.event.HttpRequestEnded;
+import org.apache.tuscany.core.component.event.HttpRequestStart;
+import org.apache.tuscany.core.component.event.HttpSessionEnd;
+import org.apache.tuscany.core.component.event.HttpSessionStart;
+import org.apache.tuscany.core.component.event.RequestEnd;
+import org.apache.tuscany.core.component.event.RequestStart;
+import org.apache.tuscany.core.launcher.CompositeContextImpl;
+import org.apache.tuscany.core.monitor.MonitorFactoryUtil;
+import org.apache.tuscany.core.runtime.AbstractRuntime;
+import org.apache.tuscany.host.MonitorFactory;
+import org.apache.tuscany.host.RuntimeInfo;
+import org.apache.tuscany.host.servlet.ServletRequestInjector;
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+import org.apache.tuscany.spi.bootstrap.RuntimeComponent;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.deployer.Deployer;
+import org.apache.tuscany.spi.event.EventPublisher;
+import org.osoa.sca.SCA;
+
+/**
+ * Bootstrapper for the Tuscany runtime in a web application host. 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 bootstrapper launches the runtime, booting system extensions and applications, according to the servlet
+ * parameters defined in {@link Constants}. When the runtime is instantiated, it is placed in the servlet context with
+ * the attribute {@link Constants.RUNTIME_ATTRIBUTE}. The runtime implements {@link WebappRuntime} so that filters and
+ * servlets loaded in the parent web app classloader may pass events and requests to it.
+ * <p/>
+ * By default, the top-most application composite component will be returned when "non-managed" web application code
+ * such as JSPs call {@link org.osoa.sca.CurrentCompositeContext}. If a composite deeper in the hierarchy should be
+ * returned instead, the <code>web.xml</code> must contain an entry for {@link Constants.CURRENT_COMPOSITE_PATH_PARAM}
+ * whose value is a component path expression using '/' as a delimeter such as foo/bar/baz.
+ *
+ * @version $$Rev$$ $$Date$$
+ */
+
+public class WebappRuntimeImpl extends AbstractRuntime implements WebappRuntime {
+ private ServletContext servletContext;
+
+
+ private ServletRequestInjector requestInjector;
+ private CompositeContextImpl context;
+ private RuntimeComponent runtime;
+ private CompositeComponent systemComponent;
+ private CompositeComponent tuscanySystem;
+ private CompositeComponent application;
+
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ public void setServletContext(ServletContext servletContext) {
+ this.servletContext = servletContext;
+ }
+
+ public void initialize() {
+ ClassLoader bootClassLoader = getClass().getClassLoader();
+
+ // Read optional system monitor factory classname
+ MonitorFactory mf = getMonitorFactory();
+
+
+ XMLInputFactory xmlFactory = XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", bootClassLoader);
+
+ Bootstrapper bootstrapper = new DefaultBootstrapper(mf, xmlFactory);
+ runtime = bootstrapper.createRuntime();
+ runtime.start();
+ systemComponent = runtime.getSystemComponent();
+
+ // register the runtime info provided by the host
+ // FIXME andyp@bea.com -- autowire appears to need an exact type match,
+ // hence the need to register this twice
+ systemComponent.registerJavaObject(RuntimeInfo.COMPONENT_NAME,
+ RuntimeInfo.class,
+ (WebappRuntimeInfo) getRuntimeInfo());
+ systemComponent.registerJavaObject(WebappRuntimeInfo.COMPONENT_NAME,
+ WebappRuntimeInfo.class,
+ (WebappRuntimeInfo) getRuntimeInfo());
+
+ // register the monitor factory provided by the host
+ systemComponent.registerJavaObject("MonitorFactory", MonitorFactory.class, mf);
+
+ systemComponent.start();
+
+ if (getSystemScdl() == null) {
+ throw new TuscanyInitException("Could not find system SCDL");
+ }
+
+ try {
+ // deploy the system scdl
+ Deployer deployer = bootstrapper.createDeployer();
+ tuscanySystem = deploySystemScdl(deployer,
+ systemComponent,
+ ComponentNames.TUSCANY_SYSTEM,
+ getSystemScdl(),
+ bootClassLoader);
+ tuscanySystem.start();
+
+ requestInjector = (ServletRequestInjector) tuscanySystem.getSystemChild("servletHost").getServiceInstance();
+
+ // switch to the system deployer
+ deployer = (Deployer) tuscanySystem.getSystemChild("deployer").getServiceInstance();
+
+ if (getApplicationScdl() == null) {
+ throw new TuscanyInitException("Could not find application SCDL");
+ }
+
+ application = deployApplicationScdl(deployer,
+ runtime.getRootComponent(),
+ getApplicationName(),
+ getApplicationScdl(),
+ getHostClassLoader());
+ application.start();
+
+ context = new CompositeContextImpl(application);
+ } catch (Exception e) {
+ throw new ServletLauncherInitException(e);
+ }
+ }
+
+ public void destroy() {
+ context = null;
+ if (application != null) {
+ application.stop();
+ application = null;
+ }
+ if (tuscanySystem != null) {
+ tuscanySystem.stop();
+ tuscanySystem = null;
+ }
+ if (systemComponent != null) {
+ systemComponent.stop();
+ systemComponent = null;
+ }
+ if (runtime != null) {
+ runtime.stop();
+ runtime = null;
+ }
+ }
+
+ public SCA getContext() {
+ return context;
+ }
+
+ public ServletRequestInjector getRequestInjector() {
+ return requestInjector;
+ }
+
+ public void sessionCreated(HttpSessionEvent event) {
+ HttpSessionStart startSession = new HttpSessionStart(this, event.getSession().getId());
+ application.publish(startSession);
+ ((EventPublisher)requestInjector).publish(startSession);
+ }
+
+ public void sessionDestroyed(HttpSessionEvent event) {
+ HttpSessionEnd endSession = new HttpSessionEnd(this, event.getSession().getId());
+ application.publish(endSession);
+ ((EventPublisher)requestInjector).publish(endSession);
+ }
+
+ public void httpRequestStarted(Object sessionid) {
+ HttpRequestStart httpRequestStart = new HttpRequestStart(this, sessionid);
+ application.publish(httpRequestStart);
+ ((EventPublisher)requestInjector).publish(httpRequestStart);
+ }
+
+ public void httpRequestEnded(Object sessionid) {
+ HttpRequestEnded httpRequestEnded = new HttpRequestEnded(this, sessionid);
+ application.publish(httpRequestEnded);
+ ((EventPublisher)requestInjector).publish(httpRequestEnded);
+ }
+
+
+ public void startRequest() {
+ application.publish(new RequestStart(this));
+ }
+
+ public void stopRequest() {
+ application.publish(new RequestEnd(this));
+ }
+
+ /**
+ * Returns a monitor factory for the funtime
+ *
+ * @param loggingLevel
+ */
+ private MonitorFactory getMonitorFactory(String loggingLevel) {
+ String factoryName = "org.apache.tuscany.core.monitor.NullMonitorFactory";
+ Map<String, Object> props = null;
+ if (loggingLevel != null) {
+ factoryName = "org.apache.tuscany.core.monitor.JavaLoggingMonitorFactory";
+ props = new HashMap<String, Object>();
+ Level level = Level.SEVERE;
+ try {
+ level = Level.parse(loggingLevel);
+ } catch (IllegalArgumentException e) {
+ // ignore bad loggingLevel
+ }
+ props.put("bundleName", "SystemMessages");
+ props.put("defaultLevel", level);
+ }
+
+ return MonitorFactoryUtil.createMonitorFactory(factoryName, props);
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/binding.axis2.scdl b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/binding.axis2.scdl
new file mode 100644
index 0000000000..7e6b39f800
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/binding.axis2.scdl
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!-- Axis2 based WebService binding extension -->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2"
+ xmlns:tuscany="http://incubator.apache.org/tuscany/xmlns/1.0-incubator-M2"
+ name="org.apache.tuscany.binding.axis2">
+
+ <!-- [rfeng] Commented it out for now. When this SCDL is loaded, the DependencyLoader component
+ has not been initiated yet. We may need to play with initLevel setting -->
+ <!--
+ <tuscany:dependency>
+ <group>axis2</group>
+ <artifact>axis2-core</artifact>
+ <version>SNAPSHOT</version>
+ </tuscany:dependency>
+ -->
+
+ <component name="webservice.bindingLoader">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.WebServiceBindingLoader"/>
+ </component>
+
+ <component name="webservice.axis2.bindingBuilder">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.Axis2BindingBuilder"/>
+ </component>
+
+</composite>
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/databinding.sdo.scdl b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/databinding.sdo.scdl
new file mode 100644
index 0000000000..3296b40f66
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/sca/databinding.sdo.scdl
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!--
+ import.sdo configuration
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2"
+ name="org.apache.tuscany.databinding.sdo">
+
+ <!-- import.sdo element loader implementations -->
+ <component name="elementLoader.import.sdo">
+ <system:implementation.system class="org.apache.tuscany.databinding.sdo.ImportSDOLoader"/>
+ </component>
+
+</composite>
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/tuscany/webapp.scdl b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/tuscany/webapp.scdl
new file mode 100644
index 0000000000..3cb2a03dea
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/main/resources/META-INF/tuscany/webapp.scdl
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!--
+ Default system configuration for the launcher environment.
+
+ $Rev$ $Date$
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:system="http://incubator.apache.org/tuscany/xmlns/system/1.0-incubator-M2"
+ name="org.apache.tuscany.runtime.webapp.System">
+
+ <!-- Component that provides the Deployer service -->
+ <component name="deployer">
+ <system:implementation.system class="org.apache.tuscany.core.deployer.DeployerImpl"/>
+ </component>
+
+ <!-- Work management -->
+ <component name="workContext">
+ <system:implementation.system class="org.apache.tuscany.core.component.WorkContextImpl"/>
+ </component>
+
+ <!-- Wire service -->
+ <component name="wireService">
+ <system:implementation.system class="org.apache.tuscany.core.wire.jdk.JDKWireService"/>
+ </component>
+
+ <!-- Scope infrastructure -->
+ <component name="scopeRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.ScopeRegistryImpl"/>
+ </component>
+
+ <!-- Builder and BuilderRegistry -->
+ <component name="builder">
+ <system:implementation.system class="org.apache.tuscany.core.builder.BuilderRegistryImpl"/>
+ </component>
+
+ <!-- Loader and LoaderRegistry -->
+ <component name="loader">
+ <system:implementation.system class="org.apache.tuscany.core.loader.LoaderRegistryImpl"/>
+ </component>
+
+ <!-- Introspector and IntrospectionRegistry -->
+ <component name="introspector">
+ <system:implementation.system class="org.apache.tuscany.core.implementation.IntrospectionRegistryImpl"/>
+ </component>
+
+ <!-- Connector infrastructure -->
+ <component name="connector">
+ <system:implementation.system class="org.apache.tuscany.core.builder.ConnectorImpl"/>
+ </component>
+
+ <component name="wirePostProcessorRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.builder.WirePostProcessorRegistryImpl"/>
+ </component>
+
+ <!-- Default scopes -->
+ <component name="scope.module">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.ModuleScopeObjectFactory"/>
+ </component>
+ <component name="scope.stateless">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.StatelessScopeObjectFactory"/>
+ </component>
+
+ <component name="scope.httpsession">
+ <system:implementation.system class="org.apache.tuscany.core.component.scope.HttpSessionScopeObjectFactory"/>
+ </component>
+
+ <!-- include loader configuration -->
+ <include name="org.apache.tuscany.launcher.Loader" scdlResource="org/apache/tuscany/core/loader.scdl"/>
+
+ <!-- include implementation processor configuration -->
+ <include name="org.apache.tuscany.launcher.Implementation" scdlResource="org/apache/tuscany/core/implementation.scdl"/>
+
+ <!-- Java interface definition language -->
+ <include name="org.apache.tuscany.launcher.InterfaceJava" scdlResource="org/apache/tuscany/core/interfaceJava.scdl"/>
+
+ <!-- include omposite implementation type -->
+ <include name="org.apache.tuscany.launcher.Composite" scdlResource="org/apache/tuscany/core/composite.scdl"/>
+
+ <!-- System implementation type -->
+ <include name="org.apache.tuscany.launcher.SystemImplementation" scdlResource="org/apache/tuscany/core/systemImplementation.scdl"/>
+
+ <!-- Java implementation type -->
+ <include name="org.apache.tuscany.launcher.JavaImplementation" scdlResource="org/apache/tuscany/core/javaImplementation.scdl"/>
+
+ <!-- Data Binding -->
+ <include name="org.apache.tuscany.launcher.DataBinding" scdlResource="org/apache/tuscany/core/databinding.scdl"/>
+
+ <!-- WorkScheduler service -->
+ <component name="workManager">
+ <system:implementation.system
+ class="org.apache.tuscany.core.services.work.jsr237.workmanager.ThreadPoolWorkManager"/>
+ <property name="poolSize">10</property>
+ </component>
+
+ <component name="workScheduler">
+ <system:implementation.system class="org.apache.tuscany.core.services.work.jsr237.Jsr237WorkScheduler"/>
+ </component>
+
+ <!-- Web app ServletHost -->
+ <component name="servletHost">
+ <system:implementation.system class="org.apache.tuscany.runtime.webapp.ServletHostImpl"/>
+ </component>
+
+ <component name="policyBuilderRegistry">
+ <system:implementation.system class="org.apache.tuscany.core.policy.PolicyBuilderRegistryImpl"/>
+ </component>
+
+ <component name="propertyFactory">
+ <system:implementation.system class="org.apache.tuscany.core.property.PropertyObjectFactoryImpl"/>
+ </component>
+
+ <component name="artifactRepository">
+ <system:implementation.system class="org.apache.tuscany.services.maven.MavenArtifactRepository"/>
+ <property name="remoteRepoUrl">http://repo1.maven.org/maven2,http://people.apache.org/repo/m2-incubating-repository,http://repo1.maven.org/maven,http://people.apache.org/repo/m2-snapshot-repository</property>
+ </component>
+
+ <component name="extender" initLevel="90">
+ <system:implementation.system class="org.apache.tuscany.runtime.webapp.WebResourceScanExtender"/>
+ <property name="path">/WEB-INF/tuscany/extensions/</property>
+ </component>
+</composite>
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/Foo.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/Foo.java
new file mode 100644
index 0000000000..75b49de188
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/Foo.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public interface Foo {
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/FooImpl.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/FooImpl.java
new file mode 100644
index 0000000000..dd938f2a58
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/FooImpl.java
@@ -0,0 +1,25 @@
+/*
+ * 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;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class FooImpl implements Foo {
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/ServletHostTestCase.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/ServletHostTestCase.java
new file mode 100644
index 0000000000..543be9b7df
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/ServletHostTestCase.java
@@ -0,0 +1,83 @@
+/*
+ * 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.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.verify;
+
+import javax.servlet.Servlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.TestCase;
+import org.easymock.EasyMock;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class ServletHostTestCase extends TestCase {
+
+ public void testDispatch() throws Exception {
+ HttpServletRequest req = createMock(HttpServletRequest.class);
+ expect(req.getPathInfo()).andReturn("foo");
+ replay(req);
+ HttpServletResponse res = createMock(HttpServletResponse.class);
+ Servlet servlet = createMock(Servlet.class);
+ servlet.service(req, res);
+ EasyMock.expectLastCall();
+ replay(servlet);
+ ServletHostImpl host = new ServletHostImpl();
+ host.registerMapping("foo", servlet);
+ host.service(req, res);
+ verify(servlet);
+ }
+
+ public void testDuplicateRegistration() throws Exception {
+ Servlet servlet = createMock(Servlet.class);
+ ServletHostImpl host = new ServletHostImpl();
+ host.registerMapping("foo", servlet);
+ try {
+ host.registerMapping("foo", servlet);
+ fail();
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ }
+
+ public void testUnregister() throws Exception {
+ HttpServletRequest req = createMock(HttpServletRequest.class);
+ expect(req.getPathInfo()).andReturn("foo");
+ replay(req);
+ HttpServletResponse res = createMock(HttpServletResponse.class);
+ Servlet servlet = createMock(Servlet.class);
+ replay(servlet);
+ ServletHostImpl host = new ServletHostImpl();
+ host.registerMapping("foo", servlet);
+ host.unregisterMapping("foo");
+ try {
+ host.service(req, res);
+ } catch (IllegalStateException e) {
+ // expected
+ }
+ verify(servlet);
+ }
+
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImplTestCase.java b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImplTestCase.java
new file mode 100644
index 0000000000..fe0269833e
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/java/org/apache/tuscany/runtime/webapp/WebappRuntimeImplTestCase.java
@@ -0,0 +1,68 @@
+/*
+ * 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 javax.servlet.ServletContext;
+
+import junit.framework.TestCase;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import org.apache.tuscany.core.monitor.NullMonitorFactory;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WebappRuntimeImplTestCase extends TestCase {
+ private URL applicationScdl;
+ private URL systemScdl;
+ private WebappRuntimeImpl runtime;
+ private ServletContext context;
+
+ /**
+ * Verifies the web app host is configured properly to perform a basic boot
+ */
+ public void testBootWithDefaults() throws Exception {
+ expect(context.getResourcePaths("/WEB-INF/tuscany/extensions/")).andReturn(null);
+ replay(context);
+ runtime.initialize();
+ verify(context);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ systemScdl = getClass().getResource("/META-INF/tuscany/webapp.scdl");
+ applicationScdl = getClass().getResource("/testapp.scdl");
+ context = createMock(ServletContext.class);
+
+ runtime = new WebappRuntimeImpl();
+ runtime.setRuntimeInfo(new WebappRuntimeInfoImpl(context, null, false));
+ runtime.setMonitorFactory(new NullMonitorFactory());
+ runtime.setHostClassLoader(getClass().getClassLoader());
+ runtime.setServletContext(context);
+ runtime.setSystemScdl(systemScdl);
+ runtime.setApplicationName("foo");
+ runtime.setApplicationScdl(applicationScdl);
+ }
+}
diff --git a/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/resources/testapp.scdl b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/resources/testapp.scdl
new file mode 100644
index 0000000000..9b5bda7fb6
--- /dev/null
+++ b/tags/java/sca/1.0-incubator-M2/runtime/webapp-host/src/test/resources/testapp.scdl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="testapp">
+
+ <component name="component">
+ <implementation.java class="org.apache.tuscany.runtime.webapp.FooImpl"/>
+ </component>
+
+</composite>