Search in sources :

Example 1 with Creatable

use of org.eclipse.e4.core.di.annotations.Creatable 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)

Aggregations

IBinding (org.eclipse.e4.core.di.IBinding)1 InjectionException (org.eclipse.e4.core.di.InjectionException)1 Creatable (org.eclipse.e4.core.di.annotations.Creatable)1 ExtendedObjectSupplier (org.eclipse.e4.core.di.suppliers.ExtendedObjectSupplier)1 IObjectDescriptor (org.eclipse.e4.core.di.suppliers.IObjectDescriptor)1