Bug 305707 - add a way to contribute object providers to dependency injection
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextChangeEvent.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextChangeEvent.java
index 3aabd9f..fe66ece 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextChangeEvent.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/ContextChangeEvent.java
@@ -10,7 +10,6 @@
*******************************************************************************/
package org.eclipse.e4.core.services.context;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
/**
* An event describing a change to an {@link IEclipseContext}. The following types of events are
@@ -67,7 +66,7 @@
public static final int UPDATE = 5;
private Object[] args;
- private IObjectProvider context;
+ private IEclipseContext context;
private int eventType;
private String key;
@@ -81,7 +80,7 @@
* @param args
* @param name
*/
- ContextChangeEvent(IObjectProvider context, int eventType, Object[] args, String name,
+ ContextChangeEvent(IEclipseContext context, int eventType, Object[] args, String name,
Object oldValue) {
this.context = context;
this.key = name;
@@ -105,7 +104,7 @@
*
* @return the context where the change occurred
*/
- public IObjectProvider getContext() {
+ public IEclipseContext getContext() {
return context;
}
@@ -135,8 +134,8 @@
public int hashCode() {
final int prime = 31;
int result = 1;
- if ((eventType == DISPOSE) || (eventType == UNINJECTED))
- result = prime * result + ((context == null) ? 0 : context.hashCode());
+ // if ((eventType == DISPOSE) || (eventType == UNINJECTED))
+ // result = prime * result + ((context == null) ? 0 : context.hashCode());
result = prime * result + eventType;
result = prime * result + ((key == null) ? 0 : key.hashCode());
return result;
@@ -151,13 +150,13 @@
return false;
ContextChangeEvent other = (ContextChangeEvent) obj;
- if ((eventType == DISPOSE) || (eventType == UNINJECTED)) {
- if (context == null) {
- if (other.context != null)
- return false;
- } else if (!context.equals(other.context))
- return false;
- }
+ // if ((eventType == DISPOSE) || (eventType == UNINJECTED)) {
+ // if (context == null) {
+ // if (other.context != null)
+ // return false;
+ // } else if (!context.equals(other.context))
+ // return false;
+ // }
if (eventType != other.eventType)
return false;
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java
index cf16ce2..5f1cf5b 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/EclipseContextFactory.java
@@ -15,9 +15,7 @@
import org.eclipse.e4.core.services.context.spi.IContextConstants;
import org.eclipse.e4.core.services.context.spi.IEclipseContextStrategy;
import org.eclipse.e4.core.services.context.spi.ILookupStrategy;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
import org.eclipse.e4.core.services.internal.context.EclipseContext;
-import org.eclipse.e4.core.services.internal.context.ObjectProviderContext;
import org.eclipse.e4.internal.core.services.osgi.OSGiContextStrategy;
import org.osgi.framework.BundleContext;
@@ -97,12 +95,6 @@
*/
public static ContextChangeEvent createContextEvent(IEclipseContext context, int eventType,
Object[] args, String name, Object oldValue) {
- return new ContextChangeEvent(new ObjectProviderContext(context), eventType, args, name,
- oldValue);
- }
-
- public static ContextChangeEvent createContextEvent(IObjectProvider provider, int eventType,
- Object[] args, String name, Object oldValue) {
- return new ContextChangeEvent(provider, eventType, args, name, oldValue);
+ return new ContextChangeEvent(context, eventType, args, name, oldValue);
}
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ContextInjectionFactory.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ContextInjectionFactory.java
index 82c7094..a85bd43 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ContextInjectionFactory.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/context/spi/ContextInjectionFactory.java
@@ -16,11 +16,11 @@
import org.eclipse.e4.core.services.IDisposable;
import org.eclipse.e4.core.services.context.IEclipseContext;
import org.eclipse.e4.core.services.context.IEclipseContextAware;
+import org.eclipse.e4.core.services.injector.AbstractObjectSupplier;
import org.eclipse.e4.core.services.injector.IInjector;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
import org.eclipse.e4.core.services.injector.InjectorFactory;
+import org.eclipse.e4.core.services.internal.context.ContextObjectSupplier;
import org.eclipse.e4.core.services.internal.context.EclipseContext;
-import org.eclipse.e4.core.services.internal.context.ObjectProviderContext;
/**
* An injection factory is used to inject data and services from a context into a domain object. The
@@ -93,8 +93,9 @@
* @return Returns the injected object
*/
static public Object inject(Object object, IEclipseContext context) {
- IObjectProvider provider = ObjectProviderContext.getObjectProvider(context);
- injector.inject(object, provider);
+ AbstractObjectSupplier supplier = ContextObjectSupplier.getObjectSupplier(context,
+ injector);
+ injector.inject(object, supplier);
return object;
}
@@ -115,8 +116,9 @@
*/
static public Object invoke(Object object, String methodName, IEclipseContext context)
throws InvocationTargetException, CoreException {
- IObjectProvider provider = ObjectProviderContext.getObjectProvider(context);
- return injector.invoke(object, methodName, provider);
+ AbstractObjectSupplier supplier = ContextObjectSupplier.getObjectSupplier(context,
+ injector);
+ return injector.invoke(object, methodName, supplier);
}
/**
@@ -136,8 +138,9 @@
*/
static public Object invoke(Object object, String methodName, IEclipseContext context,
Object defaultValue) throws InvocationTargetException {
- IObjectProvider provider = ObjectProviderContext.getObjectProvider(context);
- return injector.invoke(object, methodName, defaultValue, provider);
+ AbstractObjectSupplier supplier = ContextObjectSupplier.getObjectSupplier(context,
+ injector);
+ return injector.invoke(object, methodName, defaultValue, supplier);
}
/**
@@ -169,7 +172,8 @@
*/
static public Object make(Class clazz, final IEclipseContext context)
throws InvocationTargetException, InstantiationException {
- IObjectProvider provider = ObjectProviderContext.getObjectProvider(context);
- return injector.make(clazz, provider);
+ AbstractObjectSupplier supplier = ContextObjectSupplier.getObjectSupplier(context,
+ injector);
+ return injector.make(clazz, supplier);
}
}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/AbstractObjectSupplier.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/AbstractObjectSupplier.java
new file mode 100644
index 0000000..d7d24d1
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/AbstractObjectSupplier.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.services.injector;
+
+/**
+ * This interface describes an "object supplier" - something that knows how to instantiate objects
+ * corresponding to the descriptor. NOTE: This is a preliminary form; this API will change.
+ */
+abstract public class AbstractObjectSupplier {
+
+ final protected IInjector injector;
+
+ // TBD remove?
+ abstract public Object get(IObjectDescriptor descriptor, IRequestor requestor);
+
+ abstract public Object[] get(IObjectDescriptor[] descriptors, IRequestor requestor);
+
+ public AbstractObjectSupplier(IInjector injector) {
+ this.injector = injector;
+ }
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IBinding.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IBinding.java
new file mode 100644
index 0000000..72476a4
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IBinding.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.injector;
+
+// TBD should this be an abstract base class?
+/**
+ * Describes binding between object description and its implementation to be used by the dependency
+ * injection.
+ *
+ */
+public interface IBinding {
+
+ public IBinding named(String name);
+
+ public IBinding implementedBy(Class<?> clazz);
+
+ public Class<?> getDescribedClass();
+
+ public String getQualifierName();
+
+ public Class<?> getImplementationClass();
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IInjector.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IInjector.java
index 62c75b8..d6a67c7 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IInjector.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IInjector.java
@@ -23,17 +23,32 @@
*/
public interface IInjector {
- public boolean inject(Object object, IObjectProvider objectProvider);
+ final public static Object NOT_A_VALUE = new Object();
- public Object make(Class clazz, IObjectProvider objectProvider)
- throws InvocationTargetException, InstantiationException;
+ public boolean inject(Object object, AbstractObjectSupplier objectSupplier);
- public Object invoke(Object object, String methodName, IObjectProvider objectProvider)
+ public boolean uninject(Object object, AbstractObjectSupplier objectSupplier);
+
+ public Object invoke(Object object, String methodName, AbstractObjectSupplier objectSupplier)
throws InvocationTargetException, CoreException;
public Object invoke(Object object, String methodName, Object defaultValue,
- IObjectProvider objectProvider) throws InvocationTargetException;
+ AbstractObjectSupplier objectSupplier) throws InvocationTargetException;
- public boolean injectStatic(Class clazz, IObjectProvider objectProvider);
+ public Object make(Class<?> clazz, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException, InstantiationException;
+
+ public Object make(IObjectDescriptor descriptor, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException, InstantiationException;
+
+ public boolean injectStatic(Class<?> clazz, AbstractObjectSupplier objectSupplier);
+
+ public boolean update(IRequestor[] requestors, AbstractObjectSupplier objectSupplier);
+
+ public boolean disposed(AbstractObjectSupplier objectSupplier);
+
+ public IBinding addBinding(Class<?> clazz);
+
+ public IBinding addBinding(IBinding binding);
}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IObjectDescriptor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IObjectDescriptor.java
new file mode 100644
index 0000000..c6040af
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IObjectDescriptor.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.injector;
+
+import java.lang.reflect.Type;
+
+/**
+ * NOTE: This is a preliminary form; this API will change.
+ *
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IObjectDescriptor {
+
+ // TBD rename getDesiredClass()
+ // TBD is this needed if we can get a Type?
+ public Class<?> getElementClass();
+
+ public Type getElementType();
+
+ public boolean isOptional();
+
+ public boolean hasQualifier(String qualifier);
+
+ public String[] getQualifiers();
+
+ public String getQualifierValue(String qualifier);
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IObjectProvider.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IObjectProvider.java
deleted file mode 100644
index 3b3323f..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IObjectProvider.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.services.injector;
-
-import org.eclipse.e4.core.services.context.IRunAndTrack;
-
-/**
- * This interface describes an "object provider" - something that knows how to instantiate objects
- * corresponding to the key. NOTE: This is a preliminary form; this API will change.
- */
-public interface IObjectProvider {
-
- public boolean containsKey(ObjectDescriptor key);
-
- public Object get(ObjectDescriptor key);
-
- // TBD replace this with events specific to injection, not context
- public void runAndTrack(final IRunAndTrack runnable, Object[] args);
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IRequestor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IRequestor.java
new file mode 100644
index 0000000..5e64c9d
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/IRequestor.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.injector;
+
+// TBD this is really a "feedback" object.
+/**
+ * @noimplement This interface is not intended to be implemented by clients.
+ * @noextend This interface is not intended to be extended by clients.
+ */
+public interface IRequestor {
+
+ /**
+ * The injected object that initiated this request
+ */
+ public Object getRequestingObject();
+
+ /**
+ * Determines if the requestor wants to be called whenever one of the dependent object changes.
+ */
+ public boolean shouldTrack();
+
+ public boolean shouldGroupUpdates();
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/ObjectDescriptorFactory.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/ObjectDescriptorFactory.java
new file mode 100644
index 0000000..c2ef932
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/ObjectDescriptorFactory.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.injector;
+
+import java.lang.reflect.Type;
+import javax.inject.Named;
+import org.eclipse.e4.core.services.internal.context.ObjectDescriptor;
+
+/**
+ * NOTE: This is a preliminary form; this API will change.
+ *
+ * @noextend This class is not intended to be subclassed by clients.
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+final public class ObjectDescriptorFactory {
+
+ static final private String named = Named.class.getName();
+
+ private ObjectDescriptorFactory() {
+ // prevents instantiation
+ }
+
+ static public IObjectDescriptor make(Class<?> clazz, boolean optional) {
+ return new ObjectDescriptor(clazz, null, null, optional);
+ }
+
+ static public IObjectDescriptor make(Type type, boolean optional) {
+ return new ObjectDescriptor(type, null, null, optional);
+ }
+
+ static public IObjectDescriptor make(String name, boolean optional) {
+ return new ObjectDescriptor(null, new String[] { named }, new String[] { name }, optional);
+ }
+
+ static public IObjectDescriptor make(Class<?> clazz, String name, boolean optional) {
+ if (name == null)
+ return make(clazz, optional);
+ return new ObjectDescriptor(clazz, new String[] { named }, new String[] { name }, optional);
+ }
+
+ static public IObjectDescriptor make(Type type, String name, boolean optional) {
+ if (name == null)
+ return make(type, optional);
+ return new ObjectDescriptor(type, new String[] { named }, new String[] { name }, optional);
+ }
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/annotations/AnnotationsSupport.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/annotations/AnnotationsSupport.java
index fc007da..2fbdef5 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/annotations/AnnotationsSupport.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/annotations/AnnotationsSupport.java
@@ -13,7 +13,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
+import java.lang.reflect.Type;
import org.eclipse.e4.core.services.internal.context.InjectionProperties;
/**
@@ -25,28 +25,28 @@
// placeholder
}
- public InjectionProperties getInjectProperties(Field field, IObjectProvider context) {
+ public InjectionProperties getInjectProperties(Field field) {
return new InjectionProperties(false, null, false);
}
- public InjectionProperties getInjectProperties(Method method, IObjectProvider context) {
+ public InjectionProperties getInjectProperties(Method method) {
return new InjectionProperties(false, null, false);
}
- public InjectionProperties getInjectProperties(Constructor constructor, IObjectProvider context) {
+ public InjectionProperties getInjectProperties(Constructor constructor) {
return new InjectionProperties(true, null, false);
}
- public InjectionProperties[] getInjectParamsProperties(Constructor constructor,
- IObjectProvider context) {
- Class[] params = constructor.getParameterTypes();
+ public InjectionProperties[] getInjectParamsProperties(Constructor constructor) {
+ Type[] params = constructor.getGenericParameterTypes();
+
InjectionProperties[] result = new InjectionProperties[params.length];
for (int i = 0; i < result.length; i++)
result[i] = new InjectionProperties(false, null, false);
return result;
}
- public InjectionProperties[] getInjectParamProperties(Method method, IObjectProvider context) {
+ public InjectionProperties[] getInjectParamProperties(Method method) {
Class[] params = method.getParameterTypes();
InjectionProperties[] result = new InjectionProperties[params.length];
for (int i = 0; i < result.length; i++)
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Binding.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Binding.java
new file mode 100644
index 0000000..192af5b
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Binding.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.internal.context;
+
+import org.eclipse.e4.core.services.injector.IBinding;
+import org.eclipse.e4.core.services.injector.IInjector;
+
+public class Binding implements IBinding {
+
+ final private Class<?> clazz;
+ final private IInjector injector;
+
+ private Class<?> implementationClazz;
+ private String qualifierName;
+
+ public Binding(Class<?> clazz, IInjector injector) {
+ this.clazz = clazz;
+ this.injector = injector;
+ }
+
+ private Binding(Binding source) {
+ this.clazz = source.clazz;
+ this.injector = source.injector;
+ this.implementationClazz = source.implementationClazz;
+ this.qualifierName = source.qualifierName;
+ }
+
+ public IBinding named(String name) {
+ Binding binding = new Binding(this);
+ binding.qualifierName = name;
+ injector.addBinding(binding);
+ return binding;
+ }
+
+ public IBinding implementedBy(Class<?> clazz) {
+ Binding binding = new Binding(this);
+ binding.implementationClazz = clazz;
+ injector.addBinding(binding);
+ return binding;
+ }
+
+ public Class<?> getDescribedClass() {
+ return clazz;
+ }
+
+ public String getQualifierName() {
+ return qualifierName;
+ }
+
+ public Class<?> getImplementationClass() {
+ if (implementationClazz != null)
+ return implementationClazz;
+ return clazz;
+ }
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java
index c71570b..59afe26 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Computation.java
@@ -18,7 +18,6 @@
import java.util.Set;
import org.eclipse.e4.core.services.context.ContextChangeEvent;
import org.eclipse.e4.core.services.context.IEclipseContext;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
import org.eclipse.e4.core.services.internal.context.EclipseContext.Scheduled;
abstract class Computation {
@@ -52,8 +51,7 @@
public abstract boolean equals(Object arg0);
final void handleInvalid(ContextChangeEvent event, List<Scheduled> scheduled) {
- IObjectProvider provider = event.getContext();
- IEclipseContext context = ((ObjectProviderContext) provider).getContext();
+ IEclipseContext context = event.getContext();
String name = event.getName();
Set<String> names = dependencies.get(context);
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ConstructorRequestor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ConstructorRequestor.java
new file mode 100644
index 0000000..1407b0c
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ConstructorRequestor.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.internal.context;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Type;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+import org.eclipse.e4.core.services.injector.ObjectDescriptorFactory;
+
+public class ConstructorRequestor extends Requestor {
+
+ final private Constructor<?> constructor;
+
+ public ConstructorRequestor(Constructor<?> constructor) {
+ // TBD make an integer update types? 0 - static , 1 - normal, 2 - grouped?
+ super(null, false /* do not track */, false /* N/A: no updates */, false /* mandatory */);
+ this.constructor = constructor;
+ }
+
+ public Object execute() throws InvocationTargetException, InstantiationException {
+ return callConstructor(constructor, actualArgs);
+ }
+
+ @Override
+ public IObjectDescriptor[] getDependentObjects() {
+ // Class[] parameterTypes = constructor.getParameterTypes();
+ Type[] parameterTypes = constructor.getGenericParameterTypes();
+ InjectionProperties[] properties = annotationSupport.getInjectParamsProperties(constructor);
+ IObjectDescriptor[] descriptors = new IObjectDescriptor[properties.length];
+ for (int i = 0; i < properties.length; i++) {
+ descriptors[i] = ObjectDescriptorFactory.make(parameterTypes[i], properties[i]
+ .getPropertyName(), properties[i].isOptional());
+ }
+ return descriptors;
+ }
+
+ private Object callConstructor(Constructor<?> constructor, Object[] args)
+ throws InvocationTargetException, InstantiationException {
+ Object result = null;
+ boolean wasAccessible = true;
+ if (!constructor.isAccessible()) {
+ constructor.setAccessible(true);
+ wasAccessible = false;
+ }
+ try {
+ result = constructor.newInstance(args);
+ } catch (IllegalArgumentException e) {
+ // should not happen, is checked at the start of this method
+ logError(constructor, e);
+ return null;
+ } catch (IllegalAccessException e) {
+ // should not happen as we set constructor to be accessible
+ logError(constructor, e);
+ return null;
+ } finally {
+ if (!wasAccessible)
+ constructor.setAccessible(false);
+ }
+ return result;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextObjectSupplier.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextObjectSupplier.java
new file mode 100644
index 0000000..8fbb8e2
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ContextObjectSupplier.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.services.internal.context;
+
+import javax.inject.Named;
+import org.eclipse.e4.core.services.context.ContextChangeEvent;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.IRunAndTrack;
+import org.eclipse.e4.core.services.injector.AbstractObjectSupplier;
+import org.eclipse.e4.core.services.injector.IInjector;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+import org.eclipse.e4.core.services.injector.IRequestor;
+
+public class ContextObjectSupplier extends AbstractObjectSupplier {
+
+ static private class ContextInjectionListener implements IRunAndTrackObject {
+
+ final private Object[] result;
+ final private String[] keys;
+ final private IInjector injector;
+ final private IRequestor requestor;
+ final private AbstractObjectSupplier supplier;
+ final private IEclipseContext context;
+
+ public ContextInjectionListener(IEclipseContext context, Object[] result, String[] keys,
+ IInjector injector, IRequestor requestor, AbstractObjectSupplier supplier) {
+ this.result = result;
+ this.keys = keys;
+ this.injector = injector;
+ this.requestor = requestor;
+ this.supplier = supplier;
+ this.context = context;
+ }
+
+ public boolean notify(ContextChangeEvent event) {
+ if (event.getEventType() == ContextChangeEvent.INITIAL) {
+ // needs to be done inside runnable to establish dependencies
+ for (int i = 0; i < keys.length; i++) {
+ if (keys[i] == null)
+ continue;
+ if (context.containsKey(keys[i]))
+ result[i] = context.get(keys[i]);
+ else
+ result[i] = IInjector.NOT_A_VALUE; // TBD make sure this still creates
+ // dependency on the key
+ }
+ } else if (event.getEventType() == ContextChangeEvent.DISPOSE) {
+ injector.disposed(supplier);
+ return false;
+ } else if (event.getEventType() == ContextChangeEvent.UNINJECTED) {
+ injector.uninject(event.getArguments()[0], supplier);
+ return false;
+ } else
+ injector.update(new IRequestor[] { requestor }, supplier);
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((context == null) ? 0 : context.hashCode());
+ result = prime * result + ((injector == null) ? 0 : injector.hashCode());
+ result = prime * result + ((requestor == null) ? 0 : requestor.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ContextInjectionListener other = (ContextInjectionListener) obj;
+ if (context == null) {
+ if (other.context != null)
+ return false;
+ } else if (!context.equals(other.context))
+ return false;
+ if (injector == null) {
+ if (other.injector != null)
+ return false;
+ } else if (!injector.equals(other.injector))
+ return false;
+ if (requestor == null) {
+ if (other.requestor != null)
+ return false;
+ } else if (!requestor.equals(other.requestor))
+ return false;
+ return true;
+ }
+
+ public Object getObject() {
+ // XXX remove?
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public boolean batchProcess() {
+ return requestor.shouldGroupUpdates();
+ }
+ }
+
+ final static private String ECLIPSE_CONTEXT_NAME = IEclipseContext.class.getName();
+ final private IEclipseContext context;
+
+ public ContextObjectSupplier(IEclipseContext context, IInjector injector) {
+ super(injector);
+ this.context = context;
+ }
+
+ public IEclipseContext getContext() {
+ return context;
+ }
+
+ @Override
+ public Object get(IObjectDescriptor descriptor, IRequestor requestor) {
+ // This method is rarely or never used on the primary supplier
+ if (descriptor == null)
+ return IInjector.NOT_A_VALUE;
+ Object[] result = get(new IObjectDescriptor[] { descriptor }, requestor);
+ if (result == null)
+ return null;
+ return result[0];
+ }
+
+ @Override
+ public Object[] get(IObjectDescriptor[] descriptors, final IRequestor requestor) {
+ final Object[] result = new Object[descriptors.length];
+ final String[] keys = new String[descriptors.length];
+
+ for (int i = 0; i < descriptors.length; i++) {
+ keys[i] = (descriptors[i] == null) ? null : getKey(descriptors[i]);
+ if (ECLIPSE_CONTEXT_NAME.equals(keys[i])) {
+ result[i] = context;
+ keys[i] = null;
+ }
+ }
+
+ if (requestor != null && requestor.shouldTrack()) { // only track if requested
+ IRunAndTrack trackable = new ContextInjectionListener(context, result, keys, injector,
+ requestor, this);
+ context.runAndTrack(trackable, null);
+ } else {
+ for (int i = 0; i < descriptors.length; i++) {
+ if (keys[i] == null)
+ continue;
+ if (context.containsKey(keys[i]))
+ result[i] = context.get(keys[i]);
+ else
+ result[i] = IInjector.NOT_A_VALUE;
+ }
+ }
+ return result;
+ }
+
+ private String getKey(IObjectDescriptor descriptor) {
+ if (descriptor.hasQualifier(Named.class.getName()))
+ return descriptor.getQualifierValue(Named.class.getName());
+ Class<?> elementClass = descriptor.getElementClass();
+ if (elementClass != null)
+ return elementClass.getName();
+ return null;
+ }
+
+ static public ContextObjectSupplier getObjectSupplier(IEclipseContext context,
+ IInjector injector) {
+ String key = ContextObjectSupplier.class.getName();
+ if (context.containsKey(key, true))
+ return (ContextObjectSupplier) context.get(key);
+ ContextObjectSupplier objectSupplier = new ContextObjectSupplier(context, injector);
+ context.set(key, objectSupplier);
+ return objectSupplier;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java
index 73b280d..0811591 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/EclipseContext.java
@@ -151,8 +151,7 @@
if ((eventType == ContextChangeEvent.ADDED)
|| (eventType == ContextChangeEvent.REMOVED)) {
cachedEvent = event;
- EclipseContext eventsContext = (EclipseContext) ((ObjectProviderContext) event
- .getContext()).getContext();
+ EclipseContext eventsContext = (EclipseContext) event.getContext();
eventsContext.addWaiting(this);
// eventsContext.getRoot().waiting.add(this);
return true;
@@ -171,8 +170,7 @@
} finally {
currentComputation.set(oldComputation);
}
- EclipseContext eventsContext = (EclipseContext) ((ObjectProviderContext) event
- .getContext()).getContext();
+ EclipseContext eventsContext = (EclipseContext) event.getContext();
if (result)
startListening(eventsContext);
else
@@ -407,7 +405,7 @@
* The given name has been modified or removed in this context. Invalidate all local value
* computations and listeners that depend on this name.
*/
- private void invalidate(String name, int eventType, Object oldValue, List<Scheduled> scheduled) {
+ public void invalidate(String name, int eventType, Object oldValue, List<Scheduled> scheduled) {
if (EclipseContext.DEBUG)
System.out.println("invalidating " + this + ',' + name); //$NON-NLS-1$
removeLocalValueComputations(name);
@@ -583,18 +581,11 @@
public void removeListenersTo(Object object) {
if (object == null)
return;
- synchronized (listeners) {
- ContextChangeEvent event = EclipseContextFactory.createContextEvent(this,
- ContextChangeEvent.UNINJECTED, null, null, null);
- for (Iterator<Computation> i = listeners.keySet().iterator(); i.hasNext();) {
- Computation computation = i.next();
- if (computation instanceof TrackableComputationExt) {
- if (object == ((TrackableComputationExt) computation).getObject()) {
- ((IRunAndTrack) computation).notify(event);
- i.remove();
- }
- }
- }
+ Computation[] ls = listeners.keySet().toArray(new Computation[listeners.size()]);
+ ContextChangeEvent event = EclipseContextFactory.createContextEvent(this,
+ ContextChangeEvent.UNINJECTED, new Object[] { object }, null, null);
+ for (Computation computation : ls) {
+ ((IRunAndTrack) computation).notify(event);
}
}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/FieldRequestor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/FieldRequestor.java
new file mode 100644
index 0000000..1d07427
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/FieldRequestor.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.internal.context;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+import org.eclipse.e4.core.services.injector.ObjectDescriptorFactory;
+
+public class FieldRequestor extends Requestor {
+
+ final private Field field;
+
+ public FieldRequestor(Field field, Object requestingObject, boolean track,
+ boolean groupUpdates, boolean optional) {
+ super(requestingObject, track, groupUpdates, optional);
+ this.field = field;
+ }
+
+ public Object execute() throws InvocationTargetException, InstantiationException {
+ setField(field, actualArgs[0]);
+ return null;
+ }
+
+ @Override
+ public IObjectDescriptor[] getDependentObjects() {
+ InjectionProperties properties = annotationSupport.getInjectProperties(field);
+ IObjectDescriptor objectDescriptor = ObjectDescriptorFactory.make(field.getGenericType(),
+ properties.getPropertyName(), properties.isOptional());
+ return new IObjectDescriptor[] { objectDescriptor };
+ }
+
+ private boolean setField(Field field, Object value) {
+ Object userObject = getRequestingObject();
+ if (userObject == null)
+ return false;
+ boolean wasAccessible = true;
+ if (!field.isAccessible()) {
+ field.setAccessible(true);
+ wasAccessible = false;
+ }
+ try {
+ field.set(userObject, value);
+ } catch (IllegalArgumentException e) {
+ logError(field, e);
+ return false;
+ } catch (IllegalAccessException e) {
+ logError(field, e);
+ return false;
+ } finally {
+ if (!wasAccessible)
+ field.setAccessible(false);
+ }
+ return true;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionAbstract.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionAbstract.java
deleted file mode 100644
index c2f7435..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionAbstract.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2010 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.services.internal.context;
-
-import java.lang.ref.WeakReference;
-import org.eclipse.e4.core.services.context.ContextChangeEvent;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
-import org.eclipse.e4.core.services.internal.annotations.AnnotationsSupport;
-
-abstract public class InjectionAbstract implements IRunAndTrackObject {
-
- final static protected Object NOT_A_VALUE = new Object();
-
- final protected WeakReference userObjectRef;
- final protected AnnotationsSupport annotationSupport;
- final protected IObjectProvider primarySupplier;
-
- protected boolean optional = false;
- final private boolean batchProcess;
-
- abstract public boolean notify(ContextChangeEvent event);
-
- public InjectionAbstract(Object userObject, IObjectProvider primarySupplier,
- boolean batchProcess) {
- userObjectRef = new WeakReference(userObject);
- // plug-in class that gets replaced in Java 1.5+
- annotationSupport = new AnnotationsSupport(); // TBD this should be a static util class
- this.primarySupplier = primarySupplier;
- this.batchProcess = batchProcess;
- }
-
- public Object getObject() {
- if (userObjectRef == null)
- return null;
- return userObjectRef.get();
- }
-
- protected boolean injectNulls(int eventType, IObjectProvider changed) {
- if ((eventType != ContextChangeEvent.UNINJECTED)
- && (eventType != ContextChangeEvent.DISPOSE))
- return false;
- return (changed.equals(primarySupplier));
- }
-
- protected boolean ignoreMissing(int eventType, IObjectProvider changed) {
- if (eventType == ContextChangeEvent.REMOVED)
- return true;
- if ((eventType != ContextChangeEvent.UNINJECTED)
- && (eventType != ContextChangeEvent.DISPOSE))
- return false;
- return (changed.equals(primarySupplier));
- }
-
- protected Object getValue(ObjectDescriptor objectDescriptor, InjectionProperties properties,
- Class parameterType, boolean ignoreMissing, boolean injectWithNulls) {
- // 1) if we have a provider, use it
- Object provider = properties.getProvider();
- if (provider != null)
- return provider;
-
- // 2) if we have the key in the context
- if (primarySupplier.containsKey(objectDescriptor)) {
- if (injectWithNulls)
- return null;
- Object value = primarySupplier.get(objectDescriptor);
- if (value == null)
- return value;
- if (parameterType.isAssignableFrom(value.getClass()))
- return value;
- }
-
- // 3) can we ignore this argument?
- if (ignoreMissing || properties.isOptional())
- return null;
-
- if (!optional) {
- String msg = "Unable to find value for \"" + objectDescriptor.toString() + "\"";
- throw new IllegalArgumentException(msg);
- }
- return NOT_A_VALUE;
- }
-
- protected void logError(Object destination, Exception e) {
- String msg = "Injection failed " + destination.toString();
- logError(msg, e);
- }
-
- protected void logError(String msg, Exception e) {
- System.out.println(msg); //$NON-NLS-1$
- if (e != null)
- e.printStackTrace();
- // TBD convert this into real logging
- // String msg = NLS.bind("Injection failed", destination.toString());
- // RuntimeLog.log(new Status(IStatus.WARNING,
- // IRuntimeConstants.PI_COMMON, 0, msg, e));
- }
-
- public boolean batchProcess() {
- return batchProcess;
- }
-
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionClass.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionClass.java
deleted file mode 100644
index aa79d6a..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionClass.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.services.internal.context;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Iterator;
-import org.eclipse.e4.core.services.IDisposable;
-import org.eclipse.e4.core.services.context.ContextChangeEvent;
-import org.eclipse.e4.core.services.context.IEclipseContext;
-import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory;
-import org.eclipse.e4.core.services.context.spi.IContextConstants;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
-
-public class InjectionClass extends InjectionAbstract {
-
- final static private String JAVA_OBJECT = "java.lang.Object"; //$NON-NLS-1$
-
- public InjectionClass(Object userObject, IObjectProvider primarySupplier) {
- super(userObject, primarySupplier, false);
- }
-
- public boolean notify(ContextChangeEvent event) {
- Object object = getObject();
- if (object == null)
- return false;
- int eventType = event.getEventType();
- if (eventType == ContextChangeEvent.DISPOSE) {
- if (object instanceof IDisposable)
- ((IDisposable) object).dispose();
- processPreDestory(object, object.getClass(), new ArrayList(5));
- return false;
- }
- if (eventType == ContextChangeEvent.INITIAL) {
- processPostConstruct(object, object.getClass(), new ArrayList(5));
- }
- IObjectProvider context = event.getContext();
- // pseudo-dependency to create a link
- ObjectDescriptor desc = ObjectDescriptor.make("e4_valid_context");
- context.get(desc);
- return true;
- }
-
- private void processPostConstruct(Object userObject, Class objectClass, ArrayList classHierarchy) {
- Class superClass = objectClass.getSuperclass();
- if (superClass != null && !superClass.getName().equals(JAVA_OBJECT)) {
- classHierarchy.add(objectClass);
- processPostConstruct(userObject, superClass, classHierarchy);
- classHierarchy.remove(objectClass);
- }
- Method[] methods = objectClass.getDeclaredMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- if (!isPostConstruct(method))
- continue;
- if (!isOverridden(method, classHierarchy)) {
- InjectionMethod methodInvoke = new InjectionMethod(getObject(), primarySupplier,
- method, false);
- try {
- methodInvoke.invoke(false, false);
- } catch (InjectionException e) {
- // TBD log
- e.printStackTrace();
- }
- }
- }
- }
-
- // TBD simplify this: only one non-annotation and one "implements IInitializable"?
- /**
- * Returns whether the given method is a post-construction process method, as defined by the
- * class comment of {@link ContextInjectionFactory}.
- */
- private boolean isPostConstruct(Method method) {
- boolean isPostConstruct = annotationSupport.isPostConstruct(method);
- if (isPostConstruct)
- return true;
- if (!method.getName().equals(IContextConstants.INJECTION_SET_CONTEXT_METHOD))
- return false;
- Class[] parms = method.getParameterTypes();
- if (parms.length == 0)
- return true;
- if (parms.length == 1 && parms[0].equals(IEclipseContext.class))
- return true;
- return false;
- }
-
- private void processPreDestory(Object userObject, Class objectClass, ArrayList classHierarchy) {
- Class superClass = objectClass.getSuperclass();
- if (superClass != null && !superClass.getName().equals(JAVA_OBJECT)) {
- classHierarchy.add(objectClass);
- processPreDestory(userObject, superClass, classHierarchy);
- classHierarchy.remove(objectClass);
- }
- Method[] methods = objectClass.getDeclaredMethods();
- for (int i = 0; i < methods.length; i++) {
- Method method = methods[i];
- if (method.getParameterTypes().length > 0) // TBD why?
- continue;
- if (!annotationSupport.isPreDestory(method))
- continue;
- if (!isOverridden(method, classHierarchy)) {
- InjectionMethod methodInvoke = new InjectionMethod(getObject(), primarySupplier,
- method, false);
- try {
- methodInvoke.invoke(false, false);
- } catch (InjectionException e) {
- // TBD log
- e.printStackTrace();
- }
- }
- }
- }
-
- // TBD move into the base class? For @PostConstruct?
- /**
- * Checks if a given method is overridden with an injectable method.
- */
- private boolean isOverridden(Method method, ArrayList classHierarchy) {
- int modifiers = method.getModifiers();
- if (Modifier.isPrivate(modifiers))
- return false;
- if (Modifier.isStatic(modifiers))
- return false;
- // method is not private if we reached this line, check not(public OR protected)
- boolean isDefault = !(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers));
-
- for (Iterator i = classHierarchy.iterator(); i.hasNext();) {
- Class subClass = (Class) i.next();
- Method override = null;
- try {
- override = subClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
- } catch (SecurityException e) {
- continue;
- } catch (NoSuchMethodException e) {
- continue; // this is the desired outcome
- }
- if (override != null) {
- if (isDefault) { // must be in the same package to override
- Package originalPackage = method.getDeclaringClass().getPackage();
- Package overridePackage = subClass.getPackage();
-
- if (originalPackage == null && overridePackage == null)
- return true;
- if (originalPackage == null || overridePackage == null)
- return false;
- if (originalPackage.equals(overridePackage))
- return true;
- } else
- return true;
- }
- }
- return false;
- }
-
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionConstructor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionConstructor.java
deleted file mode 100644
index efaf0b2..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionConstructor.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.services.internal.context;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import org.eclipse.e4.core.services.context.ContextChangeEvent;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
-
-/**
- * Collection of static methods that deal with reflection-based injection at a low level.
- */
-public class InjectionConstructor extends InjectionAbstract {
-
- private final Constructor constructor;
-
- public InjectionConstructor(Object userObject, IObjectProvider primarySupplier,
- Constructor constructor) {
- super(userObject, primarySupplier, false);
- this.constructor = constructor;
- }
-
- public boolean notify(ContextChangeEvent event) {
- if (event.getEventType() == ContextChangeEvent.INITIAL)
- make();
- return false; // constructor injection is static by nature
- }
-
- public Object make() {
- Object[] actualParams = processParams();
- if (actualParams == null)
- return null;
- try {
- return callConstructor(constructor, actualParams);
- } catch (InvocationTargetException e) {
- String msg = "Could not invoke " + constructor.getName();
- logError(msg, e);
- return null;
- } catch (InstantiationException e) {
- String msg = "Could not instantiate " + constructor.getName();
- logError(msg, e);
- return null;
- }
- }
-
- private Object[] processParams() {
- Class[] parameterTypes = constructor.getParameterTypes();
- InjectionProperties[] properties = annotationSupport.getInjectParamsProperties(constructor,
- primarySupplier);
- Object[] actualParams = new Object[properties.length];
- for (int i = 0; i < actualParams.length; i++) {
- try {
- ObjectDescriptor objectDescriptor = ObjectDescriptor.make(parameterTypes[i],
- properties[i].getPropertyName());
- actualParams[i] = getValue(objectDescriptor, properties[i], parameterTypes[i],
- false, false);
- } catch (IllegalArgumentException e) {
- String msg = "Unable to find matching arguments for " + constructor.getName();
- logError(msg, e);
- return null;
- }
- }
- return actualParams;
- }
-
- private Object callConstructor(Constructor constructor, Object[] args)
- throws InvocationTargetException, InstantiationException {
- if (args != null) { // make sure args are assignable
- Class[] parameterTypes = constructor.getParameterTypes();
- if (parameterTypes.length != args.length) {
- // internal error, log it
- logError(constructor, new IllegalArgumentException());
- return null;
- }
- for (int i = 0; i < args.length; i++) {
- if ((args[i] != null) && !parameterTypes[i].isAssignableFrom(args[i].getClass()))
- return null;
- }
- }
-
- Object result = null;
- boolean wasAccessible = true;
- if (!constructor.isAccessible()) {
- constructor.setAccessible(true);
- wasAccessible = false;
- }
- try {
- result = constructor.newInstance(args);
- } catch (IllegalArgumentException e) {
- // should not happen, is checked at the start of this method
- logError(constructor, e);
- return null;
- } catch (IllegalAccessException e) {
- // should not happen as we set constructor to be accessible
- logError(constructor, e);
- return null;
- } finally {
- if (!wasAccessible)
- constructor.setAccessible(false);
- }
- return result;
- }
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionField.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionField.java
deleted file mode 100644
index b7cb645..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionField.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.services.internal.context;
-
-import java.lang.reflect.Field;
-import org.eclipse.e4.core.services.context.ContextChangeEvent;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
-
-/**
- * Collection of static methods that deal with reflection-based injection at a low level.
- */
-public class InjectionField extends InjectionAbstract {
-
- private final Field field;
-
- public InjectionField(Object userObject, IObjectProvider primarySupplier, Field field,
- boolean batchProcess) {
- super(userObject, primarySupplier, batchProcess);
- this.field = field;
- InjectionProperties fieldProps = annotationSupport.getInjectProperties(field,
- primarySupplier);
- optional = fieldProps.isOptional();
- }
-
- public boolean notify(ContextChangeEvent event) {
- Object userObject = getObject();
- if (userObject == null)
- return false;
- // set variables based on the event type
- int eventType = event.getEventType();
- IObjectProvider changed = event.getContext();
-
- boolean ignoreMissing = ignoreMissing(eventType, changed);
- boolean injectWithNulls = injectNulls(eventType, changed);
-
- InjectionProperties properties = annotationSupport.getInjectProperties(field,
- primarySupplier);
- ObjectDescriptor objectDescriptor = ObjectDescriptor.make(field.getType(), properties
- .getPropertyName());
- Object value;
- try {
- value = getValue(objectDescriptor, properties, field.getType(), ignoreMissing,
- injectWithNulls);
- } catch (IllegalArgumentException e) {
- String msg = "Could not set " + field.getName();
- logError(msg, e);
- return true; // keep trying?
- }
- setField(value);
- if (eventType == ContextChangeEvent.DISPOSE && primarySupplier.equals(changed))
- return false;
- return true;
- }
-
- private boolean setField(Object value) {
- Object userObject = getObject();
- boolean wasAccessible = true;
- if (!field.isAccessible()) {
- field.setAccessible(true);
- wasAccessible = false;
- }
- try {
- field.set(userObject, value);
- } catch (IllegalArgumentException e) {
- logError(field, e);
- return false;
- } catch (IllegalAccessException e) {
- logError(field, e);
- return false;
- } finally {
- if (!wasAccessible)
- field.setAccessible(false);
- }
- return true;
- }
-
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionMethod.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionMethod.java
deleted file mode 100644
index 69ddd8d..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectionMethod.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.services.internal.context;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import org.eclipse.e4.core.services.context.ContextChangeEvent;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
-
-/**
- * Collection of static methods that deal with reflection-based injection at a low level.
- */
-public class InjectionMethod extends InjectionAbstract {
-
- private final Method method;
-
- public InjectionMethod(Object userObject, IObjectProvider primarySupplier, Method method,
- boolean batchProcess) {
- super(userObject, primarySupplier, batchProcess);
- this.method = method;
- InjectionProperties methodProps = annotationSupport.getInjectProperties(method,
- primarySupplier);
- optional = methodProps.isOptional();
- }
-
- public boolean notify(ContextChangeEvent event) {
- Object userObject = getObject();
- if (userObject == null)
- return false;
- int eventType = event.getEventType();
- IObjectProvider changed = event.getContext();
- boolean ignoreMissing = ignoreMissing(eventType, changed);
- boolean injectWithNulls = injectNulls(eventType, changed);
- try {
- invoke(ignoreMissing, injectWithNulls);
- } catch (InjectionException e) {
- logError(method, e);
- return false;
- }
- if (eventType == ContextChangeEvent.DISPOSE && primarySupplier.equals(changed))
- return false;
- return true;
- }
-
- public Object invoke(boolean ignoreMissing, boolean injectWithNulls) throws InjectionException {
- Object[] actualParams = processParams(ignoreMissing, injectWithNulls);
- if (actualParams == null) {
- if (!optional) {
- String msg = "Unable to find matching argument to call method \""
- + method.getName() + "\"";
- throw new InjectionException(msg);
- }
- return null;
- }
- try {
- return callMethod(actualParams);
- } catch (InvocationTargetException e) {
- String msg = "Unexpected error invoking method \"" + method.getName() + "\"";
- throw new InjectionException(msg, e);
- }
- }
-
- private Object[] processParams(boolean ignoreMissing, boolean injectWithNulls) {
- Class[] parameterTypes = method.getParameterTypes();
- InjectionProperties[] properties = annotationSupport.getInjectParamProperties(method,
- primarySupplier);
- Object[] actualParams = new Object[properties.length];
- for (int i = 0; i < actualParams.length; i++) {
- try {
- ObjectDescriptor objectDescriptor = ObjectDescriptor.make(parameterTypes[i],
- properties[i].getPropertyName());
- Object actualValue = getValue(objectDescriptor, properties[i], parameterTypes[i],
- ignoreMissing, injectWithNulls);
- if (actualValue == NOT_A_VALUE)
- return null;
- actualParams[i] = actualValue;
- } catch (IllegalArgumentException e) {
- String msg = "Could not invoke " + method.getName();
- logError(msg, e);
- return null;
- }
- }
- return actualParams;
- }
-
- private Object callMethod(Object[] args) throws InvocationTargetException {
- Object userObject = getObject();
- Object result = null;
- boolean wasAccessible = true;
- if (!method.isAccessible()) {
- method.setAccessible(true);
- wasAccessible = false;
- }
- try {
- result = method.invoke(userObject, args);
- } catch (IllegalArgumentException e) {
- // should not happen, is checked during formation of the array of actual arguments
- logError(method, e);
- return null;
- } catch (IllegalAccessException e) {
- // should not happen, is checked at the start of this method
- logError(method, e);
- return null;
- } finally {
- if (!wasAccessible)
- method.setAccessible(false);
- }
- return result;
- }
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectorImpl.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectorImpl.java
index 88829a8..2ed6436 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectorImpl.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/InjectorImpl.java
@@ -10,126 +10,608 @@
*******************************************************************************/
package org.eclipse.e4.core.services.internal.context;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.inject.Named;
+import javax.inject.Provider;
+import javax.inject.Singleton;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
-import org.eclipse.e4.core.internal.services.ServicesActivator;
+import org.eclipse.e4.core.services.IDisposable;
+import org.eclipse.e4.core.services.context.IEclipseContext;
+import org.eclipse.e4.core.services.context.spi.ContextInjectionFactory;
import org.eclipse.e4.core.services.context.spi.IContextConstants;
-import org.eclipse.e4.core.services.events.IEventBroker;
+import org.eclipse.e4.core.services.injector.AbstractObjectSupplier;
+import org.eclipse.e4.core.services.injector.IBinding;
import org.eclipse.e4.core.services.injector.IInjector;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+import org.eclipse.e4.core.services.injector.IRequestor;
+import org.eclipse.e4.core.services.injector.ObjectDescriptorFactory;
import org.eclipse.e4.core.services.internal.annotations.AnnotationsSupport;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventHandler;
/**
* Reflection-based dependency injector.
*/
public class InjectorImpl implements IInjector {
- final static private String DEBUG_INJECTOR = "org.eclipse.e4.core.services/debug/injector"; //$NON-NLS-1$
- final static private boolean shouldTrace = ServicesActivator.getDefault()
- .getBooleanDebugOption(DEBUG_INJECTOR, false);
final static private String JAVA_OBJECT = "java.lang.Object"; //$NON-NLS-1$
-
+ // XXX remove
// plug-in class that gets replaced in Java 1.5+
- final private static AnnotationsSupport annotationSupport = new AnnotationsSupport(); // XXX
- // remove;
+ final private static AnnotationsSupport annotationSupport = new AnnotationsSupport();
- public InjectorImpl() {
- // placeholder
+ // TBD thread safety
+ private Map<String, AbstractObjectSupplier> extendedSuppliers = new HashMap<String, AbstractObjectSupplier>();
+
+ private Map<AbstractObjectSupplier, List<WeakReference<?>>> injectedObjects = new HashMap<AbstractObjectSupplier, List<WeakReference<?>>>();
+ private HashMap<Class<?>, Object> singletonCache = new HashMap<Class<?>, Object>();
+ private Map<Class<?>, Set<IBinding>> bindings = new HashMap<Class<?>, Set<IBinding>>();
+
+ public boolean inject(Object object, AbstractObjectSupplier objectSupplier) {
+ // Two stages: first, go and collect {requestor, descriptor[] }
+ ArrayList<Requestor> requestors = new ArrayList<Requestor>();
+ processClassHierarchy(object, false /* no static */, true /* track */, true /* normal order */,
+ requestors);
+ // Ask suppliers to fill actual values {requestor, descriptor[], actualvalues[] }
+ if (!resolveRequestorArgs(requestors, objectSupplier, false))
+ return false;
+
+ // Call requestors in order
+ for (Requestor requestor : requestors) {
+ try {
+ if (requestor.isResolved())
+ requestor.execute();
+ } catch (InvocationTargetException e) {
+ logError("Injection failed for the object \"" + object.toString()
+ + "\". Unable to execute \"" + requestor.toString() + "\"");
+ return false;
+ } catch (InstantiationException e) {
+ logError("Injection failed for the object \"" + object.toString()
+ + "\". Unable to execute \"" + requestor.toString() + "\"");
+ return false;
+ }
+ }
+ rememberInjectedObject(object, objectSupplier);
+
+ // TBD current tests assume that @PostConstruct methods will be
+ // called after injection; however, name implies that it is only
+ // called when the object is constructed. Fix this after the 1.4/1.5 merge.
+ try {
+ processPostConstruct(object, object.getClass(), objectSupplier,
+ new ArrayList<Class<?>>(5));
+ } catch (InvocationTargetException e) {
+ logError("Injection failed for the object \"" + object.toString()
+ + "\". Unable to process post-construct methods.", e);
+ return false;
+ } catch (InstantiationException e) {
+ logError("Injection failed for the object \"" + object.toString()
+ + "\". Unable to process post-construct methods.", e);
+ return false;
+ }
+ return true;
}
- public boolean inject(Object userObject, IObjectProvider objectProvider) {
- boolean result = false;
- try {
- result = processClassHierarchy(userObject, false /* process static */, objectProvider);
- } catch (InvocationTargetException e) {
- logExternalError("Exception occured while processing injecting", userObject, e);
+ private void rememberInjectedObject(Object object, AbstractObjectSupplier objectSupplier) {
+ synchronized (injectedObjects) {
+ List<WeakReference<?>> list;
+ if (!injectedObjects.containsKey(objectSupplier)) {
+ list = new ArrayList<WeakReference<?>>();
+ injectedObjects.put(objectSupplier, list);
+ } else
+ list = injectedObjects.get(objectSupplier);
+ for (WeakReference<?> ref : list) {
+ if (object == ref.get())
+ return; // we already have it
+ }
+ list.add(new WeakReference<Object>(object));
}
- objectProvider.runAndTrack(new InjectionClass(userObject, objectProvider), null);
+ }
+
+ private boolean forgetInjectedObject(Object object, AbstractObjectSupplier objectSupplier) {
+ synchronized (injectedObjects) {
+ if (!injectedObjects.containsKey(objectSupplier))
+ return false;
+ List<WeakReference<?>> list = injectedObjects.get(objectSupplier);
+ for (Iterator<WeakReference<?>> i = list.iterator(); i.hasNext();) {
+ WeakReference<?> ref = i.next();
+ if (object == ref.get())
+ i.remove();
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private List<WeakReference<?>> forgetSupplier(AbstractObjectSupplier objectSupplier) {
+ synchronized (injectedObjects) {
+ if (!injectedObjects.containsKey(objectSupplier))
+ return null;
+ return injectedObjects.remove(objectSupplier);
+ }
+ }
+
+ private List<WeakReference<?>> getSupplierObjects(AbstractObjectSupplier objectSupplier) {
+ synchronized (injectedObjects) {
+ if (!injectedObjects.containsKey(objectSupplier))
+ return null;
+ return injectedObjects.get(objectSupplier);
+ }
+ }
+
+ public boolean uninject(Object object, AbstractObjectSupplier objectSupplier) {
+ if (!forgetInjectedObject(object, objectSupplier))
+ return false; // not injected at this time
+ // Two stages: first, go and collect {requestor, descriptor[] }
+ ArrayList<Requestor> requestors = new ArrayList<Requestor>();
+ processClassHierarchy(object, false /* no static */, true /* track */,
+ false /* inverse order */, requestors);
+ // might still need to get resolved values from secondary suppliers
+ // Ask suppliers to fill actual values {requestor, descriptor[], actualvalues[] }
+ if (!resolveRequestorArgs(requestors, null, true /* fill with nulls */))
+ return false;
+
+ // Call requestors in order
+ for (Requestor requestor : requestors) {
+ try {
+ requestor.execute();
+ } catch (InvocationTargetException e) {
+ logError("Uninjection failed for the object \"" + object.toString()
+ + "\". Unable to execute \"" + requestor.toString() + "\"");
+ return false;
+ } catch (InstantiationException e) {
+ logError("Uninjection failed for the object \"" + object.toString()
+ + "\". Unable to execute \"" + requestor.toString() + "\"");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Object invoke(Object object, String methodName, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException, CoreException {
+ Object result = invokeUsingClass(object, object.getClass(), methodName,
+ IInjector.NOT_A_VALUE, objectSupplier);
+ if (result == IInjector.NOT_A_VALUE) {
+ IStatus status = new Status(IStatus.ERROR, "org.eclipse.e4.core.services",
+ "Unable to find matching method to invoke");
+ throw new CoreException(status);
+ }
return result;
}
- // TBD use null object to inject statics
- public boolean injectStatic(Class clazz, IObjectProvider objectProvider) {
+ public Object invoke(Object object, String methodName, Object defaultValue,
+ AbstractObjectSupplier objectSupplier) throws InvocationTargetException {
+ return invokeUsingClass(object, object.getClass(), methodName, defaultValue, objectSupplier);
+ }
+
+ private Object invokeUsingClass(Object userObject, Class<?> currentClass, String methodName,
+ Object defaultValue, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException {
+ Method[] methods = currentClass.getDeclaredMethods();
+ for (int j = 0; j < methods.length; j++) {
+ Method method = methods[j];
+ if (!method.getName().equals(methodName))
+ continue;
+ MethodRequestor requestor = new MethodRequestor(method, userObject, false, false, true);
+
+ Object[] actualArgs = resolveArgs(requestor, objectSupplier, false);
+ int unresolved = unresolved(actualArgs);
+ if (unresolved != -1) {
+ logError("Injection failed for object \""
+ + requestor.getRequestingObject().toString()
+ + "\". Unable to find value for \""
+ + requestor.getDependentObjects()[unresolved] + "\"");
+ return null;
+ }
+ requestor.setResolvedArgs(actualArgs);
+
+ try {
+ return requestor.execute();
+ } catch (InstantiationException e) {
+ // TBD clean up the error handling; need to propagate original exception
+ logError("Exception occured in the injected method " + method.getName(), e);
+ return null;
+ }
+ }
+ Class<?> superClass = currentClass.getSuperclass();
+ if (superClass == null) {
+ return defaultValue;
+ }
+ return invokeUsingClass(userObject, superClass, methodName, defaultValue, objectSupplier);
+ }
+
+ public Object make(Class<?> clazz, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException, InstantiationException {
+ IObjectDescriptor descriptor = ObjectDescriptorFactory.make(clazz, false);
+ return make(descriptor, objectSupplier);
+ }
+
+ public Object make(IObjectDescriptor descriptor, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException, InstantiationException {
+ IBinding binding = findBinding(descriptor);
+ if (binding == null) {
+ Class<?> desiredClass = descriptor.getElementClass();
+ return internalMake(desiredClass, objectSupplier);
+ }
+ return internalMake(binding.getImplementationClass(), objectSupplier);
+ }
+
+ private Object internalMake(Class<?> clazz, AbstractObjectSupplier objectSupplier)
+ throws InvocationTargetException, InstantiationException {
+
+ boolean isSingleton = clazz.isAnnotationPresent(Singleton.class);
+ if (isSingleton) {
+ synchronized (singletonCache) {
+ if (singletonCache.containsKey(clazz))
+ return singletonCache.get(clazz);
+ }
+ }
+
+ Constructor<?>[] constructors = clazz.getDeclaredConstructors();
+ // Sort the constructors by descending number of constructor arguments
+ ArrayList<Constructor<?>> sortedConstructors = new ArrayList<Constructor<?>>(
+ constructors.length);
+ for (Constructor<?> constructor : constructors)
+ sortedConstructors.add(constructor);
+ Collections.sort(sortedConstructors, new Comparator<Constructor<?>>() {
+ public int compare(Constructor<?> c1, Constructor<?> c2) {
+ int l1 = c1.getParameterTypes().length;
+ int l2 = c2.getParameterTypes().length;
+ return l2 - l1;
+ }
+ });
+
+ for (Constructor<?> constructor : sortedConstructors) {
+ // skip private and protected constructors; allow public and package visibility
+ int modifiers = constructor.getModifiers();
+ if (((modifiers & Modifier.PRIVATE) != 0) || ((modifiers & Modifier.PROTECTED) != 0))
+ continue;
+
+ // unless this is the default constructor, it has to be tagged
+ InjectionProperties cProps = annotationSupport.getInjectProperties(constructor);
+ if (!cProps.shouldInject() && constructor.getParameterTypes().length != 0)
+ continue;
+
+ ConstructorRequestor requestor = new ConstructorRequestor(constructor);
+ Object[] actualArgs = resolveArgs(requestor, objectSupplier, false);
+ if (unresolved(actualArgs) != -1)
+ continue;
+ requestor.setResolvedArgs(actualArgs);
+
+ Object newInstance = requestor.execute();
+ if (newInstance != null) {
+ inject(newInstance, objectSupplier);
+ if (isSingleton) {
+ synchronized (singletonCache) { // TBD this is not quite right, synch the method
+ singletonCache.put(clazz, newInstance);
+ }
+ }
+ return newInstance;
+ }
+ }
+
+ logError("Could not find satisfiable constructor in class " + clazz.getName());
+ return null;
+ }
+
+ public boolean injectStatic(Class<?> clazz, AbstractObjectSupplier objectSupplier) {
+ // TBD add processing on a null object
+ Object object;
try {
- Object object = make(clazz, objectProvider);
- return processClassHierarchy(object, true /* process static */, objectProvider);
+ object = make(clazz, objectSupplier);
} catch (InvocationTargetException e) {
// try-catch won't be necessary once we stop creating an object
e.printStackTrace();
+ return false;
} catch (InstantiationException e) {
// try-catch won't be necessary once we stop creating an object
e.printStackTrace();
+ return false;
}
- return false;
+
+ // TBD this is copy/paste from as invoke() with static = true.
+ // Two stages: first, go and collect {requestor, descriptor[] }
+ ArrayList<Requestor> requestors = new ArrayList<Requestor>();
+ processClassHierarchy(object, true /* static */, true /* track */, true /* normal order */,
+ requestors);
+ // Ask suppliers to fill actual values {requestor, descriptor[], actualvalues[] }
+ if (!resolveRequestorArgs(requestors, objectSupplier, false))
+ return false;
+
+ // Call requestors in order
+ for (Requestor requestor : requestors) {
+ try {
+ requestor.execute();
+ } catch (InvocationTargetException e) {
+ logError("Injection failed for the object \"" + object.toString()
+ + "\". Unable to execute \"" + requestor.toString() + "\"");
+ return false;
+ } catch (InstantiationException e) {
+ logError("Injection failed for the object \"" + object.toString()
+ + "\". Unable to execute \"" + requestor.toString() + "\"");
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public boolean update(IRequestor[] requestors, AbstractObjectSupplier objectSupplier) {
+ ArrayList<Requestor> list = new ArrayList<Requestor>(requestors.length);
+ for (IRequestor requestor : requestors) {
+ list.add((Requestor) requestor);
+ }
+ resolveRequestorArgs(list, objectSupplier, true);
+
+ // Call requestors in order
+ for (IRequestor requestor : requestors) {
+ try {
+ ((Requestor) requestor).execute();
+ } catch (InvocationTargetException e) {
+ logError("Injection failed for the object \""
+ + requestor.getRequestingObject().toString() + "\". Unable to execute \""
+ + requestor.toString() + "\"");
+ return false;
+ } catch (InstantiationException e) {
+ logError("Injection failed for the object \""
+ + requestor.getRequestingObject().toString() + "\". Unable to execute \""
+ + requestor.toString() + "\"");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public boolean disposed(AbstractObjectSupplier objectSupplier) {
+ List<WeakReference<?>> references = getSupplierObjects(objectSupplier);
+ if (references == null)
+ return true;
+ Object[] objects = new Object[references.size()];
+ int count = 0;
+ for (WeakReference<?> ref : references) {
+ Object object = ref.get();
+ if (object != null) {
+ objects[count] = object;
+ count++;
+ }
+ }
+ for (int i = 0; i < count; i++) {
+ processPreDestory(objects[i], objects[i].getClass(), new ArrayList<Class<?>>(5));
+ uninject(objects[i], objectSupplier);
+ }
+ forgetSupplier(objectSupplier);
+ return true;
+ }
+
+ private void processPreDestory(Object userObject, Class<?> objectClass,
+ ArrayList<Class<?>> classHierarchy) {
+ Class<?> superClass = objectClass.getSuperclass();
+ if (superClass != null && !superClass.getName().equals(JAVA_OBJECT)) {
+ classHierarchy.add(objectClass);
+ processPreDestory(userObject, superClass, classHierarchy);
+ classHierarchy.remove(objectClass);
+ }
+ Method[] methods = objectClass.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (method.getParameterTypes().length > 0) // TBD why?
+ continue;
+ if (!annotationSupport.isPreDestory(method))
+ continue;
+ if (!isOverridden(method, classHierarchy)) {
+ // TBD optional @PreDestory? might make sense if we allow args on those methods
+ MethodRequestor requestor = new MethodRequestor(method, userObject, false, false,
+ false);
+ try {
+ requestor.execute();
+ } catch (InvocationTargetException e) {
+ logError("Unable to call pre-destory method \"" + method.getName() + "\"", e);
+ } catch (InstantiationException e) {
+ logError("Unable to call pre-destory method \"" + method.getName() + "\"", e);
+ }
+ }
+ }
+ if (userObject instanceof IDisposable)
+ ((IDisposable) userObject).dispose();
+ }
+
+ private boolean resolveRequestorArgs(ArrayList<Requestor> requestors,
+ AbstractObjectSupplier objectSupplier, boolean fillNulls) {
+ for (Requestor requestor : requestors) {
+ Object[] actualArgs = resolveArgs(requestor, objectSupplier, fillNulls);
+ int unresolved = unresolved(actualArgs);
+ if (unresolved == -1) {
+ requestor.setResolvedArgs(actualArgs);
+ continue;
+ }
+
+ if (requestor.isOptional())
+ requestor.setResolvedArgs(null);
+ else {
+ logError("Injection failed for object \""
+ + requestor.getRequestingObject().toString()
+ + "\". Unable to find value for \""
+ + requestor.getDependentObjects()[unresolved] + "\"");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private Object[] resolveArgs(Requestor requestor, AbstractObjectSupplier objectSupplier,
+ boolean fillNulls) {
+ IObjectDescriptor[] descriptors = requestor.getDependentObjects();
+
+ // 0) initial fill - all are unresolved
+ Object[] actualArgs = new Object[descriptors.length];
+ for (int i = 0; i < actualArgs.length; i++) {
+ actualArgs[i] = NOT_A_VALUE;
+ }
+
+ // 1) check if we have a Provider<T>
+ for (int i = 0; i < actualArgs.length; i++) {
+ Class<?> providerClass = getProviderType(descriptors[i].getElementType());
+ if (providerClass == null)
+ continue;
+ actualArgs[i] = new ProviderImpl<Class<?>>(descriptors[i], this, objectSupplier);
+ descriptors[i] = null; // mark as used
+ }
+
+ // 2) use the primary supplier
+ if (objectSupplier != null) {
+ Object[] primarySupplierArgs = objectSupplier.get(descriptors, requestor);
+ for (int i = 0; i < actualArgs.length; i++) {
+ if (descriptors[i] == null)
+ continue; // already resolved
+ if (primarySupplierArgs[i] != NOT_A_VALUE) {
+ actualArgs[i] = primarySupplierArgs[i];
+ descriptors[i] = null; // mark as used
+ }
+ }
+ }
+
+ // 3) try extended suppliers
+ for (int i = 0; i < actualArgs.length; i++) {
+ if (descriptors[i] == null)
+ continue; // already resolved
+ AbstractObjectSupplier extendedSupplier = findExtendedSupplier(descriptors[i]);
+ if (extendedSupplier == null)
+ continue;
+ Object result = extendedSupplier.get(descriptors[i], requestor);
+ if (result != NOT_A_VALUE) {
+ actualArgs[i] = result;
+ descriptors[i] = null; // mark as used
+ }
+ }
+
+ // 4) try the bindings
+ for (int i = 0; i < actualArgs.length; i++) {
+ if (descriptors[i] == null)
+ continue; // already resolved
+ IBinding binding = findBinding(descriptors[i]);
+ if (binding != null) {
+ try {
+ actualArgs[i] = internalMake(binding.getImplementationClass(), objectSupplier);
+ } catch (InvocationTargetException e) {
+ logError("Unable to create object for class \""
+ + binding.getImplementationClass() + "\".", e);
+ continue;
+ } catch (InstantiationException e) {
+ logError("Unable to create object for class \""
+ + binding.getImplementationClass() + "\".", e);
+ continue;
+ }
+ }
+ }
+
+ // 5) post process
+ descriptors = requestor.getDependentObjects(); // reset nulled out values
+ for (int i = 0; i < descriptors.length; i++) {
+ // check that values are of a correct type
+ if (actualArgs[i] != null && actualArgs[i] != IInjector.NOT_A_VALUE) {
+ Class<?> descriptorsClass = descriptors[i].getElementClass();
+ if (!descriptorsClass.isAssignableFrom(actualArgs[i].getClass()))
+ actualArgs[i] = IInjector.NOT_A_VALUE;
+ }
+ // replace optional unresolved values with null
+ if (descriptors[i].isOptional() && actualArgs[i] == IInjector.NOT_A_VALUE)
+ actualArgs[i] = null;
+ else if (fillNulls && actualArgs[i] == IInjector.NOT_A_VALUE)
+ actualArgs[i] = null;
+ }
+
+ return actualArgs;
+ }
+
+ private AbstractObjectSupplier findExtendedSupplier(IObjectDescriptor descriptor) {
+ String[] qualifiers = descriptor.getQualifiers();
+ if (qualifiers == null)
+ return null;
+ for (String qualifier : qualifiers) {
+ if (extendedSuppliers.containsKey(qualifier))
+ return extendedSuppliers.get(qualifier);
+ }
+ return null;
+ }
+
+ private int unresolved(Object[] actualArgs) {
+ for (int i = 0; i < actualArgs.length; i++) {
+ if (actualArgs[i] == IInjector.NOT_A_VALUE)
+ return i;
+ }
+ return -1;
+ }
+
+ private void processClassHierarchy(Object userObject, boolean processStatic, boolean track,
+ boolean normalOrder, List<Requestor> requestors) {
+ processClass(userObject, (userObject == null) ? null : userObject.getClass(),
+ new ArrayList<Class<?>>(5), processStatic, track, normalOrder, requestors);
}
/**
* Make the processor visit all declared members on the given class and all superclasses
- *
- * @throws InvocationTargetException
*/
- private boolean processClass(Object userObject, Class objectsClass, ArrayList classHierarchy,
- boolean processStatic, IObjectProvider objectProvider) throws InvocationTargetException {
+ private void processClass(Object userObject, Class<?> objectsClass,
+ ArrayList<Class<?>> classHierarchy, boolean processStatic, boolean track,
+ boolean normalOrder, List<Requestor> requestors) {
// order: superclass, fields, methods
if (objectsClass != null) {
- Class superClass = objectsClass.getSuperclass();
+ Class<?> superClass = objectsClass.getSuperclass();
if (!superClass.getName().equals(JAVA_OBJECT)) {
classHierarchy.add(objectsClass);
- if (!processClass(userObject, superClass, classHierarchy, processStatic,
- objectProvider))
- return false;
+ processClass(userObject, superClass, classHierarchy, processStatic, track,
+ normalOrder, requestors);
classHierarchy.remove(objectsClass);
}
}
- if (!processFields(userObject, objectsClass, processStatic, objectProvider))
- return false;
- if (!processMethods(userObject, objectsClass, classHierarchy, processStatic, objectProvider))
- return false;
- return true;
- }
-
- private boolean processClassHierarchy(Object userObject, boolean processStatic,
- IObjectProvider objectProvider) throws InvocationTargetException {
- if (!processClass(userObject, (userObject == null) ? null : userObject.getClass(),
- new ArrayList(5), processStatic, objectProvider))
- return false;
- return true;
+ if (normalOrder) {
+ processFields(userObject, objectsClass, processStatic, track, requestors);
+ processMethods(userObject, objectsClass, classHierarchy, processStatic, track,
+ requestors);
+ } else {
+ processMethods(userObject, objectsClass, classHierarchy, processStatic, track,
+ requestors);
+ processFields(userObject, objectsClass, processStatic, track, requestors);
+ }
}
/**
* Make the processor visit all declared fields on the given class.
*/
- private boolean processFields(Object userObject, Class objectsClass, boolean processStatic,
- IObjectProvider objectProvider) {
+ private void processFields(Object userObject, Class<?> objectsClass, boolean processStatic,
+ boolean track, List<Requestor> requestors) {
Field[] fields = objectsClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
if (Modifier.isStatic(field.getModifiers()) != processStatic)
continue;
- InjectionProperties properties = annotationSupport.getInjectProperties(field,
- objectProvider);
+
+ // XXX limit to "should inject"
+ InjectionProperties properties = annotationSupport.getInjectProperties(field);
+ // XXX this will be removed on 1.4/1.5 merge
if (field.getName().startsWith(IContextConstants.INJECTION_PREFIX))
properties.setInject(true);
-
if (!properties.shouldInject())
continue;
- objectProvider.runAndTrack(new InjectionField(userObject, objectProvider, field,
- properties.groupUpdates()), null);
+
+ requestors.add(new FieldRequestor(field, userObject, track, properties.groupUpdates(),
+ properties.isOptional()));
}
- return true;
}
/**
@@ -137,9 +619,9 @@
*
* @throws InvocationTargetException
*/
- private boolean processMethods(final Object userObject, Class objectsClass,
- ArrayList classHierarchy, boolean processStatic, IObjectProvider objectProvider)
- throws InvocationTargetException {
+ private void processMethods(final Object userObject, Class<?> objectsClass,
+ ArrayList<Class<?>> classHierarchy, boolean processStatic, boolean track,
+ List<Requestor> requestors) {
Method[] methods = objectsClass.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
final Method method = methods[i];
@@ -147,50 +629,49 @@
continue; // process in the subclass
if (Modifier.isStatic(method.getModifiers()) != processStatic)
continue;
- InjectionProperties properties = annotationSupport.getInjectProperties(method,
- objectProvider);
+
+ InjectionProperties properties = annotationSupport.getInjectProperties(method);
if (method.getName().startsWith(IContextConstants.INJECTION_PREFIX))
properties.setInject(true);
- if (properties.getHandlesEvent() != null) {
- // XXX this is wrong, but it will be removed anyway
- ObjectDescriptor desc = ObjectDescriptor.make(IEventBroker.class);
- IEventBroker eventBroker = (IEventBroker) objectProvider.get(desc);
- eventBroker.subscribe(properties.getHandlesEvent(), null, new EventHandler() {
- public void handleEvent(Event event) {
- Object data = event.getProperty(IEventBroker.DATA);
- boolean wasAccessible = method.isAccessible();
- if (!wasAccessible) {
- method.setAccessible(true);
- }
- try {
- method.invoke(userObject, data);
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- if (!wasAccessible) {
- method.setAccessible(false);
- }
- }
- }
- }, properties.getEventHeadless());
- continue;
- }
+ // replace with @Event("name") qualifier
+ // if (properties.getHandlesEvent() != null) {
+ // // XXX this is wrong, but it will be removed anyway
+ // ObjectDescriptor desc = ObjectDescriptor.make(IEventBroker.class);
+ // IEventBroker eventBroker = (IEventBroker) objectProvider.get(desc);
+ // eventBroker.subscribe(properties.getHandlesEvent(), null, new EventHandler() {
+ // public void handleEvent(Event event) {
+ // Object data = event.getProperty(IEventBroker.DATA);
+ // boolean wasAccessible = method.isAccessible();
+ // if (!wasAccessible) {
+ // method.setAccessible(true);
+ // }
+ // try {
+ // method.invoke(userObject, data);
+ // } catch (Exception e) {
+ // throw new RuntimeException(e);
+ // } finally {
+ // if (!wasAccessible) {
+ // method.setAccessible(false);
+ // }
+ // }
+ // }
+ // }, properties.getEventHeadless());
+ // continue;
+ // }
if (!properties.shouldInject())
continue;
- objectProvider.runAndTrack(new InjectionMethod(userObject, objectProvider, method,
- properties.groupUpdates()), null);
+ requestors.add(new MethodRequestor(method, userObject, track,
+ properties.groupUpdates(), properties.isOptional()));
}
- return true;
}
- // TBD this is the same method as in the class injector
/**
* Checks if a given method is overridden with an injectable method.
*/
- private boolean isOverridden(Method method, ArrayList classHierarchy) {
+ private boolean isOverridden(Method method, ArrayList<Class<?>> classHierarchy) {
int modifiers = method.getModifiers();
if (Modifier.isPrivate(modifiers))
return false;
@@ -199,141 +680,175 @@
// method is not private if we reached this line, check not(public OR protected)
boolean isDefault = !(Modifier.isPublic(modifiers) || Modifier.isProtected(modifiers));
- for (Iterator i = classHierarchy.iterator(); i.hasNext();) {
- Class subClass = (Class) i.next();
- Method override = null;
+ for (Class<?> subClass : classHierarchy) {
try {
- override = subClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
+ subClass.getDeclaredMethod(method.getName(), method.getParameterTypes());
} catch (SecurityException e) {
continue;
} catch (NoSuchMethodException e) {
continue; // this is the desired outcome
}
- if (override != null) {
- if (isDefault) { // must be in the same package to override
- Package originalPackage = method.getDeclaringClass().getPackage();
- Package overridePackage = subClass.getPackage();
+ if (isDefault) { // must be in the same package to override
+ Package originalPackage = method.getDeclaringClass().getPackage();
+ Package overridePackage = subClass.getPackage();
- if (originalPackage == null && overridePackage == null)
- return true;
- if (originalPackage == null || overridePackage == null)
- return false;
- if (originalPackage.equals(overridePackage))
- return true;
- } else
+ if (originalPackage == null && overridePackage == null)
return true;
- }
+ if (originalPackage == null || overridePackage == null)
+ return false;
+ if (originalPackage.equals(overridePackage))
+ return true;
+ } else
+ return true;
}
return false;
}
- public Object invoke(Object userObject, String methodName, IObjectProvider objectProvider)
- throws InvocationTargetException, CoreException {
- Method[] methods = userObject.getClass().getDeclaredMethods();
- for (int j = 0; j < methods.length; j++) {
- Method method = methods[j];
- if (!method.getName().equals(methodName))
- continue;
-
- InjectionMethod injectMethod = new InjectionMethod(userObject, objectProvider, method,
- false);
- try {
- return injectMethod.invoke(false, false);
- } catch (InjectionException e) {
- IStatus status = new Status(IStatus.ERROR, "org.eclipse.e4.core.services",
- "Unable to invoke method");
- throw new CoreException(status);
- }
- }
- IStatus status = new Status(IStatus.ERROR, "org.eclipse.e4.core.services",
- "Unable to find matching method to invoke");
- throw new CoreException(status);
- }
-
- public Object invoke(Object userObject, String methodName, Object defaultValue,
- IObjectProvider objectProvider) throws InvocationTargetException {
- return invokeUsingClass(userObject, userObject.getClass(), methodName, defaultValue,
- objectProvider);
- }
-
- public Object invokeUsingClass(Object userObject, Class currentClass, String methodName,
- Object defaultValue, IObjectProvider objectProvider) throws InvocationTargetException {
- Method[] methods = currentClass.getDeclaredMethods();
- for (int j = 0; j < methods.length; j++) {
- Method method = methods[j];
- if (!method.getName().equals(methodName))
- continue;
-
- InjectionMethod injectMethod = new InjectionMethod(userObject, objectProvider, method,
- false);
- try {
- return injectMethod.invoke(false, false);
- } catch (InjectionException e) {
- // TBD? abort or continue?
- logExternalError("Exception occured in the injectd method " + method.getName(),
- userObject, e);
- }
- }
- Class superClass = currentClass.getSuperclass();
- if (superClass == null) {
- return defaultValue;
- }
- return invokeUsingClass(userObject, superClass, methodName, defaultValue, objectProvider);
- }
-
- public Object make(Class clazz, IObjectProvider objectProvider)
+ private void processPostConstruct(Object userObject, Class<?> objectClass,
+ AbstractObjectSupplier objectSupplier, ArrayList<Class<?>> classHierarchy)
throws InvocationTargetException, InstantiationException {
- Constructor[] constructors = clazz.getDeclaredConstructors();
+ Class<?> superClass = objectClass.getSuperclass();
+ if (superClass != null && !superClass.getName().equals(JAVA_OBJECT)) {
+ classHierarchy.add(objectClass);
+ processPostConstruct(userObject, superClass, objectSupplier, classHierarchy);
+ classHierarchy.remove(objectClass);
+ }
+ Method[] methods = objectClass.getDeclaredMethods();
+ for (int i = 0; i < methods.length; i++) {
+ Method method = methods[i];
+ if (!isPostConstruct(method))
+ continue;
+ if (isOverridden(method, classHierarchy))
+ continue;
- // Sort the constructors by descending number of constructor arguments
- ArrayList sortedConstructors = new ArrayList(constructors.length);
- for (int i = 0; i < constructors.length; i++)
- sortedConstructors.add(constructors[i]);
- Collections.sort(sortedConstructors, new Comparator() {
- public int compare(Object c1, Object c2) {
- int l1 = ((Constructor) c1).getParameterTypes().length;
- int l2 = ((Constructor) c2).getParameterTypes().length;
- return l2 - l1;
+ MethodRequestor requestor = new MethodRequestor(method, userObject, false, false, false);
+ Object[] actualArgs = resolveArgs(requestor, objectSupplier, false);
+ int unresolved = unresolved(actualArgs);
+ if (unresolved != -1) {
+ logError("Injection failed for object \""
+ + requestor.getRequestingObject().toString()
+ + "\". Unable to find value for \""
+ + requestor.getDependentObjects()[unresolved] + "\"");
+ continue;
}
- });
+ requestor.setResolvedArgs(actualArgs);
- for (Iterator i = sortedConstructors.iterator(); i.hasNext();) {
- Constructor constructor = (Constructor) i.next();
-
- // skip private and protected constructors; allow public and package visibility
- if (((constructor.getModifiers() & Modifier.PRIVATE) != 0)
- || ((constructor.getModifiers() & Modifier.PROTECTED) != 0))
- continue;
-
- // unless this is the default constructor, it has to be tagged
- InjectionProperties cProps = annotationSupport.getInjectProperties(constructor,
- objectProvider);
- if (!cProps.shouldInject() && constructor.getParameterTypes().length != 0)
- continue;
-
- InjectionConstructor injectedConstructor = new InjectionConstructor(null,
- objectProvider, constructor);
- Object newInstance = injectedConstructor.make();
- if (newInstance != null) {
- inject(newInstance, objectProvider);
- return newInstance;
+ try {
+ requestor.execute();
+ } catch (InvocationTargetException e) {
+ logError("Unable to call post-construct method \"" + method.getName() + "\"", e);
+ } catch (InstantiationException e) {
+ logError("Unable to call post-construct method \"" + method.getName() + "\"", e);
}
}
+ }
- if (shouldTrace)
- System.out
- .println("Could not find satisfiable constructor in class " + clazz.getName());
+ // TBD simplify this: only one non-annotation and one "implements IInitializable"?
+ /**
+ * Returns whether the given method is a post-construction process method, as defined by the
+ * class comment of {@link ContextInjectionFactory}.
+ */
+ private boolean isPostConstruct(Method method) {
+ boolean isPostConstruct = annotationSupport.isPostConstruct(method);
+ if (isPostConstruct)
+ return true;
+ if (!method.getName().equals(IContextConstants.INJECTION_SET_CONTEXT_METHOD))
+ return false;
+ Class<?>[] parms = method.getParameterTypes();
+ if (parms.length == 0)
+ return true;
+ if (parms.length == 1 && parms[0].equals(IEclipseContext.class))
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns null if not a provider
+ */
+ private Class<?> getProviderType(Type type) {
+ if (!(type instanceof ParameterizedType))
+ return null;
+ Type rawType = ((ParameterizedType) type).getRawType();
+ if (!(rawType instanceof Class<?>))
+ return null;
+ boolean isProvider = ((Class<?>) rawType).equals(Provider.class);
+ if (!isProvider)
+ return null;
+ Type[] actualTypes = ((ParameterizedType) type).getActualTypeArguments();
+ if (actualTypes.length != 1)
+ return null;
+ if (!(actualTypes[0] instanceof Class<?>))
+ return null;
+ return (Class<?>) actualTypes[0];
+ }
+
+ public IBinding addBinding(Class<?> clazz) {
+ return addBinding(new Binding(clazz, this));
+ }
+
+ public IBinding addBinding(IBinding binding) {
+ Class<?> clazz = binding.getDescribedClass();
+ synchronized (bindings) {
+ if (bindings.containsKey(clazz)) {
+ Set<IBinding> collection = bindings.get(clazz);
+ String desiredQualifierName = binding.getQualifierName();
+ for (Iterator<IBinding> i = collection.iterator(); i.hasNext();) {
+ IBinding collectionBinding = i.next();
+ if (eq(collectionBinding.getQualifierName(), desiredQualifierName)) {
+ i.remove();
+ break;
+ }
+ }
+ collection.add(binding);
+ } else {
+ Set<IBinding> collection = new HashSet<IBinding>(1);
+ collection.add(binding);
+ bindings.put(clazz, collection);
+ }
+ }
+ return binding;
+ }
+
+ private IBinding findBinding(IObjectDescriptor descriptor) {
+ Class<?> desiredClass = getProviderType(descriptor.getElementType());
+ if (desiredClass == null)
+ desiredClass = descriptor.getElementClass();
+ synchronized (bindings) {
+ if (!bindings.containsKey(desiredClass))
+ return null;
+ Set<IBinding> collection = bindings.get(desiredClass);
+ String desiredQualifierName = descriptor.getQualifierValue(Named.class.getName());
+
+ for (Iterator<IBinding> i = collection.iterator(); i.hasNext();) {
+ IBinding collectionBinding = i.next();
+ if (eq(collectionBinding.getQualifierName(), desiredQualifierName))
+ return collectionBinding;
+ }
+ }
return null;
}
- private void logExternalError(String msg, Object destination, Exception e) {
- System.out.println(msg + " " + destination.toString()); //$NON-NLS-1$
+ /**
+ * Are two, possibly null, string equal?
+ */
+ private boolean eq(String str1, String str2) {
+ if (str1 == null && str2 == null)
+ return true;
+ if (str1 == null || str2 == null)
+ return false;
+ return str1.equals(str2);
+ }
+
+ // TBD implement logging
+ private void logError(String msg) {
+ logError(msg, new InjectionException());
+ }
+
+ private void logError(String msg, Throwable e) {
+ if (msg != null)
+ System.err.println(msg);
if (e != null)
e.printStackTrace();
- // TBD convert this into real logging
- // String msg = NLS.bind("Injection failed", destination.toString());
- // RuntimeLog.log(new Status(IStatus.WARNING,
- // IRuntimeConstants.PI_COMMON, 0, msg, e));
}
}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/MethodRequestor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/MethodRequestor.java
new file mode 100644
index 0000000..574dcad
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/MethodRequestor.java
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.internal.context;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+import org.eclipse.e4.core.services.injector.ObjectDescriptorFactory;
+
+public class MethodRequestor extends Requestor {
+
+ final private Method method;
+
+ public MethodRequestor(Method method, Object requestingObject, boolean track,
+ boolean groupUpdates, boolean optional) {
+ super(requestingObject, track, groupUpdates, optional);
+ this.method = method;
+ }
+
+ public Object execute() throws InvocationTargetException, InstantiationException {
+ return callMethod(method, actualArgs);
+ }
+
+ @Override
+ public IObjectDescriptor[] getDependentObjects() {
+ Type[] parameterTypes = method.getGenericParameterTypes();
+ // TBD make getInjectParamProperties produce ObjectDescriptors
+ InjectionProperties[] properties = annotationSupport.getInjectParamProperties(method);
+ IObjectDescriptor[] descriptors = new IObjectDescriptor[properties.length];
+ for (int i = 0; i < properties.length; i++) {
+ descriptors[i] = ObjectDescriptorFactory.make(parameterTypes[i], properties[i]
+ .getPropertyName(), properties[i].isOptional());
+ }
+ return descriptors;
+ }
+
+ private Object callMethod(Method method, Object[] args) throws InvocationTargetException {
+ Object userObject = getRequestingObject();
+ if (userObject == null)
+ return null;
+ Object result = null;
+ boolean wasAccessible = true;
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ wasAccessible = false;
+ }
+ try {
+ result = method.invoke(userObject, args);
+ } catch (IllegalArgumentException e) {
+ // should not happen, is checked during formation of the array of actual arguments
+ logError(method, e);
+ return null;
+ } catch (IllegalAccessException e) {
+ // should not happen, is checked at the start of this method
+ logError(method, e);
+ return null;
+ } finally {
+ if (!wasAccessible)
+ method.setAccessible(false);
+ }
+ return result;
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/ObjectDescriptor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ObjectDescriptor.java
similarity index 62%
rename from bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/ObjectDescriptor.java
rename to bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ObjectDescriptor.java
index ae2be2b..4041a55 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/injector/ObjectDescriptor.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ObjectDescriptor.java
@@ -8,45 +8,50 @@
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
-package org.eclipse.e4.core.services.injector;
+package org.eclipse.e4.core.services.internal.context;
-import javax.inject.Named;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
/**
* NOTE: This is a preliminary form; this API will change.
*
* @noextend This class is not intended to be subclassed by clients.
*/
-public class ObjectDescriptor {
+public class ObjectDescriptor implements IObjectDescriptor {
- final private Class desiredClass;
+ final private Type desiredType;
final private String[] qualifiers;
final private String[] values;
- static final private String named = Named.class.getName();
+ // TBD make "Optional" a qualifier?
+ final private boolean optional;
- static public ObjectDescriptor make(Class clazz) {
- return new ObjectDescriptor(clazz, null, null);
- }
-
- static public ObjectDescriptor make(String name) {
- return new ObjectDescriptor(null, new String[] { named }, new String[] { name });
- }
-
- static public ObjectDescriptor make(Class clazz, String name) {
- if (name == null)
- return make(clazz);
- return new ObjectDescriptor(clazz, new String[] { named }, new String[] { name });
- }
-
- public ObjectDescriptor(Class desiredClass, String[] qualifiers, String[] values) {
- this.desiredClass = desiredClass;
+ public ObjectDescriptor(Type desiredType, String[] qualifiers, String[] values, boolean optional) {
+ this.desiredType = desiredType;
this.qualifiers = qualifiers;
this.values = values;
+ this.optional = optional;
}
- public Class getElementClass() {
- return desiredClass;
+ // TBD rename getDesiredClass()
+ public Class<?> getElementClass() {
+ if (desiredType instanceof Class<?>)
+ return (Class<?>) desiredType;
+ if (desiredType instanceof ParameterizedType)
+ return (Class<?>) ((ParameterizedType) desiredType).getRawType(); // XXX this is wrong;
+ // might be
+ // Param<T<T2>>
+ return null;
+ }
+
+ public Type getElementType() {
+ return desiredType;
+ }
+
+ public boolean isOptional() {
+ return optional;
}
public boolean hasQualifier(String qualifier) {
@@ -61,6 +66,10 @@
return false;
}
+ public String[] getQualifiers() {
+ return qualifiers;
+ }
+
/**
* Returns null if qualifier is not present
*
@@ -81,8 +90,8 @@
public String toString() {
StringBuffer buffer = new StringBuffer();
- if (desiredClass != null)
- buffer.append(desiredClass.getName());
+ if (desiredType != null)
+ buffer.append(((Class<?>) desiredType).getName());
else
buffer.append("_descriptor_");
if (qualifiers != null) {
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ObjectProviderContext.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ObjectProviderContext.java
deleted file mode 100644
index f8cf2cb..0000000
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ObjectProviderContext.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2010 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.services.internal.context;
-
-import javax.inject.Named;
-import org.eclipse.e4.core.services.context.IEclipseContext;
-import org.eclipse.e4.core.services.context.IRunAndTrack;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.injector.ObjectDescriptor;
-
-public class ObjectProviderContext implements IObjectProvider {
-
- final static private String ECLIPSE_CONTEXT_NAME = IEclipseContext.class.getName();
-
- final private IEclipseContext context;
-
- public ObjectProviderContext(IEclipseContext context) {
- this.context = context;
- }
-
- public boolean containsKey(ObjectDescriptor properties) {
- String key = getKey(properties);
- if (key == null)
- return false;
- if (ECLIPSE_CONTEXT_NAME.equals(key))
- return (context != null);
- return context.containsKey(key);
- }
-
- public Object get(ObjectDescriptor properties) {
- String key = getKey(properties);
- if (key == null)
- return null;
- if (ECLIPSE_CONTEXT_NAME.equals(key))
- return context;
- return context.get(key);
- }
-
- private String getKey(ObjectDescriptor descriptor) {
- if (descriptor.hasQualifier(Named.class.getName()))
- return descriptor.getQualifierValue(Named.class.getName());
- Class elementClass = descriptor.getElementClass();
- if (elementClass != null)
- return elementClass.getName();
- return null;
- }
-
- public String toString() {
- return "ContextToInjectorLink(" + context + ')'; //$NON-NLS-1$
- }
-
- public IEclipseContext getContext() {
- return context;
- }
-
- static public ObjectProviderContext getObjectProvider(IEclipseContext context) {
- String key = ObjectProviderContext.class.getName();
- if (context.containsKey(key, true))
- return (ObjectProviderContext) context.get(key);
- ObjectProviderContext objectProvider = new ObjectProviderContext(context);
- context.set(key, objectProvider);
- return objectProvider;
- }
-
- public void runAndTrack(final IRunAndTrack runnable, Object[] args) {
- context.runAndTrack(runnable, args);
- }
-
- // TBD remove?
- public boolean equals(Object obj) {
- if (obj == this)
- return true;
- if (!(obj instanceof ObjectProviderContext))
- return false;
- return context.equals(((ObjectProviderContext) obj).context);
- }
-
- // TBD remove?
- public int hashCode() {
- return context.hashCode();
- }
-
-}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ProviderImpl.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ProviderImpl.java
new file mode 100644
index 0000000..61dd4e4
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ProviderImpl.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2009, 2010 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.services.internal.context;
+
+import java.lang.reflect.InvocationTargetException;
+import javax.inject.Provider;
+import org.eclipse.e4.core.services.injector.AbstractObjectSupplier;
+import org.eclipse.e4.core.services.injector.IInjector;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+
+public class ProviderImpl<T> implements Provider<T> {
+
+ final private AbstractObjectSupplier objectProvider;
+ final private IObjectDescriptor objectDescriptor;
+ final private IInjector injector;
+
+ public ProviderImpl(IObjectDescriptor descriptor, IInjector injector,
+ AbstractObjectSupplier provider) {
+ objectDescriptor = descriptor;
+ objectProvider = provider;
+ this.injector = injector;
+ }
+
+ @SuppressWarnings("unchecked")
+ public T get() {
+ try {
+ return (T) injector.make(objectDescriptor, objectProvider);
+ } catch (ClassCastException e) {
+ return null;
+ } catch (InvocationTargetException e) {
+ // TBD add proper logging
+ e.printStackTrace();
+ return null;
+ } catch (InstantiationException e) {
+ // TBD add proper logging
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Requestor.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Requestor.java
new file mode 100644
index 0000000..bb5e53a
--- /dev/null
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/Requestor.java
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2010 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.services.internal.context;
+
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import org.eclipse.e4.core.services.injector.IObjectDescriptor;
+import org.eclipse.e4.core.services.injector.IRequestor;
+import org.eclipse.e4.core.services.internal.annotations.AnnotationsSupport;
+
+/**
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+abstract public class Requestor implements IRequestor {
+
+ final private WeakReference<Object> objectRef;
+ final private boolean track;
+ final private boolean groupUpdates;
+ final private boolean isOptional;
+
+ protected Object[] actualArgs;
+
+ // plug-in class that gets replaced in Java 1.5+
+ // TBD this will be merged-in; replace with an utility class
+ final protected AnnotationsSupport annotationSupport = new AnnotationsSupport();
+
+ public abstract IObjectDescriptor[] getDependentObjects();
+
+ public abstract Object execute() throws InvocationTargetException, InstantiationException;
+
+ public Requestor(Object requestingObject, boolean track, boolean groupUpdates,
+ boolean isOptional) {
+ if (requestingObject != null)
+ objectRef = new WeakReference<Object>(requestingObject);
+ else
+ objectRef = null;
+ this.track = track;
+ this.groupUpdates = groupUpdates;
+ this.isOptional = isOptional;
+ }
+
+ public Object getRequestingObject() {
+ if (objectRef == null)
+ return null;
+ return objectRef.get();
+ }
+
+ /**
+ * Determines if the requestor wants to be called whenever one of the dependent object changes.
+ *
+ * @return
+ */
+ public boolean shouldTrack() {
+ return track;
+ }
+
+ public boolean shouldGroupUpdates() {
+ return groupUpdates;
+ }
+
+ public boolean isOptional() {
+ return isOptional;
+ }
+
+ /**
+ * If actual arguments are resolved for this requestor
+ */
+ public boolean isResolved() {
+ return (actualArgs != null);
+ }
+
+ public void setResolvedArgs(Object[] actualArgs) {
+ this.actualArgs = actualArgs;
+ }
+
+ protected void logError(Object destination, Exception e) {
+ String msg = "Injection failed " + destination.toString();
+ logError(msg, e);
+ }
+
+ protected void logError(String msg, Exception e) {
+ System.out.println(msg); //$NON-NLS-1$
+ if (e != null)
+ e.printStackTrace();
+ // TBD convert this into real logging
+ // String msg = NLS.bind("Injection failed", destination.toString());
+ // RuntimeLog.log(new Status(IStatus.WARNING,
+ // IRuntimeConstants.PI_COMMON, 0, msg, e));
+ }
+
+}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java
index c193a08..1e09cf3 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/core/services/internal/context/ValueComputation.java
@@ -14,7 +14,6 @@
import org.eclipse.e4.core.services.context.ContextChangeEvent;
import org.eclipse.e4.core.services.context.IContextFunction;
import org.eclipse.e4.core.services.context.IEclipseContext;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
import org.eclipse.e4.core.services.internal.context.EclipseContext.Scheduled;
public class ValueComputation extends Computation {
@@ -113,14 +112,14 @@
int eventType = event.getEventType();
// if the originating context is being disposed, remove this value computation completely
if (eventType == ContextChangeEvent.DISPOSE) {
- IObjectProvider provider = event.getContext();
- IEclipseContext eventsContext = ((ObjectProviderContext) provider).getContext();
+ IEclipseContext eventsContext = event.getContext();
if (originatingContext.equals(eventsContext)) {
removeAll(originatingContext);
return;
}
}
- this.originatingContext.handleInvalid(this.name,
+ // this.originatingContext.handleInvalid(this.name,
+ ((EclipseContext) this.originatingContext).invalidate(this.name,
eventType == ContextChangeEvent.DISPOSE ? ContextChangeEvent.REMOVED : eventType,
event.getOldValue(), scheduled);
}
diff --git a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/internal/core/services/osgi/OSGiContextStrategy.java b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/internal/core/services/osgi/OSGiContextStrategy.java
index 147aadf..4961c90 100644
--- a/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/internal/core/services/osgi/OSGiContextStrategy.java
+++ b/bundles/org.eclipse.e4.core.services/src/org/eclipse/e4/internal/core/services/osgi/OSGiContextStrategy.java
@@ -22,8 +22,6 @@
import org.eclipse.e4.core.services.context.IRunAndTrack;
import org.eclipse.e4.core.services.context.spi.IContextConstants;
import org.eclipse.e4.core.services.context.spi.ILookupStrategy;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
-import org.eclipse.e4.core.services.internal.context.ObjectProviderContext;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
@@ -264,7 +262,7 @@
* we can do appropriate cleanup of our caches when the requesting context is disposed.
*/
public boolean notify(ContextChangeEvent event) {
- IEclipseContext context = getContext(event);
+ IEclipseContext context = event.getContext();
if (context == null)
return false;
if (event.getEventType() != ContextChangeEvent.DISPOSE) {
@@ -285,11 +283,4 @@
}
return true;
}
-
- private IEclipseContext getContext(ContextChangeEvent event) {
- IObjectProvider provider = event.getContext();
- if (provider instanceof ObjectProviderContext)
- return ((ObjectProviderContext) provider).getContext();
- return null;
- }
}
diff --git a/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ContextInjectionTest.java b/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ContextInjectionTest.java
index f0f9674..21d2965 100644
--- a/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ContextInjectionTest.java
+++ b/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ContextInjectionTest.java
@@ -46,7 +46,7 @@
public TestData value;
- public void contextSet(IEclipseContext context) {
+ public void inject__contextSet(IEclipseContext context) {
contextSetCalled++;
}
@@ -130,7 +130,7 @@
// check field injection
assertEquals(testString, userObject.inject__String);
assertEquals(testInt, userObject.getInt());
- assertEquals(context, userObject.context);
+ // assertEquals(context, userObject.context);
// check method injection
assertEquals(1, userObject.setMethodCalled);
@@ -170,7 +170,7 @@
// check field injection
assertEquals(testString, userObject.inject__String);
assertEquals(testInt, userObject.getInt());
- assertEquals(context, userObject.context);
+ // assertEquals(context, userObject.context);
// check method injection
assertEquals(1, userObject.setMethodCalled);
@@ -202,7 +202,7 @@
// check inherited portion
assertEquals(testString, userObject.getString());
- assertEquals(context, userObject.getContext());
+ // assertEquals(context, userObject.getContext());
assertEquals(testString, userObject.getStringViaMethod());
assertEquals(1, userObject.setStringCalled);
diff --git a/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ObjectBasic.java b/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ObjectBasic.java
index 3f0c655..c424c54 100644
--- a/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ObjectBasic.java
+++ b/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/ObjectBasic.java
@@ -49,7 +49,7 @@
this.c = c;
}
- public void contextSet(IEclipseContext context) {
+ public void inject__contextSet(IEclipseContext context) {
this.context = context;
finalized = true;
}
diff --git a/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/RunAndTrackTest.java b/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/RunAndTrackTest.java
index d923a2f..1a30d4f 100644
--- a/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/RunAndTrackTest.java
+++ b/tests/org.eclipse.e4.core.tests.services/src/org/eclipse/e4/core/services/internal/context/RunAndTrackTest.java
@@ -22,7 +22,6 @@
import org.eclipse.e4.core.services.context.IRunAndTrack;
import org.eclipse.e4.core.services.context.spi.ContextFunction;
import org.eclipse.e4.core.services.context.spi.IContextConstants;
-import org.eclipse.e4.core.services.injector.IObjectProvider;
import org.eclipse.e4.core.tests.services.TestActivator;
/**
@@ -132,8 +131,7 @@
public boolean notify(ContextChangeEvent event) {
oldValue = event.getOldValue();
- IObjectProvider provider = event.getContext();
- IEclipseContext eventsContext = ((ObjectProviderContext) provider).getContext();
+ IEclipseContext eventsContext = event.getContext();
newValue = eventsContext.get(NAME);
return true;
}
@@ -179,8 +177,7 @@
public boolean notify(ContextChangeEvent event) {
// must get a value so we aren't removed
eventType = event.getEventType();
- IObjectProvider provider = event.getContext();
- IEclipseContext eventsContext = ((ObjectProviderContext) provider).getContext();
+ IEclipseContext eventsContext = event.getContext();
eventsContext.get(NAME);
return true;
}