Search in sources :

Example 1 with MissingElementsException

use of org.apache.sling.models.factory.MissingElementsException in project sling by apache.

the class ModelAdapterFactory method newInstanceWithConstructorInjection.

private <ModelType> Result<ModelType> newInstanceWithConstructorInjection(final ModelClassConstructor<ModelType> constructor, final Object adaptable, final ModelClass<ModelType> modelClass, final DisposalCallbackRegistry registry, @Nonnull final Map<ValuePreparer, Object> preparedValues) throws InstantiationException, InvocationTargetException, IllegalAccessException {
    ConstructorParameter[] parameters = constructor.getConstructorParameters();
    List<Object> paramValues = new ArrayList<Object>(Arrays.asList(new Object[parameters.length]));
    InjectCallback callback = new SetConstructorParameterCallback(paramValues);
    MissingElementsException missingElements = new MissingElementsException("Required constructor parameters were not able to be injected on model " + modelClass.getType());
    for (int i = 0; i < parameters.length; i++) {
        RuntimeException t = injectElement(parameters[i], adaptable, registry, callback, preparedValues);
        if (t != null) {
            missingElements.addMissingElementExceptions(new MissingElementException(parameters[i].getAnnotatedElement(), t));
        }
    }
    if (!missingElements.isEmpty()) {
        return new Result<ModelType>(missingElements);
    }
    return new Result<ModelType>(constructor.getConstructor().newInstance(paramValues.toArray(new Object[paramValues.size()])));
}
Also used : ConstructorParameter(org.apache.sling.models.impl.model.ConstructorParameter) ArrayList(java.util.ArrayList) MissingElementsException(org.apache.sling.models.factory.MissingElementsException) MissingElementException(org.apache.sling.models.factory.MissingElementException)

Example 2 with MissingElementsException

use of org.apache.sling.models.factory.MissingElementsException in project sling by apache.

the class ResourceModelClassesTest method testRequiredPropertyModelWithException.

@Test
public void testRequiredPropertyModelWithException() {
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("first", "first-value");
    map.put("third", "third-value");
    ValueMap vm = spy(new ValueMapDecorator(map));
    Resource res = mock(Resource.class);
    when(res.adaptTo(ValueMap.class)).thenReturn(vm);
    boolean thrown = false;
    try {
        factory.createModel(res, ResourceModelWithRequiredField.class);
    } catch (MissingElementsException e) {
        assertEquals("required", ((Field) e.getMissingElements().iterator().next().getElement()).getName());
        thrown = true;
    }
    assertTrue(thrown);
    verify(vm).get("required", String.class);
}
Also used : ResourceModelWithRequiredField(org.apache.sling.models.testmodels.classes.ResourceModelWithRequiredField) Field(java.lang.reflect.Field) HashMap(java.util.HashMap) ValueMap(org.apache.sling.api.resource.ValueMap) ValueMapDecorator(org.apache.sling.api.wrappers.ValueMapDecorator) Resource(org.apache.sling.api.resource.Resource) MissingElementsException(org.apache.sling.models.factory.MissingElementsException) Test(org.junit.Test)

Example 3 with MissingElementsException

use of org.apache.sling.models.factory.MissingElementsException in project sling by apache.

the class ModelAdapterFactory method createObject.

private <ModelType> Result<ModelType> createObject(final Object adaptable, final ModelClass<ModelType> modelClass) throws InstantiationException, InvocationTargetException, IllegalAccessException {
    DisposalCallbackRegistryImpl registry = new DisposalCallbackRegistryImpl();
    ModelClassConstructor<ModelType> constructorToUse = getBestMatchingConstructor(adaptable, modelClass);
    if (constructorToUse == null) {
        return new Result<ModelType>(new ModelClassException("Unable to find a useable constructor for model " + modelClass.getType()));
    }
    final Map<ValuePreparer, Object> preparedValues = new HashMap<ValuePreparer, Object>(VALUE_PREPARERS_COUNT);
    final ModelType object;
    if (constructorToUse.getConstructor().getParameterTypes().length == 0) {
        // no parameters for constructor injection? instantiate it right away
        object = constructorToUse.getConstructor().newInstance();
    } else {
        // if this fails, make sure resources that may be claimed by injectors are cleared up again
        try {
            Result<ModelType> result = newInstanceWithConstructorInjection(constructorToUse, adaptable, modelClass, registry, preparedValues);
            if (!result.wasSuccessful()) {
                registry.onDisposed();
                return result;
            } else {
                object = result.getValue();
            }
        } catch (InstantiationException ex) {
            registry.onDisposed();
            throw ex;
        } catch (InvocationTargetException ex) {
            registry.onDisposed();
            throw ex;
        } catch (IllegalAccessException ex) {
            registry.onDisposed();
            throw ex;
        }
    }
    registerCallbackRegistry(object, registry);
    InjectCallback callback = new SetFieldCallback(object);
    InjectableField[] injectableFields = modelClass.getInjectableFields();
    MissingElementsException missingElements = new MissingElementsException("Could not inject all required fields into " + modelClass.getType());
    for (InjectableField field : injectableFields) {
        RuntimeException t = injectElement(field, adaptable, registry, callback, preparedValues);
        if (t != null) {
            missingElements.addMissingElementExceptions(new MissingElementException(field.getAnnotatedElement(), t));
        }
    }
    registry.seal();
    if (!missingElements.isEmpty()) {
        return new Result<ModelType>(missingElements);
    }
    try {
        invokePostConstruct(object);
    } catch (InvocationTargetException e) {
        return new Result<ModelType>(new PostConstructException("Post-construct method has thrown an exception for model " + modelClass.getType(), e.getCause()));
    } catch (IllegalAccessException e) {
        new Result<ModelType>(new ModelClassException("Could not call post-construct method for model " + modelClass.getType(), e));
    }
    return new Result<ModelType>(object);
}
Also used : PostConstructException(org.apache.sling.models.factory.PostConstructException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) ValuePreparer(org.apache.sling.models.spi.ValuePreparer) MissingElementsException(org.apache.sling.models.factory.MissingElementsException) InvocationTargetException(java.lang.reflect.InvocationTargetException) ModelClassException(org.apache.sling.models.factory.ModelClassException) InjectableField(org.apache.sling.models.impl.model.InjectableField) MissingElementException(org.apache.sling.models.factory.MissingElementException)

Example 4 with MissingElementsException

use of org.apache.sling.models.factory.MissingElementsException in project sling by apache.

the class ModelAdapterFactory method createInvocationHandler.

private <ModelType> Result<InvocationHandler> createInvocationHandler(final Object adaptable, final ModelClass<ModelType> modelClass) {
    InjectableMethod[] injectableMethods = modelClass.getInjectableMethods();
    final Map<Method, Object> methods = new HashMap<Method, Object>();
    SetMethodsCallback callback = new SetMethodsCallback(methods);
    MapBackedInvocationHandler handler = new MapBackedInvocationHandler(methods);
    DisposalCallbackRegistryImpl registry = new DisposalCallbackRegistryImpl();
    registerCallbackRegistry(handler, registry);
    final Map<ValuePreparer, Object> preparedValues = new HashMap<ValuePreparer, Object>(VALUE_PREPARERS_COUNT);
    MissingElementsException missingElements = new MissingElementsException("Could not create all mandatory methods for interface of model " + modelClass);
    for (InjectableMethod method : injectableMethods) {
        RuntimeException t = injectElement(method, adaptable, registry, callback, preparedValues);
        if (t != null) {
            missingElements.addMissingElementExceptions(new MissingElementException(method.getAnnotatedElement(), t));
        }
    }
    registry.seal();
    if (!missingElements.isEmpty()) {
        return new Result<InvocationHandler>(missingElements);
    }
    return new Result<InvocationHandler>(handler);
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) ValuePreparer(org.apache.sling.models.spi.ValuePreparer) MissingElementsException(org.apache.sling.models.factory.MissingElementsException) InjectableMethod(org.apache.sling.models.impl.model.InjectableMethod) Method(java.lang.reflect.Method) InjectableMethod(org.apache.sling.models.impl.model.InjectableMethod) MissingElementException(org.apache.sling.models.factory.MissingElementException)

Aggregations

MissingElementsException (org.apache.sling.models.factory.MissingElementsException)4 HashMap (java.util.HashMap)3 MissingElementException (org.apache.sling.models.factory.MissingElementException)3 WeakHashMap (java.util.WeakHashMap)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ValuePreparer (org.apache.sling.models.spi.ValuePreparer)2 Field (java.lang.reflect.Field)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 Method (java.lang.reflect.Method)1 ArrayList (java.util.ArrayList)1 Resource (org.apache.sling.api.resource.Resource)1 ValueMap (org.apache.sling.api.resource.ValueMap)1 ValueMapDecorator (org.apache.sling.api.wrappers.ValueMapDecorator)1 ModelClassException (org.apache.sling.models.factory.ModelClassException)1 PostConstructException (org.apache.sling.models.factory.PostConstructException)1 ConstructorParameter (org.apache.sling.models.impl.model.ConstructorParameter)1 InjectableField (org.apache.sling.models.impl.model.InjectableField)1 InjectableMethod (org.apache.sling.models.impl.model.InjectableMethod)1 ResourceModelWithRequiredField (org.apache.sling.models.testmodels.classes.ResourceModelWithRequiredField)1 Test (org.junit.Test)1