blob: 7d8281e0adbe277732bf069493a5fbcf9b89fd48 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010-present Sonatype, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
*******************************************************************************/
package org.eclipse.sisu.plexus;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.codehaus.plexus.PlexusContainer;
import org.codehaus.plexus.classworlds.realm.ClassRealm;
import org.codehaus.plexus.component.repository.ComponentDescriptor;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.context.Context;
import org.eclipse.sisu.bean.BeanManager;
import org.eclipse.sisu.wire.EntryListAdapter;
import org.eclipse.sisu.wire.EntryMapAdapter;
import com.google.inject.Singleton;
import com.google.inject.TypeLiteral;
/**
* Delegating {@link PlexusContainer} wrapper that doesn't require an actual container instance.
*/
@Singleton
@SuppressWarnings( { "unchecked", "rawtypes" } )
final class PseudoPlexusContainer
implements PlexusContainer
{
// ----------------------------------------------------------------------
// Implementation fields
// ----------------------------------------------------------------------
final PlexusBeanLocator locator;
final BeanManager manager;
final Context context;
// ----------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------
@Inject
PseudoPlexusContainer( final PlexusBeanLocator locator, final BeanManager manager, final Context context )
{
this.locator = locator;
this.manager = manager;
this.context = context;
}
// ----------------------------------------------------------------------
// Context methods
// ----------------------------------------------------------------------
public Context getContext()
{
return context;
}
// ----------------------------------------------------------------------
// Lookup methods
// ----------------------------------------------------------------------
public Object lookup( final String role )
throws ComponentLookupException
{
return lookup( role, "" );
}
public Object lookup( final String role, final String hint )
throws ComponentLookupException
{
return lookup( null, role, hint );
}
public <T> T lookup( final Class<T> role )
throws ComponentLookupException
{
return lookup( role, "" );
}
public <T> T lookup( final Class<T> role, final String hint )
throws ComponentLookupException
{
return lookup( role, null, hint );
}
public <T> T lookup( final Class<T> type, final String role, final String hint )
throws ComponentLookupException
{
try
{
return locate( role, type, hint ).iterator().next().getValue();
}
catch ( final RuntimeException e )
{
throw new ComponentLookupException( e, null != role ? role : type.getName(), hint );
}
}
public List<Object> lookupList( final String role )
throws ComponentLookupException
{
return new EntryListAdapter<Object>( locate( role, null ) );
}
public <T> List<T> lookupList( final Class<T> role )
throws ComponentLookupException
{
return new EntryListAdapter<T>( locate( null, role ) );
}
public Map<String, Object> lookupMap( final String role )
throws ComponentLookupException
{
return new EntryMapAdapter<String, Object>( locate( role, null ) );
}
public <T> Map<String, T> lookupMap( final Class<T> role )
throws ComponentLookupException
{
return new EntryMapAdapter<String, T>( locate( null, role ) );
}
// ----------------------------------------------------------------------
// Query methods
// ----------------------------------------------------------------------
public boolean hasComponent( final String role )
{
return hasComponent( role, "" );
}
public boolean hasComponent( final String role, final String hint )
{
return hasComponent( null, role, hint );
}
public boolean hasComponent( final Class role )
{
return hasComponent( role, "" );
}
public boolean hasComponent( final Class role, final String hint )
{
return hasComponent( role, null, hint );
}
public boolean hasComponent( final Class type, final String role, final String hint )
{
return hasPlexusBeans( locate( role, type, hint ) );
}
// ----------------------------------------------------------------------
// Component descriptor methods
// ----------------------------------------------------------------------
public void addComponent( final Object component, final String role )
{
throw new UnsupportedOperationException();
}
public <T> void addComponent( final T component, final Class<?> role, final String hint )
{
throw new UnsupportedOperationException();
}
public <T> void addComponentDescriptor( final ComponentDescriptor<T> descriptor )
{
throw new UnsupportedOperationException();
}
public ComponentDescriptor<?> getComponentDescriptor( final String role, final String hint )
{
throw new UnsupportedOperationException();
}
public <T> ComponentDescriptor<T> getComponentDescriptor( final Class<T> type, final String role,
final String hint )
{
throw new UnsupportedOperationException();
}
public List getComponentDescriptorList( final String role )
{
throw new UnsupportedOperationException();
}
public <T> List<ComponentDescriptor<T>> getComponentDescriptorList( final Class<T> type, final String role )
{
throw new UnsupportedOperationException();
}
public Map getComponentDescriptorMap( final String role )
{
throw new UnsupportedOperationException();
}
public <T> Map<String, ComponentDescriptor<T>> getComponentDescriptorMap( final Class<T> type, final String role )
{
throw new UnsupportedOperationException();
}
public List<ComponentDescriptor<?>> discoverComponents( final ClassRealm realm )
{
throw new UnsupportedOperationException();
}
// ----------------------------------------------------------------------
// Class realm methods
// ----------------------------------------------------------------------
public ClassRealm getContainerRealm()
{
throw new UnsupportedOperationException();
}
public ClassRealm setLookupRealm( final ClassRealm realm )
{
throw new UnsupportedOperationException();
}
public ClassRealm getLookupRealm()
{
throw new UnsupportedOperationException();
}
public ClassRealm createChildRealm( final String id )
{
throw new UnsupportedOperationException();
}
// ----------------------------------------------------------------------
// Shutdown methods
// ----------------------------------------------------------------------
public void release( final Object component )
{
manager.unmanage( component );
}
public void releaseAll( final Map<String, ?> components )
{
for ( final Object o : components.values() )
{
release( o );
}
}
public void releaseAll( final List<?> components )
{
for ( final Object o : components )
{
release( o );
}
}
public void dispose()
{
manager.unmanage();
}
// ----------------------------------------------------------------------
// Implementation methods
// ----------------------------------------------------------------------
private <T> Iterable<PlexusBean<T>> locate( final String role, final Class<T> type, final String... hints )
{
final String[] canonicalHints = Hints.canonicalHints( hints );
if ( null == role || null != type && type.getName().equals( role ) )
{
return locator.locate( TypeLiteral.get( type ), canonicalHints );
}
try
{
final Class clazz = Thread.currentThread().getContextClassLoader().loadClass( role );
final Iterable beans = locator.locate( TypeLiteral.get( clazz ), canonicalHints );
if ( hasPlexusBeans( beans ) )
{
return beans;
}
}
catch ( final Exception e )
{
// drop through...
}
catch ( final LinkageError e )
{
// drop through...
}
return Collections.EMPTY_SET;
}
private static <T> boolean hasPlexusBeans( final Iterable<PlexusBean<T>> beans )
{
final Iterator<PlexusBean<T>> i = beans.iterator();
return i.hasNext() && i.next().getImplementationClass() != null;
}
}