You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by la...@apache.org on 2001/08/16 07:24:14 UTC

cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/modules/config JservConfig.java

larryi      01/08/15 22:24:14

  Modified:    src/share/org/apache/tomcat/modules/config JservConfig.java
  Log:
  Updated to have features similar to ApacheConfig.
  
  Revision  Changes    Path
  1.3       +467 -199  jakarta-tomcat/src/share/org/apache/tomcat/modules/config/JservConfig.java
  
  Index: JservConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/modules/config/JservConfig.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- JservConfig.java	2001/07/19 20:23:34	1.2
  +++ JservConfig.java	2001/08/16 05:24:14	1.3
  @@ -61,53 +61,75 @@
   import org.apache.tomcat.util.io.FileUtil;
   import org.apache.tomcat.util.log.*;
   import java.io.*;
  -import java.net.*;
   import java.util.*;
   
   // Used to find Ajp1? connector port
   import org.apache.tomcat.modules.server.Ajp12Interceptor;
  -import org.apache.tomcat.modules.server.Ajp13Interceptor;
   
   /**
  -   
  -    Generates automatic apache configurations based on
  +    Generates automatic apache mod_jserv configurations based on
       the Tomcat server.xml settings and the war contexts
       initialized during startup.
       <p>
  -    This config interceptor is enabled by inserting an ApacheConfig
  +    This config interceptor is enabled by inserting a JservConfig
       element in the <b>\<ContextManager></b> tag body inside
       the server.xml file like so:
       <pre>
       * < ContextManager ... >
       *   ...
  -    *   <<b>JServConfig</b> <i>options</i> />
  +    *   <<b>JservConfig</b> <i>options</i> />
       *   ...
       * < /ContextManager >
       </pre>
       where <i>options</i> can include any of the following attributes:
       <ul>
  -     <li><b>confighome</b> - default parent directory for the following paths.
  +     <li><b>configHome</b> - default parent directory for the following paths.
                               If not set, this defaults to TOMCAT_HOME. Ignored
                               whenever any of the following paths is absolute.
                                </li>
  -     <li><b>jservconfig</b> - path to write apache jserv conf file to. If
  -                             not set, defaults to
  -                             "conf/jserv/tomcat-apache.conf".</li>
  -     <li><b>modjserv</b> - path to Apache JServ plugin module file. If not 
  -                           set, defaults to "modules/ApacheModuleJServ.dll"
  -                           on windows, "modules/Jserv.nlm" on netware, and 
  -                           "libexec/mod_jserv.so" everywhere else.</li>
  -     <li><b>jklog</b> - path to log file to be used by mod_jk.</li>                       
  +     <li><b>jservConfig</b> - path to use for writing Apache mod_jserv conf file. If
  +                              not set, defaults to
  +                              "conf/auto/tomcat-apache.conf".</li>
  +     <li><b>modJServ</b> - path to Apache mod_jserv plugin file.  If not set,
  +                           defaults to "modules/ApacheModuleJserv.dll" on windows,
  +                           and "libexec/mod_jserv.so" everywhere else.</li>
  +     <li><b>jservLog</b> - path to log file to be used by mod_jserv.</li>
  +     <li><b>jservDebug</b> - Jserv Loglevel setting.  May be debug, info, notice,
  +                             warn, error, crit, alert, or emerg.
  +                             If not set, defaults to debug.</li>
  +     <li><b>forwardAll</b> - If true, forward all requests to Tomcat. This helps
  +                             insure that all the behavior configured in the web.xml
  +                             file functions correctly.  If false, let Apache serve
  +                             static resources. The default is true.
  +                             Warning: When false, some configuration in
  +                             the web.xml may not be duplicated in Apache.
  +                             Review the tomcat-apache conf file to see what
  +                             configuration is actually being set in Apache.</li>
  +     <li><b>noRoot</b> - If true, the root context is not mapped to
  +                         Tomcat.  If false and forwardAll is true, all requests
  +                         to the root context are mapped to Tomcat. If false and
  +                         forwardAll is false, only JSP and servlets requests to
  +                         the root context are mapped to Tomcat. When false,
  +                         to correctly serve Tomcat's root context you must also
  +                         modify the DocumentRoot setting in Apache's httpd.conf
  +                         file to point to Tomcat's root context directory.
  +                         Otherwise some content, such as Apache's index.html,
  +                         will be served by Apache before mod_jserv gets a chance
  +                         to claim the request and pass it to Tomcat.
  +                         The default is true.</li>
       </ul>
  -    <p>
  +  <p>
       @author Costin Manolache
  +    @author Larry Isaacs
       @author Mel Martinez
  -	@version $Revision: 1.2 $ $Date: 2001/07/19 20:23:34 $
  +        @version $Revision: 1.3 $ $Date: 2001/08/16 05:24:14 $
    */
   public class JservConfig  extends BaseInterceptor { 
       
       /** default path to JServ .conf location */
  -    public static final String APACHE_CONFIG="conf/jserv/tomcat-apache.conf";
  +    public static final String APACHE_CONFIG="conf/auto/tomcat-apache.conf";
  +    /** default mod_jserv log file location */
  +    public static final String JSERV_LOG_LOCATION = "logs/mod_jserv.log";
       /** default location of mod_jserv Apache plug-in. */
       public static final String MOD_JSERV;
       public static final String AJPV12="ajpv12";
  @@ -117,8 +139,6 @@
           String os = System.getProperty("os.name").toLowerCase();
           if(os.indexOf("windows")>=0){
              MOD_JSERV = "modules/ApacheModuleJserv.dll";
  -        }else if(os.indexOf("netware")>=0){
  -           MOD_JSERV = "modules/Jserv.nlm";
           }else{
              MOD_JSERV = "libexec/mod_jserv.so";
           }
  @@ -126,8 +146,19 @@
       
       private File configHome = null;
       private File jservConfig = null;
  -    private File workersConfig = null;
       private File modJserv = null;
  +    private File jservLog = null;
  +
  +    private String tomcatHome;
  +
  +    private String jservDebug=null;
  +    private boolean noRoot=true;
  +
  +    // default is true until we can map all web.xml directives
  +    // Or detect only portable directives were used.
  +    boolean forwardAll=true;
  +
  +    Hashtable NamedVirtualHosts=null;
       
       public JservConfig() {
       }
  @@ -156,49 +187,56 @@
       	}
       }
       
  +    //-------------------- Properties --------------------
  +
  +    /** If false, we'll try to generate a config that will
  +     *  let apache serve static files.
  +     *  The default is true, forward all requests in a context
  +     *  to tomcat. 
  +     */
  +    public void setForwardAll( boolean b ) {
  +        forwardAll=b;
  +    }
  +
  +    /** Special option - do not generate mappings for the ROOT
  +        context. The default is true, and will not generate the mappings,
  +        not redirecting all pages to tomcat (since /* matches everything).
  +        This means that Apache's root remains intact but isn't completely
  +        servlet/JSP enabled. If the ROOT webapp can be configured with
  +        apache serving static files, there's no problem setting this
  +        option to false. If not, then setting it true means Apache will
  +        be out of picture for all requests.
  +    */
  +    public void setNoRoot( boolean b ) {
  +        noRoot=b;
  +    }
  +
       /**
           set a path to the parent directory of the
           conf folder.  That is, the parent directory
  -        within which setJservConfig(), setJkConfig()
  -        and setWorkerConfig() paths would be resolved against
  +        within which setJkConfig() and other path
  +        setters would be resolved against
           if relative.  For example if ConfigHome is set to "/home/tomcat"
  -        and JkConfig is set to "conf/mod_jk.conf" then the resulting 
  -        path returned from getJkConfig() would be: 
  -        "/home/tomcat/conf/mod_jk.conf".</p>
  +        and JservConfig is set to "conf/tomcat-apache.conf" then the resulting 
  +        path used would be: 
  +        "/home/tomcat/conf/tomcat-apache.conf".</p>
           <p>
  -        However, if JkConfig, JservConfig or WorkersConfig
  -        are set to absolute paths, this attribute is ignored.
  +        However, if JservConfig or other path
  +        is set to an absolute path, this attribute is ignored.
           <p>
           If not set, execute() will set this to TOMCAT_HOME.
           <p>
           @param <b>dir</b> - path to a directory
       */
       public void setConfigHome(String dir){
  -        setConfigHome(dir==null?null:new File(dir));
  -    }
  -    
  -    /**
  -        set a path to the parent directory of the
  -        conf folder.  That is, the parent directory
  -        within which setJservConfig(), setJkConfig()
  -        and setWorkerConfig() paths would be resolved against
  -        if relative.  For example if ConfigHome is set to "/home/tomcat"
  -        and JkConfig is set to "conf/mod_jk.conf" then the resulting 
  -        path returned from getJkConfig() would be: 
  -        "/home/tomcat/conf/mod_jk.conf".</p>
  -        <p>
  -        However, if JkConfig, JservConfig or WorkersConfig
  -        are set to absolute paths, this attribute is ignored.
  -        <p>
  -        @param <b>dir</b> - path to a directory
  -    */    
  -    public void setConfigHome(File dir){
  -        if(!dir.isDirectory()){
  +        if( dir==null ) return;
  +        File f=new File(dir);
  +        if(!f.isDirectory()){
               throw new IllegalArgumentException(
  -                "ApacheConfig.setConfigHome(): "+
  +                "JservConfig.setConfigHome(): "+
                   "Configuration Home must be a directory! : "+dir);
           }
  -        configHome = dir;
  +        configHome = f;
       }
       
       /**
  @@ -226,44 +264,6 @@
           
       }
   
  -
  -    /**
  -        return a File object pointing to the output file
  -        in which to write the mod_jserv configuration.
  -        If the path set using setJservConfig() was absolute,
  -        then this simply returns that File object.
  -        If the path set using setJservConfig() was relative
  -        then this method will first try to resolve it
  -        absolutely against the path returned from getConfigHome().
  -        If getConfigHome()==null, then instead the path
  -        will be resolved absolutely against the current
  -        directory (System.getProperty("user.dir")).
  -        <p>
  -        @return a File object.
  -    */
  -    public File getJservConfig(){
  -        if(jservConfig==null){
  -            jservConfig = new File(APACHE_CONFIG);
  -        }
  -        File jservF = jservConfig;
  -        if(!jservF.isAbsolute()){
  -            if(getConfigHome()!=null){
  -                jservF = new File(
  -                    getConfigHome(),jservF.getPath());
  -            }else{ //resolve against user.dir (implicit)
  -                jservF = new File(jservF.getAbsolutePath());
  -            }
  -        }
  -        File parent = new File(jservF.getParent());
  -        if(!parent.exists()){
  -            if(!parent.mkdirs()){
  -                throw new RuntimeException(
  -                    "Unable to create path to config file :"+jservF);
  -            }
  -        }
  -        return jservF;
  -    }
  -  
       /**
           set the path to the Jserv Apache Module
           @param <b>path</b> String path to a file
  @@ -281,132 +281,400 @@
       }
   
       /**
  -        returns the path to the apache module mod_jserv.  
  -        If the path set with setModJserv() was relative, this method 
  -        will try first to resolve it absolutely 
  -        against the return value of getConfigHome().  If that is null, then
  -        it instead will resolve against the current user.dir.
  -        If this file doesn't exist, the relative path is returned.
  -        <p>
  -        @return a File object with the path to the mod_jserv.so file.
  +        set the path to the mod_jserv log file
  +        @param <b>path</b> String path to a file
       */
  -    public File getModJserv(){
  -        if(modJserv==null){
  -            modJserv=new File(MOD_JSERV);
  -        }
  -        File jservF = modJserv;
  -        if(!jservF.isAbsolute()){
  -            if(getConfigHome()!=null){
  -                jservF = new File(getConfigHome(),jservF.getPath());
  -            }else{//resolve against user.dir
  -                jservF = new File(jservF.getAbsolutePath());
  -            }
  -	    if( !jservF.exists() )
  -		jservF = modJserv;
  +    public void setJservLog(String path){
  +        jservLog= ( path==null?null:new File(path));
  +    }
  +
  +    /** Set the verbosity level for mod_jserv.
  +        ( use debug, error, etc. ) If not set, no log is written.
  +     */
  +    public void setJservDebug( String level ) {
  +        jservDebug=null;
  +    }
  +
  +    // -------------------- Initialize/guess defaults --------------------
  +
  +    /** Initialize defaults for properties that are not set
  +        explicitely
  +    */
  +    public void initProperties(ContextManager cm) {
  +        tomcatHome = cm.getHome();
  +        File tomcatDir = new File(tomcatHome);
  +        if(configHome==null){
  +            configHome=tomcatDir;
           }
  -       return jservF;
  +        
  +        jservConfig=FileUtil.getConfigFile( jservConfig, configHome, APACHE_CONFIG);
  +
  +        if( modJserv == null )
  +            modJserv=new File(MOD_JSERV);
  +        else
  +            modJserv=FileUtil.getConfigFile( modJserv, configHome, MOD_JSERV );
  +        jservLog=FileUtil.getConfigFile( jservLog, configHome, JSERV_LOG_LOCATION);
       }
  -    
  +
  +
  +    // -------------------- Generate config --------------------
  +
       /**
  -        executes the ApacheConfig interceptor. This method generates apache
  -        configuration files for use with mod_jserv or mod_jk.  If not
  +        executes the JservConfig interceptor. This method generates apache
  +        configuration files for use with mod_jserv.  If not
           already set, this method will setConfigHome() to the value returned
           from <i>cm.getHome()</i>.
           <p>
           @param <b>cm</b> a ContextManager object.
       */
       public void execute(ContextManager cm) throws TomcatException {
  -    	try {
  -    	    String tomcatHome = cm.getHome();
  -    	    File tomcatDir = new File(tomcatHome);
  -    	    
  -    	    if(getConfigHome()==null){
  -    	        setConfigHome(tomcatDir);
  -    	    }
  -    	    
  -    	    PrintWriter pw=new PrintWriter(new FileWriter(getJservConfig()));
  -    	    log("Generating apache mod_jserv config = "+getJservConfig() );
  -
  -            //insert LoadModule calls:
  -            pw.println("<IfModule !mod_jserv.c>");
  -            pw.println("  LoadModule jserv_module "+
  -                     getModJserv().toString().replace('\\','/'));
  -            pw.println("</IfModule>");
  -
  -    	    pw.println("ApJServManual on");
  -    	    pw.println("ApJServDefaultProtocol " + AJPV12);
  -    	    pw.println("ApJServSecretKey DISABLED");
  -    	    pw.println("ApJServMountCopy on");
  -    	    pw.println("ApJServLogLevel notice");
  -    	    pw.println();
  -
  -    	    // Find Ajp1? connectors
  -    	    int portInt=8007;
  -    	    BaseInterceptor ci[]=cm.getContainer().getInterceptors();
  -    	    for( int i=0; i<ci.length; i++ ) {
  -		Object con=ci[i];
  -		if( con instanceof  Ajp12Interceptor ) {
  -		    Ajp12Interceptor tcpCon=(Ajp12Interceptor) con;
  -		    portInt=tcpCon.getPort();
  -		}
  -    	    }
  -    	    pw.println("ApJServDefaultPort " + portInt);
  -    	    pw.println();
  -
  -    	    pw.println("AddType text/jsp .jsp");
  -    	    pw.println("AddHandler jserv-servlet .jsp");
  -    	    pw.println();
  -
  -
  -    	    // Set up contexts
  -    	    // XXX deal with Virtual host configuration !!!!
  -    	    Enumeration  enum = cm.getContexts();
  -    	    while (enum.hasMoreElements()) {
  -                Context context = (Context)enum.nextElement();
  -                String path  = context.getPath();
  -                String vhost = context.getHost();
  +        try {
  +            initProperties(cm);
   
  -                if( vhost != null ) {
  -                    // Generate Apache VirtualHost section for this host
  -                    // You'll have to do it manually right now
  -                    // XXX
  -                    continue;
  -                }
  -                if( path.length() > 1) {
  +            NamedVirtualHosts = new Hashtable();  
   
  -                    // It's not the root context
  -                    // assert path.startsWith( "/" )
  +            PrintWriter pw=new PrintWriter(new FileWriter(jservConfig));
  +            log("Generating apache mod_jserv config = "+jservConfig );
   
  -                    // Calculate the absolute path of the document base
  -                    String docBase = context.getDocBase();
  -                    if (!FileUtil.isAbsolute(docBase)){
  -                	    docBase = tomcatHome + "/" + docBase;
  -                    }
  -                    docBase = FileUtil.patch(docBase);
  -		    if (File.separatorChar == '\\')
  -			docBase = docBase.replace('\\','/');// use separator preferred by Apache
  -		    
  -                    // All pages will be served by tomcat.
  -		    // So far nobody found a solution that can configure apache to
  -		    // match web.xml, until this happen we can't do too much.
  -
  -		    // In mod_jk/Ajp14 we'll provide special solution to redirect
  -		    // static pages to apache, and avoid overhead
  -                    pw.println("ApJServMount " + path  + " " + path);
  -
  -                } else {
  -                    // the root context
  -                    // XXX use a non-conflicting name
  -                    pw.println("ApJServMount / /ROOT");
  -                }
  +            // generate header
  +            generateJservHead(pw,cm);
   
  -    	    }//end while(enum)
  +            // Set up contexts
  +            // XXX deal with Virtual host configuration !!!!
  +            Enumeration  enum = cm.getContexts();
  +            while (enum.hasMoreElements()) {
  +                Context context = (Context)enum.nextElement();
  +                if( forwardAll )
  +                    generateStupidMappings( context, pw );
  +                else
  +                    generateContextMappings( context, pw );
  +            }
   
  -    	    pw.close();
  -    	} catch( Exception ex ) {
  +            pw.close();
  +        } catch( Exception ex ) {
               Log loghelper = Log.getLog("tc_log", this);
  -    	    loghelper.log("Error generating automatic apache configuration", ex);
  -    	}
  +            loghelper.log("Error generating automatic apache configuration", ex);
  +        }
       }//end execute()
  +
  +    // -------------------- Config sections  --------------------
  +
  +    /** Generate the loadModule and general options
  +     */
  +    private boolean generateJservHead(PrintWriter pw, ContextManager cm)
  +        throws TomcatException
  +    {
  +        //insert LoadModule calls:
  +        pw.println("<IfModule !mod_jserv.c>");
  +        pw.println("  LoadModule jserv_module "+
  +                 modJserv.toString().replace('\\','/'));
  +        pw.println("</IfModule>");
  +
  +        pw.println("ApJServManual on");
  +        pw.println("ApJServDefaultProtocol " + AJPV12);
  +        pw.println("ApJServSecretKey DISABLED");
  +        pw.println("ApJServMountCopy on");
  +        pw.println("ApJServLogLevel notice");
  +        pw.println();
  +
  +        // Find Ajp12 connector
  +        int portInt=8007;
  +        BaseInterceptor ci[]=cm.getContainer().getInterceptors();
  +        for( int i=0; i<ci.length; i++ ) {
  +            Object con=ci[i];
  +            if( con instanceof  Ajp12Interceptor ) {
  +                Ajp12Interceptor tcpCon=(Ajp12Interceptor) con;
  +                portInt=tcpCon.getPort();
  +            }
  +        }
  +        pw.println("ApJServDefaultPort " + portInt);
  +        pw.println();
  +        return true;
  +    }
  +
  +    // -------------------- Forward all mode --------------------
  +    String indent="";
       
  -}//end class ApacheConfig
  +    /** Forward all requests for a context to tomcat.
  +        The default.
  +     */
  +    private void generateStupidMappings(Context context,
  +                                           PrintWriter pw )
  +    {
  +        String ctxPath  = context.getPath();
  +        String vhost = context.getHost();
  +        String nPath=("".equals(ctxPath)) ? "/" : ctxPath;
  +
  +        if( noRoot &&  "".equals(ctxPath) ) {
  +            log("Ignoring root context in forward-all mode  ");
  +            return;
  +        } 
  +        if( vhost != null ) {
  +            String vhostip = getVirtualHostAddress(vhost,
  +                                            context.getHostAddress());
  +            generateNameVirtualHost(pw, vhostip);
  +            pw.println("<VirtualHost " + vhostip + ">");
  +            pw.println("    ServerName " + vhost );
  +            Enumeration aliases=context.getHostAliases();
  +            if( aliases.hasMoreElements() ) {
  +                pw.print("    ServerAlias " );
  +                while( aliases.hasMoreElements() ) {
  +                    pw.print( (String)aliases.nextElement() + " " );
  +                }
  +                pw.println();
  +            }
  +            indent="    ";
  +        }
  +
  +        pw.println(indent + "ApJServMount " +  nPath + " " + nPath );
  +        if( "".equals(ctxPath) )
  +            pw.println(indent + "ApJServMount " +  nPath + "* " + nPath );
  +        else
  +            pw.println(indent + "ApJServMount " +  nPath + "/* " + nPath );
  +        if( vhost != null ) {
  +            pw.println("</VirtualHost>");
  +            pw.println();
  +            indent="";
  +        }
  +    }    
  +
  +    private void generateNameVirtualHost( PrintWriter pw, String ip ) {
  +        if( !NamedVirtualHosts.containsKey(ip) ) {
  +            pw.println("NameVirtualHost " + ip + "");
  +            NamedVirtualHosts.put(ip,ip);
  +        }
  +    }
  +
  +
  +    // -------------------- Apache serves static mode --------------------
  +    // This is not going to work for all apps. We fall back to stupid mode.
  +    
  +    private void generateContextMappings(Context context, PrintWriter pw )
  +    {
  +        String ctxPath  = context.getPath();
  +        String vhost = context.getHost();
  +
  +        if( noRoot &&  "".equals(ctxPath) ) {
  +            log("Ignoring root context in non-forward-all mode  ");
  +            return;
  +        } 
  +        pw.println();
  +        pw.println("#################### " +
  +                       ((vhost!=null ) ? vhost + ":" : "" ) +
  +                       (("".equals(ctxPath)) ? "/" : ctxPath ) +
  +                       " ####################" );
  +        pw.println();
  +        if( vhost != null ) {
  +            String vhostip = getVirtualHostAddress(vhost,
  +                                            context.getHostAddress());
  +            generateNameVirtualHost(pw, vhostip);
  +            pw.println("<VirtualHost " + vhostip + ">");
  +            pw.println("    ServerName " + vhost );
  +            Enumeration aliases=context.getHostAliases();
  +            if( aliases.hasMoreElements() ) {
  +                pw.print("    ServerAlias " );
  +                while( aliases.hasMoreElements() ) {
  +                    pw.print( (String)aliases.nextElement() + " " );
  +                }
  +                pw.println();
  +            }
  +            indent="    ";
  +        }
  +        // Dynamic /servet pages go to Tomcat
  +        
  +        generateStaticMappings( context, pw );
  +
  +        // InvokerInterceptor - it doesn't have a container,
  +        // but it's implemented using a special module.
  +        
  +        // XXX we need to better collect all mappings
  +        addMapping( ctxPath + "/servlet/*", ctxPath, pw );
  +            
  +        Enumeration servletMaps=context.getContainers();
  +        while( servletMaps.hasMoreElements() ) {
  +            Container ct=(Container)servletMaps.nextElement();
  +            addMapping( context, ct , pw );
  +        }
  +        
  +        // There is a big problem with this one - it is
  +        // equivalent with JkMount path/*...
  +        // The good news - there is a container with exactly this
  +        // map ( the real path that is used by form auth ), so no need
  +        // for this one
  +        //mod_jk.println("JkMount " + path + "/*j_security_check " +
  +        //                   jkProto);
  +        //mod_jk.println();
  +        
  +        // XXX ErrorDocument
  +        // Security and filter mappings
  +            
  +        if( vhost != null ) {
  +            pw.println("</VirtualHost>");
  +            indent="";
  +        }
  +    }
  +
  +    // -------------------- Config Utils  --------------------
  +
  +    protected boolean addMapping( Context ctx, Container ct,
  +                                PrintWriter pw )
  +    {
  +        int type=ct.getMapType();
  +        String ctPath=ct.getPath();
  +        String ctxPath=ctx.getPath();
  +
  +        if( type==Container.EXTENSION_MAP ) {
  +            if( ctPath.length() < 3 ) return false;
  +            String ext=ctPath.substring( 2 );
  +            return addExtensionMapping( ctxPath, ext , pw );
  +        }
  +        String fullPath=null;
  +        if( ctPath.startsWith("/" ))
  +            fullPath=ctxPath+ ctPath;
  +        else
  +            fullPath=ctxPath + "/" + ctPath;
  +        return addMapping( fullPath, ctxPath, pw);
  +    }
  +
  +    /** Add an Apache extension mapping.
  +     */
  +    protected boolean addExtensionMapping( String ctxPath, String ext,
  +                                         PrintWriter pw )
  +    {
  +        if( debug > 0 )
  +            log( "Adding extension map for " + ctxPath + "/*." + ext );
  +        pw.println(indent + "AddHandler jserv-servlet ." + ext);
  +        if ( "jsp".equals(ext) ) {
  +            pw.println(indent + "# Forward non-cookie session requests");
  +            pw.println(indent + "<LocationMatch \"" + ctxPath + "/.*;jsessionid=.*\">");
  +            pw.println(indent + "    SetHandler jserv-servlet");
  +            pw.println(indent + "</LocationMatch>");
  +        }
  +        return true;
  +    }
  +   
  +    /** Add a fulling specified Appache mapping.
  +     */
  +    protected boolean addMapping( String fullPath, String app, PrintWriter pw ) {
  +        if( debug > 0 )
  +            log( "Adding map for " + fullPath );
  +        pw.println(indent + "ApJServMount " + fullPath + "  " + app );
  +        return true;
  +    }
  +
  +
  +    private void generateWelcomeFiles(Context context, PrintWriter pw ) {
  +        String wf[]=context.getWelcomeFiles();
  +        if( wf==null || wf.length == 0 )
  +            return;
  +        pw.print(indent + "    DirectoryIndex ");
  +        for( int i=0; i<wf.length ; i++ ) {
  +            pw.print( wf[i] + " " );
  +        }
  +        pw.println();
  +    }
  +
  +    /** Mappings for static content. XXX need to add welcome files,
  +     *  mime mappings ( all will be handled by Mime and Static modules of
  +     *  apache ).
  +     */
  +    private void generateStaticMappings(Context context, PrintWriter pw ) {
  +        String ctxPath  = context.getPath();
  +
  +        // Calculate the absolute path of the document base
  +        String docBase = getApacheDocBase(context);
  +
  +        if( !"".equals(ctxPath) ) {
  +            // Static files will be served by Apache
  +            pw.println(indent + "# Static files ");    
  +            pw.println(indent + "Alias " + ctxPath + " \"" + docBase + "\"");
  +            pw.println();
  +        } else {
  +            // For root context, ask user to update DocumentRoot setting.
  +            // Using "Alias / " interferes with the Alias for other contexts.
  +            pw.println(indent +
  +                    "# To correctly serve the Tomcat's root context, DocumentRoot must");
  +            pw.println(indent +
  +                    "# must be set to: \"" + docBase + "\"");
  +        }
  +        pw.println(indent + "<Directory \"" + docBase + "\">");
  +        pw.println(indent + "    Options Indexes FollowSymLinks");
  +
  +        generateWelcomeFiles(context, pw);
  +
  +        // XXX XXX Here goes the Mime types and welcome files !!!!!!!!
  +        pw.println(indent + "</Directory>");
  +        pw.println();            
  +        
  +
  +        // Deny serving any files from WEB-INF
  +        pw.println();            
  +        pw.println(indent +
  +                       "# Deny direct access to WEB-INF and META-INF");
  +        pw.println(indent + "#");                        
  +        pw.println(indent + "<Location \"" + ctxPath + "/WEB-INF/*\">");
  +        pw.println(indent + "    AllowOverride None");
  +        pw.println(indent + "    deny from all");
  +        pw.println(indent + "</Location>");
  +        // Deny serving any files from META-INF
  +        pw.println();            
  +        pw.println(indent + "<Location \"" + ctxPath + "/META-INF/*\">");
  +        pw.println(indent + "    AllowOverride None");
  +        pw.println(indent + "    deny from all");
  +        pw.println(indent + "</Location>");
  +        if (File.separatorChar == '\\') {
  +            pw.println(indent + "#");    
  +            pw.println(indent +
  +                           "# Use Directory too. On Windows, Location doesn't"
  +                           + " work unless case matches");
  +            pw.println(indent + "#");                        
  +            pw.println(indent +
  +                           "<Directory \"" + docBase + "/WEB-INF/\">");
  +            pw.println(indent + "    AllowOverride None");
  +            pw.println(indent + "    deny from all");
  +            pw.println(indent + "</Directory>");
  +            pw.println();
  +            pw.println(indent +
  +                           "<Directory \"" + docBase + "/META-INF/\">");
  +            pw.println(indent + "    AllowOverride None");
  +            pw.println(indent + "    deny from all");
  +            pw.println(indent + "</Directory>");
  +        }
  +        pw.println();
  +    }    
  +
  +    // -------------------- Utils --------------------
  +
  +    private String getAbsoluteDocBase(Context context)
  +    {
  +        // Calculate the absolute path of the document base
  +        String docBase = context.getDocBase();
  +        if (!FileUtil.isAbsolute(docBase)){
  +            docBase = tomcatHome + "/" + docBase;
  +        }
  +        docBase = FileUtil.patch(docBase);
  +        return docBase;
  +    }
  +
  +    private String getApacheDocBase(Context context)
  +    {
  +        // Calculate the absolute path of the document base
  +        String docBase = getAbsoluteDocBase(context);
  +        if (File.separatorChar == '\\') {
  +            // use separator preferred by Apache
  +            docBase = docBase.replace('\\','/');
  +        }
  +        return docBase;
  +    }
  +
  +    private String getVirtualHostAddress(String vhost, String vhostip) {
  +        if( vhostip == null ) {
  +            if ( vhost != null && vhost.length() > 0 && Character.isDigit(vhost.charAt(0)) )
  +                vhostip=vhost;
  +            else
  +                vhostip="*";
  +        }
  +        return vhostip;
  +    }
  +
  +}//end class JservConfig