summaryrefslogtreecommitdiffstatsabout
diff options
context:
space:
mode:
authormbishop2012-11-22 04:24:18 (EST)
committer Glyn Normington2012-11-22 04:24:18 (EST)
commitf9a31e0164c6a8df4eee492fb410e47fe70ed96f (patch)
treecf4dd44217f79358f6ca4d078feda3274a8304f9
parent2f5dfaacf286fbb8918532b10c974e6b565c4d65 (diff)
downloadorg.eclipse.gemini.blueprint-f9a31e0164c6a8df4eee492fb410e47fe70ed96f.zip
org.eclipse.gemini.blueprint-f9a31e0164c6a8df4eee492fb410e47fe70ed96f.tar.gz
org.eclipse.gemini.blueprint-f9a31e0164c6a8df4eee492fb410e47fe70ed96f.tar.bz2
392500: support recursive types
-rw-r--r--core/src/main/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactory.java302
-rw-r--r--core/src/test/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactoryTest.java505
-rw-r--r--integration-tests/bundles/pom.xml3
-rw-r--r--integration-tests/bundles/recursive.type.bundle/pom.xml20
-rw-r--r--integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/ABean.java22
-rw-r--r--integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveGenericType.java17
-rw-r--r--integration-tests/bundles/recursive.type.bundle/src/main/resources/META-INF/MANIFEST.MF6
-rw-r--r--integration-tests/bundles/recursive.type.bundle/src/main/resources/OSGI-INF/blueprint/recursive.xml13
-rw-r--r--integration-tests/tests/pom.xml7
-rw-r--r--integration-tests/tests/src/test/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveTypesTest.java30
10 files changed, 536 insertions, 389 deletions
diff --git a/core/src/main/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactory.java b/core/src/main/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactory.java
index f9a8af8..aded1e0 100644
--- a/core/src/main/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactory.java
+++ b/core/src/main/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactory.java
@@ -1,147 +1,157 @@
-/******************************************************************************
- * Copyright (c) 2006, 2010 VMware Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution.
- * The Eclipse Public License is available at
- * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
- * is available at http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.
- *
- * Contributors:
- * VMware Inc.
- *****************************************************************************/
-
-package org.eclipse.gemini.blueprint.blueprint.container;
-
-import java.lang.reflect.GenericArrayType;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import org.osgi.service.blueprint.container.ReifiedType;
-import org.springframework.core.convert.TypeDescriptor;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ObjectUtils;
-
-/**
- * Adaptor factory between Spring type descriptor and OSGi 4.2 Reified type.
- *
- * @author Costin Leau
- */
-class TypeFactory {
-
- private static final GenericsReifiedType OBJECT = new GenericsReifiedType(Object.class);
-
- private static class GenericsReifiedType extends ReifiedType {
-
- private final List<ReifiedType> arguments;
- private final int size;
-
- GenericsReifiedType(Class<?> clazz) {
- this(TypeDescriptor.valueOf(clazz));
- }
-
- GenericsReifiedType(TypeDescriptor descriptor) {
- super((descriptor == null) ? Object.class: ClassUtils.resolvePrimitiveIfNecessary(descriptor.getType()));
- arguments = getArguments(descriptor);
- size = arguments.size();
- }
-
- @Override
- public ReifiedType getActualTypeArgument(int i) {
- if (i >= 0 && i < size) {
- return arguments.get(i);
- }
- if (i == 0) {
- return super.getActualTypeArgument(0);
- }
-
- throw new IllegalArgumentException("Invalid argument index given " + i);
- }
-
- @Override
- public int size() {
- return size;
- }
- }
-
- static ReifiedType getType(TypeDescriptor targetType) {
- return new GenericsReifiedType(targetType);
- }
-
- private static List<ReifiedType> getArguments(TypeDescriptor type) {
- List<ReifiedType> arguments;
-
- if (type == null) {
- return Collections.emptyList();
- }
-
- // is it a collection or an array
- if (type.isCollection() || type.isArray()) {
- arguments = new ArrayList<ReifiedType>(1);
- Class<?> elementType = type.getElementTypeDescriptor() == null ? null : type.getElementTypeDescriptor().getType();
- arguments.add(elementType != null ? new GenericsReifiedType(elementType) : OBJECT);
- return arguments;
- }
-
- // is it a map
- if (type.isMap()) {
- arguments = new ArrayList<ReifiedType>(2);
- Class<?> keyType = type.getMapKeyTypeDescriptor() == null ? null : type.getMapKeyTypeDescriptor().getType();
- arguments.add(keyType != null ? new GenericsReifiedType(keyType) : OBJECT);
- Class<?> valueType = type.getMapValueTypeDescriptor() == null ? null : type.getMapValueTypeDescriptor().getType();
- arguments.add(valueType != null ? new GenericsReifiedType(valueType) : OBJECT);
- return arguments;
- }
-
- // some other generic type
- @SuppressWarnings("rawtypes")
- TypeVariable[] tvs = type.getType().getTypeParameters();
- arguments = new ArrayList<ReifiedType>(tvs.length);
- for (@SuppressWarnings("rawtypes") TypeVariable tv : tvs) {
- ReifiedType rType = getReifiedType(tv);
- arguments.add(rType);
- }
- return arguments;
- }
-
- private static ReifiedType getReifiedType(Type targetType) {
- if (targetType instanceof Class) {
- if (Object.class.equals(targetType)) {
- return OBJECT;
- }
- return new GenericsReifiedType((Class<?>) targetType);
- }
- if (targetType instanceof ParameterizedType) {
- Type ata = ((ParameterizedType) targetType).getActualTypeArguments()[0];
- return getReifiedType(ata);
- }
- if (targetType instanceof WildcardType) {
- WildcardType wt = (WildcardType) targetType;
- Type[] lowerBounds = wt.getLowerBounds();
- if (ObjectUtils.isEmpty(lowerBounds)) {
- // there's always an upper bound (Object)
- Type upperBound = wt.getUpperBounds()[0];
- return getReifiedType(upperBound);
- }
-
- return getReifiedType(lowerBounds[0]);
- }
-
- if (targetType instanceof TypeVariable) {
- Type[] bounds = ((TypeVariable<?>) targetType).getBounds();
- return getReifiedType(bounds[0]);
- }
-
- if (targetType instanceof GenericArrayType) {
- return getReifiedType(((GenericArrayType) targetType).getGenericComponentType());
- }
-
- throw new IllegalArgumentException("Unknown type " + targetType.getClass());
- }
+/******************************************************************************
+ * Copyright (c) 2006, 2010 VMware Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
+ * is available at http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * VMware Inc.
+ *****************************************************************************/
+
+package org.eclipse.gemini.blueprint.blueprint.container;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.lang.reflect.WildcardType;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.osgi.service.blueprint.container.ReifiedType;
+import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * Adaptor factory between Spring type descriptor and OSGi 4.2 Reified type.
+ *
+ * @author Costin Leau
+ */
+class TypeFactory {
+
+ private static final GenericsReifiedType OBJECT = new GenericsReifiedType(Object.class);
+
+ private static class GenericsReifiedType extends ReifiedType {
+
+ private final List<ReifiedType> arguments;
+ private final int size;
+
+ GenericsReifiedType(Class<?> clazz) {
+ this(TypeDescriptor.valueOf(clazz));
+ }
+
+ GenericsReifiedType(TypeDescriptor descriptor) {
+ super((descriptor == null) ? Object.class: ClassUtils.resolvePrimitiveIfNecessary(descriptor.getType()));
+ arguments = getArguments(descriptor);
+ size = arguments.size();
+ }
+
+ @Override
+ public ReifiedType getActualTypeArgument(int i) {
+ if (i >= 0 && i < size) {
+ return arguments.get(i);
+ }
+ if (i == 0) {
+ return super.getActualTypeArgument(0);
+ }
+
+ throw new IllegalArgumentException("Invalid argument index given " + i);
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+ }
+
+ static ReifiedType getType(TypeDescriptor targetType) {
+ return new GenericsReifiedType(targetType);
+ }
+
+ private static List<ReifiedType> getArguments(TypeDescriptor type) {
+ List<ReifiedType> arguments;
+
+ if (type == null) {
+ return Collections.emptyList();
+ }
+
+ // is it a collection or an array
+ if (type.isCollection() || type.isArray()) {
+ arguments = new ArrayList<ReifiedType>(1);
+ Class<?> elementType = type.getElementTypeDescriptor() == null ? null : type.getElementTypeDescriptor().getType();
+ arguments.add(elementType != null ? new GenericsReifiedType(elementType) : OBJECT);
+ return arguments;
+ }
+
+ // is it a map
+ if (type.isMap()) {
+ arguments = new ArrayList<ReifiedType>(2);
+ Class<?> keyType = type.getMapKeyTypeDescriptor() == null ? null : type.getMapKeyTypeDescriptor().getType();
+ arguments.add(keyType != null ? new GenericsReifiedType(keyType) : OBJECT);
+ Class<?> valueType = type.getMapValueTypeDescriptor() == null ? null : type.getMapValueTypeDescriptor().getType();
+ arguments.add(valueType != null ? new GenericsReifiedType(valueType) : OBJECT);
+ return arguments;
+ }
+
+ // some other generic type
+ @SuppressWarnings("rawtypes")
+ TypeVariable[] tvs = type.getType().getTypeParameters();
+ arguments = new ArrayList<ReifiedType>(tvs.length);
+ for (@SuppressWarnings("rawtypes") TypeVariable tv : tvs) {
+ ReifiedType rType = getReifiedType(tv);
+ arguments.add(rType);
+ }
+ return arguments;
+ }
+
+ private static ReifiedType getReifiedType(Type targetType) {
+ if (targetType instanceof Class) {
+ if (Object.class.equals(targetType)) {
+ return OBJECT;
+ }
+ return new GenericsReifiedType((Class<?>) targetType);
+ }
+ if (targetType instanceof ParameterizedType) {
+ Type ata = ((ParameterizedType) targetType).getActualTypeArguments()[0];
+ return getReifiedType(ata);
+ }
+ if (targetType instanceof WildcardType) {
+ WildcardType wt = (WildcardType) targetType;
+ Type[] lowerBounds = wt.getLowerBounds();
+ if (ObjectUtils.isEmpty(lowerBounds)) {
+ // there's always an upper bound (Object)
+ Type upperBound = wt.getUpperBounds()[0];
+ return getReifiedType(upperBound);
+ }
+
+ return getReifiedType(lowerBounds[0]);
+ }
+
+ if (targetType instanceof TypeVariable) {
+ TypeVariable<?> typeVariable = (TypeVariable<?>) targetType;
+ Type[] bounds = typeVariable.getBounds();
+ Type boundZero = bounds[0];
+ if (bounds.length == 1 && boundZero instanceof ParameterizedType) {
+ Type ata = ((ParameterizedType) boundZero).getActualTypeArguments()[0];
+ if (targetType.equals(ata)) {
+ //recursive declaration like <T extends Comparable<T>>
+ return OBJECT;
+ }
+ }
+
+ return getReifiedType(boundZero);
+ }
+
+ if (targetType instanceof GenericArrayType) {
+ return getReifiedType(((GenericArrayType) targetType).getGenericComponentType());
+ }
+
+ throw new IllegalArgumentException("Unknown type " + targetType.getClass());
+ }
} \ No newline at end of file
diff --git a/core/src/test/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactoryTest.java b/core/src/test/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactoryTest.java
index 90384be..94d7d16 100644
--- a/core/src/test/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactoryTest.java
+++ b/core/src/test/java/org/eclipse/gemini/blueprint/blueprint/container/TypeFactoryTest.java
@@ -1,243 +1,264 @@
-/******************************************************************************
- * Copyright (c) 2006, 2010 VMware Inc.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * and Apache License v2.0 which accompanies this distribution.
- * The Eclipse Public License is available at
- * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
- * is available at http://www.opensource.org/licenses/apache2.0.php.
- * You may elect to redistribute this code under either of these licenses.
- *
- * Contributors:
- * VMware Inc.
- *****************************************************************************/
-
-package org.eclipse.gemini.blueprint.blueprint.container;
-
-import java.awt.Point;
-import java.awt.Shape;
-import java.lang.reflect.Method;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-import java.util.TreeMap;
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.gemini.blueprint.blueprint.MyCustomDictionary;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.osgi.service.blueprint.container.ReifiedType;
-import org.springframework.beans.BeanUtils;
-import org.springframework.core.MethodParameter;
-import org.springframework.core.convert.TypeDescriptor;
-
-import static org.junit.Assert.assertEquals;
-
-/**
- * @author Costin Leau
- */
-public class TypeFactoryTest {
-
- private static class TestSet<A> {
-
- public void rawList(List arg) {
- }
-
- public void primitive(int arg) {
- }
-
- public void integer(Integer arg) {
- }
-
- public void typedList(LinkedList<Point> arg) {
- }
-
- public void array(Integer[] arg) {
- }
-
- public void extendsList(LinkedList<? extends Shape> arg) {
- }
-
- public void superList(LinkedList<? super Shape> arg) {
- }
-
- public void typedMap(TreeMap<Integer, Double> arg) {
- }
-
- public void pointMap(TreeMap<String, Point> arg) {
- }
-
- public void typedReference(AtomicReference<Boolean> arg) {
- }
-
- public void objectTypedReference(AtomicReference<Object> arg) {
- }
-
- public void wildcardReference(AtomicReference<?> arg) {
- }
-
- public void superTypedReference(AtomicReference<? super Properties> arg) {
- }
-
- public void extendsTypedReference(AtomicReference<? extends Properties> arg) {
- }
-
- public void typeVariable(AtomicReference<A> arg) {
- }
-
- public void customDictionary(MyCustomDictionary customDict) {
- }
- }
-
- @Test
- public void testJdk4Classes() throws Exception {
- ReifiedType tp = getReifiedTypeFor("rawList");
- assertEquals(1, tp.size());
- assertEquals(List.class, tp.getRawClass());
- }
-
- @Test
- public void testPrimitive() throws Exception {
- ReifiedType tp = getReifiedTypeFor("primitive");
- assertEquals(0, tp.size());
- assertEquals(Integer.class, tp.getRawClass());
- }
-
- @Test
- public void testArray() throws Exception {
- ReifiedType tp = getReifiedTypeFor("array");
- assertEquals(1, tp.size());
- assertEquals(Integer[].class, tp.getRawClass());
- assertEquals(Integer.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testInteger() throws Exception {
- ReifiedType tp = getReifiedTypeFor("integer");
- assertEquals(0, tp.size());
- assertEquals(Integer.class, tp.getRawClass());
- }
-
- @Test
- public void testTypedObjectList() throws Exception {
- ReifiedType tp = getReifiedTypeFor("typedList");
- assertEquals(1, tp.size());
- assertEquals(LinkedList.class, tp.getRawClass());
- assertEquals(Point.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testExtendsList() throws Exception {
- ReifiedType tp = getReifiedTypeFor("extendsList");
- assertEquals(1, tp.size());
- assertEquals(LinkedList.class, tp.getRawClass());
- assertEquals(Shape.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testSuperList() throws Exception {
- ReifiedType tp = getReifiedTypeFor("superList");
- assertEquals(1, tp.size());
- assertEquals(LinkedList.class, tp.getRawClass());
- assertEquals(Shape.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testTypedMap() throws Exception {
- ReifiedType tp = getReifiedTypeFor("typedMap");
- assertEquals(2, tp.size());
- assertEquals(TreeMap.class, tp.getRawClass());
- assertEquals(Integer.class, tp.getActualTypeArgument(0).getRawClass());
- assertEquals(Double.class, tp.getActualTypeArgument(1).getRawClass());
- }
-
- @Test
- public void testPointMap() throws Exception {
- ReifiedType tp = getReifiedTypeFor("pointMap");
- assertEquals(2, tp.size());
- assertEquals(TreeMap.class, tp.getRawClass());
- assertEquals(String.class, tp.getActualTypeArgument(0).getRawClass());
- assertEquals(Point.class, tp.getActualTypeArgument(1).getRawClass());
- }
-
- // Since spring 3.1 the TypeDescriptor no longer contains any reference to the MethodParameter
- // class, we we are unable to get the ParameterizedType of a method parameter.
- // So all actual type arguments just become Object.class.
- @Test
- @Ignore
- public void testTypedReference() throws Exception {
- ReifiedType tp = getReifiedTypeFor("typedReference");
- assertEquals(AtomicReference.class, tp.getRawClass());
- assertEquals(1, tp.size());
- assertEquals(Boolean.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testObjectTypedReference() throws Exception {
- ReifiedType tp = getReifiedTypeFor("objectTypedReference");
- assertEquals(AtomicReference.class, tp.getRawClass());
- assertEquals(1, tp.size());
- assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testWildcardReference() throws Exception {
- ReifiedType tp = getReifiedTypeFor("wildcardReference");
- assertEquals(AtomicReference.class, tp.getRawClass());
- assertEquals(1, tp.size());
- assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- // Since spring 3.1 the TypeDescriptor no longer contains any reference to the MethodParameter
- // class, we we are unable to get the ParameterizedType of a method parameter.
- // So all actual type arguments just become Object.class.
- @Test
- @Ignore
- public void testSuperReference() throws Exception {
- ReifiedType tp = getReifiedTypeFor("superTypedReference");
- assertEquals(AtomicReference.class, tp.getRawClass());
- assertEquals(1, tp.size());
- assertEquals(Properties.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- // Since spring 3.1 the TypeDescriptor no longer contains any reference to the MethodParameter
- // class, we we are unable to get the ParameterizedType of a method parameter.
- // So all actual type arguments just come Object.class.
- @Test
- @Ignore
- public void testExtendsReference() throws Exception {
- ReifiedType tp = getReifiedTypeFor("extendsTypedReference");
- assertEquals(AtomicReference.class, tp.getRawClass());
- assertEquals(1, tp.size());
- assertEquals(Properties.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testTypeVariable() throws Exception {
- ReifiedType tp = getReifiedTypeFor("typeVariable");
- assertEquals(1, tp.size());
- assertEquals(AtomicReference.class, tp.getRawClass());
- assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
- }
-
- @Test
- public void testCustomDictionary() throws Exception {
- ReifiedType tp = getReifiedTypeFor("customDictionary");
- assertEquals(2, tp.size());
- assertEquals(MyCustomDictionary.class, tp.getRawClass());
- assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
- assertEquals(Object.class, tp.getActualTypeArgument(1).getRawClass());
- }
-
- @Test
- public void testUnknownType() throws Exception {
- ReifiedType type = TypeFactory.getType(TypeDescriptor.forObject(null));
- assertEquals(Object.class, type.getRawClass());
- }
-
- private ReifiedType getReifiedTypeFor(String methodName) {
- Method mt = BeanUtils.findDeclaredMethodWithMinimalParameters(TestSet.class, methodName);
- TypeDescriptor td = new TypeDescriptor(new MethodParameter(mt, 0));
- return TypeFactory.getType(td);
- }
+/******************************************************************************
+ * Copyright (c) 2006, 2010 VMware Inc.; 2012 Elastic Path, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
+ * is available at http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * VMware Inc.
+ * Elastic Path, Inc.
+ *****************************************************************************/
+
+package org.eclipse.gemini.blueprint.blueprint.container;
+
+import java.awt.Point;
+import java.awt.Shape;
+import java.lang.reflect.Method;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.gemini.blueprint.blueprint.MyCustomDictionary;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.osgi.service.blueprint.container.ReifiedType;
+import org.springframework.beans.BeanUtils;
+import org.springframework.core.MethodParameter;
+import org.springframework.core.convert.TypeDescriptor;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+/**
+ * @author Costin Leau
+ */
+public class TypeFactoryTest {
+
+ private static class TestSet<A> {
+
+ public void rawList(List arg) {
+ }
+
+ public void primitive(int arg) {
+ }
+
+ public void integer(Integer arg) {
+ }
+
+ public void typedList(LinkedList<Point> arg) {
+ }
+
+ public void array(Integer[] arg) {
+ }
+
+ public void extendsList(LinkedList<? extends Shape> arg) {
+ }
+
+ public void superList(LinkedList<? super Shape> arg) {
+ }
+
+ public void typedMap(TreeMap<Integer, Double> arg) {
+ }
+
+ public void pointMap(TreeMap<String, Point> arg) {
+ }
+
+ public void typedReference(AtomicReference<Boolean> arg) {
+ }
+
+ public void objectTypedReference(AtomicReference<Object> arg) {
+ }
+
+ public void wildcardReference(AtomicReference<?> arg) {
+ }
+
+ public void superTypedReference(AtomicReference<? super Properties> arg) {
+ }
+
+ public void extendsTypedReference(AtomicReference<? extends Properties> arg) {
+ }
+
+ public void typeVariable(AtomicReference<A> arg) {
+ }
+
+ public void customDictionary(MyCustomDictionary customDict) {
+ }
+ }
+
+ private static class RecursiveGenericType<T extends Comparable<T>> {
+ }
+
+ private static class SingleAndRecursiveGenericType<S extends String, T extends Comparable<T>> {
+ }
+
+ private static class MultipleRecursiveGenericType<T extends Comparable<T>, U extends T> {
+ }
+
+ @Test
+ public void testJdk4Classes() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("rawList");
+ assertEquals(1, tp.size());
+ assertEquals(List.class, tp.getRawClass());
+ }
+
+ @Test
+ public void testPrimitive() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("primitive");
+ assertEquals(0, tp.size());
+ assertEquals(Integer.class, tp.getRawClass());
+ }
+
+ @Test
+ public void testArray() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("array");
+ assertEquals(1, tp.size());
+ assertEquals(Integer[].class, tp.getRawClass());
+ assertEquals(Integer.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testInteger() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("integer");
+ assertEquals(0, tp.size());
+ assertEquals(Integer.class, tp.getRawClass());
+ }
+
+ @Test
+ public void testTypedObjectList() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("typedList");
+ assertEquals(1, tp.size());
+ assertEquals(LinkedList.class, tp.getRawClass());
+ assertEquals(Point.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testExtendsList() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("extendsList");
+ assertEquals(1, tp.size());
+ assertEquals(LinkedList.class, tp.getRawClass());
+ assertEquals(Shape.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testSuperList() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("superList");
+ assertEquals(1, tp.size());
+ assertEquals(LinkedList.class, tp.getRawClass());
+ assertEquals(Shape.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testTypedMap() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("typedMap");
+ assertEquals(2, tp.size());
+ assertEquals(TreeMap.class, tp.getRawClass());
+ assertEquals(Integer.class, tp.getActualTypeArgument(0).getRawClass());
+ assertEquals(Double.class, tp.getActualTypeArgument(1).getRawClass());
+ }
+
+ @Test
+ public void testPointMap() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("pointMap");
+ assertEquals(2, tp.size());
+ assertEquals(TreeMap.class, tp.getRawClass());
+ assertEquals(String.class, tp.getActualTypeArgument(0).getRawClass());
+ assertEquals(Point.class, tp.getActualTypeArgument(1).getRawClass());
+ }
+
+ // Since spring 3.1 the TypeDescriptor no longer contains any reference to the MethodParameter
+ // class, we we are unable to get the ParameterizedType of a method parameter.
+ // So all actual type arguments just become Object.class.
+ @Test
+ @Ignore
+ public void testTypedReference() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("typedReference");
+ assertEquals(AtomicReference.class, tp.getRawClass());
+ assertEquals(1, tp.size());
+ assertEquals(Boolean.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testObjectTypedReference() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("objectTypedReference");
+ assertEquals(AtomicReference.class, tp.getRawClass());
+ assertEquals(1, tp.size());
+ assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testWildcardReference() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("wildcardReference");
+ assertEquals(AtomicReference.class, tp.getRawClass());
+ assertEquals(1, tp.size());
+ assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ // Since spring 3.1 the TypeDescriptor no longer contains any reference to the MethodParameter
+ // class, we we are unable to get the ParameterizedType of a method parameter.
+ // So all actual type arguments just become Object.class.
+ @Test
+ @Ignore
+ public void testSuperReference() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("superTypedReference");
+ assertEquals(AtomicReference.class, tp.getRawClass());
+ assertEquals(1, tp.size());
+ assertEquals(Properties.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ // Since spring 3.1 the TypeDescriptor no longer contains any reference to the MethodParameter
+ // class, we we are unable to get the ParameterizedType of a method parameter.
+ // So all actual type arguments just come Object.class.
+ @Test
+ @Ignore
+ public void testExtendsReference() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("extendsTypedReference");
+ assertEquals(AtomicReference.class, tp.getRawClass());
+ assertEquals(1, tp.size());
+ assertEquals(Properties.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testTypeVariable() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("typeVariable");
+ assertEquals(1, tp.size());
+ assertEquals(AtomicReference.class, tp.getRawClass());
+ assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
+ }
+
+ @Test
+ public void testCustomDictionary() throws Exception {
+ ReifiedType tp = getReifiedTypeFor("customDictionary");
+ assertEquals(2, tp.size());
+ assertEquals(MyCustomDictionary.class, tp.getRawClass());
+ assertEquals(Object.class, tp.getActualTypeArgument(0).getRawClass());
+ assertEquals(Object.class, tp.getActualTypeArgument(1).getRawClass());
+ }
+
+ @Test
+ public void testUnknownType() throws Exception {
+ ReifiedType type = TypeFactory.getType(TypeDescriptor.forObject(null));
+ assertEquals(Object.class, type.getRawClass());
+ }
+
+ @Test
+ public void testRecursiveGenericsType() throws Exception {
+ ReifiedType type = TypeFactory.getType(TypeDescriptor.valueOf(RecursiveGenericType.class));
+ assertNotNull(type);
+ ReifiedType type2 = TypeFactory.getType(TypeDescriptor.valueOf(SingleAndRecursiveGenericType.class));
+ assertNotNull(type2);
+ ReifiedType type3 = TypeFactory.getType(TypeDescriptor.valueOf(MultipleRecursiveGenericType.class));
+ assertNotNull(type3);
+ }
+
+ private ReifiedType getReifiedTypeFor(String methodName) {
+ Method mt = BeanUtils.findDeclaredMethodWithMinimalParameters(TestSet.class, methodName);
+ TypeDescriptor td = new TypeDescriptor(new MethodParameter(mt, 0));
+ return TypeFactory.getType(td);
+ }
} \ No newline at end of file
diff --git a/integration-tests/bundles/pom.xml b/integration-tests/bundles/pom.xml
index 4222600..66c0e1a 100644
--- a/integration-tests/bundles/pom.xml
+++ b/integration-tests/bundles/pom.xml
@@ -70,8 +70,9 @@
<module>proxy.listener</module>
<module>export.import.dependency.bundle</module>
<module>jdk5</module>
+ <module>recursive.type.bundle</module>
- <!-- blueprint bundles -->
+ <!-- blueprint bundles -->
<module>blueprint</module>
</modules>
diff --git a/integration-tests/bundles/recursive.type.bundle/pom.xml b/integration-tests/bundles/recursive.type.bundle/pom.xml
new file mode 100644
index 0000000..a56bc36
--- /dev/null
+++ b/integration-tests/bundles/recursive.type.bundle/pom.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.eclipse.gemini.blueprint.iandt</groupId>
+ <artifactId>gemini-blueprint-integration-test-bundles</artifactId>
+ <version>2.0.0.BUILD-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>recursive</artifactId>
+ <packaging>jar</packaging>
+ <name>Eclipse Gemini Blueprint Test Bundle: Recursive Type test bundle</name>
+ <description>An OSGi bundle that consumes a bean with a recursive Generics type definition.</description>
+ <url>http://www.eclipse.org/gemini/blueprint/</url>
+</project>
+
diff --git a/integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/ABean.java b/integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/ABean.java
new file mode 100644
index 0000000..ebb3141
--- /dev/null
+++ b/integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/ABean.java
@@ -0,0 +1,22 @@
+/******************************************************************************
+ * Copyright (c) 2012 Elastic Path Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
+ * is available at http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Elastic Path Inc.
+ *****************************************************************************/
+package org.eclipse.gemini.blueprint.iandt.recursive;
+
+public class ABean {
+
+
+ public ABean(RecursiveGenericType<?> argument) {
+ System.out.println("Loaded the generic argument:" + argument);
+ }
+}
diff --git a/integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveGenericType.java b/integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveGenericType.java
new file mode 100644
index 0000000..648a766
--- /dev/null
+++ b/integration-tests/bundles/recursive.type.bundle/src/main/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveGenericType.java
@@ -0,0 +1,17 @@
+/******************************************************************************
+ * Copyright (c) 2012 Elastic Path Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Apache License v2.0 which accompanies this distribution.
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
+ * is available at http://www.opensource.org/licenses/apache2.0.php.
+ * You may elect to redistribute this code under either of these licenses.
+ *
+ * Contributors:
+ * Elastic Path Inc.
+ *****************************************************************************/
+package org.eclipse.gemini.blueprint.iandt.recursive;
+
+public class RecursiveGenericType<T extends Comparable<T>> {
+}
diff --git a/integration-tests/bundles/recursive.type.bundle/src/main/resources/META-INF/MANIFEST.MF b/integration-tests/bundles/recursive.type.bundle/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4d40697
--- /dev/null
+++ b/integration-tests/bundles/recursive.type.bundle/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Bundle-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: org.eclipse.gemini.blueprint.iandt.recursive
+Bundle-Name: Recursive-Type-Sample
+Bundle-Vendor: SpringSource
+Export-Package: org.eclipse.gemini.blueprint.iandt.recursive
diff --git a/integration-tests/bundles/recursive.type.bundle/src/main/resources/OSGI-INF/blueprint/recursive.xml b/integration-tests/bundles/recursive.type.bundle/src/main/resources/OSGI-INF/blueprint/recursive.xml
new file mode 100644
index 0000000..230f804
--- /dev/null
+++ b/integration-tests/bundles/recursive.type.bundle/src/main/resources/OSGI-INF/blueprint/recursive.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
+
+ <bean id="recursiveTestBean" class="org.eclipse.gemini.blueprint.iandt.recursive.ABean">
+ <argument>
+ <bean class="org.eclipse.gemini.blueprint.iandt.recursive.RecursiveGenericType" />
+ </argument>
+ </bean>
+
+</blueprint> \ No newline at end of file
diff --git a/integration-tests/tests/pom.xml b/integration-tests/tests/pom.xml
index 09e446a..c640f29 100644
--- a/integration-tests/tests/pom.xml
+++ b/integration-tests/tests/pom.xml
@@ -117,6 +117,13 @@
<dependency>
<groupId>org.eclipse.gemini.blueprint.iandt</groupId>
+ <artifactId>recursive</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.eclipse.gemini.blueprint.iandt</groupId>
<artifactId>reference.proxy</artifactId>
<version>${project.parent.version}</version>
<scope>provided</scope>
diff --git a/integration-tests/tests/src/test/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveTypesTest.java b/integration-tests/tests/src/test/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveTypesTest.java
new file mode 100644
index 0000000..9477115
--- /dev/null
+++ b/integration-tests/tests/src/test/java/org/eclipse/gemini/blueprint/iandt/recursive/RecursiveTypesTest.java
@@ -0,0 +1,30 @@
+package org.eclipse.gemini.blueprint.iandt.recursive;
+
+import org.eclipse.gemini.blueprint.iandt.BaseIntegrationTest;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.eclipse.gemini.blueprint.util.OsgiServiceReferenceUtils;
+import org.eclipse.gemini.blueprint.util.OsgiStringUtils;
+import org.eclipse.gemini.blueprint.context.ConfigurableOsgiBundleApplicationContext;
+
+
+public class RecursiveTypesTest extends BaseIntegrationTest {
+
+ protected String getManifestLocation() {
+ return null;
+ }
+
+ protected String[] getTestBundlesNames() {
+ return null;
+ }
+
+ public void testBeanReference() throws Exception {
+
+ Bundle bundle = bundleContext.installBundle(getLocator().locateArtifact(
+ "org.eclipse.gemini.blueprint.iandt", "recursive", getSpringDMVersion()).getURL().toExternalForm());
+ bundle.start();
+ waitOnContextCreation(bundle.getSymbolicName());
+ System.out.println("started bundle [" + OsgiStringUtils.nullSafeSymbolicName(bundle) + "]");
+ }
+}