You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jd...@apache.org on 2011/05/17 18:57:54 UTC
svn commit: r1104405 [5/6] - in /maven/sandbox/trunk/mae: ./ boms/
boms/mae-app-bom/ boms/mae-library-bom/ mae-api/ mae-api/src/
mae-api/src/main/ mae-api/src/main/java/ mae-api/src/main/java/org/
mae-api/src/main/java/org/apache/ mae-api/src/main/java...
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/MAEContainer.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/MAEContainer.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/MAEContainer.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/MAEContainer.java Tue May 17 16:57:50 2011
@@ -0,0 +1,949 @@
+/**
+ * Copyright (c) 2009 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+package org.apache.maven.mae.internal.container;
+
+import org.apache.maven.mae.internal.container.guice.InstanceBindingModule;
+import org.apache.maven.mae.internal.container.guice.XComponentDescriptorBeanModule;
+import org.apache.maven.mae.internal.container.guice.XPlexusAnnotatedBeanModule;
+import org.apache.maven.mae.internal.container.guice.XPlexusXmlBeanModule;
+import org.apache.maven.mae.internal.container.lifecycle.XPlexusLifecycleManager;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
+import org.codehaus.plexus.MutablePlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.PlexusContainerException;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextMapAdapter;
+import org.codehaus.plexus.context.DefaultContext;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.logging.LoggerManager;
+import org.codehaus.plexus.logging.console.ConsoleLoggerManager;
+import org.apache.maven.mae.internal.container.ComponentKey;
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.sonatype.guice.bean.binders.MergedModule;
+import org.sonatype.guice.bean.binders.ParameterKeys;
+import org.sonatype.guice.bean.binders.WireModule;
+import org.sonatype.guice.bean.locators.DefaultRankingFunction;
+import org.sonatype.guice.bean.locators.EntryListAdapter;
+import org.sonatype.guice.bean.locators.EntryMapAdapter;
+import org.sonatype.guice.bean.locators.MAEBeanLocator;
+import org.sonatype.guice.bean.locators.MutableBeanLocator;
+import org.sonatype.guice.bean.locators.RankingFunction;
+import org.sonatype.guice.bean.reflect.ClassSpace;
+import org.sonatype.guice.bean.reflect.DeferredClass;
+import org.sonatype.guice.bean.reflect.DeferredProvider;
+import org.sonatype.guice.bean.reflect.LoadedClass;
+import org.sonatype.guice.bean.reflect.URLClassSpace;
+import org.sonatype.guice.plexus.binders.PlexusBeanManager;
+import org.sonatype.guice.plexus.binders.PlexusBindingModule;
+import org.sonatype.guice.plexus.config.Hints;
+import org.sonatype.guice.plexus.config.PlexusBean;
+import org.sonatype.guice.plexus.config.PlexusBeanConverter;
+import org.sonatype.guice.plexus.config.PlexusBeanLocator;
+import org.sonatype.guice.plexus.config.PlexusBeanModule;
+import org.sonatype.guice.plexus.converters.PlexusDateTypeConverter;
+import org.sonatype.guice.plexus.converters.PlexusXmlBeanConverter;
+import org.sonatype.guice.plexus.locators.ClassRealmUtils;
+import org.sonatype.guice.plexus.locators.MAEPlexusBeanLocator;
+import org.sonatype.inject.BeanScanning;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.Module;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Names;
+import com.google.inject.util.Providers;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+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.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * {@link PlexusContainer} shim that delegates to a Plexus-aware Guice {@link Injector}.
+ */
+@SuppressWarnings( { "unchecked", "rawtypes" } )
+public final class MAEContainer
+ implements ExtrudablePlexusContainer
+{
+ static
+ {
+ System.setProperty( "guice.disable.misplaced.annotation.check", "true" );
+ }
+
+ // ----------------------------------------------------------------------
+ // Constants
+ // ----------------------------------------------------------------------
+
+ private static final String DEFAULT_REALM_NAME = "plexus.core";
+
+ private static final LoggerManager CONSOLE_LOGGER_MANAGER = new ConsoleLoggerManager();
+
+ // ----------------------------------------------------------------------
+ // Implementation fields
+ // ----------------------------------------------------------------------
+
+ final Set<String> realmIds = new HashSet<String>();
+
+ final AtomicInteger plexusRank = new AtomicInteger();
+
+ final Map<ClassRealm, List<ComponentDescriptor<?>>> descriptorMap =
+ new ConcurrentHashMap<ClassRealm, List<ComponentDescriptor<?>>>();
+
+ final ThreadLocal<ClassRealm> lookupRealm = new ThreadLocal<ClassRealm>();
+
+ final MAEBeanLocator qualifiedBeanLocator = new MAEBeanLocator();
+
+ final Context context;
+
+ final Map<String, String> variables;
+
+ final ClassRealm containerRealm;
+
+ final XPlexusLifecycleManager lifecycleManager;
+
+ private final PlexusBeanLocator plexusBeanLocator;
+
+ private final String componentVisibility;
+
+ private final Module bootModule = new BootModule();
+
+ private final Module setupModule = new SetupModule();
+
+ private final Module loggerModule = new LoggerModule();
+
+ private LoggerManager loggerManager = CONSOLE_LOGGER_MANAGER;
+
+ private Logger logger;
+
+ private final ComponentSelector componentSelector;
+
+ private boolean disposing;
+
+ private final InstanceRegistry instanceRegistry;
+
+ private final InstanceBindingModule instanceBinder;
+
+ private Injector injector;
+
+ private BeanScanning scanning;
+
+ private boolean isAutoWiringEnabled;
+
+ // ----------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------
+
+ public MAEContainer( final ComponentSelector componentSelector, final InstanceRegistry instanceRegistry )
+ throws PlexusContainerException
+ {
+ this( new DefaultContainerConfiguration(), componentSelector, instanceRegistry );
+ }
+
+ @SuppressWarnings( "finally" )
+ public MAEContainer( final ContainerConfiguration configuration, final ComponentSelector selector,
+ final InstanceRegistry instanceRegistry )
+ throws PlexusContainerException
+ {
+ componentSelector = selector;
+ this.instanceRegistry = instanceRegistry;
+ final URL plexusXml = lookupPlexusXml( configuration );
+
+ context = new DefaultContext( configuration.getContext() );
+
+ context.put( PlexusConstants.PLEXUS_KEY, this );
+ variables = (Map) new ContextMapAdapter( context );
+
+ containerRealm = lookupContainerRealm( configuration );
+ lifecycleManager = new XPlexusLifecycleManager( this, context );
+ componentVisibility = configuration.getComponentVisibility();
+ isAutoWiringEnabled = configuration.getAutoWiring();
+
+ plexusBeanLocator = new MAEPlexusBeanLocator( qualifiedBeanLocator, componentVisibility );
+
+ realmIds.add( containerRealm.getId() );
+ setLookupRealm( containerRealm );
+
+ final List<PlexusBeanModule> beanModules = new ArrayList<PlexusBeanModule>();
+
+ final ClassSpace space = new URLClassSpace( containerRealm );
+ beanModules.add( new XPlexusXmlBeanModule( selector, instanceRegistry, space, variables, plexusXml ) );
+
+ scanning = parseScanningOption( configuration.getClassPathScanning() );
+ beanModules.add( new XPlexusAnnotatedBeanModule( selector, instanceRegistry, space, variables, scanning ) );
+
+ instanceBinder = new InstanceBindingModule( instanceRegistry, selector, variables );
+ beanModules.add( instanceBinder );
+
+ try
+ {
+ addPlexusInjector( beanModules, bootModule );
+ }
+ catch ( final RuntimeException e )
+ {
+ try
+ {
+ dispose(); // cleanup as much as possible
+ }
+ finally
+ {
+ throw e; // always report original failure
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // 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 Throwable e )
+ {
+ throw new ComponentLookupException( e, null != role ? role : type.getName(), hint );
+ }
+ }
+
+ public List<Object> lookupList( final String role )
+ throws ComponentLookupException
+ {
+ return new EntryListAdapter<String, Object>( locate( role, null ) );
+ }
+
+ public synchronized <T> List<T> lookupList( final Class<T> role )
+ throws ComponentLookupException
+ {
+ return new EntryListAdapter<String, 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 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 ) );
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.codehaus.plexus.PlexusContainer#hasComponent(java.lang.String)
+ */
+ @Override
+ public boolean hasComponent( final String role )
+ {
+ return hasComponent( null, role, "" );
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.codehaus.plexus.PlexusContainer#hasComponent(java.lang.String, java.lang.String)
+ */
+ @Override
+ public boolean hasComponent( final String role, final String hint )
+ {
+ return hasComponent( null, role, hint );
+ }
+
+ // ----------------------------------------------------------------------
+ // Component descriptor methods
+ // ----------------------------------------------------------------------
+
+ public void addComponent( final Object component, final String role )
+ {
+ try
+ {
+ addComponent( component, component.getClass().getClassLoader().loadClass( role ), Hints.DEFAULT_HINT );
+ }
+ catch ( final ClassNotFoundException e )
+ {
+ throw new TypeNotPresentException( role, e );
+ }
+ }
+
+ public <T> void addComponent( final T component, final java.lang.Class<?> role, final String hint )
+ {
+ // this is only used in Maven3 tests, so keep it simple...
+ qualifiedBeanLocator.add( Guice.createInjector( new AbstractModule()
+ {
+ @Override
+ protected void configure()
+ {
+ if ( Hints.isDefaultHint( hint ) )
+ {
+ bind( (Class) role ).toInstance( component );
+ }
+ else
+ {
+ bind( (Class) role ).annotatedWith( Names.named( hint ) ).toInstance( component );
+ }
+ }
+ } ), plexusRank.incrementAndGet() );
+ }
+
+ public <T> void addComponentDescriptor( final ComponentDescriptor<T> descriptor )
+ {
+ ClassRealm realm = descriptor.getRealm();
+ if ( null == realm )
+ {
+ realm = containerRealm;
+ descriptor.setRealm( realm );
+ }
+
+ List<ComponentDescriptor<?>> descriptors = descriptorMap.get( realm );
+ if ( null == descriptors )
+ {
+ descriptors = new ArrayList<ComponentDescriptor<?>>();
+ descriptorMap.put( realm, descriptors );
+ }
+ descriptors.add( descriptor );
+ if ( containerRealm == realm )
+ {
+ discoverComponents( containerRealm ); // for Maven3 testing
+ }
+ }
+
+ public ComponentDescriptor<?> getComponentDescriptor( final String role, final String hint )
+ {
+ return getComponentDescriptor( null, role, hint );
+ }
+
+ public <T> ComponentDescriptor<T> getComponentDescriptor( final Class<T> type, final String role, final String hint )
+ {
+ final Iterator<PlexusBean<T>> i = locate( role, type, hint ).iterator();
+ if ( i.hasNext() )
+ {
+ final PlexusBean<T> bean = i.next();
+ if ( bean.getImplementationClass() != null )
+ {
+ return newComponentDescriptor( role, bean );
+ }
+ }
+ return null;
+ }
+
+ public List getComponentDescriptorList( final String role )
+ {
+ return getComponentDescriptorList( null, role );
+ }
+
+ public <T> List<ComponentDescriptor<T>> getComponentDescriptorList( final Class<T> type, final String role )
+ {
+ final List<ComponentDescriptor<T>> tempList = new ArrayList<ComponentDescriptor<T>>();
+ for ( final PlexusBean<T> bean : locate( role, type ) )
+ {
+ tempList.add( newComponentDescriptor( role, bean ) );
+ }
+ return tempList;
+ }
+
+ public Map getComponentDescriptorMap( final String role )
+ {
+ return getComponentDescriptorMap( null, role );
+ }
+
+ public <T> Map<String, ComponentDescriptor<T>> getComponentDescriptorMap( final Class<T> type, final String role )
+ {
+ final Map<String, ComponentDescriptor<T>> tempMap = new LinkedHashMap<String, ComponentDescriptor<T>>();
+ for ( final PlexusBean<T> bean : locate( role, type ) )
+ {
+ tempMap.put( bean.getKey(), newComponentDescriptor( role, bean ) );
+ }
+ return tempMap;
+ }
+
+ public List<ComponentDescriptor<?>> discoverComponents( final ClassRealm realm )
+ {
+ try
+ {
+ final List<PlexusBeanModule> beanModules = new ArrayList<PlexusBeanModule>();
+
+ final ClassSpace space = new URLClassSpace( realm );
+ final List<ComponentDescriptor<?>> descriptors = descriptorMap.remove( realm );
+ if ( null != descriptors )
+ {
+ beanModules.add( new XComponentDescriptorBeanModule( componentSelector, instanceRegistry, space,
+ descriptors ) );
+ }
+ if ( realmIds.add( realm.getId() ) )
+ {
+ beanModules.add( new XPlexusXmlBeanModule( componentSelector, instanceRegistry, space, variables ) );
+ beanModules.add( new XPlexusAnnotatedBeanModule( componentSelector, instanceRegistry, space,
+ variables, scanning ) );
+ }
+ if ( !beanModules.isEmpty() )
+ {
+ addPlexusInjector( beanModules );
+ }
+ }
+ catch ( final Throwable e )
+ {
+ getLogger().warn( realm.toString(), e );
+ }
+
+ return null; // no-one actually seems to use or check the returned component list!
+ }
+
+ public void addPlexusInjector( final List<PlexusBeanModule> beanModules, final Module... customModules )
+ {
+ final List<Module> modules = new ArrayList<Module>();
+
+ modules.add( setupModule );
+ Collections.addAll( modules, customModules );
+ modules.add( new PlexusBindingModule( lifecycleManager, beanModules ) );
+ modules.add( loggerModule );
+
+ injector = Guice.createInjector( isAutoWiringEnabled ? new WireModule( modules ) : new MergedModule( modules ) );
+ }
+
+ // ----------------------------------------------------------------------
+ // Class realm methods
+ // ----------------------------------------------------------------------
+
+ public ClassWorld getClassWorld()
+ {
+ return containerRealm.getWorld();
+ }
+
+ public ClassRealm getContainerRealm()
+ {
+ return containerRealm;
+ }
+
+ public ClassRealm setLookupRealm( final ClassRealm realm )
+ {
+ final ClassRealm oldRealm = lookupRealm.get();
+ lookupRealm.set( realm );
+ return oldRealm;
+ }
+
+ public ClassRealm getLookupRealm()
+ {
+ return lookupRealm.get();
+ }
+
+ public ClassRealm createChildRealm( final String id )
+ {
+ try
+ {
+ return containerRealm.createChildRealm( id );
+ }
+ catch ( final DuplicateRealmException e1 )
+ {
+ try
+ {
+ return getClassWorld().getRealm( id );
+ }
+ catch ( final NoSuchRealmException e2 )
+ {
+ return null; // should never happen!
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Logger methods
+ // ----------------------------------------------------------------------
+
+ public synchronized LoggerManager getLoggerManager()
+ {
+ return loggerManager;
+ }
+
+ @Inject( optional = true )
+ public synchronized void setLoggerManager( final LoggerManager loggerManager )
+ {
+ if ( null != loggerManager )
+ {
+ this.loggerManager = loggerManager;
+ }
+ else
+ {
+ this.loggerManager = CONSOLE_LOGGER_MANAGER;
+ }
+ logger = null; // refresh our local logger
+ }
+
+ public synchronized Logger getLogger()
+ {
+ if ( null == logger )
+ {
+ logger = loggerManager.getLoggerForComponent( PlexusContainer.class.getName(), null );
+ }
+ return logger;
+ }
+
+ // ----------------------------------------------------------------------
+ // Shutdown methods
+ // ----------------------------------------------------------------------
+
+ public void release( final Object component )
+ {
+ lifecycleManager.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()
+ {
+ disposing = true;
+
+ lifecycleManager.unmanage();
+ containerRealm.setParentRealm( null );
+ qualifiedBeanLocator.clear();
+ }
+
+ // ----------------------------------------------------------------------
+ // Implementation methods
+ // ----------------------------------------------------------------------
+
+ /**
+ * Finds container {@link ClassRealm}, taking existing {@link ClassWorld}s or {@link ClassLoader}s into account.
+ *
+ * @param configuration The container configuration
+ * @return Container class realm
+ */
+ private ClassRealm lookupContainerRealm( final ContainerConfiguration configuration )
+ throws PlexusContainerException
+ {
+ ClassRealm realm = configuration.getRealm();
+ if ( null == realm )
+ {
+ ClassWorld world = configuration.getClassWorld();
+ if ( null == world )
+ {
+ world = new ClassWorld( DEFAULT_REALM_NAME, Thread.currentThread().getContextClassLoader() );
+ }
+ try
+ {
+ realm = world.getRealm( DEFAULT_REALM_NAME );
+ }
+ catch ( final NoSuchRealmException e )
+ {
+ final Iterator<?> realmIterator = world.getRealms().iterator();
+ if ( realmIterator.hasNext() )
+ {
+ realm = (ClassRealm) realmIterator.next();
+ }
+ }
+ }
+ if ( null == realm )
+ {
+ throw new PlexusContainerException( "Missing container class realm: " + DEFAULT_REALM_NAME );
+ }
+ return realm;
+ }
+
+ /**
+ * Finds container configuration URL, may search the container {@link ClassRealm} and local file-system.
+ *
+ * @param configuration The container configuration
+ * @return Local or remote URL
+ */
+ private URL lookupPlexusXml( final ContainerConfiguration configuration )
+ {
+ URL url = configuration.getContainerConfigurationURL();
+ if ( null == url )
+ {
+ final String configurationPath = configuration.getContainerConfiguration();
+ if ( null != configurationPath )
+ {
+ int index = 0;
+ while ( index < configurationPath.length() && configurationPath.charAt( index ) == '/' )
+ {
+ index++;
+ }
+
+ url = getClass().getClassLoader().getResource( configurationPath.substring( index ) );
+ if ( null == url )
+ {
+ final File file = new File( configurationPath );
+ if ( file.isFile() )
+ {
+ try
+ {
+ url = file.toURI().toURL();
+ }
+ catch ( final MalformedURLException e ) // NOPMD
+ {
+ // drop through and recover
+ }
+ }
+ }
+ if ( null == url )
+ {
+ getLogger().debug( "Missing container configuration: " + configurationPath );
+ }
+ }
+ }
+ return url;
+ }
+
+ private <T> Iterable<PlexusBean<T>> locate( final String role, final Class<T> type, final String... hints )
+ {
+ if ( disposing )
+ {
+ return Collections.EMPTY_LIST;
+ }
+
+ final String[] canonicalHints = Hints.canonicalHints( hints );
+ if ( null == role || null != type && type.getName().equals( role ) )
+ {
+ return plexusBeanLocator.locate( TypeLiteral.get( type ), canonicalHints );
+ }
+
+ final Set<Class> candidates = new HashSet<Class>();
+ for ( final ClassRealm realm : getVisibleRealms() )
+ {
+ try
+ {
+ final Class clazz = realm.loadClass( role );
+ if ( candidates.add( clazz ) )
+ {
+ final Iterable beans = plexusBeanLocator.locate( TypeLiteral.get( clazz ), canonicalHints );
+ if ( hasPlexusBeans( beans ) )
+ {
+ return beans;
+ }
+ }
+ }
+ catch ( final Throwable e )
+ {
+ // continue...
+ }
+ }
+
+ return Collections.EMPTY_LIST;
+ }
+
+ private Collection<ClassRealm> getVisibleRealms()
+ {
+ final Object[] realms = getClassWorld().getRealms().toArray();
+ final Set<ClassRealm> visibleRealms = new LinkedHashSet<ClassRealm>( realms.length );
+ final ClassRealm currentLookupRealm = getLookupRealm();
+ if ( null != currentLookupRealm )
+ {
+ visibleRealms.add( currentLookupRealm );
+ }
+
+ if ( PlexusConstants.REALM_VISIBILITY.equals( componentVisibility ) )
+ {
+ final Collection<String> visibleNames = ClassRealmUtils.visibleRealmNames( ClassRealmUtils.contextRealm() );
+ if ( !visibleNames.isEmpty() )
+ {
+ for ( int i = realms.length - 1; i >= 0; i-- )
+ {
+ final ClassRealm r = (ClassRealm) realms[i];
+ if ( visibleNames.contains( r.toString() ) )
+ {
+ visibleRealms.add( r );
+ }
+ }
+ return visibleRealms;
+ }
+ }
+
+ for ( int i = realms.length - 1; i >= 0; i-- )
+ {
+ visibleRealms.add( (ClassRealm) realms[i] );
+ }
+ return visibleRealms;
+ }
+
+ private <T> boolean hasPlexusBeans( final Iterable<PlexusBean<T>> beans )
+ {
+ final Iterator<PlexusBean<T>> i = beans.iterator();
+ return i.hasNext() && i.next().getImplementationClass() != null;
+ }
+
+ private <T> ComponentDescriptor<T> newComponentDescriptor( final String role, final PlexusBean<T> bean )
+ {
+ final ComponentDescriptor<T> cd = new ComponentDescriptor<T>();
+ cd.setRole( role );
+ cd.setRoleHint( bean.getKey() );
+ cd.setImplementationClass( bean.getImplementationClass() );
+ cd.setDescription( bean.getDescription() );
+ return cd;
+ }
+
+ final class BootModule
+ extends AbstractModule
+ {
+ @Override
+ protected void configure()
+ {
+ requestInjection( MAEContainer.this );
+ }
+ }
+
+ final class SetupModule
+ extends AbstractModule
+ {
+ final PlexusDateTypeConverter dateConverter = new PlexusDateTypeConverter();
+
+ final PlexusXmlBeanConverter beanConverter = new PlexusXmlBeanConverter();
+
+ @Override
+ protected void configure()
+ {
+ bind( Context.class ).toInstance( context );
+ bind( ParameterKeys.PROPERTIES ).toInstance( variables );
+
+ install( dateConverter );
+
+ bind( MutablePlexusContainer.class ).toInstance( MAEContainer.this );
+ bind( MutableBeanLocator.class ).toInstance( qualifiedBeanLocator );
+
+ bind( PlexusContainer.class ).to( MutablePlexusContainer.class );
+ bind( PlexusBeanConverter.class ).toInstance( beanConverter );
+ bind( PlexusBeanLocator.class ).toInstance( plexusBeanLocator );
+ bind( PlexusBeanManager.class ).toInstance( lifecycleManager );
+
+ // use provider wrapper to avoid repeated injections later on when configuring plugin injectors
+ bind( MutablePlexusContainer.class ).toProvider( Providers.of( MAEContainer.this ) );
+ }
+ }
+
+ final class LoggerModule
+ extends AbstractModule
+ {
+ final LoggerManagerProvider loggerManagerProvider = new LoggerManagerProvider();
+
+ final LoggerProvider loggerProvider = new LoggerProvider();
+
+ @Override
+ protected void configure()
+ {
+ bind( LoggerManager.class ).toProvider( loggerManagerProvider );
+ bind( Logger.class ).toProvider( loggerProvider );
+ }
+ }
+
+ final class DefaultsModule
+ extends AbstractModule
+ {
+ final LoggerManagerProvider loggerManagerProvider = new LoggerManagerProvider();
+
+ final LoggerProvider loggerProvider = new LoggerProvider();
+
+ @Override
+ protected void configure()
+ {
+ bind( LoggerManager.class ).toProvider( loggerManagerProvider );
+ bind( Logger.class ).toProvider( loggerProvider );
+
+ // allow plugins to override the default ranking function so we can support component profiles
+ final Key<RankingFunction> plexusRankingKey = Key.get( RankingFunction.class, Names.named( "plexus" ) );
+ bind( plexusRankingKey ).toInstance( new DefaultRankingFunction( plexusRank.incrementAndGet() ) );
+ bind( RankingFunction.class ).to( plexusRankingKey );
+ }
+ }
+
+ final class LoggerManagerProvider
+ implements DeferredProvider<LoggerManager>
+ {
+ public LoggerManager get()
+ {
+ return getLoggerManager();
+ }
+
+ public DeferredClass<LoggerManager> getImplementationClass()
+ {
+ return new LoadedClass<LoggerManager>( get().getClass() );
+ }
+ }
+
+ final class LoggerProvider
+ implements DeferredProvider<Logger>
+ {
+ public Logger get()
+ {
+ return getLogger();
+ }
+
+ public DeferredClass<Logger> getImplementationClass()
+ {
+ return new LoadedClass<Logger>( get().getClass() );
+ }
+ }
+
+ // SPECIFIC TO ExtrudablePlexusContainer
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws MultiComponentLookupException
+ * @see org.apache.maven.mae.internal.container.ExtrudablePlexusContainer#extrudeDependencies(java.lang.Object)
+ */
+ @Override
+ public Map<Object, Throwable> extrudeDependencies( final Object... instances )
+ {
+ final Map<Object, Throwable> errors = new LinkedHashMap<Object, Throwable>();
+ for ( final Object instance : instances )
+ {
+ extrude( instance, errors );
+ }
+
+ return errors;
+ }
+
+ private <T> void extrude( final T instance, final Map<Object, Throwable> errors )
+ {
+ final ComponentKey<T> key = instanceBinder.addInstance( instance );
+ if ( key != null )
+ {
+ // trigger the injection now that the instance is added.
+ try
+ {
+ lookup( key.getRoleClass(), key.getHint() );
+ }
+ catch ( final ComponentLookupException e )
+ {
+ errors.put( instance, e );
+ }
+ }
+ else
+ {
+ try
+ {
+ injector.injectMembers( instance );
+ }
+ catch ( final RuntimeException e )
+ {
+ errors.put( instance, e );
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.apache.maven.mae.internal.container.ExtrudablePlexusContainer#getInjector()
+ */
+ @Override
+ public Injector getInjector()
+ {
+ return injector;
+ }
+
+ private static BeanScanning parseScanningOption( final String scanning )
+ {
+ for ( final BeanScanning option : BeanScanning.values() )
+ {
+ if ( option.name().equalsIgnoreCase( scanning ) )
+ {
+ return option;
+ }
+ }
+ return BeanScanning.OFF;
+ }
+
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/MAEContainer.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/InstanceBindingModule.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/InstanceBindingModule.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/InstanceBindingModule.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/InstanceBindingModule.java Tue May 17 16:57:50 2011
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010 Red Hat, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.maven.mae.internal.container.guice;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.apache.maven.mae.internal.container.ComponentKey;
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.apache.maven.mae.internal.container.VirtualInstance;
+import org.sonatype.guice.bean.reflect.LoadedClass;
+import org.sonatype.guice.plexus.config.PlexusBeanModule;
+import org.sonatype.guice.plexus.config.PlexusBeanSource;
+import org.sonatype.guice.plexus.config.Roles;
+
+import com.google.inject.Binder;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Provider;
+
+import java.util.Map;
+
+public class InstanceBindingModule
+ implements PlexusBeanModule
+{
+
+ private final InstanceRegistry registry;
+
+ private final ComponentSelector selector;
+
+ private final Map<?, ?> variables;
+
+ private SelectingTypeBinder typeBinder;
+
+ public InstanceBindingModule( final InstanceRegistry registry, final ComponentSelector selector,
+ final Map<?, ?> variables )
+ {
+ this.registry = registry;
+ this.selector = selector;
+ this.variables = variables;
+ }
+
+ @SuppressWarnings( { "rawtypes", "unchecked" } )
+ public <T> ComponentKey<T> addInstance( final T instance )
+ {
+ final Component comp = instance.getClass().getAnnotation( Component.class );
+ final ComponentKey<T> key = new ComponentKey( comp.role(), comp.hint() );
+ if ( !registry.has( key ) )
+ {
+ registry.add( key, instance );
+
+ final InstanceProvider<T> provider = new InstanceProvider( instance );
+
+ typeBinder.hear( comp, new LoadedClass<Object>( instance.getClass() ), "External instance loaded from: "
+ + instance.getClass().getClassLoader(), provider );
+
+ return key;
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings( { "rawtypes", "unchecked" } )
+ @Override
+ public PlexusBeanSource configure( final Binder binder )
+ {
+ typeBinder = new SelectingTypeBinder( selector, registry, binder );
+
+ for ( final Map.Entry<ComponentKey<?>, Object> mapping : registry.getInstances().entrySet() )
+ {
+ final ComponentKey<?> key = mapping.getKey();
+ final Object instance = mapping.getValue();
+
+ if ( instance instanceof VirtualInstance )
+ {
+ final VirtualInstance vi = (VirtualInstance) instance;
+ final Class<?> cls = vi.getVirtualClass();
+
+ final Component comp = cls.getAnnotation( Component.class );
+ if ( comp != null )
+ {
+ typeBinder.hear( comp, new LoadedClass<Object>( cls ),
+ "External instance loaded from: " + cls.getClassLoader(), vi );
+ }
+ else
+ {
+ binder.bind( Roles.componentKey( key.getRoleClass(), key.getHint() ) )
+ .toProvider( (Provider) instance );
+ }
+ }
+ else
+ {
+ final InstanceProvider provider = new InstanceProvider( instance );
+
+ final Component comp = instance.getClass().getAnnotation( Component.class );
+ if ( comp != null )
+ {
+ typeBinder.hear( comp, new LoadedClass<Object>( instance.getClass() ),
+ "External instance loaded from: " + instance.getClass().getClassLoader(), provider );
+ }
+ else
+ {
+ binder.bind( Roles.componentKey( key.getRoleClass(), key.getHint() ) ).toProvider( provider );
+ }
+ }
+ }
+
+ return new XAnnotatedBeanSource( variables );
+ }
+
+ private static final class InstanceProvider<T>
+ implements Provider<T>
+ {
+ @Inject
+ private Injector injector;
+
+ private final T instance;
+
+ InstanceProvider( final T instance )
+ {
+ this.instance = instance;
+ }
+
+ @Override
+ public T get()
+ {
+ injector.injectMembers( instance );
+ return instance;
+ }
+ }
+
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/InstanceBindingModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/SelectingTypeBinder.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/SelectingTypeBinder.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/SelectingTypeBinder.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/SelectingTypeBinder.java Tue May 17 16:57:50 2011
@@ -0,0 +1,255 @@
+/**
+ * Copyright (c) 2009 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+package org.apache.maven.mae.internal.container.guice;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.apache.maven.mae.internal.container.ComponentKey;
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.sonatype.guice.bean.binders.QualifiedTypeBinder;
+import org.sonatype.guice.bean.locators.BeanDescription;
+import org.sonatype.guice.bean.reflect.DeferredClass;
+import org.sonatype.guice.bean.reflect.LoadedClass;
+import org.sonatype.guice.bean.scanners.QualifiedTypeListener;
+import org.sonatype.guice.plexus.config.Hints;
+import org.sonatype.guice.plexus.config.Roles;
+import org.sonatype.guice.plexus.config.Strategies;
+import org.sonatype.guice.plexus.scanners.PlexusTypeListener;
+
+import com.google.inject.Binder;
+import com.google.inject.Key;
+import com.google.inject.Provider;
+import com.google.inject.Scopes;
+import com.google.inject.binder.ScopedBindingBuilder;
+import com.google.inject.name.Names;
+
+import java.lang.annotation.Annotation;
+import java.util.Set;
+
+/*
+ * Given:
+ *
+ * - DefaultPluginManager.class, role=PluginManager.class, hint=<default>
+ * - CustomPluginManager.class, role=PluginManager.class, hint="custom"
+ * - ComponentSelector with:
+ *
+ * - PluginManager.class/<default> => "custom"
+ *
+ * Register the following:
+ *
+ * - PluginManager.class/<default> => Alias :: CustomPluginManager.class/"custom_"]
+ * - PluginManager.class/"custom" => Alias :: CustomPluginManager.class/"custom_"]
+ * - PluginManager.class/"custom_" => CustomPluginManager.class
+ *
+ * - PluginManager.class/"default_" => DefaultPluginManager.class
+ */
+public final class SelectingTypeBinder
+ implements PlexusTypeListener
+{
+ // ----------------------------------------------------------------------
+ // Implementation fields
+ // ----------------------------------------------------------------------
+
+ private final Binder binder;
+
+ private final QualifiedTypeListener qualifiedTypeBinder;
+
+ private final ComponentSelector componentSelector;
+
+ private final InstanceRegistry instanceRegistry;
+
+ // ----------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------
+
+ public SelectingTypeBinder( final ComponentSelector componentSelector, final InstanceRegistry instanceRegistry,
+ final Binder binder )
+ {
+ this.componentSelector = componentSelector;
+ this.instanceRegistry = instanceRegistry;
+ this.binder = binder;
+
+ qualifiedTypeBinder = new QualifiedTypeBinder( binder );
+ }
+
+ // ----------------------------------------------------------------------
+ // Public methods
+ // ----------------------------------------------------------------------
+
+ public void hear( final Annotation qualifier, final Class<?> qualifiedType, final Object source )
+ {
+ if ( Component.class == qualifier.annotationType() )
+ {
+ hear( (Component) qualifier, new LoadedClass<Object>( qualifiedType ), source );
+ }
+ else
+ {
+ qualifiedTypeBinder.hear( qualifier, qualifiedType, source );
+ }
+ }
+
+ public void hear( final Component component, final DeferredClass<?> clazz, final Object source )
+ {
+ hear( component, clazz, source, null );
+ }
+
+ public void hear( final Component component, final DeferredClass<?> clazz, final Object source,
+ final Provider<?> provider )
+ {
+ final String strategy = component.instantiationStrategy();
+ final Class<?> role = component.role();
+ final String hint = Hints.canonicalHint( component.hint() );
+
+ if ( provider == null )
+ {
+ if ( instanceRegistry.has( component.role(), component.hint() ) )
+ {
+ return;
+ }
+ }
+
+ final Binder componentBinder = componentBinder( source, component.description() );
+
+ // in case this component gets overridden with something else, we need to give users a way to "pin" to
+ // the original component, rather than blindly getting whatever resolves to a given hint.
+ // This means re-binding the component to a sort of literal hint.
+ //
+ // To use this literal reference, you can use 'hint_' instead.
+ final Key<?> literalRootKey =
+ Roles.componentKey( component.role(), Hints.canonicalHint( component.hint() ) + "_" );
+
+ if ( componentSelector.hasOverride( role, hint ) )
+ {
+ bind( literalRootKey, clazz, componentBinder, strategy, role, provider );
+ }
+ else
+ {
+ final Set<ComponentKey<?>> overriddenKeys = componentSelector.getKeysOverriddenBy( role, hint );
+
+ // bind the normal component role+hint, with the exception that we're forcing the explicit
+ // use of the default hint here to avoid Guice running into an infinite loop looking up
+ // for the component role without a hint...which could be assigned as an alias.
+ Key<?> rootKey;
+ if ( Hints.isDefaultHint( hint ) )
+ {
+ rootKey = Key.get( role, Names.named( Hints.DEFAULT_HINT ) );
+ }
+ else
+ {
+ rootKey = Roles.componentKey( component );
+ }
+
+ bind( rootKey, clazz, componentBinder, strategy, role, provider );
+ bindAlias( literalRootKey, rootKey, componentBinder );
+
+ // If this component overrides some other component, make aliases of the overridden hints
+ // that point to this component. Bind this component normally.
+ if ( overriddenKeys != null && !overriddenKeys.isEmpty() )
+ {
+ for ( final ComponentKey<?> ckey : overriddenKeys )
+ {
+ final Key<?> key = Roles.componentKey( ckey.getRoleClass(), ckey.getHint() );
+ bindAlias( key, rootKey, componentBinder );
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings( { "rawtypes", "unchecked" } )
+ private void bindAlias( final Key key, final Key rootKey, final Binder componentBinder )
+ {
+ componentBinder.bind( key ).to( rootKey );
+ }
+
+ @SuppressWarnings( { "rawtypes", "unchecked" } )
+ private void bind( final Key key, final DeferredClass clazz, final Binder componentBinder, final String strategy,
+ final Class role, final Provider provider )
+ {
+ final ScopedBindingBuilder sbb;
+ // special case when role is the implementation
+ if ( provider != null )
+ {
+ sbb = componentBinder.bind( key ).toProvider( provider );
+ }
+ else if ( role.getName().equals( clazz.getName() ) )
+ {
+ if ( key.getAnnotation() != null )
+ {
+ sbb = componentBinder.bind( key ).to( role );
+ }
+ else
+ {
+ sbb = componentBinder.bind( key );
+ }
+ }
+ else if ( Strategies.LOAD_ON_START.equals( strategy ) || clazz instanceof LoadedClass<?> )
+ {
+ sbb = componentBinder.bind( key ).to( clazz.load() ); // no need to defer
+ }
+ else
+ {
+ sbb = componentBinder.bind( key ).toProvider( clazz.asProvider() );
+ }
+
+ if ( Strategies.LOAD_ON_START.equals( strategy ) )
+ {
+ sbb.asEagerSingleton();
+ }
+ else if ( !Strategies.PER_LOOKUP.equals( strategy ) )
+ {
+ sbb.in( Scopes.SINGLETON );
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Implementation methods
+ // ----------------------------------------------------------------------
+
+ private Binder componentBinder( final Object source, final String description )
+ {
+ if ( null != description && description.length() > 0 )
+ {
+ return binder.withSource( new DefaultPlexusBeanDescription( source, description ) );
+ }
+ return binder.withSource( source );
+ }
+
+ // ----------------------------------------------------------------------
+ // Implementation types
+ // ----------------------------------------------------------------------
+
+ private static final class DefaultPlexusBeanDescription
+ implements BeanDescription
+ {
+ private final Object source;
+
+ private final String description;
+
+ DefaultPlexusBeanDescription( final Object source, final String description )
+ {
+ this.source = source;
+ this.description = description;
+ }
+
+ public String getDescription()
+ {
+ return description;
+ }
+
+ @Override
+ public String toString()
+ {
+ return source.toString();
+ }
+ }
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/SelectingTypeBinder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XAnnotatedBeanSource.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XAnnotatedBeanSource.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XAnnotatedBeanSource.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XAnnotatedBeanSource.java Tue May 17 16:57:50 2011
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2010 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+
+package org.apache.maven.mae.internal.container.guice;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.sonatype.guice.plexus.config.PlexusBeanMetadata;
+import org.sonatype.guice.plexus.config.PlexusBeanSource;
+import org.sonatype.guice.plexus.scanners.PlexusAnnotatedMetadata;
+
+import java.util.Map;
+
+final class XAnnotatedBeanSource
+ implements PlexusBeanSource
+{
+ private final PlexusBeanMetadata metadata;
+
+ XAnnotatedBeanSource( final Map<?, ?> variables )
+ {
+ metadata = new PlexusAnnotatedMetadata( variables );
+ }
+
+ public PlexusBeanMetadata getBeanMetadata( final Class<?> implementation )
+ {
+ return implementation.isAnnotationPresent( Component.class ) ? metadata : null;
+ }
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XAnnotatedBeanSource.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XComponentDescriptorBeanModule.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XComponentDescriptorBeanModule.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XComponentDescriptorBeanModule.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XComponentDescriptorBeanModule.java Tue May 17 16:57:50 2011
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2010 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+package org.apache.maven.mae.internal.container.guice;
+
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Configuration;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.component.factory.ComponentFactory;
+import org.codehaus.plexus.component.repository.ComponentDescriptor;
+import org.codehaus.plexus.component.repository.ComponentRequirement;
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.sonatype.guice.bean.reflect.BeanProperty;
+import org.sonatype.guice.bean.reflect.ClassSpace;
+import org.sonatype.guice.bean.reflect.DeferredClass;
+import org.sonatype.guice.bean.reflect.DeferredProvider;
+import org.sonatype.guice.plexus.annotations.ComponentImpl;
+import org.sonatype.guice.plexus.annotations.RequirementImpl;
+import org.sonatype.guice.plexus.config.PlexusBeanMetadata;
+import org.sonatype.guice.plexus.config.PlexusBeanModule;
+import org.sonatype.guice.plexus.config.PlexusBeanSource;
+
+import com.google.inject.Binder;
+import com.google.inject.ProvisionException;
+
+import javax.inject.Inject;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+public final class XComponentDescriptorBeanModule
+ implements PlexusBeanModule
+{
+ private final ClassSpace space;
+
+ private final Map<Component, DeferredClass<?>> componentMap = new HashMap<Component, DeferredClass<?>>();
+
+ private final Map<String, PlexusBeanMetadata> metadataMap = new HashMap<String, PlexusBeanMetadata>();
+
+ private final ComponentSelector componentSelector;
+
+ private final InstanceRegistry instanceRegistry;
+
+ public XComponentDescriptorBeanModule( final ComponentSelector componentSelector,
+ final InstanceRegistry instanceRegistry, final ClassSpace space,
+ final List<ComponentDescriptor<?>> descriptors )
+ {
+ this.componentSelector = componentSelector;
+ this.instanceRegistry = instanceRegistry;
+ this.space = space;
+
+ for ( int i = 0, size = descriptors.size(); i < size; i++ )
+ {
+ final ComponentDescriptor<?> cd = descriptors.get( i );
+ final String implementation = cd.getImplementation();
+ final String factory = cd.getComponentFactory();
+ if ( null == factory || "java".equals( factory ) )
+ {
+ componentMap.put( newComponent( cd ), space.deferLoadClass( implementation ) );
+ }
+ else
+ {
+ componentMap.put( newComponent( cd ), new DeferredFactoryClass( cd, factory ) );
+ }
+ final List<ComponentRequirement> requirements = cd.getRequirements();
+ if ( !requirements.isEmpty() )
+ {
+ metadataMap.put( implementation, new ComponentMetadata( space, requirements ) );
+ }
+ }
+ }
+
+ public PlexusBeanSource configure( final Binder binder )
+ {
+ final SelectingTypeBinder plexusTypeBinder =
+ new SelectingTypeBinder( componentSelector, instanceRegistry, binder );
+ for ( final Entry<Component, DeferredClass<?>> entry : componentMap.entrySet() )
+ {
+ plexusTypeBinder.hear( entry.getKey(), entry.getValue(), space );
+ }
+ return new PlexusDescriptorBeanSource( metadataMap );
+ }
+
+ static Component newComponent( final ComponentDescriptor<?> cd )
+ {
+ return new ComponentImpl( cd.getRoleClass(), cd.getRoleHint(), cd.getInstantiationStrategy(),
+ cd.getDescription() );
+ }
+
+ static Requirement newRequirement( final ClassSpace space, final ComponentRequirement cr )
+ {
+ return new RequirementImpl( space.deferLoadClass( cr.getRole() ), false,
+ Collections.singletonList( cr.getRoleHint() ) );
+ }
+
+ private static final class DeferredFactoryClass
+ implements DeferredClass<Object>, DeferredProvider<Object>
+ {
+ @Inject
+ private PlexusContainer container;
+
+ private final ComponentDescriptor<?> cd;
+
+ private final String hint;
+
+ DeferredFactoryClass( final ComponentDescriptor<?> cd, final String hint )
+ {
+ this.cd = cd;
+ this.hint = hint;
+ }
+
+ @SuppressWarnings( { "unchecked", "rawtypes" } )
+ public Class load()
+ throws TypeNotPresentException
+ {
+ return cd.getImplementationClass();
+ }
+
+ public String getName()
+ {
+ return cd.getImplementation();
+ }
+
+ public DeferredProvider<Object> asProvider()
+ {
+ return this;
+ }
+
+ public Object get()
+ {
+ try
+ {
+ final ComponentFactory factory = container.lookup( ComponentFactory.class, hint );
+ return factory.newInstance( cd, container.getLookupRealm(), container );
+ }
+ catch ( final Throwable e )
+ {
+ throw new ProvisionException( "Error in ComponentFactory:" + hint, e );
+ }
+ }
+
+ public DeferredClass<Object> getImplementationClass()
+ {
+ return this;
+ }
+ }
+
+ private static final class ComponentMetadata
+ implements PlexusBeanMetadata
+ {
+ private Map<String, Requirement> requirementMap = new HashMap<String, Requirement>();
+
+ ComponentMetadata( final ClassSpace space, final List<ComponentRequirement> requirements )
+ {
+ for ( int i = 0, size = requirements.size(); i < size; i++ )
+ {
+ final ComponentRequirement cr = requirements.get( i );
+ requirementMap.put( cr.getFieldName(), newRequirement( space, cr ) );
+ }
+ }
+
+ public boolean isEmpty()
+ {
+ return requirementMap.isEmpty();
+ }
+
+ public Requirement getRequirement( final BeanProperty<?> property )
+ {
+ final Requirement requirement = requirementMap.get( property.getName() );
+ if ( null != requirement && requirementMap.isEmpty() )
+ {
+ requirementMap = Collections.emptyMap();
+ }
+ return requirement;
+ }
+
+ public Configuration getConfiguration( final BeanProperty<?> property )
+ {
+ return null;
+ }
+ }
+
+ private static final class PlexusDescriptorBeanSource
+ implements PlexusBeanSource
+ {
+ private Map<String, PlexusBeanMetadata> metadataMap;
+
+ PlexusDescriptorBeanSource( final Map<String, PlexusBeanMetadata> metadataMap )
+ {
+ this.metadataMap = metadataMap;
+ }
+
+ public PlexusBeanMetadata getBeanMetadata( final Class<?> implementation )
+ {
+ if ( null == metadataMap )
+ {
+ return null;
+ }
+ final PlexusBeanMetadata metadata = metadataMap.remove( implementation.getName() );
+ if ( metadataMap.isEmpty() )
+ {
+ metadataMap = null;
+ }
+ return metadata;
+ }
+ }
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XComponentDescriptorBeanModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusAnnotatedBeanModule.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusAnnotatedBeanModule.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusAnnotatedBeanModule.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusAnnotatedBeanModule.java Tue May 17 16:57:50 2011
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2009 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+package org.apache.maven.mae.internal.container.guice;
+
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.sonatype.guice.bean.binders.SpaceModule;
+import org.sonatype.guice.bean.reflect.ClassSpace;
+import org.sonatype.guice.bean.scanners.ClassSpaceVisitor;
+import org.sonatype.guice.plexus.config.PlexusBeanModule;
+import org.sonatype.guice.plexus.config.PlexusBeanSource;
+import org.sonatype.guice.plexus.scanners.PlexusTypeVisitor;
+import org.sonatype.inject.BeanScanning;
+
+import com.google.inject.Binder;
+
+import java.util.Map;
+
+/**
+ * {@link PlexusBeanModule} that registers Plexus beans by scanning classes for runtime annotations.
+ */
+public final class XPlexusAnnotatedBeanModule
+ implements PlexusBeanModule
+{
+ // ----------------------------------------------------------------------
+ // Implementation fields
+ // ----------------------------------------------------------------------
+
+ private final ClassSpace space;
+
+ private final Map<?, ?> variables;
+
+ private final ComponentSelector componentSelector;
+
+ private final InstanceRegistry instanceRegistry;
+
+ private final BeanScanning scanning;
+
+ // ----------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------
+
+ /**
+ * Creates a bean source that scans the given class space for Plexus annotations using the given scanner.
+ *
+ * @param componentSelector
+ * @param space The local class space
+ * @param variables The filter variables
+ * @param scanning
+ */
+ public XPlexusAnnotatedBeanModule( final ComponentSelector componentSelector,
+ final InstanceRegistry instanceRegistry, final ClassSpace space,
+ final Map<?, ?> variables, BeanScanning scanning )
+ {
+ this.componentSelector = componentSelector;
+ this.instanceRegistry = instanceRegistry;
+ this.space = space;
+ this.variables = variables;
+ this.scanning = scanning;
+ }
+
+ // ----------------------------------------------------------------------
+ // Public methods
+ // ----------------------------------------------------------------------
+
+ public PlexusBeanSource configure( final Binder binder )
+ {
+ if ( null != space && scanning != BeanScanning.OFF )
+ {
+ new PlexusSpaceModule( componentSelector, instanceRegistry, space, scanning ).configure( binder );
+ }
+
+ return new XAnnotatedBeanSource( variables );
+ }
+
+ // ----------------------------------------------------------------------
+ // Implementation types
+ // ----------------------------------------------------------------------
+
+ private static final class PlexusSpaceModule
+ extends SpaceModule
+ {
+ private final InstanceRegistry instanceRegistry;
+
+ private final ComponentSelector componentSelector;
+
+ PlexusSpaceModule( final ComponentSelector componentSelector, final InstanceRegistry instanceRegistry,
+ final ClassSpace space, final BeanScanning scanning )
+ {
+ super( space, scanning );
+ this.componentSelector = componentSelector;
+ this.instanceRegistry = instanceRegistry;
+ }
+
+ @Override
+ protected ClassSpaceVisitor visitor( final Binder binder )
+ {
+ return new PlexusTypeVisitor( new SelectingTypeBinder( componentSelector, instanceRegistry, binder ) );
+ }
+ }
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusAnnotatedBeanModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusXmlBeanModule.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusXmlBeanModule.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusXmlBeanModule.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusXmlBeanModule.java Tue May 17 16:57:50 2011
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2009 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+package org.apache.maven.mae.internal.container.guice;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.apache.maven.mae.internal.container.ComponentSelector;
+import org.apache.maven.mae.internal.container.InstanceRegistry;
+import org.sonatype.guice.bean.reflect.ClassSpace;
+import org.sonatype.guice.bean.reflect.DeferredClass;
+import org.sonatype.guice.plexus.config.PlexusBeanMetadata;
+import org.sonatype.guice.plexus.config.PlexusBeanModule;
+import org.sonatype.guice.plexus.config.PlexusBeanSource;
+import org.sonatype.guice.plexus.scanners.PlexusXmlScanner;
+
+import com.google.inject.Binder;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * {@link PlexusBeanModule} that collects {@link PlexusBeanMetadata} by scanning XML resources.
+ */
+public final class XPlexusXmlBeanModule
+ implements PlexusBeanModule
+{
+ // ----------------------------------------------------------------------
+ // Implementation fields
+ // ----------------------------------------------------------------------
+
+ private final ClassSpace space;
+
+ private final Map<?, ?> variables;
+
+ private final URL plexusXml;
+
+ private final ComponentSelector componentSelector;
+
+ private final boolean root;
+
+ private final InstanceRegistry instanceRegistry;
+
+ // ----------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------
+
+ /**
+ * Creates a bean source that scans all the surrounding class spaces for XML resources.
+ *
+ * @param space
+ * The main class space
+ * @param variables
+ * The filter variables
+ * @param plexusXml
+ * The plexus.xml URL
+ */
+ public XPlexusXmlBeanModule( final ComponentSelector componentSelector, final InstanceRegistry instanceRegistry,
+ final ClassSpace space, final Map<?, ?> variables, final URL plexusXml )
+ {
+ this.componentSelector = componentSelector;
+ this.instanceRegistry = instanceRegistry;
+ this.space = space;
+ this.variables = variables;
+ this.plexusXml = plexusXml;
+ root = true;
+ }
+
+ /**
+ * Creates a bean source that only scans the local class space for XML resources.
+ *
+ * @param space
+ * The local class space
+ * @param variables
+ * The filter variables
+ */
+ public XPlexusXmlBeanModule( final ComponentSelector componentSelector, final InstanceRegistry instanceRegistry,
+ final ClassSpace space, final Map<?, ?> variables )
+ {
+ this.componentSelector = componentSelector;
+ this.instanceRegistry = instanceRegistry;
+ this.space = space;
+ this.variables = variables;
+ plexusXml = null;
+ root = false;
+ }
+
+ // ----------------------------------------------------------------------
+ // Public methods
+ // ----------------------------------------------------------------------
+
+ public PlexusBeanSource configure( final Binder binder )
+ {
+ final Map<String, PlexusBeanMetadata> metadataMap = new HashMap<String, PlexusBeanMetadata>();
+ final PlexusXmlScanner scanner = new PlexusXmlScanner( variables, plexusXml, metadataMap );
+ final Map<Component, DeferredClass<?>> components = scanner.scan( space, root );
+ final SelectingTypeBinder plexusTypeBinder =
+ new SelectingTypeBinder( componentSelector, instanceRegistry, binder );
+ for ( final Entry<Component, DeferredClass<?>> entry : components.entrySet() )
+ {
+ plexusTypeBinder.hear( entry.getKey(), entry.getValue(), space );
+ }
+
+ return new PlexusXmlBeanSource( metadataMap );
+ }
+
+ // ----------------------------------------------------------------------
+ // Implementation types
+ // ----------------------------------------------------------------------
+
+ private static final class PlexusXmlBeanSource
+ implements PlexusBeanSource
+ {
+ private Map<String, PlexusBeanMetadata> metadataMap;
+
+ PlexusXmlBeanSource( final Map<String, PlexusBeanMetadata> metadataMap )
+ {
+ this.metadataMap = metadataMap;
+ }
+
+ public PlexusBeanMetadata getBeanMetadata( final Class<?> implementation )
+ {
+ if ( null == metadataMap )
+ {
+ return null;
+ }
+ final PlexusBeanMetadata metadata = metadataMap.remove( implementation.getName() );
+ if ( metadataMap.isEmpty() )
+ {
+ metadataMap = null;
+ }
+ return metadata;
+ }
+ }
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/guice/XPlexusXmlBeanModule.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/lifecycle/XPlexusLifecycleManager.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/lifecycle/XPlexusLifecycleManager.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/lifecycle/XPlexusLifecycleManager.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/lifecycle/XPlexusLifecycleManager.java Tue May 17 16:57:50 2011
@@ -0,0 +1,293 @@
+/**
+ * Copyright (c) 2009 Sonatype, Inc. All rights reserved.
+ *
+ * This program is licensed to you under the Apache License Version 2.0,
+ * and you may not use this file except in compliance with the Apache License Version 2.0.
+ * You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the Apache License Version 2.0 is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
+ */
+package org.apache.maven.mae.internal.container.lifecycle;
+
+import org.codehaus.plexus.MutablePlexusContainer;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.context.Context;
+import org.codehaus.plexus.context.ContextException;
+import org.codehaus.plexus.logging.LogEnabled;
+import org.codehaus.plexus.logging.Logger;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Disposable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Startable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.StartingException;
+import org.sonatype.guice.bean.inject.PropertyBinding;
+import org.sonatype.guice.bean.reflect.BeanProperty;
+import org.sonatype.guice.plexus.binders.PlexusBeanManager;
+
+import com.google.inject.ProvisionException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link PlexusBeanManager} that manages Plexus components requiring lifecycle management.
+ */
+public final class XPlexusLifecycleManager
+ implements PlexusBeanManager
+{
+ // ----------------------------------------------------------------------
+ // Implementation fields
+ // ----------------------------------------------------------------------
+
+ private final List<Startable> startableBeans = new ArrayList<Startable>();
+
+ private final List<Disposable> disposableBeans = new ArrayList<Disposable>();
+
+ private final MutablePlexusContainer container;
+
+ private final Context context;
+
+ // ----------------------------------------------------------------------
+ // Constructors
+ // ----------------------------------------------------------------------
+
+ public XPlexusLifecycleManager( final MutablePlexusContainer container, final Context context )
+ {
+ this.container = container;
+ this.context = context;
+ }
+
+ // ----------------------------------------------------------------------
+ // Public methods
+ // ----------------------------------------------------------------------
+
+ public boolean manage( final Class<?> clazz )
+ {
+ return LogEnabled.class.isAssignableFrom( clazz ) || Contextualizable.class.isAssignableFrom( clazz )
+ || Initializable.class.isAssignableFrom( clazz ) || Startable.class.isAssignableFrom( clazz )
+ || Disposable.class.isAssignableFrom( clazz );
+ }
+
+ @SuppressWarnings( "rawtypes" )
+ public PropertyBinding manage( final BeanProperty property )
+ {
+ final Class clazz = property.getType().getRawType();
+ if ( "org.slf4j.Logger".equals( clazz.getName() ) )
+ {
+ return new PropertyBinding()
+ {
+ @SuppressWarnings( "unchecked" )
+ public <B> void injectProperty( final B bean )
+ {
+ property.set( bean, org.slf4j.LoggerFactory.getLogger( bean.getClass() ) );
+ }
+ };
+ }
+ if ( Logger.class.equals( clazz ) )
+ {
+ return new PropertyBinding()
+ {
+ @SuppressWarnings( "unchecked" )
+ public <B> void injectProperty( final B bean )
+ {
+ property.set( bean, getPlexusLogger( bean ) );
+ }
+ };
+ }
+ return null;
+ }
+
+ public synchronized boolean manage( final Object bean )
+ {
+ final boolean isStartable = bean instanceof Startable;
+ final boolean isContextualizable = bean instanceof Contextualizable;
+ final boolean isInitializable = bean instanceof Initializable;
+ final boolean isDisposable = bean instanceof Disposable;
+
+ /*
+ * Record this information before starting, in case there's a problem
+ */
+ if ( isStartable )
+ {
+ startableBeans.add( (Startable) bean );
+ }
+
+ if ( isDisposable )
+ {
+ disposableBeans.add( (Disposable) bean );
+ }
+
+ if ( bean instanceof LogEnabled )
+ {
+ ( (LogEnabled) bean ).enableLogging( getPlexusLogger( bean ) );
+ }
+
+ /*
+ * Run through the startup phase of the standard plexus "personality"
+ */
+ if ( isContextualizable || isInitializable || isStartable )
+ {
+ final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+ try
+ {
+ for ( Class<?> clazz = bean.getClass(); clazz != null; clazz = clazz.getSuperclass() )
+ {
+ // need to check hierarchy in case bean is proxied
+ final ClassLoader loader = clazz.getClassLoader();
+ if ( loader instanceof ClassRealm )
+ {
+ Thread.currentThread().setContextClassLoader( loader );
+ break;
+ }
+ }
+
+ if ( isContextualizable )
+ {
+ contextualize( (Contextualizable) bean );
+ }
+
+ if ( isInitializable )
+ {
+ initialize( (Initializable) bean );
+ }
+
+ if ( isStartable )
+ {
+ start( (Startable) bean );
+ }
+ }
+ finally
+ {
+ Thread.currentThread().setContextClassLoader( tccl );
+ }
+ }
+
+ return true;
+ }
+
+ public synchronized boolean unmanage( final Object bean )
+ {
+ if ( startableBeans.remove( bean ) )
+ {
+ stop( (Startable) bean );
+ }
+
+ if ( disposableBeans.remove( bean ) )
+ {
+ dispose( (Disposable) bean );
+ }
+
+ return true;
+ }
+
+ public synchronized boolean unmanage()
+ {
+ // unmanage beans in reverse order
+ while ( !startableBeans.isEmpty() )
+ {
+ stop( startableBeans.remove( startableBeans.size() - 1 ) );
+ }
+
+ while ( !disposableBeans.isEmpty() )
+ {
+ dispose( disposableBeans.remove( disposableBeans.size() - 1 ) );
+ }
+
+ return true;
+ }
+
+ public PlexusBeanManager manageChild()
+ {
+ return this;
+ }
+
+ // ----------------------------------------------------------------------
+ // Shared implementation methods
+ // ----------------------------------------------------------------------
+
+ Logger getPlexusLogger( final Object bean )
+ {
+ return container.getLoggerManager().getLoggerForComponent( bean.getClass().getName(), null );
+ }
+
+ // ----------------------------------------------------------------------
+ // Implementation methods
+ // ----------------------------------------------------------------------
+
+ private void contextualize( final Contextualizable bean )
+ {
+ try
+ {
+ bean.contextualize( context );
+ }
+ catch ( final ContextException e )
+ {
+ throw new ProvisionException( "Error contextualizing: " + bean.getClass(), e );
+ }
+ }
+
+ private static void initialize( final Initializable bean )
+ {
+ try
+ {
+ bean.initialize();
+ }
+ catch ( final InitializationException e )
+ {
+ throw new ProvisionException( "Error initializing: " + bean.getClass(), e );
+ }
+ }
+
+ private static void start( final Startable bean )
+ {
+ try
+ {
+ bean.start();
+ }
+ catch ( final StartingException e )
+ {
+ throw new ProvisionException( "Error starting: " + bean.getClass(), e );
+ }
+ }
+
+ private void stop( final Startable bean )
+ {
+ try
+ {
+ bean.stop();
+ }
+ catch ( final Throwable e )
+ {
+ warn( "Problem stopping: " + bean.getClass(), e );
+ }
+ }
+
+ private void dispose( final Disposable bean )
+ {
+ try
+ {
+ bean.dispose();
+ }
+ catch ( final Throwable e )
+ {
+ warn( "Problem disposing: " + bean.getClass(), e );
+ }
+ }
+
+ private void warn( final String message, final Throwable cause )
+ {
+ try
+ {
+ container.getLogger().warn( message, cause );
+ }
+ catch ( final Throwable ignore )
+ {
+ System.err.println( message );
+ cause.printStackTrace();
+ }
+ }
+}
Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/apache/maven/mae/internal/container/lifecycle/XPlexusLifecycleManager.java
------------------------------------------------------------------------------
svn:eol-style = native