Bug 340859 - Injection of generics using type matching
diff --git a/bundles/org.eclipse.e4.core.contexts/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.core.contexts/META-INF/MANIFEST.MF
index 3b6d906..f69926e 100644
--- a/bundles/org.eclipse.e4.core.contexts/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.e4.core.contexts/META-INF/MANIFEST.MF
@@ -1,7 +1,7 @@
 Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-SymbolicName: org.eclipse.e4.core.contexts
-Bundle-Version: 0.10.0.qualifier
+Bundle-Version: 1.0.0.qualifier
 Bundle-Name: %pluginName
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextObjectSupplier.java b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextObjectSupplier.java
index d5d3f51..6a26d00 100644
--- a/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextObjectSupplier.java
+++ b/bundles/org.eclipse.e4.core.contexts/src/org/eclipse/e4/core/internal/contexts/ContextObjectSupplier.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
  *******************************************************************************/
 package org.eclipse.e4.core.internal.contexts;
 
+import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import javax.inject.Named;
 import org.eclipse.e4.core.contexts.Active;
@@ -188,8 +189,18 @@
 			return namedAnnotation.value();
 		}
 		Type elementType = descriptor.getDesiredType();
-		if (elementType instanceof Class<?>)
-			return ((Class<?>) elementType).getName();
+		return typeToString(elementType);
+	}
+
+	private String typeToString(Type type) {
+		if (type == null)
+			return null;
+		if (type instanceof Class<?>)
+			return ((Class<?>) type).getName();
+		if (type instanceof ParameterizedType) {
+			Type rawType = ((ParameterizedType) type).getRawType();
+			return typeToString(rawType);
+		}
 		return null;
 	}
 
diff --git a/tests/org.eclipse.e4.core.tests/META-INF/MANIFEST.MF b/tests/org.eclipse.e4.core.tests/META-INF/MANIFEST.MF
index b2aa8bf..b94500a 100644
--- a/tests/org.eclipse.e4.core.tests/META-INF/MANIFEST.MF
+++ b/tests/org.eclipse.e4.core.tests/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: E4 Core Tests
 Bundle-SymbolicName: org.eclipse.e4.core.tests
-Bundle-Version: 0.9.0.qualifier
+Bundle-Version: 1.0.0.qualifier
 Bundle-Activator: org.eclipse.e4.core.internal.tests.CoreTestsActivator
 Require-Bundle: org.junit;bundle-version="3.8.2",
  org.eclipse.osgi;bundle-version="3.6.0",
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/inject/GenericsInjectionTest.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/inject/GenericsInjectionTest.java
new file mode 100644
index 0000000..25e67f7
--- /dev/null
+++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/internal/tests/contexts/inject/GenericsInjectionTest.java
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.core.internal.tests.contexts.inject;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import junit.framework.TestCase;
+
+import org.eclipse.e4.core.contexts.ContextInjectionFactory;
+import org.eclipse.e4.core.contexts.EclipseContextFactory;
+import org.eclipse.e4.core.contexts.IEclipseContext;
+
+/**
+ * Tests for the generics context injection functionality
+ */
+public class GenericsInjectionTest extends TestCase {
+
+	static public class Animal {
+	}
+
+	static public class Bird extends Animal {
+	}
+
+	static public class Feeder<T extends Animal> {
+	}
+
+	static public class BirdHouse extends Feeder<Bird> {
+	}
+
+	static public class TestNamedObject {
+		public Feeder<Bird> field;
+
+		@Inject
+		public void setFeeder(@Named("test") Feeder<Bird> value) {
+			field = value;
+		}
+	}
+
+	static public class TestGenericObject {
+		public Feeder<Bird> field;
+
+		@Inject
+		public void setFeeder(Feeder<Bird> value) {
+			field = value;
+		}
+	}
+
+	public synchronized void testNamedInjection() {
+		Animal testAnimal = new Animal();
+		Bird testBird = new Bird();
+		BirdHouse testBirdHouse = new BirdHouse();
+
+		// create context
+		IEclipseContext context = EclipseContextFactory.create();
+		context.set(Animal.class, testAnimal);
+		context.set(Bird.class, testBird);
+		context.set("test", testBirdHouse);
+
+		TestNamedObject userObject = new TestNamedObject();
+		ContextInjectionFactory.inject(userObject, context);
+
+		// check field injection
+		assertEquals(testBirdHouse, userObject.field);
+	}
+
+	public synchronized void testGenericInjection() {
+		Animal testAnimal = new Animal();
+		Bird testBird = new Bird();
+		BirdHouse testBirdHouse = new BirdHouse();
+
+		// create context
+		IEclipseContext context = EclipseContextFactory.create();
+		context.set(Animal.class, testAnimal);
+		context.set(Bird.class, testBird);
+		context.set(Feeder.class, testBirdHouse); // note that BirdHouse is
+													// added as Feeder class
+
+		TestGenericObject userObject = new TestGenericObject();
+		ContextInjectionFactory.inject(userObject, context);
+
+		// check field injection
+		assertEquals(testBirdHouse, userObject.field);
+	}
+
+	static public interface Interface<T> {
+	}
+
+	static public class Implementation implements Interface<Object> {
+	}
+
+	static public class InterfaceTarget {
+		@Inject
+		public Interface<Object> field;
+	}
+
+	public void testInterfaceGenericInjection() {
+		Implementation implementation = new Implementation();
+		// create context
+		IEclipseContext context = EclipseContextFactory.create();
+		context.set(Interface.class, implementation);
+
+		InterfaceTarget target = new InterfaceTarget();
+		ContextInjectionFactory.inject(target, context);
+
+		// check field injection
+		assertEquals(implementation, target.field);
+	}
+
+	static public class Superclass<T> {
+	}
+
+	static public class Subclass extends Superclass<Object> {
+	}
+
+	static public class ClassTarget {
+		@Inject
+		public Superclass<Object> field;
+	}
+
+	public void testClassGenericInjection() {
+		Subclass implementation = new Subclass();
+		// create context
+		IEclipseContext context = EclipseContextFactory.create();
+		context.set(Superclass.class, implementation);
+
+		ClassTarget target = new ClassTarget();
+		ContextInjectionFactory.inject(target, context);
+
+		// check field injection
+		assertEquals(implementation, target.field);
+	}
+
+}
diff --git a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/tests/CoreTestSuite.java b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/tests/CoreTestSuite.java
index 4b6dbca..407a2b6 100644
--- a/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/tests/CoreTestSuite.java
+++ b/tests/org.eclipse.e4.core.tests/src/org/eclipse/e4/core/tests/CoreTestSuite.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 IBM Corporation and others.
+ * Copyright (c) 2009, 2011 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -31,6 +31,7 @@
 import org.eclipse.e4.core.internal.tests.contexts.inject.ContextInjectionTest;
 import org.eclipse.e4.core.internal.tests.contexts.inject.DisposingReferencedContextTest;
 import org.eclipse.e4.core.internal.tests.contexts.inject.ExtraDependenciesTest;
+import org.eclipse.e4.core.internal.tests.contexts.inject.GenericsInjectionTest;
 import org.eclipse.e4.core.internal.tests.contexts.inject.GroupedUpdatesTest;
 import org.eclipse.e4.core.internal.tests.contexts.inject.InjectStaticContextTest;
 import org.eclipse.e4.core.internal.tests.contexts.inject.InjectionUpdateTest;
@@ -98,5 +99,6 @@
 		addTestSuite(Bug317183Test.class);
 		addTestSuite(DependenciesLeakTest.class);
 		addTestSuite(ActivationInjectionTest.class);
+		addTestSuite(GenericsInjectionTest.class);
 	}
 }