Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.codehaus.plexus.DefaultComponentRegistry Maven / Gradle / Ivy
package org.codehaus.plexus;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import static org.codehaus.plexus.component.CastUtils.isAssignableFrom;
import org.codehaus.plexus.component.factory.ComponentInstantiationException;
import org.codehaus.plexus.component.manager.ComponentManager;
import org.codehaus.plexus.component.manager.ComponentManagerFactory;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.ComponentRepository;
import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.component.repository.exception.ComponentRepositoryException;
import org.codehaus.plexus.lifecycle.LifecycleHandler;
import org.codehaus.plexus.lifecycle.LifecycleHandlerManager;
import org.codehaus.plexus.lifecycle.UndefinedLifecycleHandlerException;
import org.codehaus.plexus.logging.Logger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.IdentityHashMap;
import java.util.Collections;
public class DefaultComponentRegistry implements ComponentRegistry
{
private static final String DEFAULT_INSTANTIATION_STRATEGY = "singleton";
private final MutablePlexusContainer container;
private final ComponentRepository repository;
private final LifecycleHandlerManager lifecycleHandlerManager;
private final Logger logger;
private final Map componentManagerFactories =
Collections.synchronizedMap( new TreeMap() );
private final Map> componentManagers = new TreeMap>();
private final Map> componentManagersByComponent = new IdentityHashMap>();
public DefaultComponentRegistry( MutablePlexusContainer container,
ComponentRepository repository,
LifecycleHandlerManager lifecycleHandlerManager )
{
this.container = container;
this.repository = repository;
this.lifecycleHandlerManager = lifecycleHandlerManager;
logger = container.getLogger();
}
public void dispose()
{
Collection> managers;
synchronized ( this )
{
managers = new ArrayList>( componentManagers.values() );
componentManagers.clear();
componentManagersByComponent.clear();
}
// Call dispose callback outside of synchronized lock to avoid deadlocks
for ( ComponentManager> componentManager : managers )
{
try
{
componentManager.dispose();
}
catch ( Exception e )
{
// todo dain use a monitor instead of a logger
logger.error( "Error while disposing component manager. Continuing with the rest", e );
}
}
}
public void registerComponentManagerFactory( ComponentManagerFactory componentManagerFactory )
{
componentManagerFactories.put( componentManagerFactory.getId(), componentManagerFactory );
}
public void addComponentDescriptor( ComponentDescriptor> componentDescriptor ) throws ComponentRepositoryException
{
repository.addComponentDescriptor( componentDescriptor );
}
public ComponentDescriptor getComponentDescriptor( Class type, String role, String roleHint )
{
return repository.getComponentDescriptor( type, role, roleHint );
}
@Deprecated
public ComponentDescriptor> getComponentDescriptor( String role, String roleHint, ClassRealm realm )
{
return repository.getComponentDescriptor( role, roleHint, realm );
}
public Map> getComponentDescriptorMap( Class type, String role )
{
return repository.getComponentDescriptorMap( type, role );
}
public List> getComponentDescriptorList( Class type, String role )
{
return repository.getComponentDescriptorList( type, role );
}
public T lookup( Class type, String role, String roleHint ) throws ComponentLookupException
{
// verify arguments
if ( type == null )
{
throw new NullPointerException( "type is null" );
}
if ( role == null )
{
throw new NullPointerException( "role is null" );
}
if ( roleHint == null )
{
roleHint = PlexusConstants.PLEXUS_DEFAULT_HINT;
}
return getComponent( type, role, roleHint, null );
}
public Map lookupMap( Class type, String role, List roleHints )
throws ComponentLookupException
{
// verify arguments
if ( type == null )
{
throw new NullPointerException( "type is null" );
}
if ( role == null )
{
throw new NullPointerException( "role is null" );
}
// if no hints provided, get all valid hints for this role
Map components = new LinkedHashMap();
if ( roleHints == null )
{
Map> componentDescriptors = getComponentDescriptorMap( type, role );
for ( Entry> entry : componentDescriptors.entrySet() )
{
String roleHint = entry.getKey();
ComponentDescriptor componentDescriptor = entry.getValue();
// todo dain catch the exception... it isn't the callers problem when one component in a collection fails
T component = getComponent( type, role, roleHint, componentDescriptor );
components.put( roleHint, component );
}
}
else
{
for ( String roleHint : roleHints )
{
// todo dain catch the exception... it isn't the callers problem when one component in a collection fails
T component = getComponent( type, role, roleHint, null );
components.put( roleHint, component );
}
}
return components;
}
public List lookupList( Class type, String role, List roleHints ) throws ComponentLookupException
{
// verify arguments
if ( type == null )
{
throw new NullPointerException( "type is null" );
}
if ( role == null )
{
throw new NullPointerException( "role is null" );
}
// if no hints provided, get all valid hints for this role
List components = new ArrayList();
if ( roleHints == null )
{
List> componentDescriptors = getComponentDescriptorList( type, role );
for ( ComponentDescriptor componentDescriptor : componentDescriptors )
{
// todo dain catch the exception... it isn't the callers problem when one component in a collection fails
T component = getComponent( type, role, componentDescriptor.getRoleHint(), componentDescriptor );
components.add( component );
}
}
else
{
for ( String roleHint : roleHints )
{
// todo dain catch the exception... it isn't the callers problem when one component in a collection fails
T component = getComponent( type, role, roleHint, null );
components.add( component );
}
}
return components;
}
public void release( Object component )
throws ComponentLifecycleException
{
if ( component == null )
{
return;
}
// get the component manager
ComponentManager> componentManager;
synchronized ( this )
{
componentManager = componentManagersByComponent.get( component );
if ( componentManager == null )
{
// This needs to be tracked down but the user doesn't need to see this
// during the maven bootstrap this logger is null.
//logger.debug( "Component manager not found for returned component. Ignored. component=" + component );
return;
}
}
// release the component from the manager
componentManager.release( component );
// only drop the reference to this component if there are no other uses of the component
// multiple uses of a component is common with singleton beans
if ( componentManager.getConnections() <= 0 )
{
synchronized ( this )
{
componentManagersByComponent.remove( component );
}
}
}
public void removeComponentRealm( ClassRealm classRealm ) throws PlexusContainerException
{
repository.removeComponentRealm( classRealm );
List> dispose = new ArrayList>();
try
{
synchronized ( this )
{
for ( Iterator>> it = componentManagers.entrySet().iterator(); it.hasNext(); )
{
Entry> entry = it.next();
Key key = entry.getKey();
ComponentManager> componentManager = entry.getValue();
if ( key.realm.equals( classRealm ) )
{
dispose.add( componentManager );
it.remove();
}
else
{
componentManager.dissociateComponentRealm( classRealm );
}
}
}
// Call dispose callback outside of synchronized lock to avoid deadlocks
for ( ComponentManager> componentManager : dispose )
{
componentManager.dispose();
}
}
catch ( ComponentLifecycleException e )
{
throw new PlexusContainerException( "Failed to dissociate component realm: " + classRealm.getId(), e );
}
}
private T getComponent( Class type, String role, String roleHint, ComponentDescriptor descriptor )
throws ComponentLookupException
{
ComponentManager componentManager = getComponentManager( type, role, roleHint, descriptor );
// Get instance from manager... may result in creation
try
{
T component = componentManager.getComponent();
synchronized ( this )
{
componentManagersByComponent.put( component, componentManager );
}
return component;
}
catch ( ComponentInstantiationException e )
{
throw new ComponentLookupException(
"Unable to lookup component '" + componentManager.getRole() + "', it could not be created.",
componentManager.getRole(), componentManager.getRoleHint(), componentManager.getRealm(), e );
}
catch ( ComponentLifecycleException e )
{
throw new ComponentLookupException(
"Unable to lookup component '" + componentManager.getRole() + "', it could not be started.",
componentManager.getRole(), componentManager.getRoleHint(), componentManager.getRealm(), e );
}
}
private synchronized ComponentManager getComponentManager( Class type, String role, String roleHint, ComponentDescriptor descriptor )
throws ComponentLookupException
{
ComponentManager componentManager = getComponentManager( type, role, roleHint );
if ( componentManager == null )
{
// we need to create a component manager, but first we must have a descriptor
if ( descriptor == null )
{
descriptor = getComponentDescriptor( type, role, roleHint );
if ( descriptor == null )
{
throw new ComponentLookupException(
"Component descriptor cannot be found in the component repository",
role,
roleHint );
}
}
componentManager = createComponentManager( descriptor, role, roleHint );
}
return componentManager;
}
private ComponentManager getComponentManager( Class type, String role, String roleHint )
{
Set realms = getSearchRealms();
// return the component in the first realm
for ( ClassRealm realm : realms )
{
ComponentManager> manager = componentManagers.get( new Key( realm, role, roleHint ) );
if ( manager != null && isAssignableFrom( type, manager.getType() ) )
{
return (ComponentManager) manager;
}
}
return null;
}
private Set getSearchRealms()
{
// determine realms to search
Set realms = new LinkedHashSet();
for ( ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); classLoader != null; classLoader = classLoader.getParent() )
{
if ( classLoader instanceof ClassRealm )
{
ClassRealm realm = (ClassRealm) classLoader;
while ( realm != null )
{
realms.add( realm );
realm = realm.getParentRealm();
}
}
}
if ( realms.isEmpty() )
{
realms.addAll( container.getClassWorld().getRealms() );
}
return realms;
}
private ComponentManager createComponentManager( ComponentDescriptor descriptor,
String role,
String roleHint )
throws ComponentLookupException
{
// Get the ComponentManagerFactory
String instantiationStrategy = descriptor.getInstantiationStrategy();
if ( instantiationStrategy == null )
{
instantiationStrategy = DEFAULT_INSTANTIATION_STRATEGY;
}
ComponentManagerFactory componentManagerFactory = componentManagerFactories.get( instantiationStrategy );
if ( componentManagerFactory == null )
{
throw new ComponentLookupException( "Unsupported instantiation strategy: " + instantiationStrategy,
role,
roleHint,
descriptor.getRealm() );
}
// Get the LifecycleHandler
LifecycleHandler lifecycleHandler;
try
{
lifecycleHandler = lifecycleHandlerManager.getLifecycleHandler( descriptor.getLifecycleHandler() );
}
catch ( UndefinedLifecycleHandlerException e )
{
throw new ComponentLookupException( "Undefined lifecycle handler: " + descriptor.getLifecycleHandler(),
role,
roleHint,
descriptor.getRealm() );
}
// Create the ComponentManager
ComponentManager componentManager = componentManagerFactory.createComponentManager( container,
lifecycleHandler,
descriptor,
role,
roleHint );
// Add componentManager to indexes
Key key = new Key( descriptor.getRealm(), role, roleHint );
componentManagers.put( key, componentManager );
return componentManager;
}
private static class Key implements Comparable
{
private final ClassRealm realm;
private final String role;
private final String roleHint;
private final int hashCode;
private Key( ClassRealm realm, String role, String roleHint )
{
this.realm = realm;
if ( role == null )
{
role = "null";
}
this.role = role;
if ( roleHint == null )
{
roleHint = "null";
}
this.roleHint = roleHint;
int hashCode;
hashCode = ( realm != null ? realm.hashCode() : 0 );
hashCode = 31 * hashCode + role.hashCode();
hashCode = 31 * hashCode + roleHint.hashCode();
this.hashCode = hashCode;
}
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( o == null || getClass() != o.getClass() )
{
return false;
}
Key key = (Key) o;
return !( realm != null ? !realm.equals( key.realm ) : key.realm != null ) &&
role.equals( key.role ) &&
roleHint.equals( key.roleHint );
}
public int hashCode()
{
return hashCode;
}
public String toString()
{
return realm + "/" + role + "/" + roleHint;
}
public int compareTo( Key o )
{
int value;
if ( realm != null )
{
value = realm.getId().compareTo( o.realm.getId() );
}
else
{
value = o.realm == null ? 0 : 1;
}
if ( value == 0 )
{
value = role.compareTo( o.role );
if ( value == 0 )
{
value = roleHint.compareTo( o.roleHint );
}
}
return value;
}
}
}