Author: kentam
Date: Thu Jul 20 11:16:32 2006
New Revision: 424013

URL: http://svn.apache.org/viewvc?rev=424013&view=rev
Log:
Added a servlet listener that launches the SCA runtime so it can be used by 
webapps.  More info on usage will be posted to the dev list.


Added:
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/ServletLauncherListener.java
   (with props)
Modified:
    incubator/tuscany/java/sca/core/pom.xml
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/Launcher.java
    
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/MainLauncher.java
    
incubator/tuscany/java/sca/test/src/main/java/org/apache/tuscany/test/SCATestCase.java

Modified: incubator/tuscany/java/sca/core/pom.xml
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/core/pom.xml?rev=424013&r1=424012&r2=424013&view=diff
==============================================================================
--- incubator/tuscany/java/sca/core/pom.xml (original)
+++ incubator/tuscany/java/sca/core/pom.xml Thu Jul 20 11:16:32 2006
@@ -61,9 +61,12 @@
         </dependency>
 
         <dependency>
-            <groupId>tomcat</groupId>
+            <groupId>javax.servlet</groupId>
             <artifactId>servlet-api</artifactId>
+            <version>2.4</version>
+            <scope>compile</scope>
         </dependency>
+
         <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-jta_1.0.1B_spec</artifactId>

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/Launcher.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/Launcher.java?rev=424013&r1=424012&r2=424013&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/Launcher.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/Launcher.java
 Thu Jul 20 11:16:32 2006
@@ -38,17 +38,36 @@
 import 
org.apache.tuscany.core.implementation.system.component.SystemCompositeComponent;
 
 /**
- * Support class for launcher implementations.
+ * Basic launcher implementation.
  *
  * @version $Rev: 417136 $ $Date: 2006-06-26 03:54:48 -0400 (Mon, 26 Jun 2006) 
$
  */
 public class Launcher {
+    // REVIEW: ([EMAIL PROTECTED]) Perhaps this should be null / have no 
default?
+    // It seems to me it would very unusual (ie, uncommonly-simplistic) for 
the system classloader to be the desired
+    // application loader, and we might be better off requiring it to be 
injected.
     private ClassLoader applicationLoader = ClassLoader.getSystemClassLoader();
     private String className;
     private RuntimeComponent runtime;
     private Deployer deployer;
 
     /**
+     * A conventional META-INF based location for the system SCDL.  Refers to 
a location
+     * on the classloader used to load this class.
+     *
+     * @see #bootRuntime(String)
+     */
+    public static final String METAINF_SYSTEM_SCDL_PATH = 
"/META-INF/tuscany/system.scdl";
+
+    /**
+     * A conventional META-INF based location for the application SCDL.  
Refers to a location
+     * on the application classloader.
+     *
+     * @see #bootApplication(String)
+     */
+    public static final String METAINF_APPLICATION_SCDL_PATH = 
"META-INF/sca/default.scdl";
+
+    /**
      * Returns the classloader for application classes.
      *
      * @return the classloader for application classes
@@ -58,7 +77,8 @@
     }
 
     /**
-     * Set the classloader to be used for application classes.
+     * Set the classloader to be used for application classes.  You should 
almost always supply your own
+     * application classloader, based on the hosting environment that the 
runtime is embedded in.
      *
      * @param applicationLoader the classloader to be used for application 
classes
      */
@@ -139,7 +159,16 @@
         this.className = className;
     }
 
-    public CompositeComponent<?> bootRuntime() throws LoaderException {
+    /**
+     * Boots the runtime defined by the specified SCDL, which will be
+     * loaded using the classloader of this class.
+     *
+     * @see   METAINF_SYSTEM_SCDL_PATH
+     * @param systemScdlPath a resource path to the SCDL defining the system.
+     * @return a CompositeComponent for the newly booted runtime system
+     * @throws LoaderException
+     */
+    public CompositeComponent<?> bootRuntime(String systemScdlPath) throws 
LoaderException {
         ClassLoader systemClassLoader = getClass().getClassLoader();
         XMLInputFactory xmlFactory = 
XMLInputFactory.newInstance("javax.xml.stream.XMLInputFactory", 
systemClassLoader);
         Bootstrapper bootstrapper = new DefaultBootstrapper(new 
NullMonitorFactory(), xmlFactory);
@@ -156,7 +185,7 @@
 
         // create a ComponentDefinition to represent the component we are 
going to deploy
         SystemCompositeImplementation moduleImplementation = new 
SystemCompositeImplementation();
-        URL scdl = getClass().getResource("/META-INF/tuscany/system.scdl");
+        URL scdl = getClass().getResource(systemScdlPath);
         if (scdl == null) {
             throw new LoaderException("No system scdl found");
         }
@@ -176,12 +205,21 @@
         return composite;
     }
 
-    public CompositeComponent<?> bootApplication() throws LoaderException {
+    /**
+     * Boots the application defined by the specified SCDL, which will be
+     * loaded using the application loader ((@link #getApplicationLoader}).
+     *
+     * @see   METAINF_APPLICATION_SCDL_PATH
+     * @param appScdlPath a resource path to the SCDL defining the application
+     * @return a CompositeComponent for the newly booted application
+     * @throws LoaderException
+     */
+    public CompositeComponent<?> bootApplication(String appScdlPath) throws 
LoaderException {
         ClassLoader applicationLoader = getApplicationLoader();
 
         // create a ComponentDefinition to represent the component we are 
going to deploy
         SystemCompositeImplementation impl = new 
SystemCompositeImplementation();
-        URL scdl = applicationLoader.getResource("META-INF/sca/default.scdl");
+        URL scdl = applicationLoader.getResource(appScdlPath);
         if (scdl == null) {
             throw new LoaderException("No application scdl found");
         }

Modified: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/MainLauncher.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/MainLauncher.java?rev=424013&r1=424012&r2=424013&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/MainLauncher.java
 (original)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/MainLauncher.java
 Thu Jul 20 11:16:32 2006
@@ -128,8 +128,8 @@
         // The classpath to load the launcher should not contain any of 
Tuscany jar files except the launcher.
         try {
             parseArguments(args);
-            bootRuntime();
-            CompositeComponent application = bootApplication();
+            bootRuntime(METAINF_SYSTEM_SCDL_PATH);
+            CompositeComponent application = 
bootApplication(METAINF_APPLICATION_SCDL_PATH);
             application.start();
             try {
                 callApplication(application);

Added: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/ServletLauncherListener.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/ServletLauncherListener.java?rev=424013&view=auto
==============================================================================
--- 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/ServletLauncherListener.java
 (added)
+++ 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/ServletLauncherListener.java
 Thu Jul 20 11:16:32 2006
@@ -0,0 +1,106 @@
+package org.apache.tuscany.core.launcher;
+
+import org.apache.tuscany.spi.loader.LoaderException;
+import org.apache.tuscany.spi.component.CompositeComponent;
+import org.apache.tuscany.spi.bootstrap.ComponentNames;
+
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContext;
+
+/**
+ * Launcher for runtime environment that loads info from servlet context 
params.
+ * This listener manages one top-level CompositeContext per servlet context; 
the
+ * lifecycle of that CompositeContext corresponds to the the lifecycle of the
+ * associated servlet context.
+ *
+ * @version $$Rev: $$ $$Date: $$
+ */
+
+public class ServletLauncherListener implements ServletContextListener {
+    /**
+     * Servlet context-param name for user-specified system SCDL path.
+     */
+    public static final String SYSTEM_SCDL_PATH_PARAM = "systemScdlPath";
+    /**
+     * Servlet context-param name for user-specified application SCDL path.
+     */
+    public static final String APPLICATION_SCDL_PATH_PARAM = 
"applicationScdlPath";
+
+    /**
+     * Default application SCDL path used if no "applicationScdlPath" param is 
specified
+     *
+     * REVIEW: this doesn't work as expected right now because we are using 
the webapp classloader
+     * directly, which doesn't include the root of the webapp.
+     */
+    public static final String DEFAULT_APPLICATION_SCDL_PATH = 
"WEB-INF/default.scdl";
+
+    /**
+     * Context attribute to which application root component (of type 
CompositeComponent<?>)
+     * will be bound to on successful application initialization.  May be null 
on failure.
+     */
+    public static final String APPLICATION_ROOT_COMPONENT_ATTRIBUTE = 
ComponentNames.TUSCANY_ROOT;
+
+    /**
+     * Context attribute to which application root context (of type 
CompositeContext)
+     * will be bound to on successful application initialization.  May be null 
on failure.
+     */
+    public static final String APPLICATION_ROOT_CONTEXT_ATTRIBUTE = 
APPLICATION_ROOT_COMPONENT_ATTRIBUTE + ".context";
+
+    public void contextInitialized(ServletContextEvent servletContextEvent) {
+        ServletContext servletContext = 
servletContextEvent.getServletContext();
+
+        // Read optional path to system SCDL from context-param
+        String systemScdlPath = 
servletContext.getInitParameter(SYSTEM_SCDL_PATH_PARAM);
+        if (systemScdlPath == null)
+            systemScdlPath = Launcher.METAINF_SYSTEM_SCDL_PATH;
+
+        // Read optional path to application SCDL from context-param
+        String applicationScdlPath = 
servletContext.getInitParameter(APPLICATION_SCDL_PATH_PARAM);
+        if (applicationScdlPath == null)
+            applicationScdlPath = DEFAULT_APPLICATION_SCDL_PATH;
+
+        Launcher launcher = new Launcher();
+
+        // REVIEW: Not sure how reliable it is to rely on the thread context 
classloader as having
+        // reasonable semantics across a variety of servlet containers.. if 
"not very", the thread
+        // context loader works for Tomcat, so perhaps this class needs to 
become container-specific.
+        
launcher.setApplicationLoader(Thread.currentThread().getContextClassLoader());
+
+        CompositeComponent<?> component = null;
+        CompositeContextImpl context = null;
+
+        try {
+            launcher.bootRuntime(systemScdlPath);
+            component = launcher.bootApplication(applicationScdlPath);
+            component.start();
+            context = new CompositeContextImpl(component);
+            context.start();
+        }
+        catch (LoaderException le) {
+            // TODO: Need proper logging infrastructure here
+            // TODO: stash exception info in attributes?
+            le.printStackTrace();
+        }
+
+        servletContext.setAttribute(APPLICATION_ROOT_COMPONENT_ATTRIBUTE, 
component);
+        servletContext.setAttribute(APPLICATION_ROOT_COMPONENT_ATTRIBUTE, 
context);
+    }
+
+    public void contextDestroyed(ServletContextEvent servletContextEvent) {
+        ServletContext servletContext = 
servletContextEvent.getServletContext();
+
+        CompositeComponent<?> component =
+            (CompositeComponent<?>) 
servletContext.getAttribute(APPLICATION_ROOT_COMPONENT_ATTRIBUTE);
+
+        // REVIEW: may be ok to use CurrentCompositeContext.getContext(), but 
this feels safer.
+        CompositeContextImpl context =
+            (CompositeContextImpl) 
servletContext.getAttribute(APPLICATION_ROOT_CONTEXT_ATTRIBUTE);
+
+        if (component != null)
+            component.stop();
+
+        if (context != null)
+            context.stop();
+    }
+}

Propchange: 
incubator/tuscany/java/sca/core/src/main/java/org/apache/tuscany/core/launcher/ServletLauncherListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
incubator/tuscany/java/sca/test/src/main/java/org/apache/tuscany/test/SCATestCase.java
URL: 
http://svn.apache.org/viewvc/incubator/tuscany/java/sca/test/src/main/java/org/apache/tuscany/test/SCATestCase.java?rev=424013&r1=424012&r2=424013&view=diff
==============================================================================
--- 
incubator/tuscany/java/sca/test/src/main/java/org/apache/tuscany/test/SCATestCase.java
 (original)
+++ 
incubator/tuscany/java/sca/test/src/main/java/org/apache/tuscany/test/SCATestCase.java
 Thu Jul 20 11:16:32 2006
@@ -36,8 +36,8 @@
         super.setUp();
         launcher = new Launcher();
         launcher.setApplicationLoader(getClass().getClassLoader());
-        launcher.bootRuntime();
-        component = launcher.bootApplication();
+        launcher.bootRuntime(Launcher.METAINF_SYSTEM_SCDL_PATH);
+        component = 
launcher.bootApplication(Launcher.METAINF_APPLICATION_SCDL_PATH);
         component.start();
         context = new CompositeContextImpl(component);
         context.start();



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to