use of org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier in project eclipse.platform.runtime by eclipse.
the class InjectorImpl method makeFromProvider.
public Object makeFromProvider(IObjectDescriptor descriptor, PrimaryObjectSupplier objectSupplier) {
Binding binding = findBinding(descriptor);
Class<?> implementationClass;
if (binding == null)
implementationClass = getProviderType(descriptor.getDesiredType());
else
implementationClass = binding.getImplementationClass();
if (objectSupplier != null) {
IObjectDescriptor actualClass = new ObjectDescriptor(implementationClass, null);
Object[] actualArgs = new Object[] { IInjector.NOT_A_VALUE };
objectSupplier.get(new IObjectDescriptor[] { actualClass }, actualArgs, null, false, true, false);
if (actualArgs[0] != IInjector.NOT_A_VALUE)
return actualArgs[0];
}
return internalMake(implementationClass, objectSupplier, null);
}
use of org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier in project eclipse.platform.runtime by eclipse.
the class InjectorImpl method resolveArgs.
private Object[] resolveArgs(Requestor<?> requestor, PrimaryObjectSupplier objectSupplier, PrimaryObjectSupplier tempSupplier, boolean uninject, boolean initial, boolean track) {
/* Special indicator for ExtendedObjectSuppliers not having a value */
final Object EOS_NOT_A_VALUE = new Object();
IObjectDescriptor[] descriptors = requestor.getDependentObjects();
// Resolution order changed in 1.4 as we now check extended suppliers first (bug 398728)
// 0) initial fill - all values are unresolved
Object[] actualArgs = new Object[descriptors.length];
Arrays.fill(actualArgs, NOT_A_VALUE);
// 1) check if we have a Provider<T>
for (int i = 0; i < actualArgs.length; i++) {
Class<?> providerClass = getProviderType(descriptors[i].getDesiredType());
if (providerClass == null)
continue;
actualArgs[i] = new ProviderImpl<Class<?>>(descriptors[i], this, objectSupplier);
}
// 2) try extended suppliers
for (int i = 0; i < actualArgs.length; i++) {
if (actualArgs[i] != NOT_A_VALUE)
// already resolved
continue;
ExtendedObjectSupplier extendedSupplier = findExtendedSupplier(descriptors[i], objectSupplier);
if (extendedSupplier == null)
continue;
actualArgs[i] = extendedSupplier.get(descriptors[i], requestor, requestor.shouldTrack() && track, requestor.shouldGroupUpdates());
if (actualArgs[i] == NOT_A_VALUE) {
// Use special marker to prevent these annotated arguments from being resolved using temporary and primary suppliers
actualArgs[i] = EOS_NOT_A_VALUE;
}
}
// 3) use the temporary supplier
if (tempSupplier != null)
tempSupplier.get(descriptors, actualArgs, requestor, initial, false, /* no tracking */
requestor.shouldGroupUpdates());
// 4) use the primary supplier
if (objectSupplier != null)
objectSupplier.get(descriptors, actualArgs, requestor, initial, requestor.shouldTrack() && track, requestor.shouldGroupUpdates());
// 5) try the bindings
for (int i = 0; i < actualArgs.length; i++) {
if (actualArgs[i] != NOT_A_VALUE)
// already resolved
continue;
Binding binding = findBinding(descriptors[i]);
if (binding != null)
actualArgs[i] = internalMake(binding.getImplementationClass(), objectSupplier, tempSupplier);
}
// 5) create simple classes (implied bindings) - unless we uninject or optional
if (!uninject && !requestor.isOptional()) {
for (int i = 0; i < actualArgs.length; i++) {
if (actualArgs[i] != NOT_A_VALUE)
// already resolved
continue;
if (descriptors[i].hasQualifier(Optional.class))
continue;
try {
Class<?> desiredClass = getDesiredClass(descriptors[i].getDesiredType());
Creatable creatableAnnotation = desiredClass.getAnnotation(Creatable.class);
if (creatableAnnotation == null)
continue;
actualArgs[i] = internalMake(getDesiredClass(descriptors[i].getDesiredType()), objectSupplier, tempSupplier);
} catch (InjectionException e) {
e.printStackTrace();
}
}
}
// 6) post process
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 && actualArgs[i] != EOS_NOT_A_VALUE) {
Class<?> descriptorsClass = getDesiredClass(descriptors[i].getDesiredType());
if (descriptorsClass.isPrimitive()) {
// support type autoboxing
if (descriptorsClass.equals(boolean.class))
descriptorsClass = Boolean.class;
else if (descriptorsClass.equals(int.class))
descriptorsClass = Integer.class;
else if (descriptorsClass.equals(char.class))
descriptorsClass = Character.class;
else if (descriptorsClass.equals(float.class))
descriptorsClass = Float.class;
else if (descriptorsClass.equals(double.class))
descriptorsClass = Double.class;
else if (descriptorsClass.equals(long.class))
descriptorsClass = Long.class;
else if (descriptorsClass.equals(short.class))
descriptorsClass = Short.class;
else if (descriptorsClass.equals(byte.class))
descriptorsClass = Byte.class;
}
if (!descriptorsClass.isAssignableFrom(actualArgs[i].getClass()))
actualArgs[i] = IInjector.NOT_A_VALUE;
}
if (actualArgs[i] == IInjector.NOT_A_VALUE || actualArgs[i] == EOS_NOT_A_VALUE) {
// still unresolved?
if (descriptors[i].hasQualifier(Optional.class)) {
// uninject or optional - fill defaults
Class<?> descriptorsClass = getDesiredClass(descriptors[i].getDesiredType());
if (descriptorsClass.isPrimitive()) {
if (descriptorsClass.equals(boolean.class))
actualArgs[i] = DEFAULT_BOOLEAN;
else if (descriptorsClass.equals(int.class))
actualArgs[i] = DEFAULT_INTEGER;
else if (descriptorsClass.equals(char.class))
actualArgs[i] = DEFAULT_CHAR;
else if (descriptorsClass.equals(float.class))
actualArgs[i] = DEFAULT_FLOAT;
else if (descriptorsClass.equals(double.class))
actualArgs[i] = DEFAULT_DOUBLE;
else if (descriptorsClass.equals(long.class))
actualArgs[i] = DEFAULT_LONG;
else if (descriptorsClass.equals(short.class))
actualArgs[i] = DEFAULT_SHORT;
else if (descriptorsClass.equals(byte.class))
actualArgs[i] = DEFAULT_BYTE;
} else
actualArgs[i] = null;
} else if (actualArgs[i] == EOS_NOT_A_VALUE) {
// Wasn't @Optional, so replace with NOT_A_VALUE
actualArgs[i] = IInjector.NOT_A_VALUE;
}
}
}
return actualArgs;
}
use of org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier in project eclipse.platform.runtime by eclipse.
the class ProviderHelper method findProvider.
public static ExtendedObjectSupplier findProvider(String qualifier, PrimaryObjectSupplier objectSupplier) {
synchronized (extendedSuppliers) {
if (extendedSuppliers.containsKey(qualifier))
return extendedSuppliers.get(qualifier);
Bundle bundle = FrameworkUtil.getBundle(ProviderHelper.class);
if (bundle == null) {
// In case we are not in an OSGi context, see bug 513883
return null;
}
BundleContext bundleContext = bundle.getBundleContext();
try {
String filter = '(' + ExtendedObjectSupplier.SERVICE_CONTEXT_KEY + '=' + qualifier + ')';
ServiceReference<?>[] refs = bundleContext.getServiceReferences(ExtendedObjectSupplier.SERVICE_NAME, filter);
if (refs != null && refs.length > 0) {
ExtendedObjectSupplier supplier;
// Explicitly sort by ranking if more than one supplier is found
if (refs.length > 1) {
Arrays.sort(refs, Collections.reverseOrder());
}
supplier = (ExtendedObjectSupplier) bundleContext.getService(refs[0]);
if (objectSupplier != null) {
IInjector injector = InjectorFactory.getDefault();
injector.inject(supplier, objectSupplier);
}
extendedSuppliers.put(qualifier, supplier);
return supplier;
}
} catch (InvalidSyntaxException e) {
// should not happen - we tested the line above
}
extendedSuppliers.put(qualifier, null);
return null;
}
}
use of org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier in project eclipse.platform.runtime by eclipse.
the class ContextInjectionFactory method make.
/**
* Obtain an instance of the specified class and inject it with the context. This method
* allows extra values that don't need to be tracked to be passed to the object using staticContext.
* <p>
* If values for the same key present in both the context and the static context, the values from
* the static context are injected.
* </p>
* <p>
* Class'es scope dictates if a new instance of the class will be created, or existing instance
* will be reused.
* </p>
* @param clazz The class to be instantiated
* @param context The context to obtain injected values from
* @param staticContext The context containing extra values; not tracked
* @return an instance of the specified class
* @throws InjectionException if an exception occurred while performing this operation
* @see #make(Class, IEclipseContext)
*/
public static <T> T make(Class<T> clazz, IEclipseContext context, IEclipseContext staticContext) throws InjectionException {
PrimaryObjectSupplier supplier = ContextObjectSupplier.getObjectSupplier(context, injector);
PrimaryObjectSupplier tempSupplier = ContextObjectSupplier.getObjectSupplier(staticContext, injector);
return injector.make(clazz, supplier, tempSupplier);
}
use of org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier in project eclipse.platform.runtime by eclipse.
the class ContextInjectionFactory method invoke.
/**
* Call a method, injecting the parameters from two contexts. This method is useful when the method needs
* to receive some values not present in the context. In this case a local context can be created and
* populated with additional values.
* <p>
* If values for the same key present in both the context and the local context, the values from
* the local context are injected.
* </p>
* <p>
* If no matching method is found on the class, the defaultValue will be returned.
* </p>
* @param object The object to perform injection on
* @param qualifier the annotation tagging method to be called
* @param context The context to obtain injected values from
* @param localContext The context to obtain addition injected values from
* @param defaultValue A value to be returned if the method cannot be called, might be <code>null</code>
* @return the return value of the method call, might be <code>null</code>
* @throws InjectionException if an exception occurred while performing this operation
*/
public static Object invoke(Object object, Class<? extends Annotation> qualifier, IEclipseContext context, IEclipseContext localContext, Object defaultValue) throws InjectionException {
PrimaryObjectSupplier supplier = ContextObjectSupplier.getObjectSupplier(context, injector);
PrimaryObjectSupplier tempSupplier = ContextObjectSupplier.getObjectSupplier(localContext, injector);
return injector.invoke(object, qualifier, defaultValue, supplier, tempSupplier);
}
Aggregations