in src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java [722:799]
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<>(new ModelClassException("Unable to find a useable constructor for model " + modelClass.getType()));
}
final Map<ValuePreparer, Object> preparedValues = new HashMap<>(VALUE_PREPARERS_COUNT);
ModelType object;
if (constructorToUse.getConstructor().getParameterTypes().length == 0) {
// no parameters for constructor injection? instantiate it right away
object = constructorToUse.newInstance();
} else {
// instantiate with constructor injection
// 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 | InvocationTargetException | IllegalAccessException ex) {
registry.onDisposed();
throw ex;
}
}
InjectCallback callback = new SetFieldCallback(object);
InjectableField[] injectableFields = modelClass.getInjectableFields();
List<MissingElementException> missingElements = null;
final BundleContext modelContext = getModelBundleContext(modelClass);
for (InjectableField field : injectableFields) {
RuntimeException t = injectElement(field, adaptable, registry, callback, preparedValues, modelContext);
if (t != null) {
if (missingElements == null) {
missingElements = new ArrayList<>();
}
missingElements.add(new MissingElementException(field.getAnnotatedElement(), t));
}
}
if (!registry.callbacks.isEmpty()) {
registry.seal();
if (adaptable instanceof SlingHttpServletRequest &&
((SlingHttpServletRequest) adaptable).getAttribute(REQUEST_MARKER_ATTRIBUTE) == REQUEST_MARKER_VALUE) {
registerRequestCallbackRegistry((SlingHttpServletRequest) adaptable, registry);
} else {
registerCallbackRegistry(object, registry);
}
}
if (missingElements != null) {
MissingElementsException missingElementsException = new MissingElementsException("Could not inject all required fields into " + modelClass.getType());
for (MissingElementException me : missingElements) {
missingElementsException.addMissingElementExceptions(me);
}
return new Result<>(missingElementsException);
}
try {
object = invokePostConstruct(object);
if (object == null) {
return (Result<ModelType>) Result.POST_CONSTRUCT_PREVENTED_MODEL_CONSTRUCTION;
}
} catch (InvocationTargetException e) {
return new Result<>(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<>(object);
}