* Added ServiceManager interface, and several implementations. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271311 13f79535-47bb-0310-9956-ffa450edef68master
@@ -0,0 +1,144 @@ | |||
/* | |||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||
* | |||
* This software is published under the terms of the Apache Software License | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.myrmidon.components.service; | |||
import java.util.HashMap; | |||
import java.util.Iterator; | |||
import java.util.Map; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.avalon.framework.activity.Disposable; | |||
import org.apache.avalon.framework.component.ComponentException; | |||
import org.apache.avalon.framework.component.ComponentManager; | |||
import org.apache.avalon.framework.component.Composable; | |||
import org.apache.myrmidon.interfaces.service.ServiceException; | |||
import org.apache.myrmidon.interfaces.service.ServiceFactory; | |||
import org.apache.myrmidon.interfaces.service.ServiceManager; | |||
import org.apache.myrmidon.interfaces.type.TypeException; | |||
import org.apache.myrmidon.interfaces.type.TypeFactory; | |||
import org.apache.myrmidon.interfaces.type.TypeManager; | |||
/** | |||
* A service manager implementation. This implementation takes care of | |||
* creating service instances, using a {@link ServiceFactory}, and running the | |||
* service instances through the service lifecycle. Service creation happens | |||
* on demand. | |||
* | |||
* <p>This implementation uses a TypeManager to locate the service factories. | |||
* | |||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class DefaultServiceManager | |||
implements ServiceManager, Composable, Disposable | |||
{ | |||
private final static Resources REZ | |||
= ResourceManager.getPackageResources( DefaultServiceManager.class ); | |||
/** Map from service class -> service object. */ | |||
private Map m_services = new HashMap(); | |||
private TypeFactory m_typeFactory; | |||
/** | |||
* Locate the components used by this service manager. | |||
*/ | |||
public void compose( final ComponentManager componentManager ) throws ComponentException | |||
{ | |||
final TypeManager typeManager = (TypeManager)componentManager.lookup( TypeManager.ROLE ); | |||
try | |||
{ | |||
m_typeFactory = typeManager.getFactory( ServiceFactory.class ); | |||
} | |||
catch( final TypeException e ) | |||
{ | |||
throw new ComponentException( e.getMessage(), e ); | |||
} | |||
} | |||
/** | |||
* Disposes this service manager, and all services created by it. | |||
*/ | |||
public void dispose() | |||
{ | |||
// Dispose the services | |||
for( Iterator iterator = m_services.values().iterator(); iterator.hasNext(); ) | |||
{ | |||
final Object object = iterator.next(); | |||
if( object instanceof Disposable ) | |||
{ | |||
( (Disposable)object ).dispose(); | |||
} | |||
} | |||
// Ditch state | |||
m_services = null; | |||
m_typeFactory = null; | |||
} | |||
/** | |||
* Determines if this service manager contains a particular service. | |||
*/ | |||
public boolean hasService( Class serviceType ) | |||
{ | |||
// If we have already instantiated the service, or if we know how | |||
// to instantiate it, then return true | |||
if( m_services.containsKey( serviceType ) ) | |||
{ | |||
return true; | |||
} | |||
if( m_typeFactory.canCreate( serviceType.getName() ) ) | |||
{ | |||
return true; | |||
} | |||
return false; | |||
} | |||
/** | |||
* Locates a service instance. | |||
*/ | |||
public Object getService( Class serviceType ) | |||
throws ServiceException | |||
{ | |||
Object service = m_services.get( serviceType ); | |||
if( service == null ) | |||
{ | |||
// Create the service | |||
service = createService( serviceType ); | |||
m_services.put( serviceType, service ); | |||
} | |||
return service; | |||
} | |||
/** | |||
* Creates the service object for a service class. | |||
*/ | |||
private Object createService( Class serviceType ) throws ServiceException | |||
{ | |||
try | |||
{ | |||
final ServiceFactory factory = (ServiceFactory)m_typeFactory.create( serviceType.getName() ); | |||
// Create the service | |||
final Object service = factory.createService(); | |||
if( ! serviceType.isInstance( service ) ) | |||
{ | |||
final String message = REZ.getString( "mismatched-service-type.error", serviceType.getName(), service.getClass().getName() ); | |||
throw new ServiceException( message ); | |||
} | |||
return service; | |||
} | |||
catch( Exception e ) | |||
{ | |||
final String message = REZ.getString( "create-service.error", serviceType.getName() ); | |||
throw new ServiceException( message, e ); | |||
} | |||
} | |||
} |
@@ -0,0 +1,3 @@ | |||
unknown-service-type.error=Unknown service type {0}. | |||
mismatched-service-type.error=Service factory for type {0} produced an object of unexpected type {1}. | |||
create-service.error=Could not create service {0}. |
@@ -12,8 +12,8 @@ import org.apache.aut.nativelib.ExecException; | |||
import org.apache.aut.nativelib.impl.DefaultExecManager; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
import org.apache.myrmidon.services.ServiceException; | |||
import org.apache.myrmidon.services.ServiceFactory; | |||
import org.apache.myrmidon.interfaces.service.ServiceException; | |||
import org.apache.myrmidon.interfaces.service.ServiceFactory; | |||
/** | |||
* A Factory responsible for creating the ExecManager service. | |||
@@ -0,0 +1,52 @@ | |||
/* | |||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||
* | |||
* This software is published under the terms of the Apache Software License | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.myrmidon.interfaces.service; | |||
import org.apache.avalon.framework.component.ComponentException; | |||
import org.apache.avalon.framework.component.ComponentManager; | |||
/** | |||
* An adaptor from {@link ComponentManager} to {@link ServiceManager}. | |||
* | |||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class ComponentManagerAdaptor | |||
implements ServiceManager | |||
{ | |||
private final ComponentManager m_componentManager; | |||
public ComponentManagerAdaptor( final ComponentManager componentManager ) | |||
{ | |||
m_componentManager = componentManager; | |||
} | |||
/** | |||
* Determines if this service manager contains a particular service. | |||
*/ | |||
public boolean hasService( Class serviceType ) | |||
{ | |||
return m_componentManager.hasComponent( serviceType.getName() ); | |||
} | |||
/** | |||
* Locates a service instance. | |||
*/ | |||
public Object getService( Class serviceType ) | |||
throws ServiceException | |||
{ | |||
try | |||
{ | |||
return m_componentManager.lookup( serviceType.getName() ); | |||
} | |||
catch( ComponentException e ) | |||
{ | |||
throw new ServiceException( e.getMessage(), e ); | |||
} | |||
} | |||
} |
@@ -0,0 +1,79 @@ | |||
/* | |||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||
* | |||
* This software is published under the terms of the Apache Software License | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.myrmidon.interfaces.service; | |||
import java.util.ArrayList; | |||
import org.apache.avalon.excalibur.i18n.ResourceManager; | |||
import org.apache.avalon.excalibur.i18n.Resources; | |||
/** | |||
* A service manager that aggregates services from several | |||
* {@link ServiceManager} objects. | |||
* | |||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public class MultiSourceServiceManager | |||
implements ServiceManager | |||
{ | |||
private final static Resources REZ | |||
= ResourceManager.getPackageResources( MultiSourceServiceManager.class ); | |||
/** The source service managers, in order. */ | |||
private final ArrayList m_sources = new ArrayList(); | |||
/** | |||
* Adds a service manager to the end of the source list. | |||
*/ | |||
public void add( final ServiceManager mgr ) | |||
{ | |||
m_sources.add( mgr ); | |||
} | |||
/** | |||
* Determines if this service manager contains a particular service. | |||
* | |||
* @param serviceType The service interface. | |||
*/ | |||
public boolean hasService( Class serviceType ) | |||
{ | |||
for( int i = 0; i < m_sources.size(); i++ ) | |||
{ | |||
final ServiceManager serviceManager = (ServiceManager)m_sources.get( i ); | |||
if( serviceManager.hasService( serviceType ) ) | |||
{ | |||
return true; | |||
} | |||
} | |||
return false; | |||
} | |||
/** | |||
* Locates a service instance. | |||
* | |||
* @param serviceType The service interface. | |||
* @return The service instance. The returned object is guaranteed to | |||
* implement the service interface. | |||
* @throws ServiceException If the service does not exist. | |||
*/ | |||
public Object getService( Class serviceType ) | |||
throws ServiceException | |||
{ | |||
for( int i = 0; i < m_sources.size(); i++ ) | |||
{ | |||
final ServiceManager serviceManager = (ServiceManager)m_sources.get( i ); | |||
if( serviceManager.hasService( serviceType ) ) | |||
{ | |||
return serviceManager.getService( serviceType ); | |||
} | |||
} | |||
final String message = REZ.getString( "unknown-service.error", serviceType.getName() ); | |||
throw new ServiceException( message ); | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
unknown-service.error=Unknown service {0}. |
@@ -5,7 +5,7 @@ | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.myrmidon.services; | |||
package org.apache.myrmidon.interfaces.service; | |||
import org.apache.avalon.framework.CascadingException; | |||
@@ -5,7 +5,7 @@ | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.myrmidon.services; | |||
package org.apache.myrmidon.interfaces.service; | |||
/** | |||
* A ServiceFactory is used to create a service for use in the | |||
@@ -17,6 +17,8 @@ package org.apache.myrmidon.services; | |||
*/ | |||
public interface ServiceFactory | |||
{ | |||
String ROLE = ServiceFactory.class.getName(); | |||
/** | |||
* Create a service that coresponds to this factory. | |||
* This method is usually called after the factory has been |
@@ -0,0 +1,40 @@ | |||
/* | |||
* Copyright (C) The Apache Software Foundation. All rights reserved. | |||
* | |||
* This software is published under the terms of the Apache Software License | |||
* version 1.1, a copy of which has been included with this distribution in | |||
* the LICENSE.txt file. | |||
*/ | |||
package org.apache.myrmidon.interfaces.service; | |||
import org.apache.avalon.framework.component.Component; | |||
/** | |||
* Manages a set of services. | |||
* | |||
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a> | |||
* @version $Revision$ $Date$ | |||
*/ | |||
public interface ServiceManager | |||
extends Component | |||
{ | |||
String ROLE = ServiceManager.class.getName(); | |||
/** | |||
* Determines if this service manager contains a particular service. | |||
* | |||
* @param serviceType The service interface. | |||
*/ | |||
boolean hasService( Class serviceType ); | |||
/** | |||
* Locates a service instance. | |||
* | |||
* @param serviceType The service interface. | |||
* @return The service instance. The returned object is guaranteed to | |||
* implement the service interface. | |||
* @throws ServiceException If the service does not exist. | |||
*/ | |||
Object getService( Class serviceType ) | |||
throws ServiceException; | |||
} |
@@ -17,7 +17,7 @@ import org.apache.aut.nativelib.ExecMetaData; | |||
import org.apache.avalon.excalibur.io.IOUtil; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.myrmidon.framework.factorys.ExecManagerFactory; | |||
import org.apache.myrmidon.services.ServiceException; | |||
import org.apache.myrmidon.interfaces.service.ServiceException; | |||
/** | |||
* Runs an external program. | |||
@@ -17,7 +17,7 @@ import org.apache.aut.nativelib.ExecMetaData; | |||
import org.apache.avalon.excalibur.io.IOUtil; | |||
import org.apache.myrmidon.api.TaskException; | |||
import org.apache.myrmidon.framework.factorys.ExecManagerFactory; | |||
import org.apache.myrmidon.services.ServiceException; | |||
import org.apache.myrmidon.interfaces.service.ServiceException; | |||
/** | |||
* Runs an external program. | |||