Author: costin
Date: Sat Feb 11 12:42:42 2006
New Revision: 377051

URL: http://svn.apache.org/viewcvs?rev=377051&view=rev
Log:
A couple of small improvements to the 'embeded' tomcat sandbox. Now it
can work with only web.xml - or no xml files at all.


Added:
    tomcat/sandbox/java/org/apache/tomcat/standalone/ETomcat.java
    tomcat/sandbox/java/org/apache/tomcat/standalone/Main.java
    tomcat/sandbox/java/org/apache/tomcat/standalone/WebappsMain.java
      - copied, changed from r375161, 
tomcat/sandbox/java/org/apache/tomcat/standalone/Tomcat.java
Removed:
    tomcat/sandbox/java/org/apache/tomcat/standalone/Tomcat.java
Modified:
    tomcat/sandbox/.classpath
    tomcat/sandbox/build.xml
    tomcat/sandbox/java/org/apache/tomcat/servlets/jsp/JspProxyServlet.java
    tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java
    tomcat/sandbox/java/org/apache/tomcat/util/net/SimpleEndpoint.java
    tomcat/sandbox/resources/runtime.MF

Modified: tomcat/sandbox/.classpath
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/.classpath?rev=377051&r1=377050&r2=377051&view=diff
==============================================================================
--- tomcat/sandbox/.classpath (original)
+++ tomcat/sandbox/.classpath Sat Feb 11 12:42:42 2006
@@ -2,11 +2,13 @@
 <classpath>
        <classpathentry kind="src" path="java"/>
        <classpathentry kind="src" path="test"/>
-       <classpathentry kind="con" 
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+       <classpathentry combineaccessrules="false" kind="src" 
path="/container"/>
        <classpathentry combineaccessrules="false" kind="src" 
path="/connectors"/>
+       <classpathentry kind="con" 
path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="var" path="TOMCAT_LIBS_BASE/rhino1_6R2/js.jar"/>
        <classpathentry kind="var" 
path="TOMCAT_LIBS_BASE/junit3.8.1/junit.jar"/>
        <classpathentry kind="var" 
path="TOMCAT_LIBS_BASE/servlet-api-2.4/lib/servlet-api.jar"/>
        <classpathentry kind="var" 
path="TOMCAT_LIBS_BASE/commons-modeler-1.1/commons-modeler.jar"/>
+       <classpathentry kind="var" 
path="TOMCAT_LIBS_BASE/commons-el-1.0/commons-el.jar"/>
        <classpathentry kind="output" path="classes"/>
 </classpath>

Modified: tomcat/sandbox/build.xml
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/build.xml?rev=377051&r1=377050&r2=377051&view=diff
==============================================================================
--- tomcat/sandbox/build.xml (original)
+++ tomcat/sandbox/build.xml Sat Feb 11 12:42:42 2006
@@ -11,8 +11,8 @@
   <property name="tc55xbase" location=".." />
 
     <!-- Source dependencies -->
-  <property name="target.vm"     value="1.4"/>
-  <property name="source.vm"     value="1.4"/>
+  <property name="target.vm"     value="1.5"/>
+  <property name="source.vm"     value="1.5"/>
   <property name="api.home"      value="${tc55xbase}/servletapi"/>
   <property name="container.home" value="${tc55xbase}/container"/>
   <property name="jasper.home"   value="${tc55xbase}/jasper"/>
@@ -141,13 +141,14 @@
   </target>
 
   <target name="compile-sandbox">
-    <mkdir dir="${sandbox.home}/bin" />
+    <mkdir dir="${sandbox.home}/classes" />
     <javac destdir="${sandbox.home}/classes" source="${source.vm}" 
target="${target.vm}"
       deprecation="false" debug="false"  >
       <src path="${sandbox.home}/java" />
       <classpath>
         <path refid="runtime-deps" />        
-          <pathelement location="${connectors.home}/bin"/>
+        <pathelement location="${connectors.home}/bin"/>
+        <pathelement location="${container.home}/bin"/>
       </classpath>
     </javac>
     <copy todir="${sandbox.home}/classes" >
@@ -195,24 +196,29 @@
   </target>
   
   <target name="compile" 
-    
depends="compile-connectors,compile-sandbox,compile-container,compile-jasper"/>
+    
depends="compile-connectors,compile-container,compile-sandbox,compile-jasper"/>
 
   <target name="clean-compile">
     <delete dir="${container.home}/bin" includes="**"/>
-    <delete dir="${sandbox.home}/bin" includes="**"/>
+    <delete dir="${sandbox.home}/classes" includes="**"/>
     <delete dir="${connectors.home}/bin" includes="**"/>
     <delete dir="${jasper.home}/bin" includes="**"/>
   </target>
   
   
-  <target name="runtime"
-    description="Build single jar tomcat" depends="compile">
+  <target name="tomcat-runtime.jar"
+    description="Build single jar tomcat" 
depends="compile,pack_tomcat-runtime.jar">
+  </target>
+  
+  
+  <target name="pack_tomcat-runtime.jar"
+    description="Pack single jar tomcat" >
     <mkdir dir="runtime" />
     <jar jarfile="runtime/tomcat-runtime.jar" manifest="resources/runtime.MF">
       <fileset dir="${container.home}/bin" >
         <exclude name="org/apache/tomcat/util/buf/**"/>
       </fileset>
-      <fileset dir="${sandbox.home}/bin" >
+      <fileset dir="${sandbox.home}/classes" >
         <exclude name="org/apache/tomcat/util/net/Leader**"/>
         <exclude name="org/apache/tomcat/util/net/Master**"/>
         <exclude name="org/apache/tomcat/util/net/SSL**"/>
@@ -221,6 +227,7 @@
         <exclude name="org/apache/tomcat/util/net/Default**"/>
       </fileset>
       <fileset dir="${connectors.home}/bin" >
+        <exclude name="org/apache/coyote/http11/*"/>
         <exclude name="org/apache/tomcat/util/buf/**"/>
         <exclude name="org/apache/tomcat/util/net/jsse/**"/>
         <exclude name="org/apache/tomcat/util/threads/Expirer**"/>
@@ -352,7 +359,7 @@
 
   </target>
 
-  <target name="all" depends="tomcat-http11,runtime,runtime-all" />
+  <target name="all" depends="tomcat-http11,tomcat-runtime.jar,runtime-all" />
 
   <!-- ============ Download targets for deps ================ -->
 

Modified: 
tomcat/sandbox/java/org/apache/tomcat/servlets/jsp/JspProxyServlet.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/servlets/jsp/JspProxyServlet.java?rev=377051&r1=377050&r2=377051&view=diff
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/servlets/jsp/JspProxyServlet.java 
(original)
+++ tomcat/sandbox/java/org/apache/tomcat/servlets/jsp/JspProxyServlet.java Sat 
Feb 11 12:42:42 2006
@@ -5,6 +5,7 @@
 import java.util.Vector;
 
 import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -14,7 +15,12 @@
  *  
  *  If jasper is not found - i.e. runtime without jasper compiler - it'll 
  *  compute the mangled class name ( same code as jasper )
- *  and invoke the jsp servlet directly. 
+ *  and invoke the jsp servlet directly. If the class is not found, it'll 
execute
+ *   "jspc" and try again. 
+ *  
+ *  
+ * 
+ * TODO: test jspc, generate files in or out web-inf dir, modify web.xml
  * 
  * @author Costin Manolache
  */
@@ -64,11 +70,33 @@
                 Class sC=Class.forName( mangledClass );
                 jsp=(HttpServlet)sC.newInstance();
             } catch( Throwable t ) {
+            }
+        }
+        if(jsp == null) {
+            
+        }
+        // try again
+        if( jsp == null ) {
+            try {
+                Class sC=Class.forName( mangledClass );
+                jsp=(HttpServlet)sC.newInstance();
+            } catch( Throwable t ) {
                 t.printStackTrace();
                 arg1.setStatus(404);
             }
         }        
         jsp.service( req, arg1);
+    }
+    
+    private void compileJsp(ServletContext ctx, String jspPath) {
+        // Params to pass to jspc:
+        // classpath 
+        
+        // webapp base dir
+        String baseDir = ctx.getRealPath("/");
+        // jsp path ( rel. base dir )
+        
+        
     }
 
     public void init(ServletConfig arg0) throws ServletException {

Added: tomcat/sandbox/java/org/apache/tomcat/standalone/ETomcat.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/standalone/ETomcat.java?rev=377051&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/standalone/ETomcat.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/standalone/ETomcat.java Sat Feb 11 
12:42:42 2006
@@ -0,0 +1,302 @@
+/*
+ */
+package org.apache.tomcat.standalone;
+
+import java.io.File;
+import java.io.IOException;
+
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Lifecycle;
+import org.apache.catalina.LifecycleEvent;
+import org.apache.catalina.LifecycleListener;
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardEngine;
+import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.core.StandardServer;
+import org.apache.catalina.core.StandardService;
+import org.apache.catalina.core.StandardWrapper;
+import org.apache.catalina.deploy.LoginConfig;
+import org.apache.catalina.session.StandardManager;
+
+/**
+ * Minimal tomcat starter for embedding. 
+ * 
+ * Tomcat supports multiple styles of configuration. 
+ * 
+ * 1. Classical server.xml, web.xml - see the Tomcat superclass.
+ * 2. Minimal tomcat, programatically configured, using regular webapps and 
web.xml
+ * 3. For apps that only need basic servlets, or have their own deployment 
mechanism -
+ *  you can start tomcat without using web.xml
+ *  
+ *  Before people start screaming 'violation of the spec' - please read again 
the
+ *  spec, web.xml is a mechanism for _deployment_. If you ship or deploy a 
webapp, it
+ *  must have web.xml and all the war format. However the spec doesn't require 
the
+ *  container to store the files in the same format or use the web.xml file - 
they
+ *  added a lot of pain to the spec to make sure files could be stored in a 
database
+ *  for example. 
+ *  
+ *  In particular, storing the web.xml in a pre-parsed form, like a .ser file 
or 
+ *  a generated java class is (IMO) perfectly fine. One particular case of 
this is 
+ *  a hand-generated configurator - which is a good fit for apps that want to 
+ *  provide a HTTP interface and use servlets, but don't need all dynamic 
deployment
+ *  and reconfiguration.
+ *  
+ *  In fact - if you don't use jsps or use precompiled jsps, you can leave 
most of the 
+ *  xml parsing overhead out of your app, and have a more minimal http server.
+ * 
+ * This is provided as a base class and as an example - you can extend it, or 
just 
+ * cut&paste or reuse methods.
+ * 
+ * @author Costin Manolache
+ */
+public class ETomcat {
+    
+    protected StandardServer server;
+    protected StandardService service;
+    protected StandardEngine eng;
+    protected StandardHost host;
+    protected StandardContext ctx;
+
+    /** Example main. You should extend ETomcat and call start() your own way.
+     */
+    public static void main( String args[] ) {
+        try {
+            ETomcat etomcat = new ETomcat();
+            
+            etomcat.initServer(null);
+            etomcat.initConnector(8000);
+            etomcat.initHost("localhost");
+            etomcat.initWebapp("/", ".");
+            etomcat.initWebappDefaults();
+            
+            etomcat.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    
+    public void start() throws Exception {
+        server.initialize();
+        server.start();
+    }
+    
+    public StandardServer initServer(String baseDir) {
+        initHome(baseDir);
+        System.setProperty("catalina.useNaming", "false");
+        
+        server = new StandardServer();
+        server.setPort( -1 );
+        
+        //ServerLifecycleListener jmxLoader = new ServerLifecycleListener();
+        //server.addLifecycleListener(jmxLoader);
+        
+        service = new StandardService();
+        server.addService( service );
+        return server;
+    }
+
+    /** Add a default http connector.
+     * 
+     * Alternatively, you can construct a Connector and set any params,
+     * then call addConnector(Connector)
+     */
+    public Connector initConnector(int port) throws Exception {
+        Connector connector = new Connector("HTTP/1.1");
+        connector.setPort(port);
+        service.addConnector( connector );
+        return connector;
+    }
+    
+    public void addConnector( Connector connector ) {
+        service.addConnector( connector );
+    }
+    
+    /** Create a host. First host will be the default.
+     */
+    public StandardHost initHost(String hostname) {
+        if(eng == null ) {
+            eng = new StandardEngine();
+            eng.setName( "default" );
+            eng.setDefaultHost(hostname);
+            service.setContainer(eng);
+        }
+
+        
+        host = new StandardHost();
+        host.setName(hostname);
+
+        eng.addChild( host );
+        return host;
+    }
+
+    /** Initialize a webapp.
+     * 
+     * You can customize the return value to support different web.xml 
features:
+     * 
+     * context-param
+     *  ctx.addParameter("name", "value");
+     *     
+     *
+     * error-page
+     *    ErrorPage ep = new ErrorPage();
+     *    ep.setErrorCode(500);
+     *    ep.setLocation("/error.html");
+     *    ctx.addErrorPage(ep);
+     *   
+     * ctx.addMimeMapping("ext", "type");
+     *  
+     */
+    public StandardContext initWebapp(String path, String dir) {
+        ctx = new StandardContext();
+        ctx.setPath( path );
+        ctx.setDocBase(dir);
+
+        ctx.addLifecycleListener(new FixContextListener());
+
+        host.addChild(ctx);
+        return ctx;
+    }
+    
+    public void addWebapp(StandardContext ctx) {
+        this.ctx = ctx;
+        
+        ctx.addLifecycleListener(new FixContextListener());
+
+        host.addChild(ctx);
+        
+    }
+
+    public void initWebappDefaults() {
+        // Default servlet 
+        StandardWrapper defaultServletW = 
+            initServlet("default", 
"org.apache.catalina.servlets.DefaultServlet");
+        defaultServletW.addInitParameter("listings", "true");
+
+        initServlet("invoker", "org.apache.catalina.servlets.InvokerServlet");
+
+        initServlet("jsp", "org.apache.tomcat.servlets.jsp.JspProxyServlet");
+        
+        ctx.addServletMapping("/", "default");
+        ctx.addServletMapping("*.jsp", "jsp");
+        ctx.addServletMapping("*.jspx", "jsp");
+        ctx.addServletMapping("/servlet/*", "invoker");
+        
+        
+        // Mime mappings: should read from /etc/mime.types on linux, or some
+        // resource
+        
+        
+        ctx.addWelcomeFile("index.html");
+        ctx.addWelcomeFile("index.htm");
+        ctx.addWelcomeFile("index.jsp");
+        
+        ctx.setLoginConfig( new LoginConfig("NONE", null, null, null));
+        
+        ctx.setManager( new StandardManager());
+    }
+
+    /**
+     * You can customize the returned servlet, ex:
+     * 
+     *    wrapper.addInitParameter("name", "value");
+     */
+    public StandardWrapper initServlet(String servletName, String 
servletClass) {
+        // will do class for name and set init params
+        StandardWrapper sw = (StandardWrapper)ctx.createWrapper();
+        sw.setServletClass(servletClass);
+        sw.setName(servletName);
+        ctx.addChild(sw);
+        
+        return sw;
+    }
+
+    /** Use an existing servlet, no class.forName or initialization will be 
+     * performed
+     */
+    public StandardWrapper initServlet(String servletName, Servlet servlet) {
+        // will do class for name and set init params
+        StandardWrapper sw = new ExistingStandardWrapper(servlet);
+        sw.setName(servletName);
+        ctx.addChild(sw);
+        
+        return sw;
+    }
+
+    /** Init expected tomcat env. This is used as a base for the work 
directory.
+     * TODO: disable work dir if not needed ( no jsp, etc ).
+     * 
+     * Also used as a base for webapps/ and config dirs, when used.
+     */
+    private void initHome(String basedir) {
+        if( basedir != null ) {
+            System.setProperty("catalina.home", basedir);
+            System.setProperty("catalina.base", basedir);
+        }
+        String catalinaHome = System.getProperty("catalina.home");
+        if(catalinaHome==null) {
+            catalinaHome=System.getProperty("user.dir");
+            File home = new File(catalinaHome);
+            if (!home.isAbsolute()) {
+                try {
+                    catalinaHome = home.getCanonicalPath();
+                } catch (IOException e) {
+                    catalinaHome = home.getAbsolutePath();
+                }
+            }
+            System.setProperty("catalina.home", catalinaHome);
+        }
+        
+        if( System.getProperty("catalina.base") == null ) {
+            System.setProperty("catalina.base", catalinaHome);
+        }
+    }
+    
+    /** Fix startup sequence - required if you don't use web.xml.
+     * 
+     *  The start() method in context will set 'configured' to false - and
+     *  expects a listener to set it back to true.
+     * 
+     * @author Costin Manolache
+     */
+    public static class FixContextListener implements LifecycleListener {
+
+        public void lifecycleEvent(LifecycleEvent event) {
+            try {
+                Context context = (Context) event.getLifecycle();
+                if (event.getType().equals(Lifecycle.START_EVENT)) {
+                    context.setConfigured(true);
+                }
+            } catch (ClassCastException e) {
+                return;
+            }
+        }
+        
+    }
+
+    /** Helper class for wrapping existing servlets. This disables servlet 
+     * lifecycle and normal reloading, but also reduces overhead and provide
+     * more direct control over the servlet.  
+     *  
+     * @author Costin Manolache
+     */
+    public static class ExistingStandardWrapper extends StandardWrapper {
+        private Servlet existing;
+        public ExistingStandardWrapper( Servlet existing ) {
+            this.existing = existing;
+        }
+        public synchronized Servlet loadServlet() throws ServletException {
+            return existing;
+
+        }
+        public long getAvailable() {
+            return 0;
+        }
+        public boolean isUnavailable() {
+            return false;       
+        }
+    }
+}

Added: tomcat/sandbox/java/org/apache/tomcat/standalone/Main.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/standalone/Main.java?rev=377051&view=auto
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/standalone/Main.java (added)
+++ tomcat/sandbox/java/org/apache/tomcat/standalone/Main.java Sat Feb 11 
12:42:42 2006
@@ -0,0 +1,52 @@
+/*
+ */
+package org.apache.tomcat.standalone;
+
+import java.lang.reflect.Method;
+
+/** Process CLI args and dispatch to the right launcher.
+ * 
+ *  First argument may be:
+ *   
+ *   -webapps - no server.xml or conf/ is used, you just need a webapps/ dir
+ *   -app - no server.xml or webapps/ - you only need individual app dirs, 
only process 
+ *     web.xml. 
+ *   -etomcat - deeply embeded, no config file is used. Instead of web.xml 
it'll 
+ *     use programmatic settings. Experimental.
+ *   -coyote - just the http adapter - will use Adapters.
+ *   [ none of the above ] - old style Bootstrap, using server.xml 
+ * 
+ * Last 2 modes are for example - the typical use will be to cut&paste the 
start
+ * lines in your app and add the classes to your app jar(s).
+ * 
+ * @author Costin Manolache
+ */
+public class Main {
+
+    public static String HELP="";
+    
+    public static void main(String args[]) {
+        if( args.length == 0 ) {
+            System.err.println(HELP);
+            return;
+        }
+        String dispatch = args[0];
+        String launcher = "org.apache.catalina.startup.Bootstrap";
+        if( "-webapps".equals(dispatch) ) {
+            launcher = "org.apache.tomcat.standalone.WebappsMain";
+        } else if("-app".equals(dispatch)) {
+            launcher = "org.apache.tomcat.standalone.SimpleAppsMain";          
  
+        } else if("-etomcat".equals(dispatch)) {
+            launcher = "org.apache.tomcat.standalone.ETomcat";            
+        } else if("-coyote".equals(dispatch)) {
+            launcher = "org.apache.coyote.standalone.Main";            
+        }
+        try {
+            Class launcherClass = Class.forName(launcher);
+            Method main = launcherClass.getMethod("main", new Class[] { 
args.getClass() });
+            main.invoke(null, new Object[] {args} );
+        } catch( Throwable t ) {
+            t.printStackTrace();
+        }
+    }   
+}

Copied: tomcat/sandbox/java/org/apache/tomcat/standalone/WebappsMain.java (from 
r375161, tomcat/sandbox/java/org/apache/tomcat/standalone/Tomcat.java)
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/standalone/WebappsMain.java?p2=tomcat/sandbox/java/org/apache/tomcat/standalone/WebappsMain.java&p1=tomcat/sandbox/java/org/apache/tomcat/standalone/Tomcat.java&r1=375161&r2=377051&rev=377051&view=diff
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/standalone/Tomcat.java (original)
+++ tomcat/sandbox/java/org/apache/tomcat/standalone/WebappsMain.java Sat Feb 
11 12:42:42 2006
@@ -2,73 +2,45 @@
  */
 package org.apache.tomcat.standalone;
 
-import java.io.File;
-import java.io.IOException;
-
-import org.apache.catalina.connector.Connector;
-import org.apache.catalina.core.StandardEngine;
 import org.apache.catalina.core.StandardHost;
-import org.apache.catalina.core.StandardServer;
-import org.apache.catalina.core.StandardService;
 import org.apache.catalina.startup.HostConfig;
 
-public class Tomcat {
+/**
+ * Start tomcat using server.xml and web.xml and regular config files 
+ * 
+ * @author Costin Manolache
+ */
+public class WebappsMain extends ETomcat {
 
     public static void main( String args[] ) {
         try {
-            startTomcat();
+            WebappsMain etomcat = new WebappsMain();
+            
+            etomcat.initServer(null);
+            etomcat.initConnector(8000);
+
+            // This will load all webapps, context configs, etc 
+            etomcat.initAutoconfHost("localhost", "webapps");
+            
+            etomcat.start();
         } catch (Exception e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
         }
     }
 
-    private static void startTomcat() throws Exception {
-        String catalinaHome = System.getProperty("catalina.home");
-        if(catalinaHome==null) {
-            catalinaHome=System.getProperty("user.dir");
-            File home = new File(catalinaHome);
-            if (!home.isAbsolute()) {
-                try {
-                    catalinaHome = home.getCanonicalPath();
-                } catch (IOException e) {
-                    catalinaHome = home.getAbsolutePath();
-                }
-            }
-            System.setProperty("catalina.home", catalinaHome);
-        }
-        
-        if( System.getProperty("catalina.base") == null ) {
-            System.setProperty("catalina.base", catalinaHome);
-        }
-        System.setProperty("catalina.useNaming", "false");
-        
-        StandardServer server = new StandardServer();
-        server.setPort( -1 );
-        //tc.setServer( server );
-        
-        StandardService service = new StandardService();
-        server.addService( service );
+    public StandardHost initAutoconfHost(String hostName, String webappsBase) 
+    {
+        host = new StandardHost();
+        host.setName(hostName);
         
-        Connector connector = new Connector("HTTP/1.1");
-        service.addConnector( connector );
-        connector.setPort( 8000 );
-        
-        StandardEngine eng = new StandardEngine();
-        eng.setName( "default" );
-        eng.setDefaultHost("localhost");
-        service.setContainer(eng);
-        
-        StandardHost host = new StandardHost();
-        host.setName( "localhost");
-        host.setAppBase("webapps");
         HostConfig hconfig = new HostConfig();
         host.addLifecycleListener( hconfig );
-        
-        eng.addChild( host );
 
-        server.initialize();
-        
-        server.start();
+        host.setAppBase(webappsBase);
+
+        eng.addChild(host);
+        return host;
     }
+
 }

Modified: tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java?rev=377051&r1=377050&r2=377051&view=diff
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java (original)
+++ tomcat/sandbox/java/org/apache/tomcat/util/buf/ByteChunk.java Sat Feb 11 
12:42:42 2006
@@ -34,28 +34,37 @@
  * to be able to parse the request without converting to string.
  */
 
-// TODO: This class could either extend ByteBuffer, or better a ByteBuffer 
inside
-// this way it could provide the search/etc on ByteBuffer, as a helper.
-
 /**
  * This class is used to represent a chunk of bytes, and
- * utilities to manipulate byte[].
+ * utilities to manipulate bytes.
  *
  * The buffer can be modified and used for both input and output.
  *
- * There are 2 modes: The chunk can be associated with a sink - 
ByteInputChannel or ByteOutputChannel,
- * which will be used when the buffer is empty ( on input ) or filled ( on 
output ).
- * For output, it can also grow. This operating mode is selected by calling 
setLimit() or
- * allocate(initial, limit) with limit != -1.
+ * There are 3 modes: 
+ * 
+ * 1. Wrapping a chunk from another buffer. This was the original use and is 
the
+ * most common use - for example in headers. Typically there is an associated
+ * CharChunk and MessageBytes for the char[] representation - but many buffers 
+ * will not be converted or will be converted just before use. 
+ * 
+ * 2. For input, associated with a ByteInputChannel ( or ReadableByteChannel 
), 
+ * which will be called automatically when the buffer is emtpy. This is used 
for 
+ * the input stream and for the header buffer ( which will be later wrapped in 
many
+ * ByteChunks )
+ * 
+ * 3. For output, associated ( or not ) with a ByteOutputChannel. The buffer
+ * can grow up to a limit ( and will stay allocated to that limit ). When the 
limit
+ * is reached, the channel is used.
  *
  * Various search and append method are defined - similar with String and 
StringBuffer, but
  * operating on bytes.
+ * 
+ * In addition, append and substract are used in 2 and 3.
  *
  * This is important because it allows processing the http headers directly on 
the received bytes,
  * without converting to chars and Strings until the strings are needed. In 
addition, the charset
  * is determined later, from headers or user code.
  *
- *
  * @author [EMAIL PROTECTED]
  * @author James Todd [EMAIL PROTECTED]
  * @author Costin Manolache
@@ -66,6 +75,7 @@
     /** Input interface, used when the buffer is emptiy
      *
      * Same as java.nio.channel.ReadableByteChannel
+     * @deprecated
      */
     public static interface ByteInputChannel {
         /** 
@@ -78,6 +88,7 @@
     }
 
     /** Same as java.nio.channel.WrittableByteChannel.
+     * @deprecated
      */
     public static interface ByteOutputChannel {
         /** 
@@ -95,38 +106,83 @@
        8859_1, and this object is used mostly for servlets. 
     */
     public static final String DEFAULT_CHARACTER_ENCODING="ISO-8859-1";
-        
-    // byte[]
-    //private byte[] buff;
+
+    // By default in read mode - there are fewer uses of ByteChunk for output.
+    // (In most cases it's wrapping existing data) 
+    //
+    // So start == 0, end == limit. Position is not used.
+    // 
+    // if isOutout==true - the buffer is used for output. It must be 
released().
     private ByteBuffer bb;
+    private boolean isSet=false; // == ! isNull
+    
     
-    private int start=0;
-    private int end;
+    private int start=0; // used as ByteBuffer.offset and position
+    private int end; // used as limit
 
+    // not sure it's good to have it here, MessageBytes should deal with this
     private String enc;
 
-    private boolean isSet=false; // XXX
-
-    // How much can it grow, when data is added
-    private int limit=-1;
+    // Probably not needed if callers respect the rules - but good to debug.
+    private boolean inUse = false; // direct access to bb
+    private boolean isOutput=false; // byte buffer in output mode
+    private int mode = 0; 
+    //private boolean optimizedWrite=true;
+
+    // How much can it grow, when data is added. Different from the bb limit,
+    // this is how much we can resize the bb before flushing.
+    private int growLimit=-1;
 
+    // maybe a single in/out channel would be better.
     private ByteInputChannel in = null;
     private ByteOutputChannel out = null;
 
-    private boolean isOutput=false;
-    private boolean optimizedWrite=true;
-    
+    /*
+     
+    // experiment: specific structure for 2. and 3.
+    static class ByteData {
+        Channel channel; // or in, out
+        
+        int growLimit = -1;
+        String enc; // no need to have it in wrapped buffers
+        
+    }
+    private ByteData byteData;
+    */
     /**
      * Creates a new, uninitialized ByteChunk object.
      */
     public ByteChunk() {
     }
 
-    public ByteChunk( int initial ) {
-       allocate( initial, -1 );
-    }
-
     //--------------------
+    
+    public ByteBuffer getBuffer(boolean forWrite) {
+        inUse = true;
+        if( forWrite ) {
+            isOutput = true;
+            // all methods except append should throw exceptions !
+            //  start - end are existing data, end is growing on append
+            // also, start is supposed to be 0 ( or offeset ? )
+            bb.position(end);
+            bb.limit(bb.capacity());
+        }
+        return bb;
+    }
+
+    public void releaseBuffer() {
+        if( isOutput ) {
+            isOutput = false;
+            // start remain the same ( probably 0 )
+            end = bb.position();
+            // flip bb for reading
+            bb.limit(bb.position());
+            bb.position(0);
+        }
+        inUse = false;
+    }
+    
+    
     public ByteChunk getClone() {
        try {
            return (ByteChunk)this.clone();
@@ -136,18 +192,21 @@
     }
 
     public boolean isNull() {
-       return ! isSet; // buff==null;
+       return ! isSet; 
     }
     
     /**
      * Resets the message buff to an uninitialized state.
      */
     public void recycle() {
-       //      buff = null;
        enc=null;
        start=0;
        end=0;
        isSet=false;
+        if( bb != null) bb.clear();
+        inUse = false;
+        // mode remains - it shouldn't change
+        isOutput = false;
     }
 
     public void reset() {
@@ -156,20 +215,41 @@
 
     // -------------------- Setup --------------------
 
+    /**
+     * Prealocate a buffer.
+     * Called by C2B, BufferedInputFilter ( mode 2 ), catalina InputBuffer 
+     * and OutputBuffe,  
+     * 
+     * @param initial
+     */
+    public ByteChunk( int initial ) {
+        allocate( initial, -1 );
+    }
+
+    /** Used for 2. and 3. - allocate the buffer.
+     * 
+     * Called by InternalOutputBuffer, C2B ( for out ).
+     *  
+     * Called by MessageBytes ( out mode ) to hold decoded uri, other temp
+     * storages for request ( long, etc ) 
+     */
     public void allocate( int initial, int limit  ) {
        isOutput=true;
        if( bb==null || bb.capacity() < initial ) {
            //buff=new byte[initial];
             bb=ByteBuffer.allocate(initial);
        }    
-       this.limit=limit;
+       this.growLimit=limit;
        start=0;
        end=0;
        isSet=true;
+        mode = 4; // will set to 2 or 3 on first op.
+        //new Throwable().printStackTrace();
     }
 
     /**
      * Sets the message bytes to the specified subarray of bytes.
+     * Used for 1.
      * 
      * @param b the ascii bytes
      * @param off the start offset of the bytes
@@ -178,18 +258,27 @@
     public void setBytes(byte[] b, int off, int len) {
         //buff = b;
         bb=ByteBuffer.wrap( b, off, len );
-        start = off;
+        start = off; // also offset in bb.
+        // bb.arrayOffset() == off == start;
         end = start+ len;
         isSet=true;
+        if( mode > 1 ) {
+            System.err.println("Old mode: " + mode);
+            new Throwable().printStackTrace();
+        }
+        mode = 1;
     }
 
-    public void setOptimizedWrite(boolean optimizedWrite) {
-        this.optimizedWrite = optimizedWrite;
-    }
+    // --------------------------------------
+    // Doesn't seem to be used - and it shouldn't be
+    //public void setOptimizedWrite(boolean optimizedWrite) {
+    //    this.optimizedWrite = optimizedWrite;
+    //}
 
     public void setEncoding( String enc ) {
        this.enc=enc;
     }
+    
     public String getEncoding() {
         if (enc == null)
             enc=DEFAULT_CHARACTER_ENCODING;
@@ -243,11 +332,11 @@
      *  or throw exception.
      */
     public void setLimit(int limit) {
-       this.limit=limit;
+       this.growLimit=limit;
     }
     
     public int getLimit() {
-       return limit;
+       return growLimit;
     }
 
     /**
@@ -275,6 +364,8 @@
     }
 
     // -------------------- Adding data to the buffer --------------------
+    // this is mode 3.
+    
     /** Append a char, by casting it to byte. This IS NOT intended for unicode.
      *
      * @param c
@@ -292,11 +383,11 @@
        makeSpace( 1 );
 
        // couldn't make space
-       if( limit >0 && end >= limit ) {
+       if( growLimit >0 && end >= growLimit ) {
            flushBuffer();
        }
        //buff[end++]=b;
-        bb.put(end++, b);
+        bb.array()[end++] = b;
     }
 
     public void append( ByteChunk src )
@@ -314,7 +405,7 @@
        makeSpace( len );
 
        // if we don't have limit: makeSpace can grow as it wants
-       if( limit < 0 ) {
+       if( growLimit < 0 ) {
            // assert: makeSpace made enough space
            System.arraycopy( src, off, bb.array(), end, len );
            end+=len;
@@ -325,12 +416,12 @@
         // If the buffer is empty and the source is going to fill up all the
         // space in buffer, may as well write it directly to the output,
         // and avoid an extra copy
-        if ( optimizedWrite && len == limit && end == start) {
+        if ( /*optimizedWrite &&*/ len == growLimit && end == start) {
             out.realWriteBytes( src, off, len );
             return;
         }
        // if we have limit and we're below
-       if( len <= limit - end ) {
+       if( len <= growLimit - end ) {
            // makeSpace will grow the buffer to the limit,
            // so we have space
            System.arraycopy( src, off, bb.array(), end, len );
@@ -346,7 +437,7 @@
         // We chunk the data into slices fitting in the buffer limit, although
         // if the data is written directly if it doesn't fit
 
-        int avail=limit-end;
+        int avail=growLimit-end;
         System.arraycopy(src, off, bb.array(), end, avail);
         end += avail;
 
@@ -354,9 +445,9 @@
 
         int remain = len - avail;
 
-        while (remain > (limit - end)) {
-            out.realWriteBytes( src, (off + len) - remain, limit - end );
-            remain = remain - (limit - end);
+        while (remain > (growLimit - end)) {
+            out.realWriteBytes( src, (off + len) - remain, growLimit - end );
+            remain = remain - (growLimit - end);
         }
 
         System.arraycopy(src, (off + len) - remain, bb.array(), end, remain);
@@ -364,12 +455,96 @@
 
     }
 
+    /** Send the buffer to the sink. Called by append() when the limit is 
reached.
+     *  You can also call it explicitely to force the data to be written.
+     *
+     * @throws IOException
+     */
+    public void flushBuffer()
+        throws IOException
+    {
+        //assert out!=null
+        if( out==null ) {
+            throw new IOException( "Buffer overflow, no sink " + growLimit + " 
" +
+                                   bb.capacity()  );
+        }
+        out.realWriteBytes( bb.array(), start, end-start );
+        end=start;
+    }
+
 
-    // -------------------- Removing data from the buffer --------------------
+    /** Make space for len chars. If len is small, allocate
+     *  a reserve space too. Never grow bigger than limit.
+     */
+    private void makeSpace(int count)
+    {
+        // all appends call make space
+        if( mode != 3 ) {
+            if( mode == 4 ) {
+                mode = 3;
+            } else { // mode change
+                new Throwable().printStackTrace();
+            }
+            
+        }
+        
+        ByteBuffer tmp = null;
+
+        int newSize;
+        int desiredSize=end + count;
+
+        // Can't grow above the limit
+        if( growLimit > 0 &&
+            desiredSize > growLimit) {
+            desiredSize=growLimit;
+        }
+
+        if( bb==null ) {
+            if( desiredSize < 256 ) desiredSize=256; // take a minimum
+            bb=ByteBuffer.allocate(desiredSize);
+        }
+        
+        // limit < buf.length ( the buffer is already big )
+        // or we already have space XXX
+        if( desiredSize <= bb.capacity() ) {
+            return;
+        }
+        // grow in larger chunks
+        if( desiredSize < 2 * bb.capacity() ) {
+            newSize= bb.capacity() * 2;
+            if( growLimit >0 &&
+                newSize > growLimit ) newSize=growLimit;
+        } else {
+            newSize= bb.capacity() * 2 + count ;
+            if( growLimit > 0 &&
+                newSize > growLimit ) newSize=growLimit;
+        }
+        tmp=ByteBuffer.allocate(newSize);
+        
+        System.arraycopy(bb.array(), start, tmp.array(), 0, end-start);
+        bb = tmp;
+        tmp = null;
+        end=end-start;
+        start=0;
+    }
 
+    // -------------------- Removing data from the buffer --------------------
+    // mode 2.
+    private void checkMode2() {
+        if( mode != 2 ) {
+            if( mode == 4 ) {
+                System.err.println("Mode 2 buffer");
+                mode = 2;
+            } else { // mode change
+                new Throwable().printStackTrace();
+            }
+        }        
+    }
+    
     public int substract()
         throws IOException {
 
+        checkMode2();
         if ((end - start) == 0) {
             if (in == null)
                 return -1;
@@ -378,13 +553,14 @@
                 return -1;
         }
 
-        return (bb.get(start++) & 0xFF);
+        return (bb.array()[start++] & 0xFF);
 
     }
 
     public int substract(ByteChunk src)
         throws IOException {
 
+        checkMode2();
         if ((end - start) == 0) {
             if (in == null)
                 return -1;
@@ -403,6 +579,7 @@
     public int substract( byte src[], int off, int len )
         throws IOException {
 
+        checkMode2();
         if ((end - start) == 0) {
             if (in == null)
                 return -1;
@@ -418,74 +595,12 @@
         System.arraycopy(bb.array(), start, src, off, n);
         start += n;
         return n;
-
-    }
-
-
-    /** Send the buffer to the sink. Called by append() when the limit is 
reached.
-     *  You can also call it explicitely to force the data to be written.
-     *
-     * @throws IOException
-     */
-    public void flushBuffer()
-       throws IOException
-    {
-       //assert out!=null
-       if( out==null ) {
-           throw new IOException( "Buffer overflow, no sink " + limit + " " +
-                                  bb.capacity()  );
-       }
-       out.realWriteBytes( bb.array(), start, end-start );
-       end=start;
     }
 
-    /** Make space for len chars. If len is small, allocate
-     * a reserve space too. Never grow bigger than limit.
-     */
-    private void makeSpace(int count)
-    {
-       ByteBuffer tmp = null;
-
-       int newSize;
-       int desiredSize=end + count;
-
-       // Can't grow above the limit
-       if( limit > 0 &&
-           desiredSize > limit) {
-           desiredSize=limit;
-       }
-
-       if( bb==null ) {
-           if( desiredSize < 256 ) desiredSize=256; // take a minimum
-           bb=ByteBuffer.allocate(desiredSize);
-       }
-       
-       // limit < buf.length ( the buffer is already big )
-       // or we already have space XXX
-       if( desiredSize <= bb.capacity() ) {
-           return;
-       }
-       // grow in larger chunks
-       if( desiredSize < 2 * bb.capacity() ) {
-           newSize= bb.capacity() * 2;
-           if( limit >0 &&
-               newSize > limit ) newSize=limit;
-       } else {
-           newSize= bb.capacity() * 2 + count ;
-           if( limit > 0 &&
-               newSize > limit ) newSize=limit;
-       }
-       tmp=ByteBuffer.allocate(newSize);
-       
-       System.arraycopy(bb.array(), start, tmp.array(), 0, end-start);
-       bb = tmp;
-       tmp = null;
-       end=end-start;
-       start=0;
-    }
     
     // -------------------- Conversion and getters --------------------
-
+    // all modes
+    
     public String toString() {
         if (null == bb.array()) {
             return null;
@@ -685,7 +800,7 @@
        int srcEnd = srcOff + srcLen;
         
        for( int i=myOff+start; i <= (end - srcLen); i++ ) {
-           if( bb.get(i) != first ) continue;
+           if( bb.array()[i] != first ) continue;
            // found first char, now look for a match
             int myPos=i+1;
 
@@ -694,15 +809,11 @@
                 break;
             }
             
-            try {
-           for( int srcPos=srcOff + 1; srcPos< srcEnd; ) {
-                if( bb.get(myPos++) != src.charAt( srcPos++ ))
+            for( int srcPos=srcOff + 1; srcPos< srcEnd; ) {
+                if( bb.array()[myPos++] != src.charAt( srcPos++ ))
                    break;
                 if( srcPos==srcEnd ) return i-start; // found it
            }
-            } catch( Throwable t ) {
-                t.printStackTrace();
-            }
        }
        return -1;
     }

Modified: tomcat/sandbox/java/org/apache/tomcat/util/net/SimpleEndpoint.java
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/java/org/apache/tomcat/util/net/SimpleEndpoint.java?rev=377051&r1=377050&r2=377051&view=diff
==============================================================================
--- tomcat/sandbox/java/org/apache/tomcat/util/net/SimpleEndpoint.java 
(original)
+++ tomcat/sandbox/java/org/apache/tomcat/util/net/SimpleEndpoint.java Sat Feb 
11 12:42:42 2006
@@ -170,33 +170,6 @@
         serverSocket = null;
     }
 
-    protected void unlockAccept() {
-        Socket s = null;
-        try {
-            // Need to create a connection to unlock the accept();
-            if (inet == null) {
-                s = new Socket("127.0.0.1", port);
-            } else {
-                s = new Socket(inet, port);
-                    // setting soLinger to a small value will help shutdown the
-                    // connection quicker
-                s.setSoLinger(true, 0);
-            }
-        } catch(Exception e) {
-            if (log.isDebugEnabled()) {
-                log.debug(sm.getString("endpoint.debug.unlock", "" + port), e);
-            }
-        } finally {
-            if (s != null) {
-                try {
-                    s.close();
-                } catch (Exception e) {
-                    // Ignore
-                }
-            }
-        }
-    }
-
     // -------------------- Private methods
 
     Socket acceptSocket() {

Modified: tomcat/sandbox/resources/runtime.MF
URL: 
http://svn.apache.org/viewcvs/tomcat/sandbox/resources/runtime.MF?rev=377051&r1=377050&r2=377051&view=diff
==============================================================================
--- tomcat/sandbox/resources/runtime.MF (original)
+++ tomcat/sandbox/resources/runtime.MF Sat Feb 11 12:42:42 2006
@@ -1,5 +1,3 @@
-Manifest-Version: 1.0
-Ant-Version: Apache Ant 1.6.2
-Created-By: 1.5.0-b64 (Sun Microsystems Inc.)
-Main-Class: org.apache.catalina.startup.Bootstrap
-
+Manifest-Version: 1.0
+Main-Class: org.apache.tomcat.standalone.Main
+



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

Reply via email to