RuntimeException injectElementInternal()

in src/main/java/org/apache/sling/models/impl/ModelAdapterFactory.java [542:653]


    RuntimeException injectElementInternal(final InjectableElement element, final Object adaptable,
                                   final @NotNull DisposalCallbackRegistry registry, final InjectCallback callback,
                                   final @NotNull Map<ValuePreparer, Object> preparedValues,
                                   final @Nullable BundleContext modelContext) {

        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 = null;
                    if (injector instanceof OSGiServiceInjector) {
                        value = ((OSGiServiceInjector)injector).getValue(preparedValue, name, element.getType(), element.getAnnotatedElement(), registry, modelContext);
                    } else {
                        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;
    }