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 [6/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/sonatype/guice/bean/locators/MAEBeanLocator.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/MAEBeanLocator.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/MAEBeanLocator.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/MAEBeanLocator.java Tue May 17 16:57:50 2011
@@ -0,0 +1,213 @@
+/**
+ * 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.sonatype.guice.bean.locators;
+
+import org.sonatype.guice.bean.locators.BeanLocator;
+import org.sonatype.guice.bean.locators.DefaultRankingFunction;
+import org.sonatype.guice.bean.locators.InjectorPublisher;
+import org.sonatype.guice.bean.locators.XLocatedBeans;
+import org.sonatype.guice.bean.locators.MutableBeanLocator;
+import org.sonatype.guice.bean.locators.XRankedBindings;
+import org.sonatype.guice.bean.locators.RankedList;
+import org.sonatype.guice.bean.locators.RankingFunction;
+import org.sonatype.guice.bean.locators.spi.BindingDistributor;
+import org.sonatype.guice.bean.locators.spi.BindingPublisher;
+import org.sonatype.inject.BeanEntry;
+import org.sonatype.inject.Mediator;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Default {@link BeanLocator} that locates qualified beans across a dynamic group of {@link Injector}s.
+ */
+@Singleton
+@SuppressWarnings( { "rawtypes", "unchecked" } )
+public final class MAEBeanLocator
+    implements MutableBeanLocator
+{
+    // ----------------------------------------------------------------------
+    // Implementation fields
+    // ----------------------------------------------------------------------
+
+    private final RankedList<BindingPublisher> publishers = new RankedList<BindingPublisher>();
+
+    private final Map<TypeLiteral, XRankedBindings> bindingsCache = new HashMap<TypeLiteral, XRankedBindings>();
+
+    private final List<XWatchedBeans> watchedBeans = new ArrayList<XWatchedBeans>();
+    
+    // ----------------------------------------------------------------------
+    // Public methods
+    // ----------------------------------------------------------------------
+    
+    public synchronized Iterable<BeanEntry> locate( final Key key )
+    {
+        return new XLocatedBeans( key, bindingsForType( key.getTypeLiteral() ) );
+    }
+
+    public synchronized void watch( final Key key, final Mediator mediator, final Object watcher )
+    {
+        final XWatchedBeans beans = new XWatchedBeans( key, mediator, watcher );
+        for ( int i = 0, size = publishers.size(); i < size; i++ )
+        {
+            beans.add( publishers.get( i ), 0 /* unused */);
+        }
+        watchedBeans.add( beans );
+    }
+
+    public void add( final Injector injector, final int rank )
+    {
+        add( new InjectorPublisher( injector, new DefaultRankingFunction( rank ) ), rank );
+    }
+
+    public void remove( final Injector injector )
+    {
+        remove( new InjectorPublisher( injector, null ) );
+    }
+
+    public synchronized void add( final BindingPublisher publisher, final int rank )
+    {
+        if ( !publishers.contains( publisher ) )
+        {
+            publishers.insert( publisher, rank );
+            distribute( BindingEvent.ADD, publisher, rank );
+        }
+    }
+
+    public synchronized void remove( final BindingPublisher publisher )
+    {
+        if ( publishers.remove( publisher ) )
+        {
+            distribute( BindingEvent.REMOVE, publisher, 0 );
+        }
+    }
+
+    public synchronized void clear()
+    {
+        publishers.clear();
+        distribute( BindingEvent.CLEAR, null, 0 );
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Automatically publishes any {@link Injector} that contains a binding to this {@link BeanLocator}.
+     * 
+     * @param injector The injector
+     */
+    @Inject
+    void autoPublish( final Injector injector )
+    {
+        final RankingFunction function = injector.getInstance( RankingFunction.class );
+        add( new InjectorPublisher( injector, function ), function.maxRank() );
+    }
+
+    /**
+     * Returns the {@link XRankedBindings} tracking the given type; creates one if it doesn't already exist.
+     * 
+     * @param type The required type
+     * @return Sequence of ranked bindings
+     */
+    private <T> XRankedBindings<T> bindingsForType( final TypeLiteral<T> type )
+    {
+        XRankedBindings<T> bindings = bindingsCache.get( type );
+        if ( null == bindings )
+        {
+            bindings = new XRankedBindings<T>( type, publishers );
+            bindingsCache.put( type, bindings );
+        }
+        return bindings;
+    }
+
+    /**
+     * Distributes the given binding event to interested parties.
+     * 
+     * @param event The binding event
+     * @param publisher The optional publisher
+     * @param rank The optional assigned rank
+     */
+    private void distribute( final BindingEvent event, final BindingPublisher publisher, final int rank )
+    {
+        for ( final Iterator<XRankedBindings> itr = bindingsCache.values().iterator(); itr.hasNext(); )
+        {
+            final XRankedBindings bindings = itr.next();
+            if ( bindings.isActive() )
+            {
+                notify( bindings, event, publisher, rank );
+            }
+            else
+            {
+                itr.remove(); // cleanup up stale entries
+            }
+        }
+
+        for ( int i = 0; i < watchedBeans.size(); i++ )
+        {
+            final XWatchedBeans beans = watchedBeans.get( i );
+            if ( beans.isActive() )
+            {
+                notify( beans, event, publisher, rank );
+            }
+            else
+            {
+                watchedBeans.remove( i-- ); // cleanup up stale entries
+            }
+        }
+    }
+
+    /**
+     * Notifies the given distributor of the given binding event and its optional details.
+     * 
+     * @param distributor The distributor
+     * @param event The binding event
+     * @param publisher The optional publisher
+     * @param rank The optional assigned rank
+     */
+    private static void notify( final BindingDistributor distributor, final BindingEvent event,
+                                final BindingPublisher publisher, final int rank )
+    {
+        switch ( event )
+        {
+            case ADD:
+                distributor.add( publisher, rank );
+                break;
+            case REMOVE:
+                distributor.remove( publisher );
+                break;
+            case CLEAR:
+                distributor.clear();
+                break;
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation types
+    // ----------------------------------------------------------------------
+
+    private static enum BindingEvent
+    {
+        ADD, REMOVE, CLEAR
+    }
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/MAEBeanLocator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XLocatedBeans.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XLocatedBeans.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XLocatedBeans.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XLocatedBeans.java Tue May 17 16:57:50 2011
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ *   http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ *   http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+package org.sonatype.guice.bean.locators;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import org.apache.maven.mae.internal.container.ComponentKey;
+import org.sonatype.inject.BeanEntry;
+
+import com.google.inject.Binding;
+import com.google.inject.Key;
+
+import javax.inject.Named;
+
+/**
+ * Provides a sequence of {@link BeanEntry}s by iterating over qualified {@link Binding}s.
+ * 
+ * @see BeanLocator#locate(Key)
+ */
+final class XLocatedBeans<Q extends Annotation, T>
+    implements Iterable<BeanEntry<Q, T>>
+{
+    // ----------------------------------------------------------------------
+    // Implementation fields
+    // ----------------------------------------------------------------------
+
+    final Key<T> key;
+
+    final XRankedBindings<T> bindings;
+
+    final QualifyingStrategy strategy;
+
+    Map<Binding<T>, BeanEntry<Q, T>> beanCache;
+
+    // ----------------------------------------------------------------------
+    // Constructors
+    // ----------------------------------------------------------------------
+
+    XLocatedBeans( final Key<T> key, final XRankedBindings<T> bindings )
+    {
+        this.key = key;
+        this.bindings = bindings;
+
+        strategy = QualifyingStrategy.selectFor( key );
+
+        bindings.linkToBeans( this );
+    }
+
+    // ----------------------------------------------------------------------
+    // Public methods
+    // ----------------------------------------------------------------------
+
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public synchronized Iterator<BeanEntry<Q, T>> iterator()
+    {
+        return new Itr( null != beanCache ? new IdentityHashMap( beanCache ) : Collections.EMPTY_MAP );
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Evict any stale {@link BeanEntry}s from this collection; an entry is stale if its binding is gone.
+     * 
+     * @param activeBindings The active bindings
+     */
+    synchronized void retainAll( final RankedList<Binding<T>> activeBindings )
+    {
+        if ( null != beanCache )
+        {
+            for ( final Binding<T> b : new ArrayList<Binding<T>>( beanCache.keySet() ) )
+            {
+                if ( activeBindings.indexOfThis( b ) < 0 )
+                {
+                    beanCache.remove( b );
+                }
+            }
+        }
+    }
+
+    /**
+     * Caches a {@link BeanEntry} for the given qualified binding; returns existing entry if already cached.
+     * 
+     * @param qualifier The qualifier
+     * @param binding The binding
+     * @param rank The assigned rank
+     * @return Cached bean entry
+     */
+    synchronized BeanEntry<Q, T> cacheBean( final Q qualifier, final Binding<T> binding, final int rank )
+    {
+        if ( null == beanCache )
+        {
+            beanCache = new IdentityHashMap<Binding<T>, BeanEntry<Q, T>>();
+        }
+        BeanEntry<Q, T> bean = beanCache.get( binding );
+        if ( null == bean )
+        {
+            bean = new LazyBeanEntry<Q, T>( qualifier, binding, rank );
+            beanCache.put( binding, bean );
+        }
+        return bean;
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation types
+    // ----------------------------------------------------------------------
+
+    /**
+     * {@link BeanEntry} iterator that creates new elements from {@link Binding}s as required.
+     */
+    private final class Itr
+        implements Iterator<BeanEntry<Q, T>>
+    {
+        // ----------------------------------------------------------------------
+        // Implementation fields
+        // ----------------------------------------------------------------------
+
+        private final XRankedBindings<T>.Itr itr = bindings.iterator();
+
+        private final Map<Binding<T>, BeanEntry<Q, T>> readCache;
+
+        private BeanEntry<Q, T> nextBean;
+
+        // ----------------------------------------------------------------------
+        // Constructors
+        // ----------------------------------------------------------------------
+
+        Itr( final Map<Binding<T>, BeanEntry<Q, T>> readCache )
+        {
+            this.readCache = readCache;
+        }
+
+        // ----------------------------------------------------------------------
+        // Public methods
+        // ----------------------------------------------------------------------
+
+        public boolean hasNext()
+        {
+            if ( null != nextBean )
+            {
+                return true;
+            }
+            while ( itr.hasNext() )
+            {
+                final Binding<T> binding = itr.next();
+                nextBean = readCache.get( binding );
+                if ( null != nextBean )
+                {
+                    return true;
+                }
+                @SuppressWarnings( "unchecked" )
+                final Q qualifier = (Q) strategy.qualifies( key, binding );
+                
+                String name = null;
+                if ( key.getAnnotation() == null )
+                {
+                    if ( qualifier instanceof Named )
+                    {
+                        name = ((Named)qualifier).value();
+                    }
+                    else if ( qualifier instanceof com.google.inject.name.Named )
+                    {
+                        name = ((com.google.inject.name.Named)qualifier).value();
+                    }
+                }
+                
+                if ( null != qualifier && ( null == name || !ComponentKey.isLiteral( name ) ) )
+                {
+                    nextBean = cacheBean( qualifier, binding, itr.rank() );
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public BeanEntry<Q, T> next()
+        {
+            if ( hasNext() )
+            {
+                // populated by hasNext()
+                final BeanEntry<Q, T> bean = nextBean;
+                nextBean = null;
+                return bean;
+            }
+            throw new NoSuchElementException();
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+    }
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XLocatedBeans.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XRankedBindings.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XRankedBindings.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XRankedBindings.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XRankedBindings.java Tue May 17 16:57:50 2011
@@ -0,0 +1,253 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2011 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ *   http://www.eclipse.org/legal/epl-v10.html
+ * The Apache License v2.0 is available at
+ *   http://www.apache.org/licenses/LICENSE-2.0.html
+ * You may elect to redistribute this code under either of these licenses.
+ *******************************************************************************/
+package org.sonatype.guice.bean.locators;
+
+import java.lang.annotation.Annotation;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.sonatype.guice.bean.locators.spi.BindingDistributor;
+import org.sonatype.guice.bean.locators.spi.BindingPublisher;
+import org.sonatype.guice.bean.locators.spi.BindingSubscriber;
+
+import com.google.inject.Binding;
+import com.google.inject.TypeLiteral;
+
+/**
+ * Ordered sequence of {@link Binding}s of a given type; subscribes to {@link BindingPublisher}s on demand.
+ */
+final class XRankedBindings<T>
+    implements Iterable<Binding<T>>, BindingDistributor, BindingSubscriber
+{
+    // ----------------------------------------------------------------------
+    // Implementation fields
+    // ----------------------------------------------------------------------
+
+    final RankedList<Binding<T>> bindings = new RankedList<Binding<T>>();
+
+    final List<Reference<XLocatedBeans<?, T>>> locatedBeanRefs = new ArrayList<Reference<XLocatedBeans<?, T>>>();
+
+    final RankedList<BindingPublisher> pendingPublishers;
+
+    final TypeLiteral<T> type;
+
+    // ----------------------------------------------------------------------
+    // Constructors
+    // ----------------------------------------------------------------------
+
+    XRankedBindings( final TypeLiteral<T> type, final RankedList<BindingPublisher> publishers )
+    {
+        pendingPublishers = null != publishers ? publishers.clone() : new RankedList<BindingPublisher>();
+        this.type = type;
+    }
+
+    // ----------------------------------------------------------------------
+    // Public methods
+    // ----------------------------------------------------------------------
+
+    public void add( final BindingPublisher publisher, final int rank )
+    {
+        synchronized ( pendingPublishers )
+        {
+            pendingPublishers.insert( publisher, rank );
+        }
+    }
+
+    public void remove( final BindingPublisher publisher )
+    {
+        synchronized ( pendingPublishers )
+        {
+            // extra cleanup if we're already subscribed
+            if ( !pendingPublishers.remove( publisher ) )
+            {
+                publisher.unsubscribe( type, this );
+                synchronized ( bindings )
+                {
+                    boolean updated = false;
+                    for ( int i = 0; i < bindings.size(); i++ )
+                    {
+                        if ( publisher.contains( bindings.get( i ) ) )
+                        {
+                            bindings.remove( i-- );
+                            updated = true;
+                        }
+                    }
+                    if ( updated )
+                    {
+                        evictStaleBeanEntries();
+                    }
+                }
+            }
+        }
+    }
+
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public void add( final Binding binding, final int rank )
+    {
+        synchronized ( bindings )
+        {
+            bindings.insert( binding, rank );
+        }
+    }
+
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public void remove( final Binding binding )
+    {
+        synchronized ( bindings )
+        {
+            // we only want to remove this _exact_ instance
+            final int index = bindings.indexOfThis( binding );
+            if ( index >= 0 )
+            {
+                bindings.remove( index );
+            }
+        }
+    }
+
+    public void clear()
+    {
+        synchronized ( pendingPublishers )
+        {
+            pendingPublishers.clear();
+            synchronized ( bindings )
+            {
+                bindings.clear();
+                evictStaleBeanEntries();
+            }
+        }
+    }
+
+    public Itr iterator()
+    {
+        return new Itr();
+    }
+
+    // ----------------------------------------------------------------------
+    // Local methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Associates the given {@link LocatedBeans} with this binding sequence so stale beans can be eagerly evicted.
+     * 
+     * @param beans The located beans
+     */
+    <Q extends Annotation> void linkToBeans( final XLocatedBeans<Q, T> beans )
+    {
+        synchronized ( locatedBeanRefs )
+        {
+            locatedBeanRefs.add( new WeakReference<XLocatedBeans<?, T>>( beans ) );
+        }
+    }
+
+    /**
+     * @return {@code true} if this binding sequence is still associated with active beans; otherwise {@code false}
+     */
+    boolean isActive()
+    {
+        boolean isActive = false;
+        synchronized ( locatedBeanRefs )
+        {
+            for ( int i = 0; i < locatedBeanRefs.size(); i++ )
+            {
+                if ( null != locatedBeanRefs.get( i ).get() )
+                {
+                    isActive = true;
+                }
+                else
+                {
+                    locatedBeanRefs.remove( i-- );
+                }
+            }
+        }
+        return isActive;
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Evicts any stale bean entries from the associated {@link LocatedBeans}.
+     */
+    private void evictStaleBeanEntries()
+    {
+        synchronized ( locatedBeanRefs )
+        {
+            for ( int i = 0, size = locatedBeanRefs.size(); i < size; i++ )
+            {
+                final XLocatedBeans<?, T> beans = locatedBeanRefs.get( i ).get();
+                if ( null != beans )
+                {
+                    beans.retainAll( bindings );
+                }
+            }
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation types
+    // ----------------------------------------------------------------------
+
+    /**
+     * {@link Binding} iterator that only subscribes to {@link BindingPublisher}s as required.
+     */
+    final class Itr
+        implements Iterator<Binding<T>>
+    {
+        // ----------------------------------------------------------------------
+        // Implementation fields
+        // ----------------------------------------------------------------------
+
+        private final RankedList<Binding<T>>.Itr itr = bindings.iterator();
+
+        // ----------------------------------------------------------------------
+        // Public methods
+        // ----------------------------------------------------------------------
+
+        public boolean hasNext()
+        {
+            if ( pendingPublishers.size() > 0 )
+            {
+                synchronized ( pendingPublishers )
+                {
+                    // check whether the next publisher _might_ contain a higher ranked binding, and if so use it
+                    while ( pendingPublishers.size() > 0 && pendingPublishers.getRank( 0 ) > itr.peekNextRank() )
+                    {
+                        // be careful not to remove the pending publisher until after it's used
+                        // otherwise another iterator could skip past the initial size() check!
+                        pendingPublishers.get( 0 ).subscribe( type, XRankedBindings.this );
+                        pendingPublishers.remove( 0 );
+                    }
+                }
+            }
+            return itr.hasNext();
+        }
+
+        public Binding<T> next()
+        {
+            return itr.next();
+        }
+
+        public int rank()
+        {
+            return itr.rank();
+        }
+
+        public void remove()
+        {
+            throw new UnsupportedOperationException();
+        }
+    }
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XRankedBindings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XWatchedBeans.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XWatchedBeans.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XWatchedBeans.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XWatchedBeans.java Tue May 17 16:57:50 2011
@@ -0,0 +1,177 @@
+/**
+ * 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.sonatype.guice.bean.locators;
+
+import org.sonatype.guice.bean.locators.BeanLocator;
+import org.sonatype.guice.bean.locators.LazyBeanEntry;
+import org.sonatype.guice.bean.locators.QualifyingStrategy;
+import org.sonatype.guice.bean.locators.spi.BindingDistributor;
+import org.sonatype.guice.bean.locators.spi.BindingPublisher;
+import org.sonatype.guice.bean.locators.spi.BindingSubscriber;
+import org.sonatype.guice.bean.reflect.Logs;
+import org.sonatype.inject.BeanEntry;
+import org.sonatype.inject.Mediator;
+
+import com.google.inject.Binding;
+import com.google.inject.Key;
+
+import java.lang.annotation.Annotation;
+import java.lang.ref.Reference;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+/**
+ * Provides dynamic {@link BeanEntry} notifications by tracking qualified {@link Binding}s.
+ * 
+ * @see BeanLocator#watch(Key, Mediator, Object)
+ */
+final class XWatchedBeans<Q extends Annotation, T, W>
+    implements BindingDistributor, BindingSubscriber
+{
+    // ----------------------------------------------------------------------
+    // Implementation fields
+    // ----------------------------------------------------------------------
+
+    private final Map<Binding<T>, BeanEntry<Q, T>> beanCache = new IdentityHashMap<Binding<T>, BeanEntry<Q, T>>();
+
+    private final Key<T> key;
+
+    private final Mediator<Q, T, W> mediator;
+
+    private final QualifyingStrategy strategy;
+
+    private final Reference<W> watcherRef;
+
+    // ----------------------------------------------------------------------
+    // Constructors
+    // ----------------------------------------------------------------------
+
+    XWatchedBeans( final Key<T> key, final Mediator<Q, T, W> mediator, final W watcher )
+    {
+        this.key = key;
+        this.mediator = mediator;
+
+        strategy = QualifyingStrategy.selectFor( key );
+        watcherRef = new WeakReference<W>( watcher );
+    }
+
+    // ----------------------------------------------------------------------
+    // Public methods
+    // ----------------------------------------------------------------------
+
+    public synchronized void add( final BindingPublisher publisher, final int rank )
+    {
+        publisher.subscribe( key.getTypeLiteral(), this );
+    }
+
+    public synchronized void remove( final BindingPublisher publisher )
+    {
+        publisher.unsubscribe( key.getTypeLiteral(), this );
+
+        for ( final Binding<T> b : new ArrayList<Binding<T>>( beanCache.keySet() ) )
+        {
+            if ( publisher.contains( b ) )
+            {
+                notify( WatcherEvent.REMOVE, beanCache.remove( b ) );
+            }
+        }
+    }
+
+    @SuppressWarnings( { "rawtypes", "unchecked" } )
+    public synchronized void add( final Binding binding, final int rank )
+    {
+        final Q qualifier = (Q) strategy.qualifies( key, binding );
+        if ( null != qualifier )
+        {
+            final BeanEntry<Q, T> bean = new LazyBeanEntry<Q, T>( qualifier, binding, rank );
+            beanCache.put( binding, bean );
+            notify( WatcherEvent.ADD, bean );
+        }
+    }
+
+    @SuppressWarnings( "rawtypes" )
+    public synchronized void remove( final Binding binding )
+    {
+        final BeanEntry<Q, T> bean = beanCache.remove( binding );
+        if ( null != bean )
+        {
+            notify( WatcherEvent.REMOVE, bean );
+        }
+    }
+
+    public synchronized void clear()
+    {
+        for ( final BeanEntry<Q, T> bean : beanCache.values() )
+        {
+            notify( WatcherEvent.REMOVE, bean );
+        }
+        beanCache.clear();
+    }
+
+    // ----------------------------------------------------------------------
+    // Local methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * @return {@code true} if these watched beans are still in use; otherwise {@code false}
+     */
+    boolean isActive()
+    {
+        return null != watcherRef.get();
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation methods
+    // ----------------------------------------------------------------------
+
+    /**
+     * Notifies the watching object of the given watcher event; uses the {@link Mediator} pattern.
+     * 
+     * @param event The watcher event
+     * @param bean The bean entry
+     */
+    private void notify( final WatcherEvent event, final BeanEntry<Q, T> bean )
+    {
+        final W watcher = watcherRef.get();
+        if ( null != watcher )
+        {
+            try
+            {
+                switch ( event )
+                {
+                    case ADD:
+                        mediator.add( bean, watcher );
+                        break;
+                    case REMOVE:
+                        mediator.remove( bean, watcher );
+                        break;
+                }
+            }
+            catch ( final Throwable e )
+            {
+                Logs.warn( mediator.getClass(), "Problem notifying: " + watcher.getClass(), e );
+            }
+        }
+    }
+
+    // ----------------------------------------------------------------------
+    // Implementation types
+    // ----------------------------------------------------------------------
+
+    private static enum WatcherEvent
+    {
+        ADD, REMOVE
+    }
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/bean/locators/XWatchedBeans.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/plexus/locators/MAEPlexusBeanLocator.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/plexus/locators/MAEPlexusBeanLocator.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/plexus/locators/MAEPlexusBeanLocator.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/plexus/locators/MAEPlexusBeanLocator.java Tue May 17 16:57:50 2011
@@ -0,0 +1,80 @@
+/**
+ * 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.sonatype.guice.plexus.locators;
+
+import org.sonatype.guice.bean.locators.BeanLocator;
+import org.sonatype.guice.plexus.config.PlexusBean;
+import org.sonatype.guice.plexus.config.PlexusBeanLocator;
+import org.sonatype.inject.BeanEntry;
+
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import com.google.inject.name.Named;
+import com.google.inject.name.Names;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/**
+ * {@link PlexusBeanLocator} that locates beans of various types from zero or more {@link Injector}s.
+ */
+@Singleton
+public final class MAEPlexusBeanLocator
+    implements PlexusBeanLocator
+{
+    // ----------------------------------------------------------------------
+    // Constants
+    // ----------------------------------------------------------------------
+
+    private static final String REALM_VISIBILITY = "realm";
+
+    // ----------------------------------------------------------------------
+    // Implementation fields
+    // ----------------------------------------------------------------------
+
+    private final BeanLocator beanLocator;
+
+    private final String visibility;
+
+    // ----------------------------------------------------------------------
+    // Constructors
+    // ----------------------------------------------------------------------
+
+    @Inject
+    public MAEPlexusBeanLocator( final BeanLocator beanLocator )
+    {
+        this( beanLocator, REALM_VISIBILITY );
+    }
+
+    public MAEPlexusBeanLocator( final BeanLocator beanLocator, final String visibility )
+    {
+        this.beanLocator = beanLocator;
+        this.visibility = visibility;
+    }
+
+    // ----------------------------------------------------------------------
+    // Public methods
+    // ----------------------------------------------------------------------
+
+    public <T> Iterable<PlexusBean<T>> locate( final TypeLiteral<T> role, final String... hints )
+    {
+        final Key<T> key = hints.length == 1 ? Key.get( role, Names.named( hints[0] ) ) : Key.get( role, Named.class );
+        Iterable<BeanEntry<Named, T>> beans = beanLocator.locate( key );
+        if ( REALM_VISIBILITY.equalsIgnoreCase( visibility ) )
+        {
+            beans = new RealmFilter<T>( beans );
+        }
+        return hints.length <= 1 ? new DefaultPlexusBeans<T>( beans ) : new HintedPlexusBeans<T>( beans, role, hints );
+    }
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/main/java/org/sonatype/guice/plexus/locators/MAEPlexusBeanLocator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/MAEPlexusContainerTest.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/MAEPlexusContainerTest.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/MAEPlexusContainerTest.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/MAEPlexusContainerTest.java Tue May 17 16:57:50 2011
@@ -0,0 +1,112 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import org.apache.maven.mae.internal.container.MAEContainer;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
+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.fixture.Child;
+import org.apache.maven.mae.internal.container.fixture.DefaultSingletonOwner;
+import org.apache.maven.mae.internal.container.fixture.InitializedUsingRequirement;
+import org.apache.maven.mae.internal.container.fixture.MapOwner;
+import org.apache.maven.mae.internal.container.fixture.SingletonLiteralOwner;
+import org.apache.maven.mae.internal.container.fixture.SingletonOwner;
+import org.junit.Test;
+
+import java.util.Map;
+
+public class MAEPlexusContainerTest
+{
+    @Test
+    public void mappedRequirementContainsNoLiteralIds()
+        throws Throwable
+    {
+        final ContainerConfiguration config = new DefaultContainerConfiguration().setClassPathScanning( "ON" );
+
+        final MAEContainer container =
+            new MAEContainer( config, new ComponentSelector(), new InstanceRegistry() );
+
+        final MapOwner mapOwner = container.lookup( MapOwner.class );
+        final Map<String, Child> members = mapOwner.members();
+
+        System.out.println( members );
+
+        assertNull( members.get( "simple" + ComponentKey.LITERAL_SUFFIX ) );
+    }
+
+    @Test
+    public void singletonImpliedRequirementOnComponentWithImpliedHint()
+        throws Throwable
+    {
+        final ContainerConfiguration config = new DefaultContainerConfiguration().setClassPathScanning( "ON" );
+
+        final MAEContainer container =
+            new MAEContainer( config, new ComponentSelector(), new InstanceRegistry() );
+
+        final DefaultSingletonOwner owner = container.lookup( DefaultSingletonOwner.class );
+
+        assertNotNull( owner.singleton() );
+    }
+
+    @Test
+    public void singletonNonLiteralRequirement()
+        throws Throwable
+    {
+        final ContainerConfiguration config = new DefaultContainerConfiguration().setClassPathScanning( "ON" );
+
+        final MAEContainer container =
+            new MAEContainer( config, new ComponentSelector(), new InstanceRegistry() );
+
+        final SingletonOwner owner = container.lookup( SingletonOwner.class );
+
+        assertNotNull( owner.singleton() );
+    }
+
+    @Test
+    public void singletonLiteralRequirement()
+        throws Throwable
+    {
+        final ContainerConfiguration config = new DefaultContainerConfiguration().setClassPathScanning( "ON" );
+
+        final MAEContainer container =
+            new MAEContainer( config, new ComponentSelector(), new InstanceRegistry() );
+
+        final SingletonLiteralOwner owner = container.lookup( SingletonLiteralOwner.class );
+
+        assertNotNull( owner.singletonLiteral() );
+    }
+
+    @Test
+    public void initializableUsingRequirement()
+        throws Throwable
+    {
+        final ContainerConfiguration config = new DefaultContainerConfiguration().setClassPathScanning( "ON" );
+
+        final MAEContainer container =
+            new MAEContainer( config, new ComponentSelector(), new InstanceRegistry() );
+
+        container.lookup( InitializedUsingRequirement.class );
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/MAEPlexusContainerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/Child.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/Child.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/Child.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/Child.java Tue May 17 16:57:50 2011
@@ -0,0 +1,26 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+
+@Component( role = Child.class, hint = "simple" )
+public class Child
+{
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/Child.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultChild.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultChild.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultChild.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultChild.java Tue May 17 16:57:50 2011
@@ -0,0 +1,25 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+
+@Component( role = DefaultChild.class )
+public class DefaultChild
+{
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultChild.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultSingletonOwner.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultSingletonOwner.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultSingletonOwner.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultSingletonOwner.java Tue May 17 16:57:50 2011
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = DefaultSingletonOwner.class )
+public class DefaultSingletonOwner
+{
+
+    @Requirement
+    private DefaultChild singleton;
+
+    public DefaultChild singleton()
+    {
+        return singleton;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/DefaultSingletonOwner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/InitializedUsingRequirement.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/InitializedUsingRequirement.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/InitializedUsingRequirement.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/InitializedUsingRequirement.java Tue May 17 16:57:50 2011
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
+import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
+
+@Component( role = InitializedUsingRequirement.class )
+public class InitializedUsingRequirement
+    implements Initializable
+{
+
+    @Requirement
+    private DefaultChild child;
+
+    @Override
+    public void initialize()
+        throws InitializationException
+    {
+        System.out.println( child.toString() );
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/InitializedUsingRequirement.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/MapOwner.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/MapOwner.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/MapOwner.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/MapOwner.java Tue May 17 16:57:50 2011
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+import java.util.Map;
+
+@Component( role = MapOwner.class )
+public class MapOwner
+{
+
+    @Requirement( role = Child.class )
+    private Map<String, Child> members;
+
+    public Map<String, Child> members()
+    {
+        return members;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/MapOwner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonLiteralOwner.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonLiteralOwner.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonLiteralOwner.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonLiteralOwner.java Tue May 17 16:57:50 2011
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = SingletonLiteralOwner.class )
+public class SingletonLiteralOwner
+{
+
+    @Requirement( role = Child.class, hint = "simple_" )
+    private Child singletonLiteral;
+
+    public Child singletonLiteral()
+    {
+        return singletonLiteral;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonLiteralOwner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonOwner.java
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonOwner.java?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonOwner.java (added)
+++ maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonOwner.java Tue May 17 16:57:50 2011
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2010 John Casey.
+ *  
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package org.apache.maven.mae.internal.container.fixture;
+
+import org.codehaus.plexus.component.annotations.Component;
+import org.codehaus.plexus.component.annotations.Requirement;
+
+@Component( role = SingletonOwner.class )
+public class SingletonOwner
+{
+
+    @Requirement( role = Child.class, hint = "simple" )
+    private Child singleton;
+
+    public Child singleton()
+    {
+        return singleton;
+    }
+
+}

Propchange: maven/sandbox/trunk/mae/mae-container/src/test/java/org/apache/maven/mae/internal/container/fixture/SingletonOwner.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/sandbox/trunk/mae/pom.xml
URL: http://svn.apache.org/viewvc/maven/sandbox/trunk/mae/pom.xml?rev=1104405&view=auto
==============================================================================
--- maven/sandbox/trunk/mae/pom.xml (added)
+++ maven/sandbox/trunk/mae/pom.xml Tue May 17 16:57:50 2011
@@ -0,0 +1,366 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  
+  <!-- Setup Sonatype OSS deployment mechanism -->
+  <parent>
+    <groupId>org.apache.maven</groupId>
+    <artifactId>maven-parent</artifactId>
+    <version>19</version>
+  </parent>
+  
+  <groupId>org.apache.maven.mae</groupId>
+  <artifactId>mae</artifactId>
+  <version>0.6-SNAPSHOT</version>
+  
+  <packaging>pom</packaging>
+  
+  <name>Maven App Engine</name>
+  
+  <dependencyManagement>
+  	<dependencies>
+      <dependency>
+        <groupId>org.apache.maven</groupId>
+        <artifactId>maven</artifactId>
+        <version>${mavenVersion}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  
+  <properties>
+  	<mavenVersion>3.0.4-SNAPSHOT</mavenVersion>
+  	<plexusVersion>1.5.4</plexusVersion>
+  	<sisuVersion>2.1.1</sisuVersion>
+  </properties>
+  
+  <modules>
+    <module>boms</module>
+    <module>mae-api</module>
+    <module>mae-container</module>
+    <module>mae-booter</module>
+    <!-- <module>components</module>
+    <module>events</module>
+    <module>integration</module>
+    <module>distro</module> -->
+    <module>mae-app</module>
+  </modules>
+  
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/maven/sandbox/trunk/mae</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/maven/sandbox/trunk/mae</developerConnection>
+    <url>http://svn.apache.org/viewvc/maven/sandbox/trunk/mae</url>
+  </scm>
+  
+  <dependencies>
+    <dependency>
+      <groupId>org.commonjava.atservice</groupId>
+      <artifactId>atservice-annotation</artifactId>
+      <version>0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.commonjava.atservice</groupId>
+      <artifactId>atservice-processor</artifactId>
+      <version>0.1</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+    
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.codehaus.plexus</groupId>
+          <artifactId>plexus-component-metadata</artifactId>
+          <version>${plexusVersion}</version>
+          <executions>
+            <execution>
+            	<id>descriptors</id>
+            	<goals>
+                <goal>generate-metadata</goal>
+                <goal>generate-test-metadata</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <artifactId>maven-deploy-plugin</artifactId>
+          <version>2.5</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-release-plugin</artifactId>
+          <version>2.0</version>
+          <!-- <dependencies>
+            <dependency>
+              <groupId>org.apache.maven.scm</groupId>
+              <artifactId>maven-scm-provider-gitexe</artifactId>
+              <version>1.4</version>
+            </dependency>
+          </dependencies> -->
+          <configuration>
+            <autoVersionSubmodules>true</autoVersionSubmodules>
+          </configuration>
+        </plugin>
+        <plugin>
+          <artifactId>maven-resources-plugin</artifactId>
+          <version>2.4.2</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>2.5</version>
+          <configuration>
+            <excludes>
+              <exclude>**/testutil/*</exclude>
+              <!-- <exclude>**/fixture/*</exclude> -->
+            </excludes>
+          </configuration>
+        </plugin>
+        <plugin>
+          <artifactId>maven-shade-plugin</artifactId>
+          <version>1.3.1</version>
+          <executions>
+            <execution>
+              <id>shade-deps</id>
+              <phase>package</phase>
+              <goals>
+                <goal>shade</goal>
+              </goals>
+              <configuration>
+                <createDependencyReducedPom>false</createDependencyReducedPom>
+                <keepDependenciesWithProvidedScope>true</keepDependenciesWithProvidedScope>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>2.3</version>
+          <configuration>
+            <source>1.6</source>
+            <target>1.6</target>
+            <annotationProcessors>
+              <annotationProcessor>org.commonjava.atservice.processor.ServiceAnnotationProcessor</annotationProcessor>
+            </annotationProcessors>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <version>2.2</version>
+          <dependencies>
+            <dependency>
+              <groupId>org.commonjava.emb</groupId>
+              <artifactId>emb-assembly-descriptors</artifactId>
+              <version>0.5</version>
+            </dependency>
+          </dependencies>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-clean-plugin</artifactId>
+          <version>2.4</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-enforcer-plugin</artifactId>
+          <version>1.0-beta-1</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-gpg-plugin</artifactId>
+          <version>1.0-alpha-4</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-install-plugin</artifactId>
+          <version>2.3</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>2.3</version>
+          <configuration>
+            <archive>
+              <manifest>
+                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+              </manifest>
+            </archive>
+          </configuration>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-javadoc-plugin</artifactId>
+          <version>2.7</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-source-plugin</artifactId>
+          <version>2.1.1</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-remote-resources-plugin</artifactId>
+          <version>1.1</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-remote-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>process</goal>
+            </goals>
+            <phase>generate-resources</phase>
+            <configuration>
+              <resourceBundles>
+                <resourceBundle>org.apache:apache-jar-resource-bundle:1.4</resourceBundle>
+              </resourceBundles>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  
+  <reporting>
+    <plugins>
+      <plugin>
+        <artifactId>maven-project-info-reports-plugin</artifactId>
+        <version>2.1.2</version>
+      </plugin>
+    </plugins>
+  </reporting>
+  
+  <profiles>
+    <profile>
+      <id>apache-release</id>
+      <build>
+        <plugins>
+          <!-- Create a source-release artifact that contains the fully buildable 
+               project directory source structure. This is the artifact which is 
+               the official subject of any release vote. -->
+          <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <dependencies>
+              <dependency>
+                <groupId>org.apache.apache.resources</groupId>
+                <artifactId>apache-source-release-assembly-descriptor</artifactId>
+                <version>1.0.2</version>
+              </dependency>
+            </dependencies>
+            <executions>
+              <execution>
+                <id>source-release-assembly</id>
+                <phase>package</phase>
+                <goals>
+                  <goal>single</goal>
+                </goals>
+                <configuration>
+                  <runOnlyAtExecutionRoot>true</runOnlyAtExecutionRoot>
+                  <descriptorRefs>
+                    <descriptorRef>source-release</descriptorRef>
+                  </descriptorRefs>
+                  <tarLongFileFormat>gnu</tarLongFileFormat>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-gpg-plugin</artifactId>
+            <configuration>
+              <passphrase>${gpg.passphrase}</passphrase>
+            </configuration>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>sign</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <inherited>true</inherited>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-deploy-plugin</artifactId>
+            <configuration>
+              <updateReleaseInfo>true</updateReleaseInfo>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-source-plugin</artifactId>
+            <executions>
+              <execution>
+                <id>attach-sources</id>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-javadoc-plugin</artifactId>
+            <configuration>
+              <encoding>${project.build.sourceEncoding}</encoding>
+            </configuration>
+            <executions>
+              <execution>
+                <id>attach-javadocs</id>
+                <goals>
+                  <goal>jar</goal>
+                </goals>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>ci</id>
+      <distributionManagement>
+        <repository>
+          <id>nexus</id>
+          <name>CI Releases Repository</name>
+          <url>http://localhost:8081/nexus/content/repositories/releases</url>
+        </repository>
+        <snapshotRepository>
+          <id>nexus</id>
+          <name>CI Snapshots Repository</name>
+          <url>http://localhost:8081/nexus/content/repositories/snapshots</url>
+        </snapshotRepository>
+      </distributionManagement>
+    </profile>
+  </profiles>
+</project>

Propchange: maven/sandbox/trunk/mae/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native