User: dewayne 
  Date: 01/02/09 21:58:09

  Added:       tomcat/src/main/org/jboss/tomcat TomcatEntry.java
  Log:
  Entry point into Tomcat for new EmbeddedTomcat service.
  
  Revision  Changes    Path
  1.1                  contrib/tomcat/src/main/org/jboss/tomcat/TomcatEntry.java
  
  Index: TomcatEntry.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.tomcat;
  
  import java.beans.*;
  import java.io.*;
  import java.io.IOException;
  import java.lang.reflect.*;
  import java.util.Hashtable;
  import java.util.*;
  import java.net.*;
  
  import org.apache.tomcat.startup.HostConfig;
  import org.apache.tomcat.util.*;
  import org.apache.tomcat.util.xml.*;
  import org.apache.tomcat.core.*;
  import org.xml.sax.*;
  
  import org.apache.tomcat.net.*;
  import org.apache.tomcat.request.*;
  import org.apache.tomcat.service.*;
  import org.apache.tomcat.service.http.*;
  import org.apache.tomcat.session.StandardSessionInterceptor;
  import org.apache.tomcat.context.*;
  import java.security.*;
  import javax.servlet.ServletContext;
  
  /**
   * Entry point for embedding tomcat into jBoss.
   *
   * Starter for Tomcat using XML.
   * Based on Ant.
   *
   * @author [EMAIL PROTECTED]
   * @author Dewayne McNair ([EMAIL PROTECTED])
   *
   *
   * This class started it's life as org.apache.tomcat.startup.Tomcat.java
   * I (Dewayne) modified it for use in JBoss to give JBoss a clean
   * way of starting Tomcat in the same VM as JBoss.  The older
   * method was using
   * org.apache.tomcat.startup.EmbededTomcat which didn't offer
   * the appropriate methods to handle all of the server.xml connectors.
   *
   * The only downside to this method is that the dynamic deployment
   * facility in JBoss can't really be used because we can't dynamically
   * add mount points to Apache (an Apache 1.3 shortcomming -- hopefully
   * that will change in 2.0)
   *
   */
  public class TomcatEntry {
  
      private static StringManager sm =
        StringManager.getManager("org.apache.tomcat.resources");
  
        private ContextManager m_contextMgr = null;
  
      private FacadeManager m_facadeMgr = null;
  
      private Hashtable extraClassPaths = new Hashtable();
  
      public TomcatEntry() {
          try
          {
              String[] args = new String[0];
                execute( args );
          }
          catch (Exception e)
          {
              e.printStackTrace();
          }
      }
  
      public ServletContext addContext( String ctxPath, URL docRoot )
      {
          // tomcat supports only file-based contexts
          if( ! "file".equals( docRoot.getProtocol()) ) {
              // log( "addContext() invalid docRoot: " + docRoot );
              throw new RuntimeException("Invalid docRoot " + docRoot );
          }
  
          try {
              Context ctx=new Context();
              // ctx.setDebug( debug );
              ctx.setContextManager( m_contextMgr );
              ctx.setPath( ctxPath );
              // XXX if virtual host set it.
              ctx.setDocBase( docRoot.getFile());
              m_contextMgr.addContext( ctx );
              if (m_facadeMgr == null)
                  m_facadeMgr = ctx.getFacadeManager();
              return ctx.getFacade();
          } catch( Exception ex ) {
              ex.printStackTrace();
          }
          return null;
      }
  
      /** Remove a context
       */
      public void removeContext( ServletContext sctx ) {
          // if(debug>0) log( "remove context " + sctx );
          try {
              if( m_facadeMgr ==null ) {
                  System.out.println("XXX ERROR: no facade manager");
                  return;
              }
              Context ctx=m_facadeMgr .getRealContext( sctx );
              m_contextMgr.removeContext( ctx );
          } catch( Exception ex ) {
              ex.printStackTrace();
          }
      }
  
  
      /** This will make the context available.
       */
      public void initContext( ServletContext sctx )
      {
          try {
              if( m_facadeMgr == null ) {
                  System.out.println("XXX ERROR: no facade manager");
                  return;
              }
              Context ctx = m_facadeMgr.getRealContext( sctx );
              m_contextMgr.initContext( ctx );
  
              ServletLoader sl=ctx.getServletLoader();
              Object pd=ctx.getProtectionDomain();
  
              // Add any extra cpaths
              Vector cp=(Vector)extraClassPaths.get( sctx );
              if( cp!=null ) {
                  for( int i=0; i<cp.size(); i++ ) {
                      String cpath=(String)cp.elementAt(i);
                      sl.addRepository( new File(cpath), pd);
                  }
              }
          } catch( Exception ex ) {
              ex.printStackTrace();
          }
      }
  
      // Set the mappings
      void setHelper( XmlMapper xh ) {
        xh.addRule( "ContextManager", xh.setProperties() );
  
        xh.addRule( "ContextManager/ContextInterceptor",
                    xh.objectCreate(null, "className"));
        xh.addRule( "ContextManager/ContextInterceptor",
                    xh.setProperties() );
        xh.addRule( "ContextManager/ContextInterceptor",
                    xh.setParent("setContextManager") );
        xh.addRule( "ContextManager/ContextInterceptor",
                    xh.addChild( "addContextInterceptor",
                                 "org.apache.tomcat.core.ContextInterceptor"));
  
        xh.addRule( "ContextManager/RequestInterceptor",
                    xh.objectCreate(null, "className"));
        xh.addRule( "ContextManager/RequestInterceptor",
                    xh.setProperties() );
        xh.addRule( "ContextManager/RequestInterceptor",
                    xh.setParent("setContextManager") );
        xh.addRule( "ContextManager/RequestInterceptor",
                    xh.addChild( "addRequestInterceptor",
                                 "org.apache.tomcat.core.RequestInterceptor"));
  
        // Default host
        xh.addRule( "ContextManager/Context",
                    xh.objectCreate("org.apache.tomcat.core.Context"));
        xh.addRule( "ContextManager/Context",
                    xh.setParent( "setContextManager") );
        xh.addRule( "ContextManager/Context",
                    xh.setProperties() );
        xh.addRule( "ContextManager/Context",
                    xh.addChild( "addContext", null ) );
  
        // Virtual host support.
        // Push a host object on the stack
        xh.addRule( "ContextManager/Host", new XmlAction() {
                public void start( SaxContext ctx) throws Exception {
                    Stack st=ctx.getObjectStack();
                    // get attributes 
                    int top=ctx.getTagCount()-1;
                    AttributeList attributes = ctx.getAttributeList( top );
  
                    // get CM
                    ContextManager cm=(ContextManager)st.peek();
  
                    // construct virtual host config helper
                    HostConfig hc=new HostConfig(cm);
  
                    // set the host name
                    hc.setName( attributes.getValue("name")); 
                    st.push( hc );
                }
                public void cleanup( SaxContext ctx) {
                    Stack st=ctx.getObjectStack();
                    Object o=st.pop();
                }
            });
        xh.addRule( "ContextManager/Host", xh.setProperties());
        
        xh.addRule( "ContextManager/Host/Context",
                    xh.objectCreate("org.apache.tomcat.core.Context"));
        xh.addRule( "ContextManager/Host/Context",
                    xh.setProperties() );
        xh.addRule( "ContextManager/Host/Context", new XmlAction() {
                public void end( SaxContext ctx) throws Exception {
                    Stack st=ctx.getObjectStack();
                    
                    Context tcCtx=(Context)st.pop(); // get the Context
                    HostConfig hc=(HostConfig)st.peek();
                    st.push( tcCtx );
                    // put back the context, to be cleaned up corectly
                    
                    hc.addContext( tcCtx );
                }
            });
      }
  
      void setConnectorHelper( XmlMapper xh ) {
        xh.addRule( "ContextManager/Connector",
                    xh.objectCreate(null, "className"));
        xh.addRule( "ContextManager/Connector",
                    xh.setParent( "setServer", "java.lang.Object") );
        xh.addRule( "ContextManager/Connector",
                    xh.addChild( "addServerConnector",
                                 "org.apache.tomcat.core.ServerConnector") );
  
        xh.addRule( "ContextManager/Connector/Parameter",
                    xh.methodSetter("setProperty",2) );
        xh.addRule( "ContextManager/Connector/Parameter",
                    xh.methodParam(0, "name") );
        xh.addRule( "ContextManager/Connector/Parameter",
                    xh.methodParam(1, "value") );
      }
  
  
      /** Setup loggers when reading the configuration file - this will be
       *  called only when starting tomcat as deamon, all other modes will
       * output to stderr
       */
      void setLogHelper( XmlMapper xh ) {
        xh.addRule("Server/Logger",
                   xh.objectCreate("org.apache.tomcat.logging.TomcatLogger"));
        xh.addRule("Server/Logger", xh.setProperties());
        xh.addRule("Server/Logger", 
                   xh.addChild("addLogger",
                               "org.apache.tomcat.logging.Logger") );
      }
  
      /**
       * Return the configuration file we are processing.  If the
       * <code>-config filename</code> command line argument is not
       * used, the default configuration filename will be loaded from
       * the TOMCAT_HOME directory.
       *
       * If a relative config file is used, it will be relative to the current
       * working directory.
       *
       * @param cm The ContextManager we are configuring
       **/
      File getConfigFile(ContextManager cm) {
        // If configFile is already set, use it
        if (configFile != null)
            return (new File(configFile));
  
        // Use the "tomcat.home" property to resolve the default filename
        String tchome = System.getProperty("tomcat.home");
        if (tchome == null) {
            System.out.println(sm.getString("tomcat.nohome"));
            tchome = ".";
            // Assume current working directory
        }
        // Home will be identical to tomcat home if default config is used.
        cm.setInstallDir(tchome);
        return (new File(tchome, DEFAULT_CONFIG));
  
      }
  
      public void execute(String args[] ) throws Exception {
        if( ! processArgs( args ) ) {
            return;
        }
  
        if( doStop ) {
            System.out.println(sm.getString("tomcat.stop"));
            stopTomcat(); // stop serving
            return;
        }
  
        XmlMapper xh=new XmlMapper();
        xh.setDebug( 0 );
        m_contextMgr = new ContextManager();
        setHelper( xh );
        setConnectorHelper( xh );
        setLogHelper( xh );
  
        File f = getConfigFile(m_contextMgr);
        try {
            xh.readXml(f,m_contextMgr);
        } catch( Exception ex ) {
            System.out.println(sm.getString("tomcat.fatalconfigerror") );
            ex.printStackTrace();
            // System.exit(1);
        }
  
        System.out.println(sm.getString("tomcat.start"));
        m_contextMgr.init(); // set up contexts
  
        m_contextMgr.start(); // start serving
      }
  
      
      /** Stop tomcat using the configured cm
       *  The manager is set up using the same configuration file, so
       *  it will have the same port as the original instance ( no need
       *  for a "log" file).
       *  It uses the Ajp12 connector, which has a built-in "stop" method,
       *  that will change when we add real callbacks ( it's equivalent
       *  with the previous RMI method from almost all points of view )
       */
      public void stopTomcat() throws TomcatException {
        XmlMapper xh=new XmlMapper();
        xh.setDebug( 0 );
        ContextManager cm=new ContextManager();
        setConnectorHelper( xh );
        File f = getConfigFile(cm);
        try {
            xh.readXml(f,cm);
        } catch( Exception ex ) {
            System.out.println(sm.getString("tomcat.fatalconfigerror") );
            ex.printStackTrace();
            // System.exit(1);
        }
        
        org.apache.tomcat.task.StopTomcat stopTc=
            new  org.apache.tomcat.task.StopTomcat();
        stopTc.execute( cm );     
      }
      
      // -------------------- Command-line args processing --------------------
      // null means user didn't set one
      String configFile=null;
      // relative to TOMCAT_HOME 
      static final String DEFAULT_CONFIG="conf/server.xml";
  
      boolean doStop=false;
      
      /** Process arguments - set object properties from the list of args.
       */
      public  boolean processArgs(String[] args) {
        for (int i = 0; i < args.length; i++) {
            String arg = args[i];
              
            if (arg.equals("-help") || arg.equals("help")) {
                // printUsage();
                return false;
            } else if (arg.equals("-stop")) {
                doStop=true;
            } else if (arg.equals("-f") || arg.equals("-config")) {
                i++;
                if( i < args.length ) {
                    configFile = args[i];
                  } else {
                      // printUsage();
                      return (false);
                  }
            } else if (arg.equals("-h") || arg.equals("-home")) {
                i++;
                if (i < args.length) {
                    System.getProperties().put("tomcat.home", args[i]);
                  } else {
                      // // printUsage();
                      return (false);
                  }
              } else {
                  // printUsage();
                  return false;
            }
        }
        return true;
      }        
  
  }
  
  
  

Reply via email to