Repository: cayenne
Updated Branches:
  refs/heads/master d8bba279e -> 965cafc79


DI: new tests for wildcards and deprecated API
+ additions to upgrade notes.


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/965cafc7
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/965cafc7
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/965cafc7

Branch: refs/heads/master
Commit: 965cafc796d15f281335c7c61cdf0e412e8fd431
Parents: d8bba27
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Fri May 12 12:18:42 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Fri May 12 12:18:42 2017 +0300

----------------------------------------------------------------------
 .../MockImplementation1_MapWithWildcards.java   |  38 +++++
 .../di/spi/DefaultInjectorInjectionTest.java    | 141 ++++++++++++-------
 docs/doc/src/main/resources/UPGRADE.txt         |   9 +-
 3 files changed, 133 insertions(+), 55 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/965cafc7/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapWithWildcards.java
----------------------------------------------------------------------
diff --git 
a/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapWithWildcards.java
 
b/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapWithWildcards.java
new file mode 100644
index 0000000..8048b83
--- /dev/null
+++ 
b/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockImplementation1_MapWithWildcards.java
@@ -0,0 +1,38 @@
+/*****************************************************************
+ *   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.
+ ****************************************************************/
+
+package org.apache.cayenne.di.mock;
+
+import java.util.Map;
+
+import org.apache.cayenne.di.Inject;
+
+/**
+ * @since 4.0
+ */
+public class MockImplementation1_MapWithWildcards implements MockInterface1 {
+
+    @Inject
+    Map<String, Class<?>> testMap;
+
+    @Override
+    public String getName() {
+        return "map:" + testMap.size();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/965cafc7/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java
 
b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java
index 27411e3..8d7d742 100644
--- 
a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java
+++ 
b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorInjectionTest.java
@@ -19,6 +19,7 @@
 package org.apache.cayenne.di.spi;
 
 import org.apache.cayenne.di.Binder;
+import org.apache.cayenne.di.DIRuntimeException;
 import org.apache.cayenne.di.Key;
 import org.apache.cayenne.di.Module;
 import org.apache.cayenne.di.mock.MockImplementation1;
@@ -27,6 +28,7 @@ import org.apache.cayenne.di.mock.MockImplementation1Alt2;
 import org.apache.cayenne.di.mock.MockImplementation1_ListConfiguration;
 import org.apache.cayenne.di.mock.MockImplementation1_ListConfigurationMock5;
 import org.apache.cayenne.di.mock.MockImplementation1_MapConfiguration;
+import org.apache.cayenne.di.mock.MockImplementation1_MapWithWildcards;
 import org.apache.cayenne.di.mock.MockImplementation1_WithInjector;
 import org.apache.cayenne.di.mock.MockImplementation2;
 import org.apache.cayenne.di.mock.MockImplementation2Sub1;
@@ -47,10 +49,11 @@ import org.junit.Test;
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
 
 public class DefaultInjectorInjectionTest {
 
@@ -79,10 +82,8 @@ public class DefaultInjectorInjectionTest {
 
             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(Key.get(MockInterface1.class, 
"one")).to(MockImplementation1Alt.class);
+                binder.bind(Key.get(MockInterface1.class, 
"two")).to(MockImplementation1Alt2.class);
                 
binder.bind(MockInterface2.class).to(MockImplementation2_Named.class);
             }
         };
@@ -138,10 +139,8 @@ public class DefaultInjectorInjectionTest {
 
             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(Key.get(MockInterface1.class, 
"one")).to(MockImplementation1Alt.class);
+                binder.bind(Key.get(MockInterface1.class, 
"two")).to(MockImplementation1Alt2.class);
                 
binder.bind(MockInterface4.class).to(MockImplementation4Alt.class);
             }
         };
@@ -160,10 +159,8 @@ public class DefaultInjectorInjectionTest {
 
             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(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);
             }
@@ -183,8 +180,7 @@ public class DefaultInjectorInjectionTest {
 
             public void configure(Binder binder) {
                 
binder.bind(MockInterface1.class).to(MockImplementation1.class);
-                binder.bind(MockInterface2.class).to(
-                        MockImplementation2_ConstructorProvider.class);
+                
binder.bind(MockInterface2.class).to(MockImplementation2_ConstructorProvider.class);
             }
         };
 
@@ -199,8 +195,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_MapConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_MapConfiguration.class);
 
                 // empty map must be still bound
                 binder.bindMap(Object.class, "xyz");
@@ -215,16 +210,45 @@ public class DefaultInjectorInjectionTest {
     }
 
     @Test
+    @SuppressWarnings("deprecation")
+    public void mapInjectionDeprecated() {
+        final String bindingName = "xyz";
+        final Object test = "test_map";
+        Module module = new Module() {
+            @Override
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1_MapConfiguration.class);
+                binder.bindMap(bindingName).put("test", test).put("abc", 
"def");
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+        // Even with old version of binding we should use new version of key...
+        Map<String, Object> map = 
injector.getInstance(Key.getMapOf(String.class, Object.class, bindingName));
+        assertNotNull(map);
+        assertEquals(test, map.get("test"));
+
+        try {
+            // Old version of getting by key will fail...
+            injector.getInstance(Key.get(Map.class, bindingName));
+            fail("DI Exception should be thrown");
+        } catch (DIRuntimeException ignored) {
+        }
+
+        // Check that injection is working
+        MockInterface1 interface1 = injector.getInstance(MockInterface1.class);
+        assertThat(interface1, 
instanceOf(MockImplementation1_MapConfiguration.class));
+        assertEquals(";abc=def;test=test_map", interface1.getName());
+    }
+
+    @Test
     public void testMapInjection() {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_MapConfiguration.class);
-
-                binder.bindMap(Object.class,"xyz").put("x", "xvalue").put("y", 
"yvalue").put(
-                        "x",
-                        "xvalue1");
+                
binder.bind(MockInterface1.class).to(MockImplementation1_MapConfiguration.class);
+                binder.bindMap(Object.class,"xyz")
+                        .put("x", "xvalue").put("y", "yvalue").put("x", 
"xvalue1");
             }
         };
 
@@ -236,16 +260,40 @@ public class DefaultInjectorInjectionTest {
     }
 
     @Test
-    public void testMapInjection_Resumed() {
+    public void mapWithWildcardInjection() {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_MapConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_MapWithWildcards.class);
+                binder.bindMap(Class.class).put("x", String.class).put("y", 
Integer.class).put("z", Object.class);
+            }
+        };
+        DefaultInjector injector = new DefaultInjector(module);
+
+        // This is example of how to deal with wildcards:
+        // to handle it nicer we need to use some hacks with anonymous classes:
+        // Key.get(new TypeLiteral<String, Class<?>>(){});
+        Map mapUntyped = injector.getInstance(Key.getMapOf(String.class, 
Class.class));
+        @SuppressWarnings("unchecked")
+        Map<String, Class<?>> map = (Map<String, Class<?>>)mapUntyped;
+
+        assertNotNull(map);
+        assertEquals(3, map.size());
+        assertEquals(String.class, map.get("x"));
 
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("map:3", service.getName());
+    }
+
+    @Test
+    public void testMapInjection_Resumed() {
+        Module module = new Module() {
+
+            public void configure(Binder binder) {
+                
binder.bind(MockInterface1.class).to(MockImplementation1_MapConfiguration.class);
                 // bind 1
                 binder.bindMap(Object.class,"xyz").put("x", "xvalue").put("y", 
"yvalue");
-
                 // second binding attempt to the same map...
                 binder.bindMap(Object.class,"xyz").put("z", "zvalue").put("x", 
"xvalue1");
             }
@@ -263,9 +311,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
-
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
                 binder.bindList(Object.class, 
"xyz").add("xvalue").add("yvalue");
             }
         };
@@ -282,9 +328,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
             @Override
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
-
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
                 
binder.bind(MockInterface5.class).to(MockImplementation5.class);
 
                 binder.bindList(Object.class, "xyz")
@@ -308,8 +352,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
             @Override
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
 
                 Collection<Object> firstList = new ArrayList<>();
                 firstList.add("1value");
@@ -344,9 +387,7 @@ public class DefaultInjectorInjectionTest {
 
             public void configure(Binder binder) {
                 
binder.bind(MockInterface5.class).to(MockImplementation5.class);
-
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
 
                 binder.bindList(Object.class, 
"xyz").add(MockInterface5.class).add("yvalue");
             }
@@ -364,9 +405,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
-
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
                 
binder.bind(MockInterface5.class).to(MockImplementation5.class);
 
                 binder.bindList(Object.class, "xyz")
@@ -391,9 +430,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
-
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
                 binder.bindList(Object.class, 
"xyz").add(MockImplementation5.class).add("yvalue");
             }
         };
@@ -410,8 +447,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
                 binder.bindList(Object.class,"xyz");
             }
         };
@@ -428,8 +464,7 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class).to(
-                        MockImplementation1_ListConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfiguration.class);
 
                 binder.bindList(Object.class, 
"xyz").add("xvalue").add("yvalue");
                 binder.bindList(Object.class, "xyz").add("avalue");
@@ -448,10 +483,8 @@ public class DefaultInjectorInjectionTest {
         Module module = new Module() {
 
             public void configure(Binder binder) {
-                binder.bind(MockInterface1.class)
-                        .to(MockImplementation1_ListConfigurationMock5.class);
-                binder.bind(MockInterface2.class)
-                        .to(MockImplementation2_ListConfiguration.class);
+                
binder.bind(MockInterface1.class).to(MockImplementation1_ListConfigurationMock5.class);
+                
binder.bind(MockInterface2.class).to(MockImplementation2_ListConfiguration.class);
 
                 // Bind list for MockImplementation2_ListConfiguration
                 binder.bindList(Object.class,"xyz")

http://git-wip-us.apache.org/repos/asf/cayenne/blob/965cafc7/docs/doc/src/main/resources/UPGRADE.txt
----------------------------------------------------------------------
diff --git a/docs/doc/src/main/resources/UPGRADE.txt 
b/docs/doc/src/main/resources/UPGRADE.txt
index 4cd9d98..eb5514f 100644
--- a/docs/doc/src/main/resources/UPGRADE.txt
+++ b/docs/doc/src/main/resources/UPGRADE.txt
@@ -52,12 +52,19 @@ UPGRADING TO 4.0.M6
        - method after() replaced by explicit addAfter(), addAllAfter()
        - method before() replaced by insertBefore(), insertAllBefore()
 
-* Per CAY-2258 Injection of List and Map are made type-safe, if you are using 
following methods:
+* Per CAY-2258 Injection of List and Map are made type-safe, as a result small 
incompatibilities are introduced.
+  If you are using following methods:
         - bindMap(String bindingName)
         - bindList(String bindingName)
   you should change them to corresponding type-safe versions:
         - bindMap(Class<T> valueType, String bindingName)
         - bindList(Class<T> valueType, String bindingName)
+  Also if you are using DI Keys like Key.get(Map.class, "bindingName") or 
Key.get(List.class, "bindingName")
+  you should use new corresponding factory methods Key.mapOf(MapValues.class, 
"bindingName")
+  and Key.listOf(ListValues.class, "bindingName").
+  Additionally new API allows you to bind Lists and Maps without using names:
+        - binder.bindList(SomeUniqueType.class).add(...);
+        - @Inject List<SomeUniqueType> list;
 
 * Per CAY-1873 and CAY-2266 Cache and remote notification configuration was 
moved from Modeler into
   runtime DI settings. To set custom cache size, you should use custom module 
like this:

Reply via email to