Search in sources :

Example 1 with ExtendedObjectSupplier

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;
}
Also used : IBinding(org.eclipse.e4.core.di.IBinding) InjectionException(org.eclipse.e4.core.di.InjectionException) IObjectDescriptor(org.eclipse.e4.core.di.suppliers.IObjectDescriptor) Creatable(org.eclipse.e4.core.di.annotations.Creatable) ExtendedObjectSupplier(org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier)

Example 2 with ExtendedObjectSupplier

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;
    }
}
Also used : Bundle(org.osgi.framework.Bundle) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) IInjector(org.eclipse.e4.core.di.IInjector) ExtendedObjectSupplier(org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier) BundleContext(org.osgi.framework.BundleContext) ServiceReference(org.osgi.framework.ServiceReference)

Example 3 with ExtendedObjectSupplier

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);
}
Also used : LinkedHashSet(java.util.LinkedHashSet) EventAdmin(org.osgi.service.event.EventAdmin) Event(org.osgi.service.event.Event) IEclipseContext(org.eclipse.e4.core.contexts.IEclipseContext) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 4 with ExtendedObjectSupplier

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();
    }
}
Also used : IObjectDescriptor(org.eclipse.e4.core.di.suppliers.IObjectDescriptor) EventTopic(org.eclipse.e4.core.di.extensions.EventTopic) IRequestor(org.eclipse.e4.core.di.suppliers.IRequestor) Hashtable(java.util.Hashtable) ExtendedObjectSupplier(org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier) BundleContext(org.osgi.framework.BundleContext) Test(org.junit.Test)

Example 5 with ExtendedObjectSupplier

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;
}
Also used : Annotation(java.lang.annotation.Annotation) ExtendedObjectSupplier(org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier)

Aggregations

ExtendedObjectSupplier (org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier)4 IObjectDescriptor (org.eclipse.e4.core.di.suppliers.IObjectDescriptor)2 BundleContext (org.osgi.framework.BundleContext)2 Annotation (java.lang.annotation.Annotation)1 HashSet (java.util.HashSet)1 Hashtable (java.util.Hashtable)1 LinkedHashSet (java.util.LinkedHashSet)1 IEclipseContext (org.eclipse.e4.core.contexts.IEclipseContext)1 IBinding (org.eclipse.e4.core.di.IBinding)1 IInjector (org.eclipse.e4.core.di.IInjector)1 InjectionException (org.eclipse.e4.core.di.InjectionException)1 Creatable (org.eclipse.e4.core.di.annotations.Creatable)1 EventTopic (org.eclipse.e4.core.di.extensions.EventTopic)1 IRequestor (org.eclipse.e4.core.di.suppliers.IRequestor)1 Test (org.junit.Test)1 Bundle (org.osgi.framework.Bundle)1 InvalidSyntaxException (org.osgi.framework.InvalidSyntaxException)1 ServiceReference (org.osgi.framework.ServiceReference)1 Event (org.osgi.service.event.Event)1 EventAdmin (org.osgi.service.event.EventAdmin)1