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>