> But it is not clear to me exactly what you want to do.
Here is how i did it in fact :
My DefaultContentProviderSelector reads from configuration the configuration of
all the providers it needs. For each ContentProvider that it must instanciate,
it delegates the instanciation and startup to another component (called for the
moment ContainerAbstraction).
public class DefaultContentProviderSelector
extends ResponsabilityChainServiceSelector
implements
ContentProviderSelector,
Initializable,
Configurable,
LogEnabled,
Serviceable
{
/**
* Constructs a <code>ContentProviderSelector</code>.
*/
public DefaultContentProviderSelector()
{
super();
}
public void configure(Configuration configuration)
throws ConfigurationException
{
// Load configuration and look for providers specification
m_managerConfiguration = configuration;
}
private Configuration m_managerConfiguration;
private ContainerAbstraction m_containerAbstraction;
public void service(ServiceManager serviceManager) throws ServiceException
{
m_containerAbstraction =
(ContainerAbstraction) serviceManager.lookup(
ContainerAbstraction.ROLE);
}
public void initialize() throws Exception
{
// Iterate on providers specified in the configuration
// For each provider class name
// Instanciate a component
// Configure it with the provider configuration sub-node
Configuration[] providersConf = m_managerConfiguration.getChildren();
for (int i = 0; i < providersConf.length; i++)
{
Configuration aProviderConf = providersConf[i];
String providerClassName = null;
try
{
String providerName =
aProviderConf.getAttribute("name");
providerClassName =
aProviderConf.getAttribute("class");
Logger childLogger =
getLogger().getChildLogger(providerName);
ContentProvider provider =
(ContentProvider)m_containerAbstraction
.get(providerClassName, null,
childLogger, aProviderConf);
registerContentProvider(provider);
}
catch (ContainerAbstractionException e)
{
getLogger().error("Error initializing " +
providerClassName, e);
throw e;
}
}
}
/**
* Registers a store provider to this content manager.
* @param the store provider to register
*/
public void registerContentProvider(ContentProvider contentProvider)
{
getResponsabilityChain().add(contentProvider);
}
/**
* Unregisters a store provider from this content manager.
* @param the store provider to unregister
*/
public void unregisterContentProvider(ContentProvider contentProvider)
{
getResponsabilityChain().remove(contentProvider);
}
/**
* @see
com.cleverage.pudding.util.ResponsabilityChainServiceSelector#suppliedBy(java.lang.Object,
java.lang.Object)
*/
protected boolean suppliedBy(Object policy, Object object)
{
return ((ContentProvider) object).acceptsURL((String) policy);
}
}
and the ResponsabilityChainServiceProvider just manages a chain of objects for
some of which it maintains a busy state. Based on this it implements
ServiceSelector:
public abstract class ResponsabilityChainServiceSelector
extends AbstractLogEnabled
implements ServiceSelector
{
public final static String ROLE = "org.apache.avalon.service.ServiceSelector";
/**
* Constructs a <code>ResponsabilityChainServiceSelector</code>.
*/
public ResponsabilityChainServiceSelector()
{
this(new LinkedList());
}
/**
* Constructs a <code>ResponsabilityChainServiceSelector</code>.
*/
public ResponsabilityChainServiceSelector(List responsabilityChain)
{
super();
this.m_responsabilityChain = responsabilityChain;
m_busyElements = new LinkedList();
}
protected abstract boolean suppliedBy(Object policy, Object object);
protected List getResponsabilityChain()
{
return m_responsabilityChain;
}
private List m_responsabilityChain;
/*
* Methods from org.apache.avalon.framework.service.ServiceSelector
*/
public boolean isSelectable(Object policy)
{
Iterator theChainElements = m_responsabilityChain.iterator();
while (theChainElements.hasNext())
{
Object chainElement = theChainElements.next();
if (suppliedBy(policy, chainElement))
return true;
}
return false;
}
public Object select(Object policy) throws ServiceException
{
Iterator theChainElements = m_responsabilityChain.iterator();
while (theChainElements.hasNext())
{
Object chainElement = theChainElements.next();
if (!busy(chainElement) && suppliedBy(policy, chainElement))
{
take(chainElement);
return chainElement;
}
}
throw new ServiceException(ROLE, "Can't select such service");
}
private LinkedList m_busyElements;
private boolean take(Object chainElement)
{
synchronized (m_busyElements)
{
return true; // busyElements.add(chainElement);
}
}
private boolean busy(Object chainElement)
{
synchronized (m_busyElements)
{
return m_busyElements.contains(chainElement);
}
}
public void release(Object chainElement)
{
synchronized (m_busyElements)
{
m_busyElements.remove(chainElement);
}
}
}
> when "do other stuff" becomes a lot of work you can think about putting
> in place an actual container implementation like fortress, but you often
> don't really need one.
As i want my selectors to container-independent, i prefer to define the
container abstraction services right now.
In fact there are two aspects i must abstract: the one i presented you here to
delegate instanciation for individual components and an abstraction of the
container itself for my main application component.
An alternative design for the first part is to do something like a
ClassNameBasedServiceSelector that does implement a selector but where the
policy is a implementation class name. Maybe that's the way i'll go.
>I guess it's obvious from the example I'm not too fond of ServiceSelector ;)
So am i... :) If you have any comments, there are really welcome!!
> cheers,
>
> - Leo
Cheers, Didier.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]