You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@turbine.apache.org by he...@apache.org on 2002/12/20 01:07:21 UTC

cvs commit: jakarta-turbine-2/src/java/org/apache/turbine/services ServiceManager.java BaseServiceBroker.java ServiceBroker.java TurbineServices.java

henning     2002/12/19 16:07:21

  Modified:    src/java/org/apache/turbine/services BaseServiceBroker.java
                        ServiceBroker.java TurbineServices.java
  Added:       src/java/org/apache/turbine/services ServiceManager.java
  Log:
  - Backport of the Fulcrum Service Broker structure. Removed dependency
    on the BaseInitableBroker (which should no longer be used)
  
  - added explicit "early / late" init code
  
  - removed implicit logging, all logging now commons-logging
  
  Revision  Changes    Path
  1.7       +363 -108  jakarta-turbine-2/src/java/org/apache/turbine/services/BaseServiceBroker.java
  
  Index: BaseServiceBroker.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-2/src/java/org/apache/turbine/services/BaseServiceBroker.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BaseServiceBroker.java	23 Jul 2002 00:06:54 -0000	1.6
  +++ BaseServiceBroker.java	20 Dec 2002 00:07:21 -0000	1.7
  @@ -54,49 +54,102 @@
    * <http://www.apache.org/>.
    */
   
  +import java.io.ByteArrayOutputStream;
  +import java.io.File;
  +import java.io.PrintWriter;
  +
   import java.util.ArrayList;
  +import java.util.Date;
  +import java.util.Enumeration;
   import java.util.Hashtable;
   import java.util.Iterator;
  +import java.util.List;
   import java.util.Properties;
  +import java.util.Stack;
  +
   import org.apache.commons.configuration.BaseConfiguration;
   import org.apache.commons.configuration.Configuration;
  -import org.apache.turbine.util.StringUtils;
   
  +import org.apache.commons.lang.StringUtils;
  +
  +import org.apache.commons.logging.Log;
  +import org.apache.commons.logging.LogFactory;
   
   /**
  - * A generic implementation of a <code>ServiceBroker</code>.
  - *
  - * Functionality that <code>ServiceBroker</code> provides in addition
  - * to <code>InitableBroker</code> functionality includes:
  + * A generic implementation of a <code>ServiceBroker</code> which
  + * provides:
    *
    * <ul>
  - *
    * <li>Maintaining service name to class name mapping, allowing
    * plugable service implementations.</li>
  - *
  - * <li>Providing <code>Services</code> with <code>Properties</code>
  - * based on system wide configuration mechanism.</li>
  - *
  + * <li>Providing <code>Services</code> with a configuration based on
  + * system wide configuration mechanism.</li>
    * </ul>
    *
    * @author <a href="mailto:burton@apache.org">Kevin Burton</a>
    * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
    * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
  + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
  + * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
  + * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    * @version $Id$
    */
   public abstract class BaseServiceBroker
  -    extends BaseInitableBroker
       implements ServiceBroker
   {
  -    /** Mapping of Service names to class names. */
  -    //protected Hashtable mapping = new Hashtable();
  +    /**
  +     * Mapping of Service names to class names.
  +     */
       protected Configuration mapping = (Configuration) new BaseConfiguration();
   
  -    /** A repository of Service instances. */
  +    /**
  +     * A repository of Service instances.
  +     */
       protected Hashtable services = new Hashtable();
   
       /**
  -     * Default constructor of InitableBroker.
  +     * Configuration for the services broker.
  +     * The configuration should be set by the application
  +     * in which the services framework is running.
  +     */
  +    protected Configuration configuration;
  +
  +    /**
  +     * A prefix for <code>Service</code> properties in
  +     * TurbineResource.properties.
  +     */
  +    public static final String SERVICE_PREFIX = "services.";
  +
  +    /**
  +     * A <code>Service</code> property determining its implementing
  +     * class name .
  +     */
  +    public static final String CLASSNAME_SUFFIX = ".classname";
  +
  +    /**
  +     * These are objects that the parent application
  +     * can provide so that application specific
  +     * services have a mechanism to retrieve specialized
  +     * information. For example, in Turbine there are services
  +     * that require the RunData object: these services can
  +     * retrieve the RunData object that Turbine has placed
  +     * in the service manager. This alleviates us of
  +     * the requirement of having init(Object) all
  +     * together.
  +     */
  +    protected Hashtable serviceObjects = new Hashtable();
  +
  +    /** Logging */
  +    private Log log = LogFactory.getLog(this.getClass());
  +
  +    /**
  +     * Application root path as set by the
  +     * parent application.
  +     */
  +    protected String applicationRoot;
  +
  +    /**
  +     * Default constructor, protected as to only be useable by subclasses.
        *
        * This constructor does nothing.
        */
  @@ -105,6 +158,127 @@
       }
   
       /**
  +     * Set the configuration object for the services broker.
  +     * This is the configuration that contains information
  +     * about all services in the care of this service
  +     * manager.
  +     *
  +     * @param configuration Broker configuration.
  +     */
  +    public void setConfiguration(Configuration configuration)
  +    {
  +        this.configuration = configuration;
  +    }
  +
  +    /**
  +     * Get the configuration for this service manager.
  +     *
  +     * @return Broker configuration.
  +     */
  +    public Configuration getConfiguration()
  +    {
  +        return configuration;
  +    }
  +
  +    /**
  +     * Initialize this service manager.
  +     */
  +    public void init() throws InitializationException
  +    {
  +        // Check:
  +        //
  +        // 1. The configuration has been set.
  +        // 2. Make sure the application root has been set.
  +
  +        // FIXME: Make some service framework exceptions to throw in
  +        // the event these requirements aren't satisfied.
  +
  +        // Create the mapping between service names
  +        // and their classes.
  +        initMapping();
  +
  +        // Start services that have their 'earlyInit'
  +        // property set to 'true'.
  +        initServices(false);
  +    }
  +
  +    /**
  +     * Set an application specific service object
  +     * that can be used by application specific
  +     * services.
  +     *
  +     * @param String name of service object
  +     * @param Object value of service object
  +     */
  +    public void setServiceObject(String name, Object value)
  +    {
  +        serviceObjects.put(name, value);
  +    }
  +
  +    /**
  +     * Get an application specific service object.
  +     *
  +     * @return Object application specific service object
  +     */
  +    public Object getServiceObject(String name)
  +    {
  +        return serviceObjects.get(name);
  +    }
  +
  +    /**
  +     * Creates a mapping between Service names and class names.
  +     *
  +     * The mapping is built according to settings present in
  +     * TurbineResources.properties.  The entries should have the
  +     * following form:
  +     *
  +     * <pre>
  +     * services.MyService.classname=com.mycompany.MyServiceImpl
  +     * services.MyOtherService.classname=com.mycompany.MyOtherServiceImpl
  +     * </pre>
  +     *
  +     * <br>
  +     *
  +     * Generic ServiceBroker provides no Services.
  +     */
  +    protected void initMapping()
  +    {
  +        /*
  +         * These keys returned in an order that corresponds
  +         * to the order the services are listed in
  +         * the TR.props.
  +         *
  +         * When the mapping is created we use a Configuration
  +         * object to ensure that the we retain the order
  +         * in which the order the keys are returned.
  +         *
  +         * There's no point in retrieving an ordered set
  +         * of keys if they aren't kept in order :-)
  +         */
  +        Iterator keys = configuration.getKeys();
  +
  +        while(keys.hasNext())
  +        {
  +            String key = (String)keys.next();
  +            String [] keyParts = StringUtils.split(key, ".");
  +
  +            if ((keyParts.length == 3) 
  +                && (keyParts[0] + ".").equals(SERVICE_PREFIX) 
  +                && ("." + keyParts[2]).equals(CLASSNAME_SUFFIX))
  +            {
  +                String serviceKey = keyParts[1];
  +                log.info("Added Mapping for Service: " + serviceKey);
  +
  +                if (! mapping.containsKey(serviceKey))
  +                {
  +                    mapping.setProperty(serviceKey,
  +                                        configuration.getString(key));
  +                }
  +            }
  +        }
  +    }
  +
  +    /**
        * Determines whether a service is registered in the configured
        * <code>TurbineResources.properties</code>.
        *
  @@ -117,6 +291,28 @@
       }
   
       /**
  +     * Returns an Iterator over all known service names.
  +     *
  +     * @return An Iterator of service names.
  +     */
  +    public Iterator getServiceNames()
  +    {
  +        return mapping.getKeys();
  +    }
  +
  +    /**
  +     * Returns an Iterator over all known service names beginning with
  +     * the provided prefix.
  +     *
  +     * @param prefix The prefix against which to test.
  +     * @return An Iterator of service names which match the prefix.
  +     */
  +    public Iterator getServiceNames(String prefix)
  +    {
  +        return mapping.getKeys(prefix);
  +    }
  +
  +    /**
        * Performs early initialization of specified service.
        *
        * @param name The name of the service (generally the
  @@ -126,120 +322,130 @@
        * @exception InitializationException Initialization of this
        * service was not successful.
        */
  -    public void initService( String name, Object data )
  +    public synchronized void initService(String name)
           throws InitializationException
       {
  -        String className = mapping.getString(name);
  -        if (StringUtils.isEmpty(className))
  +        // Calling getServiceInstance(name) assures that the Service
  +        // implementation has its name and broker reference set before
  +        // initialization.
  +        Service instance = getServiceInstance(name);
  +
  +        if (!instance.getInit())
           {
  -            throw new InitializationException(
  -                "ServiceBroker: initialization of unknown service " +
  -                name + " requested.");
  +            // this call might result in an indirect recursion
  +            instance.init();
           }
  -        initClass(className, data);
       }
   
       /**
        * Performs early initialization of all services.  Failed early
        * initialization of a Service may be non-fatal to the system,
  -     * thuss the exceptions are logged and then discarded.
  -     *
  -     * @param data An Object to use for initialization activities.
  +     * thus any exceptions are logged and the initialization process
  +     * continues.
        */
  -    public void initServices( Object data )
  +    public void initServices()
       {
           try
           {
  -            initServices(data, false);
  +            initServices(false);
           }
  -        catch(InstantiationException notThrown)
  +        catch (InstantiationException notThrown)
           {
           }
  -        catch(InitializationException notThrown)
  +        catch (InitializationException notThrown)
           {
           }
       }
   
       /**
  -     * Performs early initiailzation of all services. You can decide
  -     * to handle failed initizalizations if you wish, but then
  +     * Performs early initialization of all services. You can decide
  +     * to handle failed initializations if you wish, but then
        * after one service fails, the other will not have the chance
        * to initialize.
        *
  -     * @param data An Object to use for initialization activities.
        * @param report <code>true</code> if you want exceptions thrown.
        */
  -    public void initServices( Object data, boolean report )
  +    public void initServices(boolean report)
           throws InstantiationException, InitializationException
       {
  -        notice("Initializing all services using: " +
  -                data.getClass().getName());
  -        Iterator names = mapping.getKeys();
  -        // throw exceptions
  -        if(report)
  +        Iterator names = getServiceNames();
  +        if (report)
           {
  -            while(names.hasNext())
  +            // Throw exceptions
  +            while (names.hasNext())
               {
  -                doInitService(data, (String)names.next());
  +                doInitService((String) names.next());
               }
           }
  -        // eat exceptions
           else
           {
  -            while(names.hasNext())
  +            // Eat exceptions
  +            while (names.hasNext())
               {
                   try
                   {
  -                    doInitService(data, (String)names.next());
  +                    doInitService((String) names.next());
                   }
                   // In case of an exception, file an error message; the
                   // system may be still functional, though.
  -                catch(InstantiationException e)
  +                catch (InstantiationException e)
                   {
  -                    error(e);
  +                    log.error(e);
                   }
  -                catch(InitializationException e)
  +                catch (InitializationException e)
                   {
  -                    error(e);
  +                    log.error(e);
                   }
               }
           }
  -        notice("Finished initializing all services!");
  +        log.info("Finished initializing all services!");
       }
   
       /**
  -     * Internal utility method for use in initServices()
  +     * Internal utility method for use in {@link #initServices(boolean)}
        * to prevent duplication of code.
        */
  -    private void doInitService(Object data, String name)
  +    private void doInitService(String name)
           throws InstantiationException, InitializationException
       {
  -        notice("Start Initializing service (early): " + name);
  -
  -        // Make sure the service has it's name and broker
  -        // reference set before initialization.
  -        getServiceInstance(name);
  -
  -        // Perform early initialization.
  -        initClass(mapping.getString(name), data);
  -
  -        notice("Finish Initializing service (early): " + name);
  +        // Only start up services that have their earlyInit flag set.
  +        if (getConfiguration(name).getBoolean("earlyInit", false))
  +        {
  +            log.info("Start Initializing service (early): " + name);
  +            initService(name);
  +            log.info("Finish Initializing service (early): " + name);
  +        }
       }
   
       /**
  -     * Shuts down a <code>Service</code>.
  +     * Shuts down a <code>Service</code>, releasing resources
  +     * allocated by an <code>Service</code>, and returns it to its
  +     * initial (uninitialized) state.
        *
  -     * This method is used to release resources allocated by a
  -     * Service, and return it to its initial (uninitialized) state.
  -     *
  -     * @param name The name of the <code>Service</code> to be uninitialized.
  +     * @param name The name of the <code>Service</code> to be
  +     * uninitialized.
        */
  -    public void shutdownService( String name )
  +    public synchronized void shutdownService(String name)
       {
  -        String className = mapping.getString(name);
  -        if (className != null)
  +        try
  +        {
  +            Service service = getServiceInstance(name);
  +            if (service != null && service.getInit())
  +            {
  +                service.shutdown();
  +                if (service.getInit() && service instanceof BaseService)
  +                {
  +                    // BaseService::shutdown() does this by default,
  +                    // but could've been overriden poorly.
  +                    ((BaseService) service).setInit(false);
  +                }
  +            }
  +        }
  +        catch (InstantiationException e)
           {
  -            shutdownClass(className);
  +            // Assuming harmless -- log the error and continue.
  +            log.error("Shutdown of a nonexistent Service '"
  +                      + name + "' was requested", e);
           }
       }
   
  @@ -247,11 +453,11 @@
        * Shuts down all Turbine services, releasing allocated resources and
        * returning them to their initial (uninitialized) state.
        */
  -    public void shutdownServices( )
  +    public void shutdownServices()
       {
  -        notice("Shutting down all services!");
  +        log.info("Shutting down all services!");
   
  -        Iterator serviceNames = mapping.getKeys();
  +        Iterator serviceNames = getServiceNames();
           String serviceName = null;
   
           /*
  @@ -265,7 +471,7 @@
   
           while (serviceNames.hasNext())
           {
  -            serviceName = (String)serviceNames.next();
  +            serviceName = (String) serviceNames.next();
               reverseServicesList.add(0, serviceName);
           }
   
  @@ -273,8 +479,8 @@
   
           while (serviceNames.hasNext())
           {
  -            serviceName = (String)serviceNames.next();
  -            notice("Shutting down service: " + serviceName);
  +            serviceName = (String) serviceNames.next();
  +            log.info("Shutting down service: " + serviceName);
               shutdownService(serviceName);
           }
       }
  @@ -287,26 +493,26 @@
        * @exception InstantiationException, if the service is unknown or
        * can't be initialized.
        */
  -    public Service getService( String name )
  +    public Service getService(String name)
           throws InstantiationException
       {
           Service service;
           try
           {
               service = getServiceInstance(name);
  -            if(!service.getInit())
  +            if (!service.getInit())
               {
  -                synchronized(service.getClass())
  +                synchronized (service.getClass())
                   {
  -                    if(!service.getInit())
  +                    if (!service.getInit())
                       {
  -                        notice("Start Initializing service (late): " + name);
  +                        log.info("Start Initializing service (late): " + name);
                           service.init();
  -                        notice("Finish Initializing service (late): " + name);
  +                        log.info("Finish Initializing service (late): " + name);
                       }
                   }
               }
  -            if(!service.getInit())
  +            if (!service.getInit())
               {
                   // this exception will be caught & rethrown by this very method.
                   // getInit() returning false indicates some initialization issue,
  @@ -317,10 +523,10 @@
               }
               return service;
           }
  -        catch( InitializationException e )
  +        catch (InitializationException e)
           {
               throw new InstantiationException("Service " + name +
  -                " failed to initialize", e);
  +                                             " failed to initialize", e);
           }
       }
   
  @@ -338,33 +544,76 @@
        * instances.
        *
        * @param name The name of the service requested.
  -     * @exception InstantiationException, if the service is unknown or
  +     * @exception InstantiationException The service is unknown or
        * can't be initialized.
        */
  -    protected Service getServiceInstance( String name )
  +    protected Service getServiceInstance(String name)
           throws InstantiationException
       {
  -        Service service = (Service)services.get(name);
  +        Service service = (Service) services.get(name);
   
  -        if(service == null)
  +        if (service == null)
           {
               String className = mapping.getString(name);
  -            if(className == null)
  +            if (StringUtils.isEmpty(className))
               {
                   throw new InstantiationException(
                       "ServiceBroker: unknown service " + name + " requested");
               }
               try
               {
  -                service = (Service)getInitableInstance(className);
  +                service = (Service) services.get(className);
  +
  +                if (service == null)
  +                {
  +                    try
  +                    {
  +                        service = (Service) Class.forName(className).newInstance();
  +                    }
  +                    // those two errors must be passed to the VM
  +                    catch (ThreadDeath t)
  +                    {
  +                        throw t;
  +                    }
  +                    catch (OutOfMemoryError t)
  +                    {
  +                        throw t;
  +                    }
  +                    catch (Throwable t)
  +                    {
  +                        // Used to indicate error condition.
  +                        String msg = null;
  +
  +                        if (t instanceof NoClassDefFoundError)
  +                        {
  +                            msg = "A class referenced by " + className +
  +                                " is unavailable. Check your jars and classes.";
  +                        }
  +                        else if (t instanceof ClassNotFoundException)
  +                        {
  +                            msg = "Class " + className +
  +                                " is unavailable. Check your jars and classes.";
  +                        }
  +                        else if (t instanceof ClassCastException)
  +                        {
  +                            msg = "Class " + className +
  +                                " doesn't implement the Service interface";
  +                        }
  +                        else
  +                        {
  +                            msg = "Failed to instantiate " + className;
  +                        }
  +
  +                        throw new InstantiationException(msg, t);
  +                    }
  +                }
               }
  -            catch(ClassCastException e)
  +            catch (ClassCastException e)
               {
  -                throw new InstantiationException(
  -                    "ServiceBroker: class " + className +
  -                    " does not implement Service interface.", e);
  +                throw new InstantiationException("ServiceBroker: Class "
  +                    + className + " does not implement Service interface.", e);
               }
  -            catch(InstantiationException e)
  +            catch (InstantiationException e)
               {
                   throw new InstantiationException(
                       "Failed to instantiate service " + name, e);
  @@ -378,28 +627,34 @@
       }
   
       /**
  -     * Returns the properites of a specific service.
  -     *
  -     * Generic ServiceBroker returns empty set of Properties.
  +     * Returns the configuration for the specified service.
        *
        * @param name The name of the service.
  -     * @return Properties of requested Service.
  +     * @return Configuration of requested Service.
        */
  -    public Properties getProperties( String name )
  +    public Configuration getConfiguration(String name)
       {
  -        return new Properties();
  +        return configuration.subset(SERVICE_PREFIX + name);
       }
   
       /**
  -     * Returns the Configuration of a specific service.
  +     * Set the application root.
        *
  -     * Generic ServiceBroker returns empty Configuration
  +     * @param String application root
  +     */
  +    public void setApplicationRoot(String applicationRoot)
  +    {
  +        this.applicationRoot = applicationRoot;
  +    }
  +
  +    /**
  +     * Get the application root as set by
  +     * the parent application.
        *
  -     * @param name The name of the service.
  -     * @return Properties of requested Service.
  +     * @return String application root
        */
  -    public Configuration getConfiguration( String name )
  +    public String getApplicationRoot()
       {
  -        return (Configuration) new BaseConfiguration();
  +        return applicationRoot;
       }
   }
  
  
  
  1.4       +9 -27     jakarta-turbine-2/src/java/org/apache/turbine/services/ServiceBroker.java
  
  Index: ServiceBroker.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-2/src/java/org/apache/turbine/services/ServiceBroker.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ServiceBroker.java	16 Apr 2002 22:07:07 -0000	1.3
  +++ ServiceBroker.java	20 Dec 2002 00:07:21 -0000	1.4
  @@ -78,10 +78,10 @@
    * @author <a href="mailto:burton@apache.org">Kevin Burton</a>
    * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
    * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
  + * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    * @version $Id$
    */
   public interface ServiceBroker
  -    extends InitableBroker
   {
       /**
        * Determines whether a service is registered in the configured
  @@ -90,7 +90,7 @@
        * @param serviceName The name of the service whose existance to check.
        * @return Registration predicate for the desired services.
        */
  -    public boolean isRegistered( String serviceName );
  +    boolean isRegistered(String serviceName);
   
       /**
        * Performs early initialization of specified service.
  @@ -100,18 +100,10 @@
        * @exception InitializationException, if the service is unknown
        * or can't be initialized.
        */
  -    public void initService( String name,
  -                             Object data )
  +    void initService(String name)
           throws InitializationException;
   
       /**
  -     * Performs early initialization of all services.
  -     *
  -     * @param data An Object to use for initialization activities.
  -     */
  -    public void initServices( Object data );
  -
  -    /**
        * Shutdowns a Service.
        *
        * This method is used to release resources allocated by a
  @@ -119,16 +111,15 @@
        *
        * @param name The name of the Service to be uninitialized.
        */
  -    public void shutdownService( String name );
  +    void shutdownService(String name);
   
       /**
        * Shutdowns all Services.
        *
        * This method is used to release resources allocated by
  -     * Services, and return them to initial (uninitailized) state.
  +     * Services, and return them to initial (uninitialized) state.
        */
  -    public void shutdownServices( );
  -
  +    void shutdownServices();
   
       /**
        * Returns an instance of requested Service.
  @@ -138,24 +129,15 @@
        * @exception InstantiationException, if the service is unknown or
        * can't be initialized.
        */
  -    public Service getService( String name )
  +    Service getService(String name)
           throws InstantiationException;
   
       /**
  -     * Returns the properites of a specific service.  Services use
  -     * this method to retrieve their properties.
  -     *
  -     * @param name The name of the service.
  -     * @return Properties of requested Service.
  -     */
  -     public Properties getProperties( String name );
  -
  -    /**
        * Returns the configuration of a specific service. Services
        * use this method to retrieve their configuration.
        *
        * @param name The name of the service.
        * @return Configuration of the requested service.
        */
  -    public Configuration getConfiguration( String name );
  +    Configuration getConfiguration(String name);
   }
  
  
  
  1.10      +14 -382   jakarta-turbine-2/src/java/org/apache/turbine/services/TurbineServices.java
  
  Index: TurbineServices.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-2/src/java/org/apache/turbine/services/TurbineServices.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- TurbineServices.java	27 Jul 2002 12:36:12 -0000	1.9
  +++ TurbineServices.java	20 Dec 2002 00:07:21 -0000	1.10
  @@ -54,20 +54,6 @@
    * <http://www.apache.org/>.
    */
   
  -import java.io.PrintWriter;
  -import java.io.StringWriter;
  -import java.util.Iterator;
  -import java.util.Properties;
  -import java.util.Vector;
  -import javax.servlet.ServletConfig;
  -import org.apache.commons.configuration.Configuration;
  -import org.apache.commons.lang.StringUtils;
  -import org.apache.turbine.services.component.ComponentService;
  -import org.apache.turbine.services.logging.LoggingService;
  -import org.apache.turbine.services.resources.ResourceService;
  -import org.apache.turbine.services.resources.TurbineResources;
  -
  -
   /**
    * This is a singleton utility class that acts as a Services broker.
    *
  @@ -76,84 +62,16 @@
    * @author <a href="mailto:burton@apache.org">Kevin Burton</a>
    * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
    * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
  + * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
    * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
    * @version $Id$
    */
   public class TurbineServices
       extends BaseServiceBroker
  +    implements ServiceManager
   {
  -    /**
  -     * Servlet initialization parameter name for defining the resources
  -     * service implementation to use (<code>resources</code>).
  -     */
  -    public final static String RESOURCES_CLASS_KEY = "resources";
  -
  -    /**
  -     * Default resources service implementation to use when none explicitly
  -     * specified (<code>
  -     * org.apache.turbine.services.resources.TurbineResourceService</code>)
  -     */
  -    public final static String RESOURCES_CLASS_DEFAULT =
  -        "org.apache.turbine.services.resources.TurbineResourceService";
  -
  -    /**
  -     * Servlet initialization parameter name for defining the logging
  -     * service implementation to use.
  -     */
  -    public final static String LOGGING_CLASS_KEY="logging";
  -
  -    /** Default bootstrap logger implementation */
  -    public final static String LOGGING_CLASS_DEFAULT =
  -        "org.apache.turbine.services.logging.TurbineLoggingService";
  -
  -    /**
  -     * Servlet initialization parameter name for defining the component loader
  -     * service implementation to load Stratum based components.
  -     */
  -    public final static String COMPONENT_CLASS_KEY = "component";
  -
  -    /** Default component service implementation */
  -    public final static String COMPONENT_CLASS_DEFAULT =
  -        "org.apache.turbine.services.component.TurbineComponentService";
  -
  -    /**
  -     * Servlet initialization parameter name for the path to
  -     * TurbineResources.properties file used by
  -     * {@link org.apache.turbine.services.resources.TurbineResourceService}
  -     * (<code>properties</code>).
  -     */
  -    public static final String PROPERTIES_PATH_KEY = "properties";
  -
  -    /**
  -     * Default value of TurbineResources.properties file path
  -     * (<code>/WEB-INF/conf/TurbineResources.properties</code>).
  -     */
  -    public static final String PROPERTIES_PATH_DEFAULT =
  -        "/WEB-INF/conf/TurbineResources.properties";
  -
  -    /**
  -     * A prefix for <code>Service</code> properties in
  -     * TurbineResource.properties.
  -     */
  -    public static final String SERVICE_PREFIX = "services.";
  -
  -    /**
  -     * A <code>Service</code> property determining its implementing
  -     * class name .
  -     */
  -    public static final String CLASSNAME_SUFFIX = ".classname";
  -
       /** The single instance of this class. */
  -    protected static ServiceBroker instance = new TurbineServices();
  -
  -    /** True if logging should go throught LoggingService, false if not. */
  -    private boolean enabledLogging = false;
  -
  -    /** caches log messages before logging is enabled */
  -    private Vector logCache = new Vector(5);
  -
  -    /** the logger */
  -    private LoggingService logger;
  +    private static ServiceManager instance = new TurbineServices();
   
       /**
        * This constructor is protected to force clients to use
  @@ -165,313 +83,27 @@
       }
   
       /**
  -     * The method through which this class is accessed.
  +     * The method through which this class is accessed as a broker.
        *
        * @return The single instance of this class.
        */
  -    public static ServiceBroker getInstance()
  +    public static ServiceManager getInstance()
       {
           return instance;
       }
   
       /**
  -     * Initialize the primary services (Logging and Resources).
  -     */
  -    public void initPrimaryServices(ServletConfig config)
  -        throws InstantiationException, InitializationException
  -    {
  -        // Resource service must start as the very first
  -        String resourcesClass = config.getInitParameter(RESOURCES_CLASS_KEY);
  -
  -        try
  -        {
  -            if (resourcesClass == null)
  -            {
  -                resourcesClass = RESOURCES_CLASS_DEFAULT;
  -            }
  -            mapping.setProperty(ResourceService.SERVICE_NAME, resourcesClass);
  -            initService(ResourceService.SERVICE_NAME, config);
  -
  -            // Now logging can be initialized.
  -            String loggingClass = config.getInitParameter(LOGGING_CLASS_KEY);
  -            if (loggingClass == null)
  -            {
  -                loggingClass = LOGGING_CLASS_DEFAULT;
  -            }
  -            mapping.setProperty(LoggingService.SERVICE_NAME, loggingClass);
  -            try
  -            {
  -                initService(LoggingService.SERVICE_NAME, config);
  -                logger = getLogger();
  -            }
  -            catch (InitializationException e)
  -            {
  -                mapping.clearProperty(LoggingService.SERVICE_NAME);
  -                throw e;
  -            }
  -            catch (InstantiationException e)
  -            {
  -                mapping.clearProperty(LoggingService.SERVICE_NAME);
  -                throw e;
  -            }
  -
  -            // Now the Component Service can be initialized
  -            // Just set up the mapping and let Turbine call us early.
  -            String componentClass = config.getInitParameter(COMPONENT_CLASS_KEY);
  -            if (componentClass == null)
  -            {
  -                componentClass = COMPONENT_CLASS_DEFAULT;
  -            }
  -            mapping.setProperty(ComponentService.SERVICE_NAME, componentClass);
  -        }
  -        finally
  -        {
  -            // All further messages will go through LoggingService
  -            // if logging service could not be initialized we still want
  -            // to enable logging for further messages to go to console
  -            enableLogging();
  -        }
  -        // Since we have ResourceService running, real mappings of services
  -        // may be loaded now
  -        initMapping();
  -    }
  -
  -    /**
  -     * Creates mapping of Service names to class names.
  -     * BaseServiceBroker knows no mappings.
  -     */
  -    public void initMapping(Configuration mapping)
  -    {
  -        this.mapping = mapping;
  -    }
  -
  -    /**
  -     * Creates a mapping between Service names and class names.
  -     *
  -     * The mapping is built according to settings present in
  -     * TurbineResources.properties.  The entries should have the
  -     * following form:
  -     *
  -     * <pre>
  -     * services.MyService.classname=com.mycompany.MyServiceImpl
  -     * services.MyOtherService.classname=com.mycompany.MyOtherServiceImpl
  -     * </pre>
  -     *
  -     * <br>
  -     *
  -     * Generic ServiceBroker provides no Services.
  -     */
  -    protected void initMapping()
  -    {
  -        /*
  -         * These keys returned in an order that corresponds
  -         * to the order the services are listed in
  -         * the TR.props.
  -         *
  -         * When the mapping is created we use a Configuration
  -         * object to ensure that the we retain the order
  -         * in which the order the keys are returned.
  -         *
  -         * There's no point in retrieving an ordered set
  -         * of keys if they aren't kept in order :-)
  -         */
  -        Iterator keys = TurbineResources.getKeys();
  -        while(keys.hasNext())
  -        {
  -            String key = (String)keys.next();
  -            String [] keyParts = StringUtils.split(key, ".");
  -            if ((keyParts.length == 3) 
  -                && (keyParts[0] + ".").equals(SERVICE_PREFIX) 
  -                && ("." + keyParts[2]).equals(CLASSNAME_SUFFIX))
  -            {
  -                String serviceKey = keyParts[1];
  -                notice ("Added Mapping for Service: " + serviceKey);
  -
  -                if (!mapping.containsKey(serviceKey))
  -                {
  -                    mapping.setProperty(serviceKey, TurbineResources.getString(key));
  -                }
  -            }
  -        }
  -    }
  -
  -    /**
  -     * Returns the properites of a specific service.  Properties are
  -     * retrieved from TurbineResources.properties provided that you
  -     * have the following entries:
  -     *
  -     * <br>
  -     *
  -     * services.MyService.greeting=Hello\, I'm Jan B.
  -     *
  -     * <br>
  -     *
  -     * services.MyService.defaultAction=beep
  -     *
  -     * <br>
  -     *
  -     * Service "MyService" will get a set of two properites:
  -     * "greeting" = "Hello, I'm Jan B." and "defaultAction" = "beep".
  -     *
  -     * <p> Note that this way you will receive a 'collapsed' version
  -     * of your resources - multiple entries with the same key will
  -     * have only one value stored.  Use the {@link #getConfiguration}
  -     * or {@link #getResources} method to take advantage of the capabilities
  -     * of the {@link org.apache.turbine.services.resources.TurbineResources}
  -     * class.
  -     *
  -     * @param name The name of the service.
  -     * @return Properties of requested Service.
  -     */
  -    public Properties getProperties( String name )
  -    {
  -        Properties properties = new Properties();
  -
  -        String servicePrefix = SERVICE_PREFIX + name + '.';
  -        Iterator keys = TurbineResources.getKeys(servicePrefix);
  -
  -        while(keys.hasNext())
  -        {
  -            String key = (String)keys.next();
  -            String value;
  -            try
  -            {
  -                value = TurbineResources.getString(key);
  -            }
  -            catch (ClassCastException propIsArray)
  -            {
  -                String[] values = TurbineResources.getStringArray(key);
  -                value = values[values.length - 1];
  -            }
  -            properties.setProperty(key.substring(servicePrefix.length()),
  -                                   value);
  -        }
  -
  -        return properties;
  -    }
  -
  -    /**
  -     * Returns the Configuration for the specified service.
  -     *
  -     * @param name The name of the service.
  -     */
  -    public Configuration getConfiguration( String name )
  -    {
  -        return TurbineResources.getConfiguration(SERVICE_PREFIX + name);
  -    }
  -
  -    /**
  -     * Returns the configuration resources of a specific service.
  -     *
  -     * This method extracts the configuration options of a service
  -     * from global Turbine configuration. The interface
  -     * {@link org.apache.turbine.services.resources.ResourceService}
  -     * offers significant advantages over plain java.util.Properties -
  -     * you can request for exaple you can retrieve <code>int</code>s
  -     * <code>boolean</code>s, and vectors of <code>String</code>s.
  -     *
  -     * <p> Note that the proces extracting the configuration might
  -     * be time consuming, it might be a good idea to store the
  -     * reference returned by this method in an instance variable
  -     * of the service.</p>
  -     *
  -     * @param name The name of the Service.
  -     * @return The configuration resources of the Service.
  -     */
  -    public ResourceService getResources( String name )
  -    {
  -        return TurbineResources.getResources(SERVICE_PREFIX + name);
  -    }
  -
  -    /**
  -     * Output a diagnostic notice.
  -     *
  -     * This method is used by the service framework classes for producing
  -     * tracing mesages that might be useful for debugging.
  -     *
  -     * <p>Standard Turbine logging facilities are used.
  -     *
  -     * @param msg the message to print.
  -     */
  -    public void notice(String msg)
  -    {
  -        if (enabledLogging)
  -        {
  -            if (logger == null)
  -            {
  -                System.out.println("(!) NOTICE: " + msg);
  -            }
  -            else
  -            {
  -                logger.info(msg);
  -            }
  -        }
  -        else
  -        {
  -            // cache the message to log as soon as logging is on
  -            logCache.add(msg);
  -        }
  -    }
  -
  -    /**
  -     * Output an error message.
  -     *
  -     * This method is used by the service framework classes for displaying
  -     * stacktraces of any exceptions that might be caught during processing.
  -     *
  -     * <p>Standard Turbine logging facilities are used.
  -     *
  -     * @param msg the message to print.
  +     * The method through which to change the default manager.
  +     * Note that services of the previous manager will be shutdown.
  +     * @param manager a new service manager.
        */
  -    public void error(Throwable t)
  +    public static synchronized void setManager(ServiceManager manager)
       {
  -        if (enabledLogging)
  -        {
  -            if (logger == null)
  -            {
  -                System.out.println("(!) ERROR: " + t.getMessage());
  -            }
  -            else
  -            {
  -                logger.error("", t);
  -            }
  -        }
  -        else
  +        ServiceManager previous = instance;
  +        instance = manager;
  +        if (previous != null)
           {
  -            // cache the message to log as soon as logging is on
  -            logCache.add("ERROR: " + t.getMessage());
  -            StringWriter sw = new StringWriter();
  -            t.printStackTrace(new PrintWriter(sw));
  -            logCache.add(sw.toString());
  +            previous.shutdownServices();
           }
  -
  -    }
  -
  -    /**
  -     * Allows logging using a logging service instead of console
  -     * This method should be called after initialization of the logging service
  -     */
  -    private void enableLogging()
  -    {
  -        enabledLogging = true;
  -        //log all cached log messages
  -        for (int i = 0; i < logCache.size(); i++)
  -        {
  -            String s = (String) logCache.elementAt(i);
  -            notice(s);
  -        }
  -        //dispose of the cache
  -        logCache = null;
  -
  -        notice("ServiceBroker: LoggingService enabled.");
  -
  -    }
  -
  -    /**
  -     * Macro to reduce duplicated code and casting.
  -     */
  -    private final LoggingService getLogger()
  -    {
  -        return (LoggingService) getService(LoggingService.SERVICE_NAME);
       }
   }
  
  
  
  1.1                  jakarta-turbine-2/src/java/org/apache/turbine/services/ServiceManager.java
  
  Index: ServiceManager.java
  ===================================================================
  package org.apache.turbine.services;
  
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Apache" and "Apache Software Foundation" and
   *    "Apache Turbine" must not be used to endorse or promote products
   *    derived from this software without prior written permission. For
   *    written permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    "Apache Turbine", nor may "Apache" appear in their name, without
   *    prior written permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  import org.apache.commons.configuration.Configuration;
  
  /**
   * Classes that implement this interface can act as a manager for
   * <code>Service</code> classes.
   *
   * Functionality that <code>ServiceManager</code> provides in addition
   * to <code>ServiceBroker</code> functionality includes configuration
   * of the manager.
   *
   * @author <a href="mailto:ilkka.priha@simsoft.fi">Ilkka Priha</a>
   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
   * @version $Id: ServiceManager.java,v 1.1 2002/12/20 00:07:21 henning Exp $
   */
  public interface ServiceManager extends ServiceBroker
  {
      /**
       * Initialize this service manager.
       */
      public void init() throws InitializationException;
  
      /**
       * Get the configuration for this service manager.
       *
       * @return Manager configuration.
       */
      public Configuration getConfiguration();
  
      /**
       * Set the configuration object for the services broker.
       * This is the configuration that contains information
       * about all services in the care of this service
       * manager.
       *
       * @param configuration Manager configuration.
       */
      public void setConfiguration(Configuration configuration);
  
      /**
       * Set the application root.
       *
       * @param String application root
       */
      public void setApplicationRoot(String applicationRoot);
  }
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>