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 static com.google.common.base.ReferenceType.WEAK;
import static com.google.common.collect.Iterables.concat;
import com.google.common.collect.ListMultimap;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newConcurrentHashMap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.ReferenceMap;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import static org.codehaus.plexus.component.CastUtils.cast;
import org.codehaus.plexus.component.ComponentIndex;
import static org.codehaus.plexus.component.ComponentStack.pushComponentStack;
import static org.codehaus.plexus.component.ComponentStack.popComponentStack;
import org.codehaus.plexus.component.manager.ComponentManager;
import org.codehaus.plexus.component.manager.ComponentManagerFactory;
import org.codehaus.plexus.component.manager.StaticComponentManager;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.ComponentDescriptorListener;
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 org.codehaus.plexus.logging.NullLogger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
public class DefaultComponentRegistry implements ComponentRegistry
{
private static final String DEFAULT_INSTANTIATION_STRATEGY = "singleton";
private final MutablePlexusContainer container;
private final LifecycleHandlerManager lifecycleHandlerManager;
private final Logger logger;
private final AtomicBoolean disposed = new AtomicBoolean( false );
private final ConcurrentMap componentManagerFactories = newConcurrentHashMap();
private final ComponentIndex> index = new ComponentIndex>();
private final Map, ComponentManager>> componentManagersByComponentDescriptor =
new ReferenceMap, ComponentManager>>( WEAK, WEAK);
private final Map> componentManagersByComponent =
new ReferenceMap>( WEAK, WEAK);
private final ListMultimap, String>, ComponentDescriptorListener>> listeners = Multimaps.newArrayListMultimap();
public DefaultComponentRegistry( MutablePlexusContainer container, LifecycleHandlerManager lifecycleHandlerManager )
{
this.container = container;
this.lifecycleHandlerManager = lifecycleHandlerManager;
Logger containerLogger = container.getLogger();
if ( containerLogger != null )
{
logger = containerLogger;
}
else
{
logger = new NullLogger();
}
}
public void dispose()
{
if (disposed.getAndSet( true )) {
// already disposed
return;
}
List> managers;
synchronized ( index )
{
managers = new ArrayList>( index.clear() );
componentManagersByComponentDescriptor.clear();
componentManagersByComponent.clear();
}
// reverse sort the managers by startId
Collections.sort( managers, new Comparator>() {
public int compare( ComponentManager> left, ComponentManager> right )
{
if (left.getStartId() < right.getStartId() )
{
return 1;
}
else if (left.getStartId() == right.getStartId() )
{
return 0;
}
else
{
return -1;
}
}
});
// 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 );
}
fireComponentDescriptorRemoved( componentManager.getComponentDescriptor() );
}
}
//
// Component Manager Factories
//
public void registerComponentManagerFactory( ComponentManagerFactory componentManagerFactory )
{
if ( disposed.get() )
{
throw new IllegalStateException("ComponentRegistry has been disposed");
}
componentManagerFactories.put( componentManagerFactory.getId(), componentManagerFactory );
}
//
// Component Descriptors
//
public void addComponentDescriptor( ComponentDescriptor componentDescriptor ) throws ComponentRepositoryException
{
if ( disposed.get() )
{
throw new ComponentRepositoryException("ComponentRegistry has been disposed", componentDescriptor);
}
// verify the descriptor matches the role hint and type
verifyComponentDescriptor( componentDescriptor );
// Get the ComponentManagerFactory
String instantiationStrategy = componentDescriptor.getInstantiationStrategy();
if ( instantiationStrategy == null )
{
instantiationStrategy = DEFAULT_INSTANTIATION_STRATEGY;
}
ComponentManagerFactory componentManagerFactory = componentManagerFactories.get( instantiationStrategy );
if ( componentManagerFactory == null )
{
throw new ComponentRepositoryException( "Unsupported instantiation strategy: " + instantiationStrategy,
componentDescriptor );
}
// Get the LifecycleHandler
LifecycleHandler lifecycleHandler;
try
{
lifecycleHandler = lifecycleHandlerManager.getLifecycleHandler( componentDescriptor.getLifecycleHandler() );
}
catch ( UndefinedLifecycleHandlerException e )
{
throw new ComponentRepositoryException( "Undefined lifecycle handler: " + componentDescriptor.getLifecycleHandler(),
componentDescriptor );
}
// Create the ComponentManager
ComponentManager componentManager = componentManagerFactory.createComponentManager( container,
lifecycleHandler,
componentDescriptor );
// Add componentManager to indexe
synchronized ( index )
{
index.add( componentDescriptor.getRealm(),
componentDescriptor.getRoleClass(),
componentDescriptor.getRoleHint(),
componentManager);
componentManagersByComponentDescriptor.put(componentDescriptor, componentManager);
}
fireComponentDescriptorAdded( componentDescriptor );
}
public ComponentDescriptor getComponentDescriptor( Class type, String roleHint )
{
ComponentManager componentManager = (ComponentManager) index.get( type, roleHint );
if ( componentManager == null )
{
return null;
}
return componentManager.getComponentDescriptor();
}
public Map> getComponentDescriptorMap( Class type )
{
Map> componentManagers = cast( index.getAllAsMap( type ) );
Map> descriptors = new LinkedHashMap>(componentManagers.size());
for ( Entry> entry : componentManagers.entrySet() )
{
descriptors.put(entry.getKey(), entry.getValue().getComponentDescriptor());
}
return Collections.unmodifiableMap( descriptors );
}
public List> getComponentDescriptorList( Class type )
{
List> componentManagers = cast( index.getAll( type ) );
List> descriptors = new ArrayList>(componentManagers.size());
for ( ComponentManager componentManager : componentManagers )
{
descriptors.add( componentManager.getComponentDescriptor() );
}
return Collections.unmodifiableList( descriptors );
}
//
// Component Instances
//
public void addComponent( T instance, Class> type, String roleHint, ClassRealm realm ) throws ComponentRepositoryException
{
if ( disposed.get() )
{
throw new ComponentRepositoryException("ComponentRegistry has been disposed", type, roleHint, realm);
}
StaticComponentManager componentManager = new StaticComponentManager( container, instance, type, roleHint, realm );
// verify descriptor is consistent
ComponentDescriptor descriptor = componentManager.getComponentDescriptor();
verifyComponentDescriptor( descriptor );
synchronized ( index )
{
index.add( descriptor.getRealm(), descriptor.getRoleClass(), descriptor.getRoleHint(), componentManager);
componentManagersByComponentDescriptor.put( descriptor, componentManager);
}
fireComponentDescriptorAdded( descriptor );
}
public T lookup( Class type, String roleHint ) throws ComponentLookupException
{
// verify arguments
if ( type == null )
{
throw new NullPointerException( "type is null" );
}
if ( roleHint == null )
{
roleHint = PlexusConstants.PLEXUS_DEFAULT_HINT;
}
return getComponent( type, roleHint );
}
public T lookup( ComponentDescriptor componentDescriptor ) throws ComponentLookupException
{
ComponentManager componentManager = (ComponentManager) componentManagersByComponentDescriptor.get( componentDescriptor );
if ( componentManager == null )
{
throw new ComponentLookupException( "Component descriptor is not registered with PlexusContainer", componentDescriptor );
}
return getComponent( componentManager );
}
public Map lookupMap( Class type, List roleHints )
throws ComponentLookupException
{
// verify arguments
if ( type == null )
{
throw new NullPointerException( "type is null" );
}
// if no hints provided, get all valid hints for this role
Map components = new LinkedHashMap();
if ( roleHints == null )
{
Map> componentManagers = cast( index.getAllAsMap( type ) );
for ( Entry> entry : componentManagers.entrySet() )
{
String roleHint = entry.getKey();
ComponentManager componentManager = entry.getValue();
// todo dain catch the exception... it isn't the callers problem when one component in a collection fails
T component = getComponent( componentManager );
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, roleHint );
components.put( roleHint, component );
}
}
return components;
}
public List lookupList( Class type, List roleHints ) throws ComponentLookupException
{
// verify arguments
if ( type == null )
{
throw new NullPointerException( "type is null" );
}
// if no hints provided, get all valid hints for this role
List components = new ArrayList();
if ( roleHints == null )
{
List> componentManagers = cast( index.getAll( type ) );
for ( ComponentManager componentManager : componentManagers )
{
// todo dain catch the exception... it isn't the callers problem when one component in a collection fails
T component = getComponent( componentManager );
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, roleHint );
components.add( component );
}
}
return components;
}
public void addComponentDescriptorListener( ComponentDescriptorListener listener )
{
Class type = listener.getType();
List roleHints = listener.getRoleHints();
synchronized ( this )
{
if (roleHints == null )
{
listeners.put(new Pair, String>(type, null), listener);
}
else
{
for ( String roleHint : roleHints )
{
listeners.put(new Pair, String>(type, roleHint), listener);
}
}
}
// if no hints provided, get all valid hints for this role
if ( roleHints == null )
{
List> componentManagers = cast( index.getAll( type ) );
for ( ComponentManager componentManager : componentManagers )
{
listener.componentDescriptorAdded( componentManager.getComponentDescriptor() );
}
}
else
{
for ( String roleHint : roleHints )
{
ComponentManager componentManager = (ComponentManager) index.get( type, roleHint );
if (componentManager != null) {
listener.componentDescriptorAdded( componentManager.getComponentDescriptor() );
}
}
}
}
public synchronized void removeComponentDescriptorListener( ComponentDescriptorListener listener )
{
Class> type = listener.getType();
List roleHints = listener.getRoleHints();
if (roleHints == null || roleHints.isEmpty())
{
listeners.remove(new Pair, String>(type, null), listener);
}
else
{
for ( String roleHint : roleHints )
{
listeners.remove(new Pair, String>(type, roleHint), listener);
}
}
}
private synchronized List> getListeners(ComponentDescriptor descriptor)
{
List> allHintListeners =
cast( listeners.get( new Pair, String>( descriptor.getRoleClass(), null ) ) );
List> specificHintListeners =
cast( listeners.get( new Pair, String>( descriptor.getRoleClass(), descriptor.getRoleHint() ) ) );
return newArrayList( concat(allHintListeners, specificHintListeners) );
}
private void fireComponentDescriptorAdded( ComponentDescriptor componentDescriptor )
{
for ( ComponentDescriptorListener listener : getListeners( componentDescriptor ))
{
try
{
listener.componentDescriptorAdded( componentDescriptor );
}
catch ( Throwable e )
{
logger.debug( "ComponentDescriptorListener threw exception while processing " + componentDescriptor, e );
}
}
}
private void fireComponentDescriptorRemoved( ComponentDescriptor componentDescriptor )
{
for ( ComponentDescriptorListener listener : getListeners( componentDescriptor ))
{
try
{
listener.componentDescriptorRemoved( componentDescriptor );
}
catch ( Throwable e )
{
logger.error( "ComponentDescriptorListener threw exception while processing " + componentDescriptor, e );
}
}
}
public void release( Object component ) throws ComponentLifecycleException
{
if ( component == null )
{
return;
}
// get the component manager
ComponentManager> 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 );
}
public void removeComponentRealm( ClassRealm classRealm ) throws PlexusContainerException
{
try
{
// remove all component managers associated with the realm
LinkedHashSet> dispose;
synchronized ( index )
{
dispose = new LinkedHashSet>(index.removeAll( classRealm ));
for ( ComponentManager> componentManager : dispose )
{
ComponentDescriptor> descriptor = componentManager.getComponentDescriptor();
componentManagersByComponentDescriptor.remove( descriptor );
fireComponentDescriptorRemoved( descriptor );
}
}
// 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 roleHint ) throws ComponentLookupException
{
ComponentManager componentManager = (ComponentManager) index.get( type, roleHint );
if ( componentManager == null )
{
throw new ComponentLookupException( "Component descriptor cannot be found", type, roleHint );
}
return getComponent( componentManager );
}
private T getComponent( ComponentManager componentManager ) throws ComponentLookupException
{
ComponentDescriptor descriptor = componentManager.getComponentDescriptor();
// Get instance from manager... may result in creation
pushComponentStack( descriptor );
try
{
T component = componentManager.getComponent();
componentManagersByComponent.put( component, componentManager );
return component;
}
catch ( Exception e )
{
// get real cause
Throwable cause = e.getCause();
if ( cause == null )
{
cause = e;
}
// do not rewrap ComponentLookupException
if (cause instanceof ComponentLookupException )
{
throw (ComponentLookupException) cause;
}
throw new ComponentLookupException( e.getMessage(), descriptor, cause );
}
finally
{
popComponentStack();
}
}
private void verifyComponentDescriptor( ComponentDescriptor descriptor ) throws ComponentRepositoryException
{
ClassLoader classLoader = descriptor.getRealm();
if ( classLoader == null)
{
throw new ComponentRepositoryException( "ComponentDescriptor realm is null", descriptor);
}
Class> implementationClass = descriptor.getImplementationClass();
if (implementationClass.equals( Object.class ))
{
throw new ComponentRepositoryException( "ComponentDescriptor implementation class could not be loaded", descriptor);
}
String role = descriptor.getRole();
if (role == null)
{
throw new ComponentRepositoryException( "ComponentDescriptor role is null", descriptor);
}
Class> roleClass;
try
{
roleClass = classLoader.loadClass( role );
}
catch ( ClassNotFoundException e )
{
throw new ComponentRepositoryException( "ComponentDescriptor role class can not be loaded", descriptor);
}
if (!roleClass.isAssignableFrom( implementationClass ))
{
throw new ComponentRepositoryException( "ComponentDescriptor implementation class does not implement the role class:" +
" implementationClass=" + implementationClass.getName() + " roleClass=" + roleClass.getName(),
descriptor);
}
}
public static class Pair {
private final L left;
private final R right;
public Pair( L left, R right )
{
this.left = left;
this.right = right;
}
public L getLeft()
{
return left;
}
public R getRight()
{
return right;
}
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( !( o instanceof Pair ) )
{
return false;
}
Pair,?> pair = (Pair,?>) o;
return
( left == null ? pair.left == null : left.equals( pair.left ) ) &&
( right == null ? pair.right == null : right.equals( pair.right ) );
}
public int hashCode()
{
int result;
result = ( left != null ? left.hashCode() : 0 );
result = 31 * result + ( right != null ? right.hashCode() : 0 );
return result;
}
public String toString()
{
StringBuilder buf = new StringBuilder( );
buf.append("[").append(left).append(", ").append(right).append("]");
return buf.toString();
}
}
}