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 2016/08/25 09:49:57 UTC

[2/4] cayenne git commit: CAY-2108 cayenne-di: StackOverflow for decorator that takes Provider of the delegate

CAY-2108 cayenne-di: StackOverflow for decorator that takes Provider of the delegate


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

Branch: refs/heads/master
Commit: 023d5f18f8fb97f66b23bc13accf015c6d4f11b4
Parents: 3d96be6
Author: Andrus Adamchik <an...@objectstyle.com>
Authored: Thu Aug 25 12:38:06 2016 +0300
Committer: Andrus Adamchik <an...@objectstyle.com>
Committed: Thu Aug 25 12:43:59 2016 +0300

----------------------------------------------------------------------
 .../ConstructorInjectingDecoratorProvider.java  | 21 +++++++++--
 .../di/spi/FieldInjectingDecoratorProvider.java | 23 ++++++++++--
 .../di/mock/MockInterface1_Decorator4.java      | 36 ++++++++++++++++++
 .../di/mock/MockInterface1_Decorator5.java      | 33 +++++++++++++++++
 .../di/spi/DefaultInjectorDecorationTest.java   | 39 ++++++++++++++++++++
 5 files changed, 146 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/023d5f18/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingDecoratorProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingDecoratorProvider.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingDecoratorProvider.java
index 4ad974f..a235847 100644
--- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingDecoratorProvider.java
+++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/ConstructorInjectingDecoratorProvider.java
@@ -18,11 +18,11 @@
  ****************************************************************/
 package org.apache.cayenne.di.spi;
 
-import java.lang.reflect.Type;
-
 import org.apache.cayenne.di.DIRuntimeException;
 import org.apache.cayenne.di.Provider;
 
+import java.lang.reflect.Type;
+
 /**
  * @since 4.0
  */
@@ -43,7 +43,22 @@ public class ConstructorInjectingDecoratorProvider<T> implements DecoratorProvid
             @Override
             protected Object value(Class<?> parameter, Type genericType, String bindingName, InjectionStack stack) {
 
-                if (parameter.isAssignableFrom(implementation)) {
+                // delegate (possibly) injected as Provider
+                if (Provider.class.equals(parameter)) {
+
+                    Class<?> objectClass = DIUtil.parameterClass(genericType);
+
+                    if (objectClass == null) {
+                        throw new DIRuntimeException("Constructor provider parameter %s must be "
+                                + "parameterized to be usable for injection", parameter.getName());
+                    }
+
+                    if(objectClass.isAssignableFrom(implementation)) {
+                        return undecorated;
+                    }
+                }
+                // delegate injected as value
+                else if (parameter.isAssignableFrom(implementation)) {
                     return undecorated.get();
                 }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/023d5f18/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingDecoratorProvider.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingDecoratorProvider.java b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingDecoratorProvider.java
index e6c072b..6cbbad0 100644
--- a/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingDecoratorProvider.java
+++ b/cayenne-di/src/main/java/org/apache/cayenne/di/spi/FieldInjectingDecoratorProvider.java
@@ -18,11 +18,11 @@
  ****************************************************************/
 package org.apache.cayenne.di.spi;
 
-import java.lang.reflect.Field;
-
 import org.apache.cayenne.di.DIRuntimeException;
 import org.apache.cayenne.di.Provider;
 
+import java.lang.reflect.Field;
+
 /**
  * @since 4.0
  */
@@ -45,7 +45,24 @@ class FieldInjectingDecoratorProvider<T> implements DecoratorProvider<T> {
 
             @Override
             protected Object value(Field field, String bindingName) {
-                if (field.getType().isAssignableFrom(implementation)) {
+                Class<?> fieldType = field.getType();
+
+                // delegate (possibly) injected as Provider
+                if (Provider.class.equals(fieldType)) {
+
+                    Class<?> objectClass = DIUtil.parameterClass(field.getGenericType());
+
+                    if (objectClass == null) {
+                        throw new DIRuntimeException("Provider field %s.%s of type %s must be "
+                                + "parameterized to be usable for injection", field.getDeclaringClass().getName(),
+                                field.getName(), fieldType.getName());
+                    }
+
+                    if(objectClass.isAssignableFrom(implementation)) {
+                        return undecorated;
+                    }
+                }
+                else if (fieldType.isAssignableFrom(implementation)) {
                     return undecorated.get();
                 }
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/023d5f18/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator4.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator4.java b/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator4.java
new file mode 100644
index 0000000..d30f358
--- /dev/null
+++ b/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator4.java
@@ -0,0 +1,36 @@
+/*****************************************************************
+ *   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 org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+public class MockInterface1_Decorator4 implements MockInterface1 {
+
+    private Provider<MockInterface1> delegate;
+
+    public MockInterface1_Decorator4(@Inject Provider<MockInterface1> delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public String getName() {
+        return "[4" + delegate.get().getName() + "4]";
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cayenne/blob/023d5f18/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator5.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator5.java b/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator5.java
new file mode 100644
index 0000000..0b3cd35
--- /dev/null
+++ b/cayenne-di/src/test/java/org/apache/cayenne/di/mock/MockInterface1_Decorator5.java
@@ -0,0 +1,33 @@
+/*****************************************************************
+ *   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 org.apache.cayenne.di.Inject;
+import org.apache.cayenne.di.Provider;
+
+public class MockInterface1_Decorator5 implements MockInterface1 {
+
+    @Inject
+    private Provider<MockInterface1> delegate;
+
+    @Override
+    public String getName() {
+        return "[5" + delegate.get().getName() + "5]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/cayenne/blob/023d5f18/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorDecorationTest.java
----------------------------------------------------------------------
diff --git a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorDecorationTest.java b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorDecorationTest.java
index 266ade2..dfe34ff 100644
--- a/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorDecorationTest.java
+++ b/cayenne-di/src/test/java/org/apache/cayenne/di/spi/DefaultInjectorDecorationTest.java
@@ -25,6 +25,8 @@ import org.apache.cayenne.di.mock.MockInterface1;
 import org.apache.cayenne.di.mock.MockInterface1_Decorator1;
 import org.apache.cayenne.di.mock.MockInterface1_Decorator2;
 import org.apache.cayenne.di.mock.MockInterface1_Decorator3;
+import org.apache.cayenne.di.mock.MockInterface1_Decorator4;
+import org.apache.cayenne.di.mock.MockInterface1_Decorator5;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -92,4 +94,41 @@ public class DefaultInjectorDecorationTest {
         assertEquals("<[{MyName}]>", service.getName());
     }
 
+    @Test
+    public void testSingleDecorator_Provider_ConstructorInjection() {
+
+        Module module = new Module() {
+
+            @Override
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                binder.decorate(MockInterface1.class).before(MockInterface1_Decorator4.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("[4MyName4]", service.getName());
+    }
+
+    @Test
+    public void testSingleDecorator_Provider_FieldInjection() {
+
+        Module module = new Module() {
+
+            @Override
+            public void configure(Binder binder) {
+                binder.bind(MockInterface1.class).to(MockImplementation1.class);
+                binder.decorate(MockInterface1.class).before(MockInterface1_Decorator5.class);
+            }
+        };
+
+        DefaultInjector injector = new DefaultInjector(module);
+
+        MockInterface1 service = injector.getInstance(MockInterface1.class);
+        assertNotNull(service);
+        assertEquals("[5MyName5]", service.getName());
+    }
 }