mcconnell    2004/02/02 11:30:11

  Modified:    merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl
                        DefaultServer.java
  Added:       merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl
                        ComponentModelHolder.java
                        ContainmentModelHandler.java
  Removed:     merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl
                        DefaultServletHolder.java
  Log:
  Addition of a containment model handler and a component model holder to support 
interception of http requests and request handling redirection.
  
  Revision  Changes    Path
  1.4       +85 -32    
avalon/merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl/DefaultServer.java
  
  Index: DefaultServer.java
  ===================================================================
  RCS file: 
/home/cvs/avalon/merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl/DefaultServer.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultServer.java        24 Jan 2004 23:25:31 -0000      1.3
  +++ DefaultServer.java        2 Feb 2004 19:30:11 -0000       1.4
  @@ -34,6 +34,9 @@
   
   import org.apache.excalibur.configuration.ConfigurationUtil;
   
  +import org.apache.avalon.composition.model.ComponentModel;
  +import org.apache.avalon.composition.model.ContainmentModel;
  +
   import org.apache.avalon.http.HttpService;
   
   import org.mortbay.http.HttpServer;
  @@ -43,6 +46,8 @@
   import org.mortbay.http.handler.ResourceHandler;
   import org.mortbay.http.SunJsseListener;
   import org.mortbay.http.ajp.AJP13Listener;
  +import org.mortbay.jetty.servlet.ServletHandler;
  +import org.mortbay.jetty.servlet.ServletHolder;
   import org.mortbay.util.Log;
   
   /**
  @@ -116,6 +121,11 @@
           m_logger = logger;
       }
   
  +    private Logger getLogger()
  +    {
  +        return m_logger;
  +    }
  +
      //---------------------------------------------------------
      // Contextualizable
      //---------------------------------------------------------
  @@ -159,6 +169,8 @@
               m_logger.debug( "initialization" );
           }
   
  +        m_server.setTrace( true );
  +
           //
           // map the jetty logging channel to the avalon logger
           //
  @@ -185,15 +197,15 @@
           // content under the directory "root"
           //
   
  -        if( null == m_config.getChild( "context", false ))
  -        {
  -            HttpContext context = createContext( "/", "./root/" );
  -            m_server.addContext( context );
  -        }
  +        //if( null == m_config.getChild( "context", false ))
  +        //{
  +        //    HttpContext context = createContext( "/", "./root/" );
  +        //    m_server.addContext( context );
  +        //}
   
           //
           // handle the children declared in the configuration
  -        // (includes listeners, context, etc.)
  +        // (includes listeners, etc.)
           //
   
           Configuration[] children = m_config.getChildren();
  @@ -206,11 +218,11 @@
                   HttpListener listener = createListener( child );
                   m_server.addListener( listener );
               }
  -            else if( name.equalsIgnoreCase( "context" ) )
  -            {
  -                HttpContext context = createContext( child );
  -                m_server.addContext( context );
  -            }
  +            //else if( name.equalsIgnoreCase( "context" ) )
  +            //{
  +            //    HttpContext context = createContext( child );
  +            //    m_server.addContext( context );
  +            //}
               else
               {
                   final String error = 
  @@ -231,7 +243,7 @@
       */
       public void start() throws Exception
       {
  -       m_server.start();
  +        m_server.start();
       }
   
      /**
  @@ -246,6 +258,46 @@
      // HttpServer
      //---------------------------------------------------------
   
  +   /**
  +    * Register a servlet under a context.
  +    * @param model the component model
  +    */
  +    public void register( ComponentModel model )
  +    {
  +        getLogger().info( 
  +          "registering servlet: " 
  +          + model );
  +
  +        final String path = model.getPath();
  +        HttpContext context = m_server.getContext( path + "*" );
  +        ContainmentModelHandler handler = getContainmentHandler( context, path );
  +        handler.addComponentModel( model );
  +        m_server.addContext( context );
  +        if( m_server.isStarted() )
  +        {
  +            try
  +            {
  +                context.start();
  +            }
  +            catch( Throwable e )
  +            {
  +                getLogger().error( "context startup failure", e );
  +            }
  +        }
  +    }
  +
  +    private ContainmentModelHandler getContainmentHandler( 
  +      HttpContext context, String partition )
  +    {
  +        ContainmentModelHandler handler = 
  +          (ContainmentModelHandler) context.getHandler( 
  +             ContainmentModelHandler.class );
  +        if( null != handler ) return handler;
  +        handler = new ContainmentModelHandler( partition );
  +        context.addHandler( handler );
  +        return handler;
  +    }
  +
      //---------------------------------------------------------
      // implementation
      //---------------------------------------------------------
  @@ -254,30 +306,29 @@
        * Create a context defined in the component configuration.
        * @param config the context configuration
        */
  -    private HttpContext createContext( Configuration config ) 
  -      throws Exception 
  -    {
  -        HttpContext context = new HttpContext();
  -        String path = config.getAttribute( PATH_ATTRIBUTE_NAME, "/*" );
  -        String base = config.getAttribute( BASE_ATTRIBUTE_NAME, null );
  -        return createContext( path, base );
  -    }
  +    //private HttpContext createContext( Configuration config ) 
  +    //  throws Exception 
  +    //{
  +    //    String path = config.getAttribute( PATH_ATTRIBUTE_NAME, "/*" );
  +    //    String base = config.getAttribute( BASE_ATTRIBUTE_NAME, null );
  +    //    return createContext( path, base );
  +    //}
   
       /**
        * Create a context using the supplied parameters.
        * @param path the context path
        * @param base the base directory
        */
  -    private HttpContext createContext( String path, String base ) 
  -      throws Exception 
  -    {
  -        HttpContext context = new HttpContext();
  -        context.setContextPath( path );
  -        String dir = getDerivedPath( base );
  -        context.setResourceBase( dir );
  -        context.addHandler( new ResourceHandler() );
  -        return context;
  -    }
  +    //private HttpContext createContext( String path, String base ) 
  +    //  throws Exception 
  +    //{
  +    //    HttpContext context = new HttpContext();
  +    //    context.setContextPath( path );
  +    //    String dir = getDerivedPath( base );
  +    //    context.setResourceBase( dir );
  +    //    context.addHandler( new ResourceHandler() );
  +    //    return context;
  +    //}
   
       /**
        * Add a listener defined in the component configuration.
  @@ -419,8 +470,10 @@
           }
       }
   
  -    private File getBaseDirectory( Context context ) throws ContextException
  +    private File getBaseDirectory( Context context ) 
  +      throws ContextException
       {
  -        return (File) context.get( "urn:composition:dir" );
  +        return (File) 
  +          context.get( "urn:composition:dir" );
       }
   }
  
  
  
  1.1                  
avalon/merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl/ComponentModelHolder.java
  
  Index: ComponentModelHolder.java
  ===================================================================
  /* 
   * Copyright 2004 Apache Software Foundation
   * Licensed  under the  Apache License,  Version 2.0  (the "License");
   * you may not use  this file  except in  compliance with the License.
   * You may obtain a copy of the License at 
   * 
   *   http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed  under the  License is distributed on an "AS IS" BASIS,
   * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
   * implied.
   * 
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.avalon.http.impl;
  
  import java.io.IOException;
  
  import org.apache.avalon.activation.appliance.Appliance;
  import org.apache.avalon.composition.model.ComponentModel;
  import org.apache.avalon.http.HttpRuntimeException;
  import org.mortbay.jetty.servlet.ServletHolder;
  import org.mortbay.jetty.servlet.ServletHandler;
  
  import javax.servlet.ServletRequest;
  import javax.servlet.ServletResponse;
  import javax.servlet.ServletException;
  import javax.servlet.Servlet;
  import javax.servlet.UnavailableException;
  
  /**
   * The ComponentModelHolder ...
   *
   * @author  <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   * @version 1.0
   */
  class ComponentModelHolder extends ServletHolder
  {
      private final ComponentModel m_model;
  
     /**
      * Construct a Servlet Holder using a supplied ComponentModel.
      *
      * @param model the component model
      * @param handler the servlet handler
      */
      public ComponentModelHolder( 
        ServletHandler handler, ComponentModel model )
      {
          super( 
            handler, model.getName(), 
            model.getType().getInfo().getClassname() );
          m_model = model;
      }
  
     /** 
      * Intercept the servlet request and handle it locally
      * by redirecting the request directly to our component.
      *
      * @request the servlet request
      * @param response the servlet response
      * @exception ServletException if a servlet exception occurs
      * @exception UnavailableException if the servlet is unavailable
      * @exception IOException if an io related error occurs
      */
      public void handle(ServletRequest request,
                         ServletResponse response)
          throws ServletException,
                 UnavailableException,
                 IOException
      {        
          Servlet servlet = getServletInstance();
  
          boolean servlet_error=true;
  
          try
          {
              servlet.service(request,response);
              servlet_error=false;
          }
          catch(UnavailableException e)
          {
              servlet.destroy();
              throw e;
          }
          finally
          {
              if( servlet_error )
              {
                  request.setAttribute( 
                    "javax.servlet.error.servlet_name", 
                    m_model.getName() );
              }
          }
      }
  
     /**
      * Get the servlet.
      * @return The servlet
      */
      private Servlet getServletInstance()
          throws UnavailableException
      {
          try
          {
              Appliance appliance = (Appliance)m_model.getHandler();
              return (Servlet) appliance.resolve();
          }
          catch( Throwable e )
          {
              throw new UnavailableException( e.toString() );
          }
      }
  }
  
  
  
  1.1                  
avalon/merlin/facilities/http/impl/src/java/org/apache/avalon/http/impl/ContainmentModelHandler.java
  
  Index: ContainmentModelHandler.java
  ===================================================================
  /* 
   * Copyright 2004 Apache Software Foundation
   * Licensed  under the  Apache License,  Version 2.0  (the "License");
   * you may not use  this file  except in  compliance with the License.
   * You may obtain a copy of the License at 
   * 
   *   http://www.apache.org/licenses/LICENSE-2.0
   * 
   * Unless required by applicable law or agreed to in writing, software
   * distributed  under the  License is distributed on an "AS IS" BASIS,
   * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
   * implied.
   * 
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.avalon.http.impl;
  
  import java.io.IOException;
  import java.util.Map;
  import java.util.HashMap;
  import java.util.Iterator;
  
  import org.apache.avalon.activation.appliance.Appliance;
  import org.apache.avalon.composition.model.ComponentModel;
  import org.apache.avalon.http.HttpRuntimeException;
  import org.mortbay.jetty.servlet.ServletHolder;
  import org.mortbay.jetty.servlet.ServletHandler;
  import org.mortbay.http.HttpContext;
  import org.mortbay.http.HttpRequest;
  import org.mortbay.http.HttpResponse;
  
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.ServletException;
  import javax.servlet.UnavailableException;
  
  /**
   * The ContainmentModelHandler handles holders relative to a container
   * partition.
   *
   * @author  <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
   * @version 1.0
   */
  class ContainmentModelHandler extends ServletHandler
  {
      private final String m_partition;
  
      private Map m_models = new HashMap();
      private Map m_holders = new HashMap();
  
     /**
      * Construct a Servlet Handler using a supplied servlet holder.
      *
      * @param partition the partition that this handler handles
      */
      public ContainmentModelHandler( String partition )
      {
          super();
          m_partition = partition;
      }
  
      public void addComponentModel( ComponentModel model )
      {
          String name = model.getName();
          if( null == m_models.get( name ) )
          {
              m_models.put( name, model );
          }
          else
          {
              final String error = 
                "Duplicate name [" + name 
                + "] in partition handler [" 
                + m_partition + "].";
              throw new IllegalArgumentException( error );
          }
      }
  
      //public ServletHolder getServletHolder(String name)
      //{
      //    System.out.println( "### getServletHolder: " + name );
      //    return (ServletHolder) m_holders.get( name );
      //}
  
     /**
      * Creation of a new servlet holder.
      * @param name the name of the servlet
      * @param clazz the servlet class
      * @param path the forced path
      */
      public ServletHolder newServletHolder( String name, String classname, String 
path )
      {
           System.out.println( "### new holder request: " + name );
           ComponentModel model = (ComponentModel) m_models.get( name );
           if( null == model )
           {
               final String error = 
                 "Unknow name [" + name + "] in handler [" + m_partition + "].";
               throw new IllegalArgumentException( error );
           }
           ComponentModelHolder holder =
              new ComponentModelHolder( this, model );
           m_holders.put( name, holder );
           return holder;
      }
  
      /** Initialize load-on-startup servlets.
       * Called automatically from start if autoInitializeServlet is true.
       */
      public void initializeServlets()
        throws Exception
      {
          ComponentModel[] models = 
            (ComponentModel[]) m_models.values().toArray( new ComponentModel[0] );
          for( int i=0; i<models.length; i++ )
          {
              ComponentModel model = models[i];
              ComponentModelHolder holder =
                  new ComponentModelHolder( this, model );
              m_holders.put( model.getName(), holder );
          }
      }
  
     /**
      * ServletHolder matching the supplied path.
      * @param pathInContext Path within context.
      * @return PathMap Entries pathspec to ServletHolder
      */
      public Map.Entry getHolderEntry( String path )
      {
          Iterator iterator = m_holders.entrySet().iterator();
          while( iterator.hasNext() )
          {
              Map.Entry entry = (Map.Entry) iterator.next();
              if( entry.getKey().equals( path.substring( 1 ) ) )
              {
                  return entry;
              }  
          }
          return null;
      }
  }
  
  
  

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

Reply via email to