You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/09/17 08:47:25 UTC

cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/task ApacheConfig.java StopTomcat.java

costin      00/09/16 23:47:25

  Modified:    src/share/org/apache/tomcat/core BaseInterceptor.java
                        Container.java ContextManager.java Request.java
               src/share/org/apache/tomcat/startup EmbededTomcat.java
               src/share/org/apache/tomcat/task ApacheConfig.java
                        StopTomcat.java
  Log:
  - Added code to detect what methods are overriden in interceptors.
  This allows to call only the interceptors that are interested in a certain
  event.
  
  - copied the comments from Request and ContextInterceptor to BaseInterceptor.
  
  - moved the code handling interceptors from ContextManager to Container.
  This is based on Nacho's changes that allows setting per/container interceptor.
  
  - added individual chains. Right now this duplicates the old system,
  after more tests the old requestInterceptors[] will be removed and replaced
  by the new chains.
  
  - Updated comments in ContextManager, removed old debug messages, removed unused
  code hanging around
  
  Revision  Changes    Path
  1.18      +174 -16   jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java
  
  Index: BaseInterceptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/BaseInterceptor.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- BaseInterceptor.java	2000/08/13 02:04:12	1.17
  +++ BaseInterceptor.java	2000/09/17 06:47:21	1.18
  @@ -67,8 +67,12 @@
   import java.io.*;
   import java.net.*;
   import java.util.*;
  +import java.lang.reflect.*;
   
  -/**
  +/** Implement "Chain of Responsiblity" pattern ( == hooks ).
  + *
  + *  You can extend this class and implement a number of hooks.
  + *
    */
   public class BaseInterceptor implements RequestInterceptor, ContextInterceptor {
       protected ContextManager cm;
  @@ -83,10 +87,39 @@
       public BaseInterceptor() {
       }
   
  +    // -------------------- Helpers -------------------- 
       public void setDebug( int d ) {
   	debug=d;
       }
   
  +    public static final String BASE_I="org.apache.tomcat.core.BaseInterceptor";
  +
  +    /** Test if the interceptor implements a particular
  +	method
  +    */
  +    public boolean hasHook( String methodN ) {
  +	// all interceptors will participate in all context-level
  +	// hooks - no need to exagerate
  +	if( "engineInit".equals( methodN ) )
  +	    return true;
  +	try {
  +	    Method myMethods[]=this.getClass().getMethods();
  +	    for( int i=0; i< myMethods.length; i++ ) {
  +		if( methodN.equals ( myMethods[i].getName() )) {
  +		    // check if it's overriden
  +		    Class declaring=myMethods[i].getDeclaringClass();
  +		    if( ! BASE_I.equals(declaring.getName() )) {
  +			//log( "Found overriden method " + methodN); 
  +			return true;
  +		    }
  +		}
  +	    }
  +	} catch ( Exception ex ) {
  +	    ex.printStackTrace();
  +	}
  +	return false;
  +    }
  +
       public void setContextManager( ContextManager cm ) {
   	this.cm=cm;
   	this.ct=cm.getContainer();
  @@ -115,44 +148,96 @@
       }
       
       // -------------------- Request notifications --------------------
  +    
  +    /** Handle mappings inside a context.
  +     *  You are required to respect the mappings in web.xml.
  +     */
       public int requestMap(Request request ) {
   	return 0;
       }
  -
  +    /** Will detect the context path for a request.
  +     *  It need to set: context, contextPath, lookupPath
  +     *
  +     *  A possible use for this would be a "user-home" interceptor
  +     *  that will implement ~costin servlets ( add and map them at run time).
  +     */
       public int contextMap( Request rrequest ) {
   	return 0;
       }
   
  +    /** 
  +     *  This callback is used to extract and verify the user identity
  +     *  and credentials.
  +     *
  +     *  It will set the RemoteUser field if it can authenticate.
  +     *  The auth event is generated by a user asking for the remote
  +     *  user field of by tomcat if a request requires authenticated
  +     *  id.
  +     */
       public int authenticate(Request request, Response response) {
   	return 0;
       }
   
  +    /**
  +     *  Will check if the current ( authenticated ) user is authorized
  +     *  to access a resource, by checking if it have one of the
  +     *  required roles.
  +     *
  +     *  This is used by tomcat to delegate the authorization to modules.
  +     *  The authorize is called by isUserInRole() and by ContextManager
  +     *  if the request have security constraints.
  +     *
  +     *  @returns 0 if the module can't take a decision
  +     *           401 If the user is not authorized ( doesn't have
  +     *               any of the required roles )
  +     *           200 If the user have the right roles. No further module
  +     *               will be called.
  +     */
       public int authorize(Request request, Response response,
   			 String reqRoles[]) {
   	return 0;
       }
   
  +    /** Called before service method is invoked. 
  +     */
       public int preService(Request request, Response response) {
   	return 0;
       }
   
  +    /** Called before the first body write, and before sending
  +     *  the headers. The interceptor have a chance to change the
  +     *  output headers. 
  +     */
       public int beforeBody( Request rrequest, Response response ) {
   	return 0;
       }
   
  +    /** New Session notification - called when the servlet
  +	asks for a new session. You can do all kind of stuff with
  +	this notification - the most important is create a session
  +	object. This will be the base for controling the
  +	session allocation.
  +    */
       public int newSessionRequest( Request request, Response response) {
   	return 0;
       }
       
  +    /** Called before the output buffer is commited.
  +     */
       public int beforeCommit( Request request, Response response) {
   	return 0;
       }
   
   
  +    /** Called after the output stream is closed ( either by servlet
  +     *  or automatically at end of service ).
  +     */
       public int afterBody( Request request, Response response) {
   	return 0;
       }
   
  +    /** Called after service method ends. Log is a particular use.
  +     */
       public int postService(Request request, Response response) {
   	return 0;
       }
  @@ -162,15 +247,56 @@
       }
   
       // -------------------- Context notifications --------------------
  -    public void contextInit(Context ctx) throws TomcatException {
  +    /** Notify when a context is initialized.
  +     *  The first interceptor in the chain for contextInit must read web.xml
  +     *  and set the context. When this method is called you can expect the
  +     *  context to be filled in with all the informations from web.xml.
  +     */
  +    public void contextInit(Context ctx)
  +	throws TomcatException
  +    {
       }
   
  -    public void contextShutdown(Context ctx) throws TomcatException {
  +    /** Called when a context is stoped, before removeContext.
  +     *  You must free all resources.
  +     * XXX  - do we need this or removeContext is enough ?? ( will be
  +     * removed from 3.1 if nobody asks for it)
  +     */
  +    public void contextShutdown(Context ctx)
  +	throws TomcatException
  +    {
       }
  -    public void addContainer(Container container) throws TomcatException {
  +
  +    /** A new location was added to the server. A location is defined as a
  +     *  set of URL patterns with common properties. All servlet mappings
  +     *  and security constraints are in this category - with a common
  +     *  handler and a common set of authorized roles.
  +     *
  +     *  An interceptor interested in mapping  must implement this method
  +     *  and construct it's internal representation. The mapper is _required_
  +     *  to find the Container associated with a request using the mapping
  +     *  rules defined in the Servlet API.
  +     *
  +     *  The interceptor must also take care of "merging" parent with child
  +     *  containers. It is possible that this method will be called several
  +     *  times for the same url pattern ( for example to define a handler
  +     *  and then security constraints), the interceptor needs to
  +     *  merge the 2 containers.
  +     * 
  +     *  XXX  define "merging" of containers 
  +     */
  +    public void addContainer(Container container)
  +	throws TomcatException
  +    {
       }
  +
  +    /** A rule was removed, update the internal strucures. You can also
  +     *  clean up and reload everything using Context.getContainers()
  +     */
   
  -    public void removeContainer(Container container) throws TomcatException {
  +    public void removeContainer(Container container)
  +	throws TomcatException
  +    {
       }
   
       /** 
  @@ -182,27 +308,51 @@
   
       /** Called when the ContextManger is started
        */
  -    public void engineInit(ContextManager cm) throws TomcatException {
  +    public void engineInit(ContextManager cm)
  +	throws TomcatException
  +    {
   	this.cm=cm;
       }
   
       /** Called before the ContextManager is stoped.
        *  You need to stop any threads and remove any resources.
        */
  -    public void engineShutdown(ContextManager cm) throws TomcatException {
  +    public void engineShutdown(ContextManager cm)
  +	throws TomcatException
  +    {
       }
   
   
  -    /** Called when a context is added to a CM
  +    /** Called when a context is added to a CM. The context is probably not
  +     *  initialized yet, only path and docRoot are probably set.
  +     *
  +     *  If you need informations that are available in web.xml use
  +     *  contextInit()( a WebXmlReader needs to be the first interceptor in
  +     *  the contextInit chain ).
  +     * 
  +     *  We do that to support ( eventualy ) a "lazy" init, where you have
  +     *  many contexts, most of them not in active use, and you'll init them
  +     *  at first request. ( for example an ISP with many users )
  +     *
        */
  -    public void addContext( ContextManager cm, Context ctx ) throws TomcatException {
  +    public void addContext( ContextManager cm, Context ctx )
  +	throws TomcatException
  +    {
       }
   
  -    /** Called when a context is removed from a CM
  +    /** Called when a context is removed from a CM. A context is removed
  +     *  either as a result of admin ( remove or update), to support "clean"
  +     *  servlet reloading or at shutdown.
        */
  -    public void removeContext( ContextManager cm, Context ctx ) throws TomcatException {
  +    public void removeContext( ContextManager cm, Context ctx )
  +	throws TomcatException
  +    {
       }
   
  +    /** Reload notification - called whenever a reload is done.
  +	This can be used to serialize sessions, log the event,
  +	remove any resource that was class-loader dependent.
  +     */
       public void reload( Request req, Context ctx)
   	throws TomcatException
       {
  @@ -210,20 +360,28 @@
   
       /** Servlet Init  notification
        */
  -    public void preServletInit( Context ctx, Handler sw ) throws TomcatException {
  +    public void preServletInit( Context ctx, Handler sw )
  +	throws TomcatException
  +    {
       }
   
       
  -    public void postServletInit( Context ctx, Handler sw ) throws TomcatException {
  +    public void postServletInit( Context ctx, Handler sw )
  +	throws TomcatException
  +    {
       }
   
       /** Servlet Destroy  notification
        */
  -    public void preServletDestroy( Context ctx, Handler sw ) throws TomcatException {
  +    public void preServletDestroy( Context ctx, Handler sw )
  +	throws TomcatException
  +    {
       }
   
       
  -    public void postServletDestroy( Context ctx, Handler sw ) throws TomcatException {
  +    public void postServletDestroy( Context ctx, Handler sw )
  +	throws TomcatException
  +    {
       }
   
   }
  
  
  
  1.30      +207 -78   jakarta-tomcat/src/share/org/apache/tomcat/core/Container.java
  
  Index: Container.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Container.java,v
  retrieving revision 1.29
  retrieving revision 1.30
  diff -u -r1.29 -r1.30
  --- Container.java	2000/08/15 23:29:32	1.29
  +++ Container.java	2000/09/17 06:47:22	1.30
  @@ -121,16 +121,6 @@
       // notes, as the access time is much smaller
       private Hashtable attributes = new Hashtable();
   
  -    /** Per/container interceptors.
  -	XXX Not implemented, it's easy to wire it in ( 2-3 h).
  -     */
  -    Vector contextInterceptors=new Vector();
  -    Vector requestInterceptors=new Vector();
  -    // interceptor cache - avoid Vector enumeration
  -    ContextInterceptor cInterceptors[];
  -    RequestInterceptor rInterceptors[];
  -    RequestInterceptor rCachedRequestInterceptors[]={};
  -    ContextInterceptor rCachedContextInterceptors[]={};
       /** The handler associated with this container.
        */
       Handler handler;
  @@ -147,10 +137,12 @@
       /** Get the context manager
        */
       public ContextManager getContextManager() {
  -	if( contextM==null ) {
  +	if( contextM==null && context==null ) {
   	    /* assert */
   	    throw new RuntimeException( "Assert: container.contextM==null" );
   	}
  +	if( contextM==null )
  +	    contextM=context.getContextManager();
   	return contextM;
       }
   
  @@ -296,65 +288,6 @@
   	this.roles=roles;
       }
   
  -    // -------------------- Per-container interceptors
  -    
  -    /** Add a per/container context interceptor. It will be notified
  -     *  of all context events happening inside this container.
  -     *   XXX incomplete implementation
  -     */
  -    public void addContextInterceptor( ContextInterceptor ci) {
  -	contextInterceptors.addElement( ci );
  -    }
  -
  -    /** Return the context interceptors as an array.
  -     *	For performance reasons we use an array instead of
  -     *  returning the vector - the interceptors will not change at
  -     *	runtime and array access is faster and easier than vector
  -     *	access
  -     */
  -    public ContextInterceptor[] getContextInterceptors() {
  -	if( cInterceptors == null ||
  -	    cInterceptors.length != contextInterceptors.size()) {
  -	    cInterceptors=new ContextInterceptor[contextInterceptors.size()];
  -	    for( int i=0; i<cInterceptors.length; i++ ) {
  -		cInterceptors[i]=(ContextInterceptor)contextInterceptors.
  -		    elementAt(i);
  -	    }
  -	}
  -	return cInterceptors;
  -    }
  -
  -    /** Add a per/container request interceptor. It will be called back for
  -     *  all operations for requests that are mapped to this container.
  -     *  Note that all global interceptors will be called first.
  -     *   XXX incomplete implementation.
  -     */
  -    public void addRequestInterceptor( RequestInterceptor ri) {
  -	requestInterceptors.addElement( ri );
  -	if( ri instanceof ContextInterceptor )
  -	    addContextInterceptor( (ContextInterceptor)ri );
  -    }
  -
  -    /** Return the context interceptors as an array.
  -	For performance reasons we use an array instead of
  -	returning the vector - the interceptors will not change at
  -	runtime and array access is faster and easier than vector
  -	access
  -    */
  -    public RequestInterceptor[] getRequestInterceptors() {
  -	if( rInterceptors == null ||
  -	    rInterceptors.length != requestInterceptors.size())
  -	{
  -	    rInterceptors=new RequestInterceptor[requestInterceptors.size()];
  -	    for( int i=0; i<rInterceptors.length; i++ ) {
  -		rInterceptors[i]=(RequestInterceptor)requestInterceptors.
  -		    elementAt(i);
  -	    }
  -	}
  -	return rInterceptors;
  -    }
  -
  -
       /** Per container attributes. Not used - can be removed
        *  ( it's here for analogy with the other components )
        */
  @@ -420,20 +353,216 @@
   	return notes[pos];
       }
   
  -    public RequestInterceptor[] getCachedRequestInterceptors() {
  -        return rCachedRequestInterceptors;
  +    // -------------------- Interceptors --------------------
  +    public static final int MAX_HOOKS=20;
  +    public static final String PREDEFINED_I[]= {
  +	"requestMap", "contextMap", "authenticate",
  +	"authorize", "preService", "beforeBody",
  +	"newSessionRequest", "beforeCommit",
  +	"afterBody", "postService",
  +	// special case - all interceptors will be added to the "context"
  +	// chain. We plan to use a simpler Event/Listener model for
  +	// all context hooks, since they don't have any performance requirement
  +	"engineInit" };
  +    
  +    // local interceptors - all interceptors added to this
  +    // container
  +    Vector interceptors[]=new Vector[ MAX_HOOKS ];
  +
  +    // Merged interceptors - local and global ( upper-level ) interceptors
  +    BaseInterceptor hooks[][]=new BaseInterceptor[MAX_HOOKS][];
  +
  +    // used internally 
  +    Vector getLocalInterceptors(int hookId) {
  +	if( interceptors[hookId]==null )
  +	    interceptors[hookId]=new Vector();
  +	return interceptors[hookId];
  +    }
  +    
  +    /** Add the interceptor to all the hook chains it's interested
  +	in
  +    */
  +    public void addInterceptor( BaseInterceptor bi ) {
  +	for( int i=0; i< PREDEFINED_I.length; i++ ) {
  +	    if( bi.hasHook( PREDEFINED_I[i] )) {
  +		if( interceptors[i]==null )
  +		    interceptors[i]=new Vector();
  +		interceptors[i].addElement( bi );
  +	    }
  +	}
       }
   
  -    public void setCachedRequestInterceptors(RequestInterceptor[] newRCachedInterceptors) {
  -        rCachedRequestInterceptors = newRCachedInterceptors;
  +    // make sure we reset the cache.
  +    // dynamic addition of interceptors is not implemented,
  +    // but this is a start
  +    public void resetInterceptorCache( int id ) {
  +	hooks[id]=null;
       }
  -    public ContextInterceptor[] getCachedContextInterceptors() {
  -        return rCachedContextInterceptors;
  +
  +    public static int getHookId( String hookName ) {
  +	for( int i=0; i< PREDEFINED_I.length; i++ ) {
  +	    if( PREDEFINED_I[i].equals(hookName)){
  +		return i;
  +	    }
  +	}
  +	// get all interceptors for unknown hook names
  +	return PREDEFINED_I.length-1;
       }
  +    
  +    public BaseInterceptor[] getInterceptors( int type ) {
  +	if( hooks[type] != null ) {
  +	    return hooks[type];
  +	}
  +	Container globalIntContainer=getContextManager().getContainer();
  +	Vector globals=globalIntContainer.getLocalInterceptors( type );
  +	Vector locals=this.getLocalInterceptors( type );
  +
  +	int gsize=globals.size();
  +	int lsize=locals.size();
  +	hooks[type]=new BaseInterceptor[gsize+lsize];
  +	
  +	for ( int i = 0 ; i < gsize ; i++ ){
  +	    hooks[type][i]=(BaseInterceptor)globals.elementAt(i);
  +	}
  +	for ( int i = 0 ; i < lsize  ; i++ ){
  +	    hooks[type][gsize+i]=(BaseInterceptor)locals.elementAt(i);
  +	}
  +
  +	return hooks[type];
  +    }
  +
  +
  +
  +
  +    
  +    // -------------------- Old code handling interceptors 
  +    // DEPRECATED ( after the new code is tested )
  +
  +    /** Per/container interceptors.
  +     */
  +    Vector contextInterceptors=new Vector();
  +    Vector requestInterceptors=new Vector();
  +
  +    // interceptor cache - avoid Vector enumeration
  +    ContextInterceptor cInterceptors[];
  +    RequestInterceptor rInterceptors[];
  +    RequestInterceptor rCachedRequestInterceptors[]={};
  +    ContextInterceptor rCachedContextInterceptors[]={};
   
  -    public void setCachedContextInterceptors(ContextInterceptor[] newRCachedInterceptors) {
  -        rCachedContextInterceptors = newRCachedInterceptors;
  +    /** Add a per/container context interceptor. It will be notified
  +     *  of all context events happening inside this container.
  +     *   XXX incomplete implementation
  +     */
  +    public void addContextInterceptor( ContextInterceptor ci) {
  +	contextInterceptors.addElement( ci );
  +	addInterceptor( (BaseInterceptor) ci );
       }
   
  +    /** Add a per/container request interceptor. It will be called back for
  +     *  all operations for requests that are mapped to this container.
  +     *  Note that all global interceptors will be called first.
  +     *   XXX incomplete implementation.
  +     */
  +    public void addRequestInterceptor( RequestInterceptor ri) {
  +	requestInterceptors.addElement( ri );
  +	addInterceptor( (BaseInterceptor) ri );
  +	if( ri instanceof ContextInterceptor )
  +	    addContextInterceptor( (ContextInterceptor)ri );
  +    }
   
  +    // -------------------- Getting the active interceptors 
  +    
  +    /** Return the context interceptors as an array.
  +     *	For performance reasons we use an array instead of
  +     *  returning the vector - the interceptors will not change at
  +     *	runtime and array access is faster and easier than vector
  +     *	access
  +     */
  +    public ContextInterceptor[] getContextInterceptors() {
  +	if( cInterceptors == null ||
  +	    cInterceptors.length != contextInterceptors.size()) {
  +	    cInterceptors=new ContextInterceptor[contextInterceptors.size()];
  +	    for( int i=0; i<cInterceptors.length; i++ ) {
  +		cInterceptors[i]=(ContextInterceptor)contextInterceptors.
  +		    elementAt(i);
  +	    }
  +	}
  +	return cInterceptors;
  +    }
  +
  +    /** Return the context interceptors as an array.
  +	For performance reasons we use an array instead of
  +	returning the vector - the interceptors will not change at
  +	runtime and array access is faster and easier than vector
  +	access
  +    */
  +    public RequestInterceptor[] getRequestInterceptors() {
  +	if( rInterceptors == null ||
  +	    rInterceptors.length != requestInterceptors.size())
  +	{
  +	    rInterceptors=new RequestInterceptor[requestInterceptors.size()];
  +	    for( int i=0; i<rInterceptors.length; i++ ) {
  +		rInterceptors[i]=(RequestInterceptor)requestInterceptors.
  +		    elementAt(i);
  +	    }
  +	}
  +	return rInterceptors;
  +    }
  +
  +    /** Return all interceptors for this container ( local and
  +	global )
  +    */
  +    public RequestInterceptor[] getCachedRequestInterceptors()
  +    {
  +	RequestInterceptor[] ari=rCachedRequestInterceptors;
  +	
  +	if (ari.length == 0){
  +            RequestInterceptor[] cri=this.getRequestInterceptors();
  +            RequestInterceptor[] gri=getContextManager()
  +		.getRequestInterceptors();
  +            if  (cri!=null && cri.length > 0) {
  +                int al=cri.length+gri.length;
  +                ari=new RequestInterceptor[al];
  +                int i;
  +                for ( i = 0 ; i < gri.length ; i++ ){
  +                    ari[i]=gri[i];
  +                }
  +                for (int j = 0 ; j < cri.length ; j++ ){
  +                    ari[i+j]=cri[j];
  +                }
  +            } else {
  +                ari=gri;
  +            }
  +            rCachedRequestInterceptors=ari;
  +        }
  +        return rCachedRequestInterceptors;
  +    }
  +
  +    /** Return all interceptors for this container ( local and
  +	global )
  +    */
  +    public ContextInterceptor[] getCachedContextInterceptors()
  +    {
  +	ContextInterceptor[] aci=rCachedContextInterceptors;
  +	if (aci.length == 0){
  +            ContextInterceptor[] cci=this.getContextInterceptors();
  +            ContextInterceptor[] gci=getContextManager().
  +		getContextInterceptors();
  +            if  (cci!=null && cci.length > 0) {
  +                int al=cci.length+gci.length;
  +                aci=new ContextInterceptor[al];
  +                int i;
  +                for ( i = 0 ; i < gci.length ; i++ ){
  +                    aci[i]=gci[i];
  +                }
  +                for (int j = 0 ; j < cci.length ; j++ ){
  +                    aci[i+j]=cci[j];
  +                }
  +            } else {
  +                aci=gci;
  +            }
  +            rCachedContextInterceptors=aci;
  +        }
  +	return rCachedContextInterceptors;
  +    }
   }
  
  
  
  1.130     +76 -204   jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
  
  Index: ContextManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
  retrieving revision 1.129
  retrieving revision 1.130
  diff -u -r1.129 -r1.130
  --- ContextManager.java	2000/09/14 00:40:16	1.129
  +++ ContextManager.java	2000/09/17 06:47:22	1.130
  @@ -71,59 +71,37 @@
   import java.net.*;
   import java.util.*;
   
  -//import java.security.*;
  -
  -/* XXX The main function of CM is to serve as an entry point into
  -   tomcat and manage a list of resources that are part of the servlet
  -   processing. ( manage == keep a list and provide centralized access ).
  -
  -   It also have helper functions for common callbacks - but we need to
  -   review and change that.
  -*/
  -/*
  - * It is possible to extend and override some of the methods ( this is not
  - * "final" ), but this is an extreme case and shouldn't be used - if you want
  - * to extend the server you should use interceptors.
  - * Another extreme case is having more than one ContextManager instances.
  - * Each will corespond to a separate servlet engine/container that will work
  - * independent of each other in the same VM ( each having possible multiple
  - * virtual hosts, etc). Both uses are not forbiden, but shouldn't be used
  - * unless there is real need for that - and if that happen we should
  - * add interfaces to express the use cases.
  - */
  -
  -
   /**
    * ContextManager is the entry point and "controler" of the servlet execution.
  - * It maintains a list of WebApplications and a list of global event interceptors
  - * that are set up to handle the actual execution.
  + * It maintains a list of WebApplications and a list of global event
  + * interceptors that are set up to handle the actual execution.
    *
  - * The ContextManager is a helper that will direct the request processing flow
  + * The ContextManager will direct the request processing flow
    * from its arrival from the server/protocl adapter ( in service() ).
  - * It is also responsible for controlling the request processing steps, from
  - * request parsing and mapping, auth, autorization, pre/post service, actual
  - * invocation and logging.
  + * It will do that by calling a number of hooks implemented by Interceptors.
    *
  - * It will also store properties that are global to the servlet container -
  - * like root directory, install dir, work dir.
  + * Hooks are provided for request parsing and mapping, auth, autorization,
  + * pre/post service, actual invocation and logging.
    *
  + * ContextManager will also store properties that are global to the servlet
  + * container - like root directory, install dir, work dir.
    *
  + * The extension mechanism for tomcat is the Interceptor.
  + * This class is final - if you need to change certain functionality
  + * you should add a new hook.
  + *
  + * ContextManager is not a singleton - it represent a servlet container
  + * instance ( with all associated ports and configurations ).
  + * One application may try to embed multiple ( distinct ) servlet containers -
  + * this feature hasn't been tested or used
  + *
    * @author James Duncan Davidson [duncan@eng.sun.com]
    * @author James Todd [gonzo@eng.sun.com]
    * @author Harish Prabandham
    * @author costin@eng.sun.com
    * @author Hans Bergsten [hans@gefionsoftware.com]
    */
  -public class ContextManager implements LogAware{
  -    /**
  -     * The default security permissions to use
  -     */
  -    private Object permissions;
  -
  -    /** Adapters for the incoming protocol
  -     */
  -    Vector connectors=new Vector();
  -
  +public final class ContextManager implements LogAware{
       /** Contexts managed by this server
        */
       private Vector contextsV=new Vector();
  @@ -146,6 +124,11 @@
        */
       String installDir;
   
  +    /** Property used to set the random number generator
  +     */
  +    public static final String RANDOM_CLASS_PROPERTY=
  +	"tomcat.sessionid.randomclass";
  +    
       /** Default work dir, relative to home
        */
       public static final String DEFAULT_WORK_DIR="work";
  @@ -165,6 +148,7 @@
       public ContextManager() {
           defaultContainer=new Container();
           defaultContainer.setContext( null );
  +	defaultContainer.setContextManager( this );
           defaultContainer.setPath( null ); // default container
       }
   
  @@ -191,16 +175,6 @@
        *  just throw error instead of guessing wrong.
        */
       public String getHome() {
  -	if( debug > 20 ) {
  -	    // we want to know all places that need this property
  -	    // and find how it's computed - for embeding tc.
  -	    log( "getHome " + home + " " + installDir + " " +
  -		 System.getProperty("tomcat.home") + " " +
  -		 FileUtil.getCanonicalPath( "." ),
  -		 new Throwable("trace")
  -		 );
  -	}
  -
   	if(home!=null) return home;
   
   	// If none defined, assume tomcat.home is used as base.
  @@ -223,14 +197,6 @@
        *  evaluate it relative to the current working directory.
        */
       public String getInstallDir() {
  -	if( debug > 20 ) {
  -	    // we want to know all places that need this property
  -	    // and find how it's computed - for embeding tc.
  -	    log( "getInstallDir " + installDir + " " +
  -		 System.getProperty("tomcat.home"),
  -		 new Throwable("trace"));
  -	}
  -
   	if(installDir!= null) return installDir;
   
   	installDir=System.getProperty("tomcat.home");
  @@ -255,14 +221,7 @@
        */
       public void setWorkDir( String wd ) {
   	if(debug>0) log("set work dir " + wd);
  -	// make it absolute
  -	File f=new File( wd );
  -	if( ! f.isAbsolute() ) {
  -	    File wdF=getAbsolute( f );
  -	    wd= wdF.getAbsolutePath();
  -	}
  -
  -	this.workDir=wd;
  +	this.workDir=FileUtil.getCanonicalPath( wd );
       }
   
       /**
  @@ -274,20 +233,6 @@
   	return workDir;
       }
   
  -    /**
  -     * Get the default Security Permissions for this server
  -     */
  -    public Object getPermissions() {
  -	return permissions;
  -    }
  -
  -    /**
  -     * Add a Permission to the default Permissions
  -     */
  -    public void setPermissions(Object permissions) {
  -	this.permissions = permissions;
  -    }
  -
       /** Parent loader is the "base" class loader of the
        *	application that starts tomcat, and includes no
        *	tomcat classes. All servlet loaders will have it as
  @@ -314,12 +259,13 @@
       public void setServerClassPath( URL urls[] ) {
   	serverClassPath=urls;
       }
  -    
  -    /** Get the name of the class to be used for generating random numbers by the
  -     * session id generator. By default this is <code>java.security.SecureRandom</code>.
  +
  +    /** Get the name of the class to be used for generating random numbers by
  +     * the session id generator. By default this is
  +     *  <code>java.security.SecureRandom</code>.
        **/
       public String getRandomClass() {
  -        String randomClass = System.getProperty("tomcat.sessionid.randomclass");
  +        String randomClass = System.getProperty(RANDOM_CLASS_PROPERTY);
           return randomClass == null ? "java.security.SecureRandom" : randomClass;
       }
       
  @@ -327,24 +273,28 @@
        *  session id generator. 
        */
       public void setRandomClass(String randomClass) {
  -        System.setProperty("tomcat.sessionid.randomclass", randomClass);
  +        System.setProperty(RANDOM_CLASS_PROPERTY, randomClass);
       }
   
   
       // -------------------- Support functions --------------------
  -    /** Init() is called after the context manager is set up
  -     *  and configured. It will init all internal components
  -     *  to be ready for start.
  +
  +    /**
  +     *  Init() is called after the context manager is set up
  +     *  and configured ( all setFoo methods are called, all initial
  +     *  interceptors are added and their setters are called ).
        *
  -     *  There is a difference between Context and Adapters - the
  -     *  adapter has start/stop, the Context has init/shutdown(destroy
  -     *  may be a better name ? ). ( Initializing is different from starting.)
  +     *  CM will call the following hooks:
  +     *   - Interceptor.engineInit()
  +     *
  +     *  It will tehn call initContext() for all the contexts (
  +     *  including those added by interceptors )
        */
       public void init()  throws TomcatException {
   	if(debug>0 ) log( "Tomcat classpath = " +
   			     System.getProperty( "java.class.path" ));
   
  -	setAccount( ACC_INIT_START, System.currentTimeMillis());
  +	cntr.touchCounter( ACC_INIT_START );
   
   	ContextInterceptor cI[]=getContextInterceptors();
   	for( int i=0; i< cI.length; i++ ) {
  @@ -352,7 +302,6 @@
   	}
   
       	// init contexts
  -	// XXX init must be called whith no context inside !!!
   	Enumeration enum = getContexts();
   	while (enum.hasMoreElements()) {
   	    Context context = (Context)enum.nextElement();
  @@ -361,15 +310,15 @@
   	    } catch (TomcatException ex ) {
   		if( context!=null ) {
   		    log( "ERROR initializing " + context.toString(), ex );
  -		    // log will print root cause too if it's there
   		    removeContext( context  );
   		}
   	    }
   	}
  -	setAccount( ACC_INIT_END, System.currentTimeMillis() );
  +	cntr.touchCounter( ACC_INIT_END);
       }
   
  -    /** Will shutdown all contexts
  +    /** Remove all contexts.
  +     *  Call Intereptor.engineShutdown hooks.
        */
       public void shutdown() throws TomcatException {
   	Enumeration enum = getContexts();
  @@ -391,7 +340,7 @@
        * <p>This method must be called
        * before any requests are handled by this context. It will be called
        * after the context was added, typically when the engine starts
  -     * or after the admin added a new context.
  +     * or after the admin adds a new context.
        */
       public void initContext( Context ctx ) throws TomcatException {
   	ContextInterceptor cI[]=getContextInterceptors(ctx);
  @@ -428,24 +377,16 @@
   
       /** Will start the connectors and begin serving requests.
        *  It must be called after init.
  +     *  XXX Do nothing ?? Tomcat is started up by calling the init
  +     *  hooks, there is no need for special code here - in the worst
  +     *  case we should add a new hook
        */
  -    public void start() throws Exception {// XXX TomcatException {
  -	// XXX we may need a special callback to disable/enable the
  -	// server from accepting connections ( to allow for startup ).
  -        // 	Enumeration connE=getConnectors();
  -        // 	while( connE.hasMoreElements() ) {
  -        // 	    ((ServerConnector)connE.nextElement()).start();
  -        // 	}
  +    public void start() throws Exception {
       }
   
       /** Will stop all connectors
        */
  -    public void stop() throws Exception {// XXX TomcatException {
  -	// 	if(debug>0) log("Stopping context manager ");
  -	// 	Enumeration connE=getConnectors();
  -	// 	while( connE.hasMoreElements() ) {
  -	// 	    ((ServerConnector)connE.nextElement()).stop();
  -	// 	}
  +    public void stop() throws Exception {
   	shutdown();
       }
   
  @@ -539,25 +480,13 @@
   	    cI[i].removeContainer( container);
   	}
       }
  -
  -    // -------------------- Connectors and Interceptors --------------------
  -
  -    /**
  -     * Add the specified server connector to the those attached to this server.
  -     *
  -     * @param con The new server connector
  -     */
  -    public synchronized void addServerConnector( ContextInterceptor con ) {
  -	if(debug>0) log("Add connector javaClass=\"" +
  -			   con.getClass().getName() + "\"");
  -	//	con.setServer( this );
  -	connectors.addElement( con );
  -    }
  -
  -    public Enumeration getConnectors() {
  -	return connectors.elements();
  -    }
   
  +    // -------------------- Interceptors --------------------
  +    // The interceptors are handled per/container ( thanks to Nacho
  +    // for this contribution ). We just delegate to the right
  +    // container ( in future we should remove this, and use the
  +    // right objects )
  +    
       public void addRequestInterceptor( RequestInterceptor ri ) {
           defaultContainer.addRequestInterceptor(ri);
       }
  @@ -570,10 +499,9 @@
   	For performance reasons we use arrays and cache the result inside
   	containers.
   
  -	XXX Todo: container-level interceptors are not supported.
  +	XXX Todo: 
   	Dynamic add of interceptors is not supported.
       */
  -
       public RequestInterceptor[] getRequestInterceptors( Request req ) {
           Context ctx=req.getContext();
           // if Bad request (ctx == null) only global interceptors are called
  @@ -581,34 +509,10 @@
              return getRequestInterceptors();
           Container ct=ctx.getContainer();
           RequestInterceptor[] ari=ct.getCachedRequestInterceptors();
  -        if (ari.length == 0){
  -            RequestInterceptor[] cri=ct.getRequestInterceptors();
  -            RequestInterceptor[] gri=getRequestInterceptors();
  -            if  (cri!=null && cri.length > 0) {
  -                int al=cri.length+gri.length;
  -                ari=new RequestInterceptor[al];
  -                int i;
  -                for ( i = 0 ; i < gri.length ; i++ ){
  -                    ari[i]=gri[i];
  -                }
  -                for (int j = 0 ; j < cri.length ; j++ ){
  -                    ari[i+j]=cri[j];
  -                }
  -            } else {
  -                ari=gri;
  -            }
  -            ct.setCachedRequestInterceptors(ari);
  -        }
   
   	return ari;
       }
   
  -    /** Return the context interceptors as an array.
  -	For performance reasons we use an array instead of
  -	returning the vector - the interceptors will not change at
  -	runtime and array access is faster and easier than vector
  -	access
  -    */
       public RequestInterceptor[] getRequestInterceptors() {
   	return defaultContainer.getRequestInterceptors();
       }
  @@ -617,38 +521,12 @@
           defaultContainer.addContextInterceptor(ci);
       }
   
  -
  -    /** Return the context interceptors as an array.
  -	For performance reasons we use an array instead of
  -	returning the vector - the interceptors will not change at
  -	runtime and array access is faster and easier than vector
  -	access
  -    */
       public ContextInterceptor[] getContextInterceptors() {
   	return defaultContainer.getContextInterceptors();
       }
   
       public ContextInterceptor[] getContextInterceptors(Container ct) {
           ContextInterceptor[] aci=ct.getCachedContextInterceptors();
  -        if (aci.length == 0){
  -            ContextInterceptor[] cci=ct.getContextInterceptors();
  -            ContextInterceptor[] gci=getContextInterceptors();
  -            if  (cci!=null && cci.length > 0) {
  -                int al=cci.length+gci.length;
  -                aci=new ContextInterceptor[al];
  -                int i;
  -                for ( i = 0 ; i < gci.length ; i++ ){
  -                    aci[i]=gci[i];
  -                }
  -                for (int j = 0 ; j < cci.length ; j++ ){
  -                    aci[i+j]=cci[j];
  -                }
  -            } else {
  -                aci=gci;
  -            }
  -            ct.setCachedContextInterceptors(aci);
  -        }
  -
   	return aci;
       }
   
  @@ -741,27 +619,33 @@
   	}
       }
   
  +    static int contextMap_ID=Container.getHookId( "contextMap");
  +    static int requestMap_ID=Container.getHookId( "requestMap");
  +
  +
       /** Will find the Handler for a servlet, assuming we already have
        *  the Context. This is also used by Dispatcher and getResource -
        *  where the Context is already known.
        */
       public int processRequest( Request req ) {
  -	if(debug>9) log("ProcessRequest: "+req.toString());
  +	if(debug>9) log("Before processRequest(): "+req.toString());
  +
   	int status=0;
  -        RequestInterceptor ri[]=getRequestInterceptors();
  +        BaseInterceptor ri[];
  +	ri=defaultContainer.getInterceptors(contextMap_ID);
  +	
   	for( int i=0; i< ri.length; i++ ) {
  -	    status=((RequestInterceptor)ri[i]).
  -		contextMap( req );
  +	    status=ri[i].contextMap( req );
   	    if( status!=0 ) return status;
   	}
   
  +	ri=defaultContainer.getInterceptors( requestMap_ID);
   	for( int i=0; i< ri.length; i++ ) {
  -	    status=((RequestInterceptor)ri[i]).
  -		requestMap( req );
  +	    status=ri[i].requestMap( req );
   	    if( status!=0 ) return status;
   	}
   
  -	if(debug>9) log("After processing: "+req.toString());
  +	if(debug>9) log("After processRequest(): "+req.toString());
   
   	return 0;
       }
  @@ -933,16 +817,9 @@
   	    urlPath = urlPath.substring(0, i);
   	}
   
  -	/** Creates an "internal" request
  -	 */
   	Request lr = new Request();
   	lr.setRequestURI( urlPath );
   	lr.setQueryString( queryString );
  -	//	lr.processQueryString();
  -
  -	//	lr.setContext( ctx );
  -
  -	// XXX set query string too
   	return lr;
       }
   
  @@ -966,7 +843,7 @@
   	// error
   	// XXX this log was intended to debug the status code generation.
   	// it can be removed for all cases.
  -	if( code != 302 && code != 401 ) // tuneme
  +	if( code != 302 && code != 401 && code!=400  ) // tuneme
   	    ctx.log( "Status code:" + code + " request:"  + req + " msg:" +
   		     req.getAttribute("javax.servlet.error.message"));
   	
  @@ -1272,21 +1149,16 @@
   
       // -------------------- Accounting --------------------
       // XXX Can be implemented as note !
  -
       public static final int ACC_INIT_START=0;
       public static final int ACC_INIT_END=0;
  -
       public static final int ACCOUNTS=7;
  -    long accTable[]=new long[ACCOUNTS];
   
  -    public void setAccount( int pos, long value ) {
  -	accTable[pos]=value;
  -    }
  +    Counters cntr=new Counters(ACCOUNTS);
   
  -    public long getAccount( int pos ) {
  -	return accTable[pos];
  +    public Counters getCounters() {
  +	return cntr;
       }
  -
  +    
       // -------------------- DEPRECATED --------------------
       // XXX host and port are used only to construct a unique
       // work-dir for contexts, using them and the path
  
  
  
  1.58      +12 -7     jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java
  
  Index: Request.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Request.java,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -r1.57 -r1.58
  --- Request.java	2000/08/29 03:44:20	1.57
  +++ Request.java	2000/09/17 06:47:23	1.58
  @@ -477,10 +477,9 @@
   
   	if( ! create ) return null;
   
  -	//	context.log("Request:  created new session!");
   	contextM.doNewSessionRequest( this, response );
  +
   	if ( serverSession == null ) {
  -	    //	    context.log("Request: no session created!");
   	    return null;
   	}
   
  @@ -797,12 +796,18 @@
       }
   
   
  -    // XXX I hate this - but the only way to remove this method from the
  -    // inteface is to implement it on top of doRead(b[]).
  -    // Don't use this method if you can ( it is bad for performance !!)
  -    // you need to override this method if you want non-empty InputStream
  +    // This method must be removed and replaced with a real buffer !!!
       public int doRead() throws IOException {
  -	return -1;
  +        byte []b = new byte[1];
  +        int rc = doRead(b, 0, 1);
  +
  +        if(rc <= 0) {
  +            return -1;
  +        }
  +
  +	return b[0];
  +	// ??
  +	//return ((int)b[0]) & 0x000000FF;
       }
   
       // -------------------- "cooked" info --------------------
  
  
  
  1.20      +20 -20    jakarta-tomcat/src/share/org/apache/tomcat/startup/EmbededTomcat.java
  
  Index: EmbededTomcat.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/EmbededTomcat.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- EmbededTomcat.java	2000/08/27 21:03:33	1.19
  +++ EmbededTomcat.java	2000/09/17 06:47:24	1.20
  @@ -5,8 +5,9 @@
   
   import org.apache.tomcat.core.*;
   import org.apache.tomcat.request.*;
  -import org.apache.tomcat.service.*;
  -import org.apache.tomcat.service.http.*;
  +import org.apache.tomcat.modules.server.*;
  +//import org.apache.tomcat.service.*;
  +//import org.apache.tomcat.service.http.*;
   import org.apache.tomcat.session.StandardSessionInterceptor;
   import org.apache.tomcat.context.*;
   import org.apache.tomcat.logging.*;
  @@ -103,16 +104,16 @@
   	if(debug>0) log( "addConnector " + port + " " + addr +
   			 " " + hostname );
   
  -	PoolTcpConnector sc=new PoolTcpConnector();
  +	HttpInterceptor sc=new HttpInterceptor();
   	sc.setServer( contextM );
   	sc.setDebug( debug );
  -	sc.setAttribute( "vhost_port" , new Integer( port ) );
  -	if( addr != null ) sc.setAttribute( "vhost_address", addr );
  -	if( hostname != null ) sc.setAttribute( "vhost_name", hostname );
  +	sc.setPort( port ) ;
  +	if( addr != null ) sc.setAddress( addr );
  +	if( hostname != null ) sc.setHostName( hostname );
   	
  -	sc.setTcpConnectionHandler( new HttpConnectionHandler());
  +	//	sc.setTcpConnectionHandler( new HttpConnectionHandler());
   	
  -	contextM.addServerConnector(  sc );
  +	contextM.addRequestInterceptor(  sc );
       }
   
       /** Add a secure web service.
  @@ -122,22 +123,21 @@
       {
   	if(debug>0) log( "addSecureConnector " + port + " " + addr + " " +
   			 hostname );
  -
  -	PoolTcpConnector sc=new PoolTcpConnector();
  +	
  +	HttpInterceptor sc=new HttpInterceptor();
   	sc.setServer( contextM );
  -	sc.setAttribute( "vhost_port" , new Integer( port ) );
  -	if( addr != null ) sc.setAttribute( "vhost_address", addr );
  -	if( hostname != null ) sc.setAttribute( "vhost_name", hostname );
  -
  -	sc.setAttribute( "socketFactory",
  -			 "org.apache.tomcat.net.SSLSocketFactory");
  +	sc.setPort( port ) ;
  +	if( addr != null ) sc.setAddress(  addr );
  +	if( hostname != null ) sc.setHostName( hostname );
  +	
  +	sc.setSocketFactory("org.apache.tomcat.net.SSLSocketFactory");
   	//	log("XXX " + keyFile + " " + keyPass);
  -	HttpConnectionHandler hc=new HttpConnectionHandler();
  -	hc.setSecure(true);
  -	sc.setTcpConnectionHandler( hc );
  +	//	HttpConnectionHandler hc=new HttpConnectionHandler();
  +	sc.setSecure(true);
  +	// sc.setTcpConnectionHandler( hc );
   	// XXX add the secure socket
   	
  -	contextM.addServerConnector(  sc );
  +	contextM.addRequestInterceptor(  sc );
       }
   
       // -------------------- Context add/remove --------------------
  
  
  
  1.16      +11 -14    jakarta-tomcat/src/share/org/apache/tomcat/task/ApacheConfig.java
  
  Index: ApacheConfig.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/task/ApacheConfig.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ApacheConfig.java	2000/09/09 23:15:34	1.15
  +++ ApacheConfig.java	2000/09/17 06:47:24	1.16
  @@ -133,20 +133,17 @@
   	    pw.println("ApJServLogLevel notice");
   	    pw.println();
   
  -		// Find Ajp12 connector
  -		int portInt=8007;
  -		Enumeration enum=cm.getConnectors();
  -		while( enum.hasMoreElements() ) {
  -			Object con=enum.nextElement();
  -			if( con instanceof  PoolTcpConnector ) {
  -				PoolTcpConnector tcpCon=(PoolTcpConnector) con;
  -				if( tcpCon.getTcpConnectionHandler()
  -						instanceof Ajp12ConnectionHandler ) {
  -					portInt=tcpCon.getPort();
  -				}
  -			}
  +	    // Find Ajp12 connector
  +	    int portInt=8007;
  +	    ContextInterceptor ci[]=cm.getContextInterceptors();
  +	    for( int i=0; i<ci.length; i++ ) {
  +		Object con=ci[i];
  +		if( con instanceof  Ajp12ConnectionHandler ) {
  +		    PoolTcpConnector tcpCon=(PoolTcpConnector) con;
  +		    portInt=tcpCon.getPort();
   		}
  -		pw.println("ApJServDefaultPort " + portInt);
  +	    }
  +	    pw.println("ApJServDefaultPort " + portInt);
   	    pw.println();
   
   	    pw.println("AddType text/jsp .jsp");
  @@ -200,7 +197,7 @@
   
   	    // Set up contexts
   	    // XXX deal with Virtual host configuration !!!!
  -	    enum = cm.getContexts();
  +	Enumeration  enum = cm.getContexts();
   	    while (enum.hasMoreElements()) {
   		Context context = (Context)enum.nextElement();
   		String path  = context.getPath();
  
  
  
  1.7       +6 -9      jakarta-tomcat/src/share/org/apache/tomcat/task/StopTomcat.java
  
  Index: StopTomcat.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/task/StopTomcat.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- StopTomcat.java	2000/08/18 03:42:16	1.6
  +++ StopTomcat.java	2000/09/17 06:47:24	1.7
  @@ -172,16 +172,13 @@
   	// Find Ajp12 connector
   	int portInt=8007;
   	InetAddress address=null;
  -	Enumeration enum=cm.getConnectors();
  -	while( enum.hasMoreElements() ) {
  -	    Object con=enum.nextElement();
  -	    if( con instanceof  PoolTcpConnector ) {
  +	ContextInterceptor ci[]=cm.getContextInterceptors();
  +	for( int i=0; i<ci.length; i++ ) {
  +	    Object con=ci[i];
  +	    if( con instanceof  Ajp12ConnectionHandler ) {
   		PoolTcpConnector tcpCon=(PoolTcpConnector) con;
  -		if( tcpCon.getTcpConnectionHandler()
  -		    instanceof Ajp12ConnectionHandler ) {
  -		    portInt=tcpCon.getPort();
  -		    address=tcpCon.getAddress();
  -		}
  +		portInt=tcpCon.getPort();
  +		address=tcpCon.getAddress();
   	    }
   	}