You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by dr...@apache.org on 2010/03/05 09:12:12 UTC

svn commit: r919328 - in /tapestry/tapestry5/trunk/tapestry-ioc/src: main/java/org/apache/tapestry5/ioc/annotations/ main/java/org/apache/tapestry5/ioc/def/ main/java/org/apache/tapestry5/ioc/internal/ main/java/org/apache/tapestry5/ioc/internal/util/ ...

Author: drobiazko
Date: Fri Mar  5 08:12:12 2010
New Revision: 919328

URL: http://svn.apache.org/viewvc?rev=919328&view=rev
Log:
TAP5-69: Add annotation, @Contribute, to allow service contributor methods to be arbitrary named

Added:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java   (with props)
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java   (with props)
Modified:
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties
    tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,40 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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.tapestry5.ioc.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation that may be placed on a contributor method of a module. The annotation may/should be used in combination with
+ * {@link Marker} annotation to disambiguate the service to contribute into. This annotation was introduced as an alternative 
+ * to the naming convention for contributor methods.
+ * 
+ * @since 5.2.0
+ *
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Contribute
+{
+    /**
+     * Type of the service to contribute into.
+     */
+    Class value();
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/annotations/Contribute.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,47 @@
+// Copyright 2009 The Apache Software Foundation
+//
+// 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.tapestry5.ioc.def;
+
+import java.util.Set;
+
+import org.apache.tapestry5.ioc.annotations.Contribute;
+
+/**
+ * Extended version of {@link org.apache.tapestry5.ioc.def.ContributionDef} introduced to determine any 
+ * module method annotated with {@link Contribute} as a contributor method. As of version 5.2 a contribution 
+ * identifies the service contributed either by the service id or by a combination of {@link Contribute} annotation and
+ * a set of marker annotations. This means that {@link #getServiceId()} may to return <code>null</code> if {@link #getServiceInterface()}
+ * returns a non <code>null</code> value.
+ *
+ * @since 5.2.0
+ *
+ */
+public interface ContributionDef2 extends ContributionDef
+{
+    /**
+     * Returns an optional <em>marker annotation</em>. Marker annotations are used to disambiguate services; the
+     * combination of a marker annotation and a service type is expected to be unique.
+     * 
+     * @see ServiceDef#getMarkers()
+     *
+     */
+    Set<Class> getMarkers();
+    
+    /**
+     * Returns the service interface associated with the service to contribute into.
+     * 
+     * @see ServiceDef#getServiceInterface()
+     */
+    Class getServiceInterface();
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/def/ContributionDef2.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ContributionDefImpl.java Fri Mar  5 08:12:12 2010
@@ -16,30 +16,38 @@
 
 import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
 import org.apache.tapestry5.ioc.internal.util.*;
 import org.apache.tapestry5.ioc.services.ClassFactory;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Map;
+import java.util.Set;
 import java.util.logging.Logger;
 
-public class ContributionDefImpl implements ContributionDef
+public class ContributionDefImpl implements ContributionDef2
 {
     private final String serviceId;
 
     private final Method contributorMethod;
 
     private final ClassFactory classFactory;
+    
+    private final Set<Class> markers;
+    
+    private final Class serviceInterface;
 
     private static final Class[] CONFIGURATION_TYPES = new Class[] {Configuration.class, MappedConfiguration.class,
             OrderedConfiguration.class};
 
-    public ContributionDefImpl(String serviceId, Method contributorMethod, ClassFactory classFactory)
+    public ContributionDefImpl(String serviceId, Method contributorMethod, ClassFactory classFactory, Class serviceInterface, Set<Class> markers)
     {
         this.serviceId = serviceId;
         this.contributorMethod = contributorMethod;
         this.classFactory = classFactory;
+        this.serviceInterface = serviceInterface;
+        this.markers = markers;
     }
 
     @Override
@@ -122,4 +130,14 @@
             throw new RuntimeException(IOCMessages
                     .contributionMethodError(contributorMethod, fail), fail);
     }
+
+    public Set<Class> getMarkers()
+    {
+        return markers;
+    }
+
+    public Class getServiceInterface()
+    {
+        return serviceInterface;
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/DefaultModuleDefImpl.java Fri Mar  5 08:12:12 2010
@@ -17,6 +17,7 @@
 import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.annotations.*;
 import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
 import org.apache.tapestry5.ioc.def.DecoratorDef;
 import org.apache.tapestry5.ioc.def.ModuleDef2;
 import org.apache.tapestry5.ioc.def.ServiceDef;
@@ -218,7 +219,7 @@
                 continue;
             }
 
-            if (name.startsWith(CONTRIBUTE_METHOD_NAME_PREFIX))
+            if (name.startsWith(CONTRIBUTE_METHOD_NAME_PREFIX) || m.isAnnotationPresent(Contribute.class))
             {
                 addContributionDef(m);
                 remainingMethods.remove(m);
@@ -236,7 +237,12 @@
 
     private void addContributionDef(Method method)
     {
-        String serviceId = stripMethodPrefix(method, CONTRIBUTE_METHOD_NAME_PREFIX);
+        Contribute annotation = method.getAnnotation(Contribute.class);
+        		
+        
+        Class serviceInterface = annotation==null?null:annotation.value();
+        
+        String serviceId = annotation!=null?null:stripMethodPrefix(method, CONTRIBUTE_METHOD_NAME_PREFIX);
 
         Class returnType = method.getReturnType();
         if (!returnType.equals(void.class))
@@ -260,8 +266,11 @@
 
         if (type == null)
             throw new RuntimeException(IOCMessages.noContributionParameter(method));
+        
+        Set<Class> markers = CollectionFactory.newSet();
+        markers.addAll(extractMarkers(method));
 
-        ContributionDef def = new ContributionDefImpl(serviceId, method, classFactory);
+        ContributionDef2 def = new ContributionDefImpl(serviceId, method, classFactory, serviceInterface, markers);
 
         contributionDefs.add(def);
     }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/IOCMessages.java Fri Mar  5 08:12:12 2010
@@ -16,6 +16,7 @@
 
 import org.apache.tapestry5.ioc.Messages;
 import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
 import org.apache.tapestry5.ioc.def.ServiceDef;
 import org.apache.tapestry5.ioc.def.ServiceDef2;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
@@ -312,4 +313,14 @@
     {
         return MESSAGES.format("no-convention-service-implementation-found", clazz.getName(), clazz.getName());
     }
+    
+    static String contributionForNonexistentService(ContributionDef cd)
+    {
+        return MESSAGES.format("contribution-for-nonexistent-service", cd, cd.getServiceId());
+    }
+    
+    static String contributionForUnqualifiedService(ContributionDef2 cd)
+    {
+        return MESSAGES.format("contribution-for-unqualified-service", cd, cd.getServiceInterface(), cd.getMarkers());
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/Module.java Fri Mar  5 08:12:12 2010
@@ -14,16 +14,16 @@
 
 package org.apache.tapestry5.ioc.internal;
 
+import java.util.Collection;
+import java.util.Set;
+
 import org.apache.tapestry5.ioc.AdvisorDef;
 import org.apache.tapestry5.ioc.ModuleBuilderSource;
-import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
 import org.apache.tapestry5.ioc.def.DecoratorDef;
 import org.apache.tapestry5.ioc.def.ServiceDef;
 import org.apache.tapestry5.ioc.def.ServiceDef2;
 
-import java.util.Collection;
-import java.util.Set;
-
 /**
  * A module within the Tapestry IoC registry. Each Module is constructed around a corresponding module builder instance;
  * the methods and annotations of that instance define the services provided by the module.
@@ -70,9 +70,9 @@
     Set<AdvisorDef> findMatchingServiceAdvisors(ServiceDef serviceDef);
 
     /**
-     * Finds any contributions that are targetted at the indicated service.
+     * Finds any contributions that are targeted at the indicated service.
      */
-    Set<ContributionDef> getContributorDefsForService(String serviceId);
+    Set<ContributionDef2> getContributorDefsForService(ServiceDef serviceDef);
 
     /**
      * Locates services with the {@link org.apache.tapestry5.ioc.annotations.EagerLoad} annotation and generates proxies

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java Fri Mar  5 08:12:12 2010
@@ -14,20 +14,48 @@
 
 package org.apache.tapestry5.ioc.internal;
 
-import org.apache.tapestry5.ioc.*;
-import org.apache.tapestry5.ioc.def.*;
-import org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator;
-import org.apache.tapestry5.ioc.internal.util.*;
-import org.apache.tapestry5.ioc.services.*;
-import org.slf4j.Logger;
+import static java.lang.String.format;
 
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import static java.lang.String.format;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Modifier;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tapestry5.ioc.AdvisorDef;
+import org.apache.tapestry5.ioc.Invokable;
+import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.ObjectLocator;
+import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.ServiceBuilderResources;
+import org.apache.tapestry5.ioc.ServiceLifecycle2;
+import org.apache.tapestry5.ioc.ServiceResources;
+import org.apache.tapestry5.ioc.annotations.Local;
+import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
+import org.apache.tapestry5.ioc.def.DecoratorDef;
+import org.apache.tapestry5.ioc.def.ModuleDef;
+import org.apache.tapestry5.ioc.def.ModuleDef2;
+import org.apache.tapestry5.ioc.def.ServiceDef;
+import org.apache.tapestry5.ioc.def.ServiceDef2;
+import org.apache.tapestry5.ioc.internal.services.JustInTimeObjectCreator;
+import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier;
+import org.apache.tapestry5.ioc.internal.util.Defense;
+import org.apache.tapestry5.ioc.internal.util.InjectionResources;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.internal.util.MapInjectionResources;
+import org.apache.tapestry5.ioc.services.AspectDecorator;
+import org.apache.tapestry5.ioc.services.ClassFab;
+import org.apache.tapestry5.ioc.services.ClassFactory;
+import org.apache.tapestry5.ioc.services.MethodSignature;
+import org.apache.tapestry5.ioc.services.Status;
+import org.slf4j.Logger;
 
 public class ModuleImpl implements Module
 {
@@ -497,17 +525,40 @@
         }
     }
 
-    public Set<ContributionDef> getContributorDefsForService(String serviceId)
+    public Set<ContributionDef2> getContributorDefsForService(ServiceDef serviceDef)
     {
-        Set<ContributionDef> result = CollectionFactory.newSet();
+        Set<ContributionDef2> result = CollectionFactory.newSet();
 
-        for (ContributionDef def : moduleDef.getContributionDefs())
+        for (ContributionDef next : moduleDef.getContributionDefs())
         {
-            if (def.getServiceId().equals(serviceId)) result.add(def);
+            ContributionDef2 def = InternalUtils.toContributionDef2(next);
+            
+            if (serviceDef.getServiceId().equals(def.getServiceId())) 
+            {
+                result.add(def);
+            }
+            else
+            {
+                Set<Class> markers = CollectionFactory.newSet(def.getMarkers());
+                
+                if(markers.contains(Local.class))
+                {
+                    if(moduleDef.getServiceDef(serviceDef.getServiceId()) == null)
+                        continue;
+                    
+                    markers.remove(Local.class);
+                }
+                
+                if(serviceDef.getMarkers().equals(markers) && serviceDef.getServiceInterface() == def.getServiceInterface())
+                {
+                    result.add(def);
+                }
+            }
         }
 
         return result;
     }
+    
 
     public ServiceDef2 getServiceDef(String serviceId)
     {

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java Fri Mar  5 08:12:12 2010
@@ -195,10 +195,54 @@
         for (ContributionDef cd : contributionDefs)
         {
             String serviceId = cd.getServiceId();
+            
+            ContributionDef2 cd2 = InternalUtils.toContributionDef2(cd);
+            
+            if (cd2.getServiceId() != null)
+            {
+                if (!serviceIdToModule.containsKey(serviceId)) 
+                { 
+                    throw new IllegalArgumentException(IOCMessages.contributionForNonexistentService(cd)); 
+                }
+            }
+            else if(!isContributionForExistentService(cd2))
+            {
+                throw new IllegalArgumentException(IOCMessages.contributionForUnqualifiedService(cd2));
+            }
+        }
+            
+    }
+    
+    private boolean isContributionForExistentService(ContributionDef2 cd)
+    {
+        Set<Class> markers = CollectionFactory.newSet(cd.getMarkers());
+        markers.remove(Local.class); 
 
-            if (!serviceIdToModule.containsKey(serviceId)) { throw new IllegalArgumentException(String.format(
-                    "Contribution %s is for service '%s', which does not exist.", cd, serviceId)); }
+        for (Class markerClass : markers)
+        {
+            boolean exists = existsServiceDefWithTypeAndMarker(cd.getServiceInterface(), markerClass);
+            
+            if(!exists)
+                return false;
+        }
+        
+        return true;
+    }
+    
+    private boolean existsServiceDefWithTypeAndMarker(Class serviceInterface, Class markerClass)
+    {
+        List<ServiceDef2> serviceDefs = markerToServiceDef.get(markerClass);
+        
+        if(serviceDefs == null)
+            return false;
+        
+        for (ServiceDef2 serviceDef : serviceDefs)
+        {
+            if(serviceDef.getServiceInterface() == serviceInterface)
+                return true;
         }
+        
+        return false;
     }
 
     /**
@@ -444,7 +488,7 @@
             final Module module)
     {
         String serviceId = serviceDef.getServiceId();
-        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+        Set<ContributionDef2> contributions = module.getContributorDefsForService(serviceDef);
 
         if (contributions.isEmpty())
             return;
@@ -479,7 +523,7 @@
             final Module module)
     {
         String serviceId = serviceDef.getServiceId();
-        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+        Set<ContributionDef2> contributions = module.getContributorDefsForService(serviceDef);
 
         if (contributions.isEmpty())
             return;
@@ -515,7 +559,7 @@
             final Module module)
     {
         String serviceId = serviceDef.getServiceId();
-        Set<ContributionDef> contributions = module.getContributorDefsForService(serviceId);
+        Set<ContributionDef2> contributions = module.getContributorDefsForService(serviceDef);
 
         if (contributions.isEmpty())
             return;

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/util/InternalUtils.java Fri Mar  5 08:12:12 2010
@@ -38,6 +38,7 @@
 import org.apache.tapestry5.ioc.annotations.InjectService;
 import org.apache.tapestry5.ioc.annotations.PostInjection;
 import org.apache.tapestry5.ioc.def.ContributionDef;
+import org.apache.tapestry5.ioc.def.ContributionDef2;
 import org.apache.tapestry5.ioc.def.DecoratorDef;
 import org.apache.tapestry5.ioc.def.ModuleDef;
 import org.apache.tapestry5.ioc.def.ModuleDef2;
@@ -933,4 +934,54 @@
 
         return result;
     }
+    
+
+    
+    /**
+     * 
+     * @since 5.2.0
+     */
+    public static ContributionDef2 toContributionDef2(final ContributionDef contribution)
+    {
+        if(contribution instanceof ContributionDef2)
+            return (ContributionDef2) contribution;
+        
+        return new ContributionDef2()
+        {
+
+            public Set<Class> getMarkers()
+            {
+                return Collections.emptySet();
+            }
+
+            public Class getServiceInterface()
+            {
+                return null;
+            }
+
+            public void contribute(ModuleBuilderSource moduleSource, ServiceResources resources,
+                    Configuration configuration)
+            {
+                contribution.contribute(moduleSource, resources, configuration);
+            }
+
+            public void contribute(ModuleBuilderSource moduleSource, ServiceResources resources,
+                    OrderedConfiguration configuration)
+            {
+                contribution.contribute(moduleSource, resources, configuration);
+            }
+
+            public void contribute(ModuleBuilderSource moduleSource, ServiceResources resources,
+                    MappedConfiguration configuration)
+            {
+                contribution.contribute(moduleSource, resources, configuration);
+            }
+
+            public String getServiceId()
+            {
+                return contribution.getServiceId();
+            }
+            
+        };
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/IOCStrings.properties Fri Mar  5 08:12:12 2010
@@ -79,3 +79,5 @@
 unexpected-service-proxy-provider=Unexpected service proxy provider when clearing the provider. This may indicate that you have multiple IoC Registries.
 no-proxy-provider=Service token for service '%s' can not be converted back into a proxy because no proxy provider has been registered. This may indicate that an IoC Registry has not been started yet.
 no-convention-service-implementation-found=No service implements the interface %s. Please provide the implementation %sImpl or bind the service interface to a service implementation.
+contribution-for-nonexistent-service=Contribution %s is for service '%s', which does not exist.
+contribution-for-unqualified-service=Contribution %s is for service '%s' qualified with marker annotations %s, which does not exist.
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/site/apt/configuration.apt Fri Mar  5 08:12:12 2010
@@ -81,6 +81,47 @@
   a much later date. With no change to the FileServicerDispatcher service or its module class,
   the new services "plug into" the overall solution, simply by having their JAR's on runtime classpath. 
   
+Naming conventions vs. Annotations
+	
+	If you prefer annotations over naming conventions you can use the {{{apidocs/org/apache/tapestry5/ioc/annotations/Contribute.html}@Contribute}}
+	annotation. As of version 5.2 this annotation that may be placed on a contributor method of a module instead of starting the methods name 
+	with "contribute". The value of the annotation is the type of the service to contribute into. The following example is an alternative for the contribution method above.
+	
++------+
+  @Contribute(FileServiceDispatcher.class)
+  public static void arbitraryMethodName(MappedConfiguration<String,FileServicer> configuration)
+  {
+    configuration.add("doc", new WordFileServicer());
+    configuration.add("ppt", new PowerPointFileServicer());
+  }  
++------+
+
+	If you have several implementations of a service interface, you have to disambiguate the services. For this purpose the 
+	{{{apidocs/org/apache/tapestry5/ioc/annotations/Marker.html}@Marker}} annotation should be placed on the contributor method.
+	
++------+
+  @Contribute(FileServiceDispatcher.class)
+  @Marker({Red.class, Blue.class})
+  public static void arbitraryMethodName(MappedConfiguration<String,FileServicer> configuration)
+  {
+    configuration.add("doc", new WordFileServicer());
+    configuration.add("ppt", new PowerPointFileServicer());
+  }  
++------+  
+
+	If the {{{apidocs/org/apache/tapestry5/ioc/annotations/Local.html}@Local}} annotation is present, 
+	then contribution is made only to the configuration of a service being constructed in the same module.
+
++------+
+  @Contribute(FileServiceDispatcher.class)
+  @Marker(Local.class)
+  public static void arbitraryMethodName(MappedConfiguration<String,FileServicer> configuration)
+  {
+    configuration.add("doc", new WordFileServicer());
+    configuration.add("ppt", new PowerPointFileServicer());
+  }  
++------+ 
+
 Configuration Types
 
   There are three different styles of configurations (with matching contributions):

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java Fri Mar  5 08:12:12 2010
@@ -14,18 +14,32 @@
 
 package org.apache.tapestry5.ioc;
 
-import org.apache.tapestry5.ioc.internal.*;
-import org.apache.tapestry5.ioc.services.*;
-import org.apache.tapestry5.ioc.util.NonmatchingMappedConfigurationOverrideModule;
-import org.easymock.EasyMock;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
 import java.io.File;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.sql.PreparedStatement;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tapestry5.ioc.internal.AlphabetModule;
+import org.apache.tapestry5.ioc.internal.AlphabetModule2;
+import org.apache.tapestry5.ioc.internal.ExceptionInConstructorModule;
+import org.apache.tapestry5.ioc.internal.ExtraPublicConstructorsModule;
+import org.apache.tapestry5.ioc.internal.IOCInternalTestCase;
+import org.apache.tapestry5.ioc.internal.PrivateConstructorModule;
+import org.apache.tapestry5.ioc.internal.UpcaseService;
+import org.apache.tapestry5.ioc.services.Builtin;
+import org.apache.tapestry5.ioc.services.ServiceActivity;
+import org.apache.tapestry5.ioc.services.ServiceActivityScoreboard;
+import org.apache.tapestry5.ioc.services.Status;
+import org.apache.tapestry5.ioc.services.TypeCoercer;
+import org.apache.tapestry5.ioc.util.NonmatchingMappedConfigurationOverrideModule;
+import org.easymock.EasyMock;
+import org.testng.Assert;
+import org.testng.annotations.Test;
 
 /**
  * A few tests that are easiest (or even just possible) by building a Registry and trying out a few
@@ -1417,4 +1431,66 @@
 
         assertEquals(g.getGreeting(), "ADVICE IS EASY!");
     }
+    
+    @Test
+    public void contribute_by_annotation()
+    {
+        Registry r = buildRegistry(AlphabetModule.class, AlphabetModule2.class);
+
+        NameListHolder greek = r.getService("Greek", NameListHolder.class);
+
+        assertEquals(greek.getNames(), Arrays.asList("Alpha", "Beta", "Gamma", "Delta"));
+        
+        NameListHolder anotherGreek = r.getService("AnotherGreek", NameListHolder.class);
+        
+        assertEquals(anotherGreek.getNames(), Arrays.asList("Alpha", "Beta", "Gamma", "Delta", "Epsilon"));
+        
+        NameListHolder hebrew = r.getService("Hebrew", NameListHolder.class);
+        
+        assertEquals(hebrew.getNames(), Arrays.asList("Alef", "Bet", "Gimel", "Dalet", "He", "Vav"));
+        
+        NameListHolder2 holder = r.getService("ServiceWithEmptyConfiguration", NameListHolder2.class);
+        
+        assertEquals(holder.getNames(), Arrays.asList());
+        
+    }
+    
+    @Test
+    public void contribute_by_annotation_to_nonexistent_service()
+    {
+        try
+        {
+            buildRegistry(InvalidContributeDefModule2.class);
+            unreachable();
+        }
+        catch (Exception e) 
+        {
+            assertMessageContains(
+                e,
+                "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule2.provideConfiguration(OrderedConfiguration)",
+                "is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
+                "qualified with marker annotations [",
+                "interface org.apache.tapestry5.ioc.BlueMarker", 
+                "interface org.apache.tapestry5.ioc.RedMarker",
+                "], which does not exist.");
+        }
+    }
+    
+    @Test
+    public void contribute_by_annotation_wrong_marker()
+    {
+        try
+        {
+            buildRegistry(InvalidContributeDefModule3.class);
+            unreachable();
+        }
+        catch (Exception e) 
+        {
+            assertMessageContains(
+                e,
+                "Contribution org.apache.tapestry5.ioc.InvalidContributeDefModule3.provideConfiguration(OrderedConfiguration)",
+                "is for service 'interface org.apache.tapestry5.ioc.NameListHolder'",
+                "qualified with marker annotations [interface org.apache.tapestry5.ioc.BlueMarker], which does not exist.");
+        }
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,46 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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.tapestry5.ioc;
+
+import java.util.List;
+
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Marker;
+
+public class InvalidContributeDefModule2
+{
+    @Marker(BlueMarker.class)
+    public NameListHolder build(final List<String> configuration)
+    {
+
+        return new NameListHolder()
+        {
+            public List<String> getNames()
+            {
+                return configuration;
+            }
+        };
+    }
+    
+    /**
+     * Its a contribute method, but to a service that does not exist.
+     */
+    @Contribute(NameListHolder.class)
+    @Marker({BlueMarker.class,RedMarker.class})
+    public void provideConfiguration(OrderedConfiguration<String> configuration)
+    {
+        
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule2.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,46 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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.tapestry5.ioc;
+
+import java.util.List;
+
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Marker;
+
+public class InvalidContributeDefModule3
+{
+    @Marker(BlueMarker.class)
+    public Runnable build(final List<String> configuration)
+    {
+
+        return new Runnable()
+        {
+            public void run()
+            {
+                
+            }
+ 
+        };
+    }
+    /**
+     * Its a contribute method, but to a service that does not exist.
+     */
+    @Contribute(NameListHolder.class)
+    @Marker(BlueMarker.class)
+    public void provideConfiguration(OrderedConfiguration<String> configuration)
+    {
+        
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/InvalidContributeDefModule3.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,27 @@
+// Copyright 2006 The Apache Software Foundation
+//
+// 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.tapestry5.ioc;
+
+import java.util.List;
+
+/**
+ * Used for testing of ordered and unordered contributions. The names are contributed in from multiple modules. For
+ * unordered contributions, the values are sorted alphabetically. For ordered contributions, the values are ordered as
+ * per the contributions.
+ */
+public interface NameListHolder2
+{
+    public List<String> getNames();
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/NameListHolder2.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,71 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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.tapestry5.ioc.internal;
+
+import java.util.List;
+
+import org.apache.tapestry5.ioc.BlueMarker;
+import org.apache.tapestry5.ioc.NameListHolder;
+import org.apache.tapestry5.ioc.NameListHolder2;
+import org.apache.tapestry5.ioc.OrderedConfiguration;
+import org.apache.tapestry5.ioc.RedMarker;
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Marker;
+
+public class AlphabetModule
+{
+    @Marker(BlueMarker.class)
+    public NameListHolder buildGreek(final List<String> configuration)
+    {
+
+        return new NameListHolder()
+        {
+            public List<String> getNames()
+            {
+                return configuration;
+            }
+        };
+    }
+    
+    @Contribute(NameListHolder.class)
+    @Marker(BlueMarker.class)
+    public void provideGreekConfiguration(OrderedConfiguration<String> configuration)
+    {
+        configuration.add("Alpha", "Alpha", "before:*");
+        configuration.add("Beta", "Beta", "after:Alpha");
+    }
+    
+    @Contribute(NameListHolder.class)
+    @Marker({RedMarker.class, BlueMarker.class})
+    public void addToHebrew(OrderedConfiguration<String> configuration)
+    {
+        configuration.add("Alef", "Alef", "before:*");
+        configuration.add("Bet", "Bet", "after:Alef");
+        configuration.add("Gimel", "Gimel", "after:Bet");
+    }
+    
+    @Marker(BlueMarker.class)
+    public NameListHolder2 buildServiceWithEmptyConfiguration(final List<String> configuration)
+    {
+        return new NameListHolder2()
+        {
+            public List<String> getNames()
+            {
+                return configuration;
+            }
+        };
+        
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java?rev=919328&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java Fri Mar  5 08:12:12 2010
@@ -0,0 +1,82 @@
+// Copyright 2010 The Apache Software Foundation
+//
+// 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.tapestry5.ioc.internal;
+
+import java.util.List;
+
+import org.apache.tapestry5.ioc.BlueMarker;
+import org.apache.tapestry5.ioc.NameListHolder;
+import org.apache.tapestry5.ioc.OrderedConfiguration;
+import org.apache.tapestry5.ioc.RedMarker;
+import org.apache.tapestry5.ioc.annotations.Contribute;
+import org.apache.tapestry5.ioc.annotations.Local;
+import org.apache.tapestry5.ioc.annotations.Marker;
+
+public class AlphabetModule2
+{
+    @Marker({BlueMarker.class, RedMarker.class})
+    public NameListHolder buildHebrew(final List<String> configuration)
+    {
+
+        return new NameListHolder()
+        {
+            public List<String> getNames()
+            {
+                return configuration;
+            }
+        };
+    }
+
+    @Marker(BlueMarker.class)
+    public NameListHolder buildAnotherGreek(final List<String> configuration)
+    {
+
+        return new NameListHolder()
+        {
+            public List<String> getNames()
+            {
+                return configuration;
+            }
+        };
+    }
+
+    @Contribute(NameListHolder.class)
+    @Marker(BlueMarker.class)
+    public void extendGreekConfiguration(OrderedConfiguration<String> configuration)
+    {
+        configuration.add("Gamma", "Gamma", "after:Beta");
+        configuration.add("Delta", "Delta", "after:Gamma");
+    }
+
+    @Contribute(NameListHolder.class)
+    @Marker({ BlueMarker.class, Local.class })
+    public void contributeXyz(OrderedConfiguration<String> configuration)
+    {
+        configuration.add("Epsilon", "Epsilon", "after:*");
+    }
+    
+    @Contribute(NameListHolder.class)
+    @Marker({RedMarker.class, BlueMarker.class})
+    public void someMoreHebrewLetters(OrderedConfiguration<String> configuration)
+    {
+        configuration.add("Dalet", "Dalet", "after:Gimel");
+        configuration.add("He", "He", "after:Dalet");
+    }
+    
+    public void contributeHebrew(OrderedConfiguration<String> configuration)
+    {
+        configuration.add("Vav", "Vav", "after:He");
+    }
+}

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/AlphabetModule2.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ContributionDefImplTest.java Fri Mar  5 08:12:12 2010
@@ -14,15 +14,20 @@
 
 package org.apache.tapestry5.ioc.internal;
 
-import org.apache.tapestry5.ioc.*;
+import java.lang.reflect.Method;
+
+import org.apache.tapestry5.ioc.Configuration;
+import org.apache.tapestry5.ioc.MappedConfiguration;
+import org.apache.tapestry5.ioc.ModuleBuilderSource;
+import org.apache.tapestry5.ioc.OperationTracker;
+import org.apache.tapestry5.ioc.OrderedConfiguration;
+import org.apache.tapestry5.ioc.ServiceResources;
 import org.apache.tapestry5.ioc.annotations.InjectService;
 import org.apache.tapestry5.ioc.def.ContributionDef;
 import org.apache.tapestry5.ioc.test.IOCTestCase;
 import org.slf4j.Logger;
 import org.testng.annotations.Test;
 
-import java.lang.reflect.Method;
-
 public class ContributionDefImplTest extends IOCTestCase implements ModuleBuilderSource
 {
     private final OperationTracker tracker = new QuietOperationTracker();
@@ -51,7 +56,7 @@
         replay();
 
         Method m = findMethod("contributeUnordered");
-        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
 
         def.contribute(this, serviceResources, configuration);
 
@@ -76,7 +81,7 @@
         replay();
 
         Method m = findMethod("contributeUnorderedParameter");
-        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
 
         def.contribute(this, resources, configuration);
 
@@ -96,7 +101,7 @@
         replay();
 
         Method m = findMethod("contributeUnorderedWrongParameter");
-        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
 
         try
         {
@@ -136,7 +141,7 @@
         replay();
 
         Method m = findMethod("contributeOrderedParameter");
-        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
 
         def.contribute(this, resources, configuration);
 
@@ -162,7 +167,7 @@
         replay();
 
         Method m = findMethod("contributeMappedParameter");
-        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null);
+        ContributionDef def = new ContributionDefImpl("foo.Bar", m, null, null, null);
 
         def.contribute(this, resources, configuration);
 

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java?rev=919328&r1=919327&r2=919328&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/ValidatingMappedConfigurationWrapperTest.java Fri Mar  5 08:12:12 2010
@@ -14,16 +14,17 @@
 
 package org.apache.tapestry5.ioc.internal;
 
+import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
+
+import java.util.List;
+import java.util.Map;
+
 import org.apache.tapestry5.ioc.MappedConfiguration;
 import org.apache.tapestry5.ioc.ObjectLocator;
 import org.apache.tapestry5.ioc.def.ContributionDef;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
-import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
 import org.testng.annotations.Test;
 
-import java.util.List;
-import java.util.Map;
-
 public class ValidatingMappedConfigurationWrapperTest extends IOCInternalTestCase
 {
     private static final String SERVICE_ID = "Baz";
@@ -211,7 +212,7 @@
 
     private ContributionDef newContributionDef(String methodName)
     {
-        return new ContributionDefImpl(SERVICE_ID, findMethod(methodName), getClassFactory());
+        return new ContributionDefImpl(SERVICE_ID, findMethod(methodName), getClassFactory(), null, null);
     }
 
     public void contributionPlaceholder1()