diff options
author | mbishop | 2012-11-22 09:24:18 +0000 |
---|---|---|
committer | Glyn Normington | 2012-11-22 09:24:18 +0000 |
commit | f9a31e0164c6a8df4eee492fb410e47fe70ed96f (patch) | |
tree | cf4dd44217f79358f6ca4d078feda3274a8304f9 | |
parent | 2f5dfaacf286fbb8918532b10c974e6b565c4d65 (diff) | |
download | org.eclipse.gemini.blueprint-f9a31e0164c6a8df4eee492fb410e47fe70ed96f.tar.gz org.eclipse.gemini.blueprint-f9a31e0164c6a8df4eee492fb410e47fe70ed96f.tar.xz org.eclipse.gemini.blueprint-f9a31e0164c6a8df4eee492fb410e47fe70ed96f.zip |
392500: support recursive types
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) + "]"); + } +} |