alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Jetty example source code file (AbstractConfiguration.java)

This example Jetty source code file (AbstractConfiguration.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Jetty tags/keywords

class, class, classnotfoundexception, couldn't, exception, exception, injection, injectioncollection, lifecyclecallback, no, no, object, servlet, string, string, util

The Jetty AbstractConfiguration.java source code

// ========================================================================
// $Id: AbstractConfiguration.java 1594 2007-02-14 02:45:12Z janb $
// Copyright 2006 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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.mortbay.jetty.plus.webapp;


import java.util.EventListener;
import java.util.Iterator;

import javax.servlet.UnavailableException;


import org.mortbay.jetty.plus.annotation.Injection;
import org.mortbay.jetty.plus.annotation.InjectionCollection;
import org.mortbay.jetty.plus.annotation.LifeCycleCallback;
import org.mortbay.jetty.plus.annotation.LifeCycleCallbackCollection;
import org.mortbay.jetty.plus.annotation.PostConstructCallback;
import org.mortbay.jetty.plus.annotation.PreDestroyCallback;
import org.mortbay.jetty.plus.annotation.RunAsCollection;
import org.mortbay.jetty.plus.servlet.ServletHandler;
import org.mortbay.jetty.security.SecurityHandler;
import org.mortbay.jetty.servlet.FilterHolder;
import org.mortbay.jetty.servlet.FilterMapping;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.ServletMapping;
import org.mortbay.jetty.webapp.WebAppContext;
import org.mortbay.jetty.webapp.WebXmlConfiguration;
import org.mortbay.log.Log;
import org.mortbay.util.TypeUtil;
import org.mortbay.xml.XmlParser;



/**
 * Configuration
 *
 *
 */
public abstract class AbstractConfiguration extends WebXmlConfiguration
{
    
    protected LifeCycleCallbackCollection _callbacks = new LifeCycleCallbackCollection();
    protected InjectionCollection _injections = new InjectionCollection();
    protected RunAsCollection _runAsCollection = new RunAsCollection();
    
    private boolean _metadataComplete = true;
    
    public abstract void bindEnvEntry (String name, Object value) throws Exception;
    
    public abstract void bindResourceRef (String name, Class type) throws Exception;
    
    public abstract void bindResourceEnvRef (String name, Class type) throws Exception;
    
    public abstract void bindUserTransaction () throws Exception;
    
    public abstract void bindMessageDestinationRef (String name, Class type)  throws Exception;
    
    
    public void setWebAppContext (WebAppContext context)
    {
        super.setWebAppContext(context);
        
        //set up our special ServletHandler to remember injections and lifecycle callbacks
        ServletHandler servletHandler = new ServletHandler();
        SecurityHandler securityHandler = getWebAppContext().getSecurityHandler();        
        org.mortbay.jetty.servlet.ServletHandler existingHandler = getWebAppContext().getServletHandler();       
        servletHandler.setFilterMappings(existingHandler.getFilterMappings());
        servletHandler.setFilters(existingHandler.getFilters());
        servletHandler.setServlets(existingHandler.getServlets());
        servletHandler.setServletMappings(existingHandler.getServletMappings());
        getWebAppContext().setServletHandler(servletHandler);
        securityHandler.setHandler(servletHandler);       
    }
    
    public void configureDefaults ()
    throws Exception
    {
        super.configureDefaults();
    }
   
    public void configureWebApp ()
    throws Exception
    {
        super.configureWebApp();
        bindUserTransaction();
    }
    
    public void deconfigureWebApp()
    throws Exception
    {
        //call any preDestroy methods on the listeners
        callPreDestroyCallbacks();
        
        super.deconfigureWebApp();
    }
    
    public void configure(String webXml)
    throws Exception
    {
        //parse web.xml
        super.configure(webXml);
        
        //parse classes for annotations, if necessary
        if (!_metadataComplete)
        {
            if (Log.isDebugEnabled()) Log.debug("Processing annotations");
            parseAnnotations();
        }
        //do any injects on the listeners that were created and then
        //also callback any postConstruct lifecycle methods
        injectAndCallPostConstructCallbacks();
    }

    
  
    
    
    protected void initialize(XmlParser.Node config) 
    throws ClassNotFoundException,UnavailableException
    {
        super.initialize(config);
        
        //configure injections and callbacks to be called by the FilterHolder and ServletHolder
        //when they lazily instantiate the Filter/Servlet.
        ((ServletHandler)getWebAppContext().getServletHandler()).setInjections(_injections);
        ((ServletHandler)getWebAppContext().getServletHandler()).setCallbacks(_callbacks);
        
        //find out if we need to process annotations
        //  servlet 2.5 web.xml && metadata-complete==false
        if (_version == 25)
            _metadataComplete = Boolean.valueOf((String)config.getAttribute("metadata-complete", "false")).booleanValue();
    }
    
    
    protected void initWebXmlElement(String element,XmlParser.Node node) throws Exception
    {
        if ("env-entry".equals(element))
        {
            initEnvEntry (node);
        }
        else if ("resource-ref".equals(element))
        {
            //resource-ref entries are ONLY for connection factories
            //the resource-ref says how the app will reference the jndi lookup relative
            //to java:comp/env, but it is up to the deployer to map this reference to
            //a real resource in the environment. At the moment, we insist that the
            //jetty.xml file name of the resource has to be exactly the same as the
            //name in web.xml deployment descriptor, but it shouldn't have to be
            initResourceRef(node);
        }
        else if ("resource-env-ref".equals(element))
        {
            //resource-env-ref elements are a non-connection factory type of resource
            //the app looks them up relative to java:comp/env
            //again, need a way for deployer to link up app naming to real naming.
            //Again, we insist now that the name of the resource in jetty.xml is
            //the same as web.xml
            initResourceEnvRef(node);      
        }
        else if ("message-destination-ref".equals(element))
        {
            initMessageDestinationRef(node);
        }
        else if ("post-construct".equals(element))
        {
            //post-construct is the name of a class and method to call after all
            //resources have been setup but before the class is put into use
            initPostConstruct(node);
        }
        else if ("pre-destroy".equals(element))
        {
            //pre-destroy is the name of a class and method to call just as
            //the instance is being destroyed
            initPreDestroy(node);
        }
        else
        {
            super.initWebXmlElement(element, node);
        }
 
    }
    
    /**
     * JavaEE 5.4.1.3 
     * 
     * 
     * @param node
     * @throws Exception
     */
    protected void initEnvEntry (XmlParser.Node node)
    throws Exception
    {
        String name=node.getString("env-entry-name",false,true);
        String type = node.getString("env-entry-type",false,true);
        String valueStr = node.getString("env-entry-value",false,true);
        
        //if there's no value there's no point in making a jndi entry
        //nor processing injection entries
        if (valueStr==null || valueStr.equals(""))
        {
            Log.warn("No value for env-entry-name "+name);
            return;
        }
      
        //the javaee_5.xsd says that the env-entry-type is optional
        //if there is an <injection> element, because you can get
        //type from the element, but what to do if there is more
        //than one <injection> element, do you just pick the type
        //of the first one?
        
        //check for <injection> elements
        initInjection (node, name, TypeUtil.fromName(type));
       
        //bind the entry into jndi
        Object value = TypeUtil.valueOf(type,valueStr);
        bindEnvEntry(name, value);
        
    }
    
    
    /**
     * Common Annotations Spec section 2.3:
     *  resource-ref is for:
     *    - javax.sql.DataSource
     *    - javax.jms.ConnectionFactory
     *    - javax.jms.QueueConnectionFactory
     *    - javax.jms.TopicConnectionFactory
     *    - javax.mail.Session
     *    - java.net.URL
     *    - javax.resource.cci.ConnectionFactory
     *    - org.omg.CORBA_2_3.ORB
     *    - any other connection factory defined by a resource adapter
     * @param node
     * @throws Exception
     */
    protected void initResourceRef (XmlParser.Node node)
    throws Exception
    {
        String jndiName = node.getString("res-ref-name",false,true);
        String type = node.getString("res-type", false, true);
        String auth = node.getString("res-auth", false, true);
        String shared = node.getString("res-sharing-scope", false, true);

        //check for <injection> elements
        Class typeClass = TypeUtil.fromName(type);
        if (typeClass==null)
            typeClass = getWebAppContext().loadClass(type);
        initInjection (node, jndiName, typeClass);
        
        bindResourceRef(jndiName, typeClass);
    }
    
    
    /**
     * Common Annotations Spec section 2.3:
     *   resource-env-ref is for:
     *     - javax.transaction.UserTransaction
     *     - javax.resource.cci.InteractionSpec
     *     - anything else that is not a connection factory
     * @param node
     * @throws Exception
     */
    protected void initResourceEnvRef (XmlParser.Node node)
    throws Exception
    {
        String jndiName = node.getString("resource-env-ref-name",false,true);
        String type = node.getString("resource-env-ref-type", false, true);

        //check for <injection> elements
        
        //JavaEE Spec sec 5.7.1.3 says the resource-env-ref-type
        //is mandatory, but the schema says it is optional!
        Class typeClass = TypeUtil.fromName(type);
        if (typeClass==null)
            typeClass = getWebAppContext().loadClass(type);
        initInjection (node, jndiName, typeClass);
        
        bindResourceEnvRef(jndiName, typeClass);
    }
    
    
    /**
     * Common Annotations Spec section 2.3:
     *   message-destination-ref is for:
     *     - javax.jms.Queue
     *     - javax.jms.Topic
     * @param node
     * @throws Exception
     */
    protected void initMessageDestinationRef (XmlParser.Node node)
    throws Exception
    {
        String jndiName = node.getString("message-destination-ref-name",false,true);
        String type = node.getString("message-destination-type",false,true);
        String usage = node.getString("message-destination-usage",false,true);
        
        Class typeClass = TypeUtil.fromName(type);
        if (typeClass==null)
            typeClass = getWebAppContext().loadClass(type);
        initInjection(node, jndiName, typeClass);
        
        bindMessageDestinationRef(jndiName, typeClass);
    }
    
    
    
    /**
     * Process <post-construct>
     * @param node
     */
    protected void initPostConstruct(XmlParser.Node node)
    {
        String className = node.getString("lifecycle-callback-class", false, true);
        String methodName = node.getString("lifecycle-callback-method", false, true);
        
        if (className==null || className.equals(""))
        {
            Log.warn("No lifecycle-callback-class specified");
            return;
        }
        if (methodName==null || methodName.equals(""))
        {
            Log.warn("No lifecycle-callback-method specified for class "+className);
            return;
        }
        
        try
        {
            Class clazz = getWebAppContext().loadClass(className);
            LifeCycleCallback callback = new PostConstructCallback();
            callback.setTarget(clazz, methodName);
            _callbacks.add(callback);
        }
        catch (ClassNotFoundException e)
        {
            Log.warn("Couldn't load post-construct target class "+className);
        }
    }
    
    
    /**
     * Process <pre-destroy>
     * @param node
     */
    protected void initPreDestroy(XmlParser.Node node)
    {
        String className = node.getString("lifecycle-callback-class", false, true);
        String methodName = node.getString("lifecycle-callback-method", false, true);
        if (className==null || className.equals(""))
        {
            Log.warn("No lifecycle-callback-class specified for pre-destroy");
            return;
        }
        if (methodName==null || methodName.equals(""))
        {
            Log.warn("No lifecycle-callback-method specified for pre-destroy class "+className);
            return;
        } 
        
        try
        {
            Class clazz = getWebAppContext().loadClass(className);
            LifeCycleCallback callback = new PreDestroyCallback();
            callback.setTarget(clazz, methodName);
            _callbacks.add(callback);
        }
        catch (ClassNotFoundException e)
        {
            Log.warn("Couldn't load pre-destory target class "+className);
        }
    }
    
    
    /**
     * Iterate over the <injection-target> entries for a node
     * 
     * @param node
     * @param jndiName
     * @param valueClass
     * @return the type of the injectable
     */
    protected void initInjection (XmlParser.Node node, String jndiName, Class valueClass)
    {
        Iterator  itor = node.iterator("injection-target");
        
        while(itor.hasNext())
        {
            XmlParser.Node injectionNode = (XmlParser.Node)itor.next(); 
            String targetClassName = injectionNode.getString("injection-target-class", false, true);
            String targetName = injectionNode.getString("injection-target-name", false, true);
            if ((targetClassName==null) || targetClassName.equals(""))
            {
                Log.warn("No classname found in injection-target");
                continue;
            }
            if ((targetName==null) || targetName.equals(""))
            {
                Log.warn("No field or method name in injection-target");
                continue;
            }

            // comments in the javaee_5.xsd file specify that the targetName is looked
            // for first as a java bean property, then if that fails, as a field
            try
            {
                Class clazz = getWebAppContext().loadClass(targetClassName);
                Injection injection = new Injection();
                injection.setTargetClass(clazz);
                injection.setJndiName(jndiName);
                injection.setTarget(clazz, targetName, valueClass);
                 _injections.add(injection);
            }
            catch (ClassNotFoundException e)
            {
                Log.warn("Couldn't load injection target class "+targetClassName);
            }
        }
    }
    
    
    /**
     * Parse all classes that are mentioned in web.xml (servlets, filters, listeners)
     * for annotations.
     * 
     * 
     * 
     * @throws Exception
     */
    protected abstract void parseAnnotations () throws Exception;
   
    
    
    protected void injectAndCallPostConstructCallbacks()
    throws Exception
    {
        //look thru the servlets to apply any runAs annotations
        //NOTE: that any run-as in web.xml will already have been applied
        ServletHolder[] holders = getWebAppContext().getServletHandler().getServlets();
        for (int i=0;holders!=null && i<holders.length;i++)
        {
            _runAsCollection.setRunAs(holders[i]);
        }
        
        
        EventListener[] listeners = getWebAppContext().getEventListeners();
        for (int i=0;i<listeners.length;i++)
        {
            _injections.inject(listeners[i]);
            _callbacks.callPostConstructCallback(listeners[i]);
        }
    }
    
    
    protected void callPreDestroyCallbacks ()
    throws Exception
    {
        EventListener[] listeners = getWebAppContext().getEventListeners();
        for (int i=0;i<listeners.length;i++)
        {
            _callbacks.callPreDestroyCallback(listeners[i]);
        }
    }
   
}

Other Jetty examples (source code examples)

Here is a short list of links related to this Jetty AbstractConfiguration.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.