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

svn commit: r940352 - in /cayenne/main/trunk/framework/cayenne-di-unpublished/src: main/java/org/apache/cayenne/di/ main/java/org/apache/cayenne/di/spi/ test/java/org/apache/cayenne/di/mock/ test/java/org/apache/cayenne/di/spi/

Author: aadamchik
Date: Mon May  3 03:25:46 2010
New Revision: 940352

URL: http://svn.apache.org/viewvc?rev=940352&view=rev
Log:
CAY-1424 DI: support for named service injection and flexible map/list binding

* API for adding multiple map/list entries at once
* Fixing binding of empty lists/maps
* fixing binding with mixed @Inject costructor parameter annotations

Added:
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/mock/MockImplementation4Alt2.java
      - copied, changed from r940121, cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java
Modified:
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/MapBuilder.java
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingProvider.java
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
    cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java

Modified: cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java?rev=940352&r1=940351&r2=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java Mon May  3 03:25:46 2010
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+import java.util.Collection;
+
 import org.apache.cayenne.ConfigurationException;
 
 /**
@@ -31,6 +33,8 @@ public interface ListBuilder<T> {
     ListBuilder<T> add(Class<? extends T> interfaceType) throws ConfigurationException;
 
     ListBuilder<T> add(T value) throws ConfigurationException;
+    
+    ListBuilder<T> addAll(Collection<T> values) throws ConfigurationException;
 
     void in(Scope scope);
 }

Modified: cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/MapBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/MapBuilder.java?rev=940352&r1=940351&r2=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/MapBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/MapBuilder.java Mon May  3 03:25:46 2010
@@ -18,6 +18,8 @@
  ****************************************************************/
 package org.apache.cayenne.di;
 
+import java.util.Map;
+
 import org.apache.cayenne.ConfigurationException;
 
 /**
@@ -33,6 +35,8 @@ public interface MapBuilder<T> {
             throws ConfigurationException;
 
     MapBuilder<T> put(String key, T value) throws ConfigurationException;
-    
+
+    MapBuilder<T> putAll(Map<String, T> map) throws ConfigurationException;
+
     void in(Scope scope);
 }

Modified: cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingProvider.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingProvider.java?rev=940352&r1=940351&r2=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingProvider.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingProvider.java Mon May  3 03:25:46 2010
@@ -107,10 +107,11 @@ class ConstructorInjectingProvider<T> im
 
         Annotation[][] annotations = lastMatch.getParameterAnnotations();
         this.bindingNames = new String[annotations.length];
-        for (Annotation[] parameterAnnotations : annotations) {
+        for (int i = 0; i < annotations.length; i++) {
 
-            for (int i = 0; i < parameterAnnotations.length; i++) {
-                Annotation annotation = parameterAnnotations[i];
+            Annotation[] parameterAnnotations = annotations[i];
+            for (int j = 0; j < parameterAnnotations.length; j++) {
+                Annotation annotation = parameterAnnotations[j];
                 if (annotation.annotationType().equals(Inject.class)) {
                     Inject inject = (Inject) annotation;
                     bindingNames[i] = inject.value();

Modified: cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java?rev=940352&r1=940351&r2=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultListBuilder.java Mon May  3 03:25:46 2010
@@ -18,6 +18,7 @@
  ****************************************************************/
 package org.apache.cayenne.di.spi;
 
+import java.util.Collection;
 import java.util.List;
 
 import org.apache.cayenne.ConfigurationException;
@@ -37,6 +38,10 @@ class DefaultListBuilder<T> implements L
     DefaultListBuilder(Key<List<?>> bindingKey, DefaultInjector injector) {
         this.injector = injector;
         this.bindingKey = bindingKey;
+
+        // trigger initialization of the ListProvider right away, as we need to bind an
+        // empty list even if the user never calls 'put'
+        getListProvider();
     }
 
     public ListBuilder<T> add(Class<? extends T> interfaceType)
@@ -57,6 +62,23 @@ class DefaultListBuilder<T> implements L
         return this;
     }
 
+    public ListBuilder<T> addAll(Collection<T> values) throws ConfigurationException {
+
+        ListProvider listProvider = getListProvider();
+
+        for (T value : values) {
+            Provider<T> provider0 = new InstanceProvider<T>(value);
+            Provider<T> provider1 = new FieldInjectingProvider<T>(
+                    provider0,
+                    injector,
+                    bindingKey);
+
+            listProvider.add(provider1);
+        }
+
+        return this;
+    }
+
     private ListProvider getListProvider() {
 
         ListProvider provider = null;

Modified: cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java?rev=940352&r1=940351&r2=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/spi/DefaultMapBuilder.java Mon May  3 03:25:46 2010
@@ -19,6 +19,7 @@
 package org.apache.cayenne.di.spi;
 
 import java.util.Map;
+import java.util.Map.Entry;
 
 import org.apache.cayenne.ConfigurationException;
 import org.apache.cayenne.di.Key;
@@ -37,6 +38,10 @@ class DefaultMapBuilder<T> implements Ma
     DefaultMapBuilder(Key<Map<String, ?>> bindingKey, DefaultInjector injector) {
         this.injector = injector;
         this.bindingKey = bindingKey;
+
+        // trigger initialization of the MapProvider right away, as we need to bind an
+        // empty map even if the user never calls 'put'
+        getMapProvider();
     }
 
     public MapBuilder<T> put(String key, Class<? extends T> interfaceType)
@@ -60,6 +65,23 @@ class DefaultMapBuilder<T> implements Ma
         return this;
     }
 
+    public MapBuilder<T> putAll(Map<String, T> map) throws ConfigurationException {
+
+        MapProvider provider = getMapProvider();
+
+        for (Entry<String, T> entry : map.entrySet()) {
+
+            Provider<T> provider0 = new InstanceProvider<T>(entry.getValue());
+            Provider<T> provider1 = new FieldInjectingProvider<T>(
+                    provider0,
+                    injector,
+                    bindingKey);
+            provider.put(entry.getKey(), provider1);
+        }
+
+        return this;
+    }
+
     private MapProvider getMapProvider() {
         MapProvider provider = null;
 

Copied: cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/mock/MockImplementation4Alt2.java (from r940121, cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java)
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/mock/MockImplementation4Alt2.java?p2=cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/mock/MockImplementation4Alt2.java&p1=cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java&r1=940121&r2=940352&rev=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/main/java/org/apache/cayenne/di/ListBuilder.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/mock/MockImplementation4Alt2.java Mon May  3 03:25:46 2010
@@ -16,21 +16,23 @@
  *  specific language governing permissions and limitations
  *  under the License.
  ****************************************************************/
-package org.apache.cayenne.di;
+package org.apache.cayenne.di.mock;
 
-import org.apache.cayenne.ConfigurationException;
+import org.apache.cayenne.di.Inject;
 
-/**
- * A binding builder for list configurations.
- * 
- * @param <T> A type of list values.
- * @since 3.1
- */
-public interface ListBuilder<T> {
+public class MockImplementation4Alt2 implements MockInterface4 {
 
-    ListBuilder<T> add(Class<? extends T> interfaceType) throws ConfigurationException;
+    private MockInterface1 service1;
+    private MockInterface3 service3;
 
-    ListBuilder<T> add(T value) throws ConfigurationException;
+    public MockImplementation4Alt2(@Inject("two") MockInterface1 service1,
+            @Inject MockInterface3 service3) {
+        this.service1 = service1;
+        this.service3 = service3;
+    }
+
+    public String getName() {
+        return "constructor_" + service1.getName() + "_" + service3.getName();
+    }
 
-    void in(Scope scope);
 }

Modified: cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java?rev=940352&r1=940351&r2=940352&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java (original)
+++ cayenne/main/trunk/framework/cayenne-di-unpublished/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java Mon May  3 03:25:46 2010
@@ -36,6 +36,7 @@ import org.apache.cayenne.di.mock.MockIm
 import org.apache.cayenne.di.mock.MockImplementation3;
 import org.apache.cayenne.di.mock.MockImplementation4;
 import org.apache.cayenne.di.mock.MockImplementation4Alt;
+import org.apache.cayenne.di.mock.MockImplementation4Alt2;
 import org.apache.cayenne.di.mock.MockImplementation5;
 import org.apache.cayenne.di.mock.MockInterface1;
 import org.apache.cayenne.di.mock.MockInterface2;
@@ -139,6 +140,28 @@ public class DefaultInjectorInjectionTes
         assertEquals("constructor_alt2", service.getName());
     }
 
+    public void testConstructorInjection_Named_Mixed() {
+
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                binder.bind(Key.get(MockInterface1.class, "one")).to(
+                        MockImplementation1Alt.class);
+                binder.bind(Key.get(MockInterface1.class, "two")).to(
+                        MockImplementation1Alt2.class);
+                binder.bind(MockInterface3.class).to(MockImplementation3.class);
+                binder.bind(MockInterface4.class).to(MockImplementation4Alt2.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface4 service = injector.getInstance(MockInterface4.class);
+        assertNotNull(service);
+        assertEquals("constructor_alt2_XName", service.getName());
+    }
+
     public void testProviderInjection_Constructor() {
 
         Module module = new Module() {
@@ -156,6 +179,25 @@ public class DefaultInjectorInjectionTes
         assertEquals("altered_MyName", service.getAlteredName());
     }
 
+    public void testMapInjection_Empty() {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(
+                        MockImplementation1_MapConfiguration.class);
+
+                // empty map must be still bound
+                binder.bindMap("xyz");
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("", service.getName());
+    }
+
     public void testMapInjection() {
         Module module = new Module() {
 
@@ -236,6 +278,23 @@ public class DefaultInjectorInjectionTes
         assertEquals(";xyz;yvalue", service.getName());
     }
 
+    public void testListInjection_empty() {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(
+                        MockImplementation1_ListConfiguration.class);
+                binder.bindList("xyz");
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("", service.getName());
+    }
+
     public void testListInjection_resumed() {
         Module module = new Module() {