Search in sources :

Example 1 with InjectionException

use of org.eclipse.e4.core.di.InjectionException in project eclipse.platform.runtime by eclipse.

the class ConstructorRequestor method execute.

@Override
public Object execute() throws InjectionException {
    Object result = null;
    if (!location.isAccessible()) {
        location.setAccessible(true);
    }
    boolean pausedRecording = false;
    if ((primarySupplier != null)) {
        primarySupplier.pauseRecording();
        pausedRecording = true;
    }
    try {
        result = location.newInstance(actualArgs);
    } catch (IllegalArgumentException | IllegalAccessException e) {
        throw new InjectionException(e);
    } catch (InstantiationException e) {
        // $NON-NLS-1$
        throw new InjectionException("Unable to instantiate " + location, e);
    } catch (InvocationTargetException e) {
        Throwable originalException = e.getCause();
        // http://bugs.eclipse.org/bugs/show_bug.cgi?id=457687
        if (originalException instanceof Error) {
            throw (Error) originalException;
        }
        throw new InjectionException((originalException != null) ? originalException : e);
    } finally {
        if (pausedRecording)
            primarySupplier.resumeRecording();
        clearResolvedArgs();
    }
    return result;
}
Also used : InjectionException(org.eclipse.e4.core.di.InjectionException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 2 with InjectionException

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

use of org.eclipse.e4.core.di.InjectionException in project eclipse.platform.runtime by eclipse.

the class InjectionOrderTest method testSpecialMethodOnFailure.

/**
 * Make sure special methods are not getting called in case injection failed
 */
@Test
public void testSpecialMethodOnFailure() {
    IEclipseContext appContext = EclipseContextFactory.create();
    boolean exception = false;
    try {
        ContextInjectionFactory.make(InjectUnsatisfied.class, appContext);
    } catch (InjectionException e) {
        exception = true;
    }
    assertTrue(exception);
    appContext.dispose();
    assertEquals(0, InjectUnsatisfied.count);
}
Also used : InjectionException(org.eclipse.e4.core.di.InjectionException) IEclipseContext(org.eclipse.e4.core.contexts.IEclipseContext) Test(org.junit.Test)

Example 4 with InjectionException

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

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

InjectionException (org.eclipse.e4.core.di.InjectionException)10 IEclipseContext (org.eclipse.e4.core.contexts.IEclipseContext)4 Test (org.junit.Test)4 PrimaryObjectSupplier (org.eclipse.e4.core.di.suppliers.PrimaryObjectSupplier)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 ArrayList (java.util.ArrayList)2 BundleContext (org.osgi.framework.BundleContext)2 Constructor (java.lang.reflect.Constructor)1 Type (java.lang.reflect.Type)1 Hashtable (java.util.Hashtable)1 IBinding (org.eclipse.e4.core.di.IBinding)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 IRequestor (org.eclipse.e4.core.di.suppliers.IRequestor)1 Bundle (org.osgi.framework.Bundle)1 EventHandler (org.osgi.service.event.EventHandler)1