use of org.apache.sling.models.factory.ModelClassException in project sling by apache.
the class ModelAdapterFactory method injectElement.
@CheckForNull
private RuntimeException injectElement(final InjectableElement element, final Object adaptable, @Nonnull final DisposalCallbackRegistry registry, final InjectCallback callback, @Nonnull final Map<ValuePreparer, Object> preparedValues) {
InjectAnnotationProcessor annotationProcessor = null;
String source = element.getSource();
boolean wasInjectionSuccessful = false;
// find an appropriate annotation processor
for (InjectAnnotationProcessorFactory2 factory : injectAnnotationProcessorFactories2) {
annotationProcessor = factory.createAnnotationProcessor(adaptable, element.getAnnotatedElement());
if (annotationProcessor != null) {
break;
}
}
if (annotationProcessor == null) {
for (InjectAnnotationProcessorFactory factory : injectAnnotationProcessorFactories) {
annotationProcessor = factory.createAnnotationProcessor(adaptable, element.getAnnotatedElement());
if (annotationProcessor != null) {
break;
}
}
}
String name = getName(element, annotationProcessor);
final Object injectionAdaptable = getAdaptable(adaptable, element, annotationProcessor);
RuntimeException lastInjectionException = null;
if (injectionAdaptable != null) {
// prepare the set of injectors to process. if a source is given only use injectors with this name.
final RankedServices<Injector> injectorsToProcess;
if (StringUtils.isEmpty(source)) {
injectorsToProcess = sortedInjectors;
} else {
injectorsToProcess = injectors.get(source);
if (injectorsToProcess == null) {
throw new IllegalArgumentException("No Sling Models Injector registered for source '" + source + "'.");
}
}
// find the right injector
for (Injector injector : injectorsToProcess) {
if (name != null || injector instanceof AcceptsNullName) {
Object preparedValue = injectionAdaptable;
// only do the ValuePreparer optimization for the original adaptable
if (injector instanceof ValuePreparer && adaptable == injectionAdaptable) {
final ValuePreparer preparer = (ValuePreparer) injector;
Object fromMap = preparedValues.get(preparer);
if (fromMap != null) {
preparedValue = fromMap;
} else {
preparedValue = preparer.prepareValue(injectionAdaptable);
preparedValues.put(preparer, preparedValue);
}
}
Object value = injector.getValue(preparedValue, name, element.getType(), element.getAnnotatedElement(), registry);
if (value != null) {
lastInjectionException = callback.inject(element, value);
if (lastInjectionException == null) {
wasInjectionSuccessful = true;
break;
}
}
}
}
}
// if injection failed, use default
if (!wasInjectionSuccessful) {
Result<Boolean> defaultInjectionResult = injectDefaultValue(element, annotationProcessor, callback);
if (defaultInjectionResult.wasSuccessful()) {
wasInjectionSuccessful = defaultInjectionResult.getValue();
// log previous injection error, if there was any
if (lastInjectionException != null && wasInjectionSuccessful) {
log.debug("Although falling back to default value worked, injection into {} failed because of: " + lastInjectionException.getMessage(), element.getAnnotatedElement(), lastInjectionException);
}
} else {
return defaultInjectionResult.getThrowable();
}
}
// if default is not set, check if mandatory
if (!wasInjectionSuccessful) {
if (element.isOptional(annotationProcessor)) {
// log previous injection error, if there was any
if (lastInjectionException != null) {
log.debug("Injection into optional element {} failed because of: " + lastInjectionException.getMessage(), element.getAnnotatedElement(), lastInjectionException);
}
if (element.isPrimitive()) {
RuntimeException throwable = injectPrimitiveInitialValue(element, callback);
if (throwable != null) {
return throwable;
}
}
} else {
if (lastInjectionException != null) {
return lastInjectionException;
} else {
return new ModelClassException("No injector returned a non-null value!");
}
}
}
return null;
}
use of org.apache.sling.models.factory.ModelClassException in project sling by apache.
the class ModelAdapterFactory method adapt.
/**
* Preferably adapt via the {@link ModelFactory} in case the target type is a Sling Model itself, otherwise use regular {@link Adaptable#adaptTo(Class)}.
* @param value the object from which to adapt
* @param type the target type
* @param isWithinCollection
* @return a Result either encapsulating an exception or the adapted value
*/
@CheckForNull
private Result<Object> adapt(final Object value, final Class<?> type, boolean isWithinCollection) {
Object adaptedValue = null;
final String messageSuffix = isWithinCollection ? " in collection" : "";
if (isModelClass(type) && canCreateFromAdaptable(value, type)) {
Result<?> result = internalCreateModel(value, type);
if (result.wasSuccessful()) {
adaptedValue = result.getValue();
} else {
return new Result<Object>(new ModelClassException(String.format("Could not create model from %s: %s%s", value.getClass(), result.getThrowable().getMessage(), messageSuffix), result.getThrowable()));
}
} else if (value instanceof Adaptable) {
adaptedValue = ((Adaptable) value).adaptTo(type);
if (adaptedValue == null) {
return new Result<Object>(new ModelClassException(String.format("Could not adapt from %s to %s%s", value.getClass(), type, messageSuffix)));
}
}
if (adaptedValue != null) {
return new Result<Object>(adaptedValue);
} else {
return new Result<Object>(new ModelClassException(String.format("Could not adapt from %s to %s%s, because this class is not adaptable!", value.getClass(), type, messageSuffix)));
}
}
use of org.apache.sling.models.factory.ModelClassException in project sling by apache.
the class ModelAdapterFactory method injectPrimitiveInitialValue.
/**
* Injects the default initial value for the given primitive class which
* cannot be null (e.g. int = 0, boolean = false).
*
* @param point Annotated element
* @param callback Inject callback
*/
private RuntimeException injectPrimitiveInitialValue(InjectableElement point, InjectCallback callback) {
Type primitiveType = ReflectionUtil.mapWrapperClasses(point.getType());
Object value = null;
if (primitiveType == int.class) {
value = 0;
} else if (primitiveType == long.class) {
value = 0L;
} else if (primitiveType == boolean.class) {
value = Boolean.FALSE;
} else if (primitiveType == double.class) {
value = 0.0d;
} else if (primitiveType == float.class) {
value = 0.0f;
} else if (primitiveType == short.class) {
value = (short) 0;
} else if (primitiveType == byte.class) {
value = (byte) 0;
} else if (primitiveType == char.class) {
value = '