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]