use of org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier 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.ExtendedObjectSupplier 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.ExtendedObjectSupplier in project eclipse.platform.runtime by eclipse.
the class EclipseContext method dispose.
@Override
public void dispose() {
// dispose of child contexts first
for (EclipseContext childContext : getChildren()) {
childContext.dispose();
}
ContextChangeEvent event = new ContextChangeEvent(this, ContextChangeEvent.DISPOSE, null, null, null);
Set<Computation> allComputations = new HashSet<>();
allComputations.addAll(activeComputations.values());
allComputations.addAll(activeRATs);
activeComputations.clear();
activeRATs.clear();
Set<Scheduled> scheduled = new LinkedHashSet<>();
allComputations.addAll(getListeners());
weakListeners.clear();
for (Computation computation : allComputations) {
computation.handleInvalid(event, scheduled);
}
processScheduled(scheduled);
synchronized (notifyOnDisposal) {
for (IContextDisposalListener listener : notifyOnDisposal) {
listener.disposed(this);
}
notifyOnDisposal.clear();
}
for (ValueComputation computation : localValueComputations.values()) {
computation.dipose();
}
localValueComputations.clear();
// if this was the parent's active child, deactivate it
EclipseContext parent = getParent();
EclipseContext rootContext = null;
if (parent != null) {
rootContext = getRoot();
if (this == parent.getActiveChild())
parent.set(ACTIVE_CHILD, null);
}
localValues.clear();
if (parent != null) {
parent.removeChild(this);
if (rootContext != null) {
rootContext.cleanup();
}
// inform the OSGi layer via EventAdmin about the context disposal
// used for example to be able to cleanup cached requestors in
// ExtendedObjectSupplier implementations
EventAdmin admin = parent.get(EventAdmin.class);
if (admin != null) {
Event osgiEvent = new Event(IEclipseContext.TOPIC_DISPOSE, (Map<String, ?>) null);
admin.postEvent(osgiEvent);
}
}
if (debugAddOn != null)
debugAddOn.notify(this, IEclipseContextDebugger.EventType.DISPOSED, null);
}
use of org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier in project eclipse.platform.runtime by eclipse.
the class ExtendedSupplierInjectionTests method testSupplierOrdering.
/**
* bug 428837: ensure suppliers are ranked by service.ranking
*/
@Test
public void testSupplierOrdering() {
BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext();
ExtendedObjectSupplier supplier = new ExtendedObjectSupplier() {
@Override
public Object get(IObjectDescriptor descriptor, IRequestor requestor, boolean track, boolean group) {
// TODO Auto-generated method stub
return null;
}
};
Dictionary<String, Object> properties = new Hashtable<>();
properties.put(ExtendedObjectSupplier.SERVICE_CONTEXT_KEY, EventTopic.class.getName());
properties.put(Constants.SERVICE_RANKING, 100);
ServiceRegistration<?> sr = bc.registerService(ExtendedObjectSupplier.SERVICE_NAME, supplier, properties);
try {
assertEquals(supplier, ProviderHelper.findProvider(EventTopic.class.getName(), null));
} finally {
sr.unregister();
}
}
use of org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier in project eclipse.platform.runtime by eclipse.
the class InjectorImpl method findExtendedSupplier.
private ExtendedObjectSupplier findExtendedSupplier(IObjectDescriptor descriptor, PrimaryObjectSupplier objectSupplier) {
Annotation[] qualifiers = descriptor.getQualifiers();
if (qualifiers == null)
return null;
for (Annotation qualifier : qualifiers) {
Class<?> type = qualifier.annotationType();
String key = ((Class<?>) type).getName();
ExtendedObjectSupplier supplier;
try {
// use qualified name to refer to a class that might be missing
supplier = org.eclipse.e4.core.internal.di.osgi.ProviderHelper.findProvider(key, defaultSupplier);
} catch (NoClassDefFoundError e) {
// OSGi framework not present
return null;
}
if (supplier != null)
return supplier;
}
return null;
}
Aggregations