Just realized that I didn't include the servlet configuration section
into the javadoc. Please use the attached source file instead.
/*
 * Copyright (C) The Apache Software Foundation. All rights reserved.
 *
 * This software is published under the terms of the Apache Software License
 * version 1.1, a copy of which has been included with this distribution in
 * the LICENSE file.
 */
package org.apache.avalon.excalibur.servlet;

import java.io.InputStream;
import java.io.IOException;

import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;

import org.xml.sax.SAXException;


import org.apache.log.Hierarchy;
import org.apache.avalon.framework.component.ComponentManager;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.context.DefaultContext;
import org.apache.avalon.excalibur.component.ExcaliburComponentManager;
import org.apache.avalon.excalibur.component.DefaultRoleManager;
import org.apache.avalon.excalibur.component.RoleManager;

/**
 * Initializes servlet component manager. Puts it into the
 * servlet context. Typical usage of the ComponentManager from a JSP
 * page is:
 * <pre>
 *  <%@ page import="org.apache.avalon.framework.component.ComponentManager" %>
 *  <%@ page 
import="org.apache.avalon.excalibur.servlet.ComponentManagerCreator" %>
 *  <%@ page import="com.mycompany.MyComponent" %>
 *  ComponentManager cm = (ComponentManager)
 *    
getServletConfig().getServletContext().getAttribute(ComponentManagerCreator.COMPONENT_MANAGER);
 *  MyComponent myC = (MyComponent) cm.lookup(MyComponent.ROLE);
 *  message = myC.getMessage();
 *  cm.release(myC);
 * </pre>
 * Configures itself from servlet parameters. Here's what a typical section in
 * web.xml should look like:
 * <pre>
 * &lt;servlet&gt;
 *  &lt;servlet-name&gt;ComponentManagerCreator&lt;/servlet-name&gt;
 *  &lt;display-name&gt;ComponentManagerCreator&lt;/display-name&gt;
 *  &lt;description&gt;Creates component manager, does not service 
requests.&lt;/description&gt;
 *  
&lt;servlet-class&gt;org.apache.avalon.excalibur.servlet.ComponentManagerCreator&lt;/servlet-class&gt;
 *
 *  &lt;!--
 *    This parameter points to the main configuration file.
 *    Note that the path is specified in absolute notation but it will be
 *    resolved relative to the servlets webapp context path
 *  --&gt;
 *  &lt;init-param&gt;
 *    &lt;param-name&gt;configuration&lt;/param-name&gt;
 *    &lt;param-value&gt;/WEB-INF/components.xml&lt;/param-value&gt;
 *  &lt;/init-param&gt;
 *  &lt;!-- Roles file supplements configuration file to make the latter
 *       more readable. Most likely you don't want to change the roles
 *       file --&gt;
 *  &lt;init-param&gt;
 *    &lt;param-name&gt;roles&lt;/param-name&gt;
 *    &lt;param-value&gt;/WEB-INF/roles.xml&lt;/param-value&gt;
 *  &lt;/init-param&gt;
 *  &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
 * &lt;/servlet&gt;
 * </pre>
 * @author Gregory Steuck mailto:[EMAIL PROTECTED]
 */
public class ComponentManagerCreator extends GenericServlet {
    /**
     * Name of the servlet context attribute that contains our
     * component manager.
     */
    public static final String COMPONENT_MANAGER = 
"org.apache.avalon.excalibur.servlet.ComponentManager";

    /**
     * Builds the component manager, stores it as an attribute of the
     * ServletContext.
     */
    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
        try {
            InputStream roleStream = streamFromParameter(config, "roles");
            InputStream configStream = streamFromParameter(config, 
"configuration");
            ServletContext ctx = getServletContext();
            ctx.setAttribute(COMPONENT_MANAGER,
                             buildComponentManager(configStream,
                                                   roleStream));
            configStream.close();
            roleStream.close();
        } catch (IOException e) {
            abort(e);
        } catch (SAXException e) {
            abort(e);
        } catch (ConfigurationException e) {
            abort(e);
        }
    }

    
    /**
     * Does not process any requests, complains if attempted.  Since
     * it is not mapped to URLs this method should never be called.
     */
    public void service(ServletRequest req, ServletResponse res)
        throws UnavailableException
    {
        abort(getClass().getName() + " doesn't service requests");
    }

    /**
     * Removes the component manager from the servlet context.
     * Hardly ever called, but is here for consistency.
     */
    public void destroy() {
        log(getClass().getName() + " destroyed, removing component manager");
        ServletContext ctx = getServletContext();
        ExcaliburComponentManager cm =
            (ExcaliburComponentManager) ctx.getAttribute(COMPONENT_MANAGER);
        ctx.removeAttribute(COMPONENT_MANAGER);
        cm.dispose();
    }

    /**
     * Creates Avalon component manager from the passed config stream
     * and role config stream.
     * @param config input stream containing components definitions
     * @param roles input stream with role definitions
     */
    private ComponentManager buildComponentManager(InputStream configStream,
                                                   InputStream roleStream)
        throws IOException, SAXException, ConfigurationException
    {
        DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
        Configuration roleConfig = builder.build(roleStream);

        DefaultRoleManager roles = new DefaultRoleManager();
        
roles.setLogger(Hierarchy.getDefaultHierarchy().getLoggerFor("document.roles"));
        roles.configure(roleConfig);

        Configuration systemConf = builder.build(configStream);
        ExcaliburComponentManager manager = new ExcaliburComponentManager();

        manager.setLogger(Hierarchy.getDefaultHierarchy().getLoggerFor("bp"));
        manager.contextualize(new DefaultContext());
        manager.setRoleManager(roles);
        manager.configure(systemConf);
        manager.initialize();
        return manager;
    }

    /**
     * Logs the error message and makes servlet unavailable
     * by throwing UnavailableException.
     *
     * @param msg reason for failure
     */
    private void abort(String msg) throws UnavailableException {
        log(msg);
        throw new UnavailableException(msg);
    }

    /**
     * Logs passed exception and makes servlet unavailable
     * by throwing UnavailableException.
     * @param e exception that caused the original failure
     */
    private void abort(Exception e) throws UnavailableException {
        log("", e);
        throw new UnavailableException(e.getMessage());
    }

    /**
     * Finds the value for given key in the servlet init parameters,
     * treats it as a file name, opens a resource stream with this
     * name.
     * @param resourceName key into init parameters
     * @param config connection to the world
     * @return opened resorce stream
     * @throws ServletException if init parameter does not exist, or resource 
can't be opened
     */
    private InputStream streamFromParameter(ServletConfig config,
                                            String resourceName)
        throws ServletException
    {
        String configFileName = config.getInitParameter(resourceName);
        if (configFileName == null) {
            abort(resourceName + " parameter must be provided");
        }
        ServletContext ctx = config.getServletContext();
        log("Attempting to use file " + configFileName);
        InputStream result = ctx.getResourceAsStream(configFileName);
        if (result == null) {
            abort("Resource '" + configFileName + "' is not available.");
        }
        return result;
    }
}

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

Reply via email to