From bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a Mon Sep 17 00:00:00 2001 From: dims Date: Tue, 17 Jun 2008 00:23:01 +0000 Subject: Move Tuscany from Incubator to top level. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/tuscany/runtime/webapp/Constants.java | 89 +++++++++++++++ .../runtime/webapp/InvalidResourcePath.java | 31 ++++++ .../runtime/webapp/ServletLauncherMonitor.java | 33 ++++++ .../runtime/webapp/TuscanyContextListener.java | 110 ++++++++++++++++++ .../tuscany/runtime/webapp/TuscanyFilter.java | 75 +++++++++++++ .../runtime/webapp/TuscanyInitException.java | 48 ++++++++ .../runtime/webapp/TuscanyRequestListener.java | 76 +++++++++++++ .../tuscany/runtime/webapp/TuscanyServlet.java | 58 ++++++++++ .../runtime/webapp/TuscanySessionListener.java | 53 +++++++++ .../tuscany/runtime/webapp/WebappRuntime.java | 77 +++++++++++++ .../tuscany/runtime/webapp/WebappRuntimeInfo.java | 36 ++++++ .../runtime/webapp/WebappRuntimeInfoImpl.java | 67 +++++++++++ .../apache/tuscany/runtime/webapp/WebappUtil.java | 56 ++++++++++ .../tuscany/runtime/webapp/WebappUtilImpl.java | 124 +++++++++++++++++++++ 14 files changed, 933 insertions(+) create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java create mode 100644 branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java (limited to 'branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java') diff --git a/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java new file mode 100644 index 0000000000..28a4cc2ca3 --- /dev/null +++ b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/Constants.java @@ -0,0 +1,89 @@ +package org.apache.tuscany.runtime.webapp; + +/** + * Constants used by the web application booter + * + * @version $Rev$ $Date$ + */ +public final class Constants { + + /** + * 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"; + + /** + * Servlet context-param name for user-specified application SCDL path. + */ + static final String APPLICATION_SCDL_PATH_PARAM = "tuscany.applicationScdlPath"; + + /** + * Default application SCDL path. + */ + static final String APPLICATION_SCDL_PATH_DEFAULT = "/WEB-INF/default.scdl"; + + /** + * Servlet context-param name for setting if the runtime is online. + */ + static final String ONLINE_PARAM = "tuscany.online"; + + /** + * Context attribute to which the Tuscany runtime for this servlet context is stored. + */ + static final String RUNTIME_ATTRIBUTE = "tuscany.runtime"; + + /** + * Context attribute for storing the CompositeContext that should be bound to the thread.` + */ + @Deprecated + static final String CONTEXT_ATTRIBUTE = "tuscany.context"; + + /** + * 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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/InvalidResourcePath.java new file mode 100644 index 0000000000..3d1353de25 --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/ServletLauncherMonitor.java new file mode 100644 index 0000000000..5936240481 --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java new file mode 100644 index 0000000000..15f8133a3d --- /dev/null +++ b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyContextListener.java @@ -0,0 +1,110 @@ +/* + * 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 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.ONLINE_PARAM; +import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE; + +/** + * 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. + *

+ * 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. + *

+ * The web.xml 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 web.xml 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 + * /services. + * + * @version $Rev$ $Date$ + */ +public class TuscanyContextListener implements ServletContextListener { + + public void contextInitialized(ServletContextEvent event) { + ServletContext servletContext = event.getServletContext(); + WebappUtil utils = getUtils(servletContext); + try { + ClassLoader webappClassLoader = Thread.currentThread().getContextClassLoader(); + ClassLoader bootClassLoader = utils.getBootClassLoader(webappClassLoader); + WebappRuntime runtime = utils.getRuntime(bootClassLoader); + boolean online = Boolean.valueOf(utils.getInitParameter(ONLINE_PARAM, "true")); + WebappRuntimeInfo info = new WebappRuntimeInfoImpl(servletContext, + servletContext.getResource("/WEB-INF/tuscany/"), + online); + URL systemScdl = utils.getSystemScdl(bootClassLoader); + URL applicationScdl = utils.getApplicationScdl(webappClassLoader); + String name = utils.getApplicationName(); + + runtime.setServletContext(servletContext); + runtime.setRuntimeInfo(info); + runtime.setHostClassLoader(webappClassLoader); + runtime.setSystemScdl(systemScdl); + runtime.setApplicationName(name); + runtime.setApplicationScdl(applicationScdl); + runtime.initialize(); + + servletContext.setAttribute(RUNTIME_ATTRIBUTE, runtime); + } catch (TuscanyRuntimeException e) { + servletContext.log(e.getMessage(), e); + e.printStackTrace(); + throw e; + } catch (MalformedURLException e) { + servletContext.log(e.getMessage(), e); + e.printStackTrace(); + throw new TuscanyInitException(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 destorying runtume", e); + } + } + +} diff --git a/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java new file mode 100644 index 0000000000..58e3895bc7 --- /dev/null +++ b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyFilter.java @@ -0,0 +1,75 @@ +/* + * 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 org.osoa.sca.CompositeContext; +import org.osoa.sca.CurrentCompositeContext; + +import static org.apache.tuscany.runtime.webapp.Constants.RUNTIME_ATTRIBUTE; +import static org.apache.tuscany.runtime.webapp.Constants.CONTEXT_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 CompositeContext context; + 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"); + } + context = (CompositeContext) servletContext.getAttribute(CONTEXT_ATTRIBUTE); + if (context == null) { + throw new ServletException("No context specified"); + } + } + + public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) + throws IOException, ServletException { + CompositeContext oldContext = CurrentCompositeContext.setContext(context); + try { + runtime.startRequest(); + filterChain.doFilter(req, resp); + } finally { + CurrentCompositeContext.setContext(oldContext); + runtime.stopRequest(); + } + } + + public void destroy() { + context = null; + runtime = null; + } +} diff --git a/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyInitException.java new file mode 100644 index 0000000000..a929dd6307 --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyRequestListener.java new file mode 100644 index 0000000000..325532aef6 --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanyServlet.java new file mode 100644 index 0000000000..3132559fdd --- /dev/null +++ b/branches/pre-spec-changes/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 /services in the web.xml + *

+ * 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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/TuscanySessionListener.java new file mode 100644 index 0000000000..0335c7bc6a --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java new file mode 100644 index 0000000000..48b4ee8292 --- /dev/null +++ b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntime.java @@ -0,0 +1,77 @@ +/* + * 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.http.HttpServletRequest; +import javax.servlet.http.HttpSessionListener; + +import org.apache.tuscany.host.runtime.TuscanyRuntime; +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 { + /** + * 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 + */ + 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 + */ + void httpRequestStarted(HttpServletRequest request); + + /** + * Request has been ended with the given session id + */ + void httpRequestEnded(Object id); + +} diff --git a/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java new file mode 100644 index 0000000000..d08ae10e07 --- /dev/null +++ b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfo.java @@ -0,0 +1,36 @@ +/* + * 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 { + String COMPONENT_NAME = "WebappRuntimeInfo"; + /** + * Returns the ServletContext associated with this webapp runtime. + * + * @return the ServletContext associated with this webapp runtime. + */ + ServletContext getServletContext(); +} diff --git a/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappRuntimeInfoImpl.java new file mode 100644 index 0000000000..1f08fa2790 --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtil.java new file mode 100644 index 0000000000..263436bd96 --- /dev/null +++ b/branches/pre-spec-changes/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/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java b/branches/pre-spec-changes/runtime/webapp/webapp-api/src/main/java/org/apache/tuscany/runtime/webapp/WebappUtilImpl.java new file mode 100644 index 0000000000..fcaec7f8ac --- /dev/null +++ b/branches/pre-spec-changes/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; + } +} -- cgit v1.2.3