Search in sources :

Example 1 with PrimaryObjectSupplier

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

Example 2 with PrimaryObjectSupplier

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;
}
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 3 with PrimaryObjectSupplier

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;
    }
}
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 4 with PrimaryObjectSupplier

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);
}
Also used : PrimaryObjectSupplier(org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier)

Example 5 with PrimaryObjectSupplier

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);
}
Also used : PrimaryObjectSupplier(org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier)

Aggregations

PrimaryObjectSupplier (org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier)4 InjectionException (org.eclipse.e4.core.di.InjectionException)3 ExtendedObjectSupplier (org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier)3 ArrayList (java.util.ArrayList)2 IBinding (org.eclipse.e4.core.di.IBinding)2 IObjectDescriptor (org.eclipse.e4.core.di.suppliers.IObjectDescriptor)2 Annotation (java.lang.annotation.Annotation)1 Constructor (java.lang.reflect.Constructor)1 IInjector (org.eclipse.e4.core.di.IInjector)1 Creatable (org.eclipse.e4.core.di.annotations.Creatable)1 IRequestor (org.eclipse.e4.core.di.suppliers.IRequestor)1 Bundle (org.osgi.framework.Bundle)1 BundleContext (org.osgi.framework.BundleContext)1 InvalidSyntaxException (org.osgi.framework.InvalidSyntaxException)1 ServiceReference (org.osgi.framework.ServiceReference)1