private ProviderOutcome loadObject()

in src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/JavaUseProvider.java [152:236]


    private ProviderOutcome loadObject(
            @NotNull Class<?> cls,
            @NotNull ServiceLoader serviceLoader,
            @NotNull Bindings globalBindings,
            @NotNull Bindings arguments)
            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // OSGi service
        Object serviceResult = serviceLoader.getService(cls);
        if (serviceResult != null) {
            return ProviderOutcome.success(serviceResult);
        }
        // adaptable
        Object adaptableCandidate = arguments.get(ADAPTABLE);
        Adaptable adaptable = null;

        if (adaptableCandidate instanceof Adaptable) {
            adaptable = (Adaptable) adaptableCandidate;
        } else {
            LOG.debug("The provided adaptable argument value, was not of type Adaptable");
        }

        SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
        Resource resource = BindingsUtils.getResource(globalBindings);
        // Sling Model
        if (modelFactory != null && ((ModelFactory) modelFactory).isModelClass(cls)) {
            try {
                // Attempt to instantiate via sling models
                // first, try to use the provided adaptable
                if (adaptable != null && ((ModelFactory) modelFactory).canCreateFromAdaptable(adaptable, cls)) {
                    LOG.debug("Trying to instantiate class {} as Sling Model from provided adaptable.", cls);
                    return ProviderOutcome.notNullOrFailure(((ModelFactory) modelFactory).createModel(adaptable, cls));
                }
                // then, try to use the request
                if (request != null && ((ModelFactory) modelFactory).canCreateFromAdaptable(request, cls)) {
                    LOG.debug("Trying to instantiate class {} as Sling Model from request.", cls);
                    return ProviderOutcome.notNullOrFailure(((ModelFactory) modelFactory).createModel(request, cls));
                }
                // finally, try to use the resource
                if (resource != null && ((ModelFactory) modelFactory).canCreateFromAdaptable(resource, cls)) {
                    LOG.debug("Trying to instantiate class {} as Sling Model from resource.", cls);
                    return ProviderOutcome.notNullOrFailure(((ModelFactory) modelFactory).createModel(resource, cls));
                }
                return ProviderOutcome.failure(new IllegalStateException(
                        "Could not adapt the given Sling Model from neither request nor resource: " + cls));
            } catch (Exception e) {
                return ProviderOutcome.failure(e);
            }
        }

        Object adaptableResult = null;
        if (adaptable != null) {
            LOG.debug("Trying to instantiate class {} as sling adapter via adaptable.adaptTo().", cls);
            adaptableResult = adaptable.adaptTo(cls);
        }
        if (adaptableResult == null && request != null) {
            LOG.debug("Trying to instantiate class {} as sling adapter via request.adaptTo().", cls);
            adaptableResult = request.adaptTo(cls);
        }
        if (adaptableResult == null && resource != null) {
            LOG.debug("Trying to instantiate class {} as sling adapter via resource.adaptTo().", cls);
            adaptableResult = resource.adaptTo(cls);
        }

        if (adaptableResult != null) {
            return ProviderOutcome.success(adaptableResult);
        } else if (cls.isInterface() || Modifier.isAbstract(cls.getModifiers())) {
            LOG.debug("Won't attempt to instantiate an interface or abstract class {}", cls.getName());
            return ProviderOutcome.failure(new IllegalArgumentException(String.format(
                    " %s represents an interface or an abstract " + "class which cannot be instantiated.",
                    cls.getName())));
        } else if (cls.isEnum()) {
            // for enum, just return the class
            return ProviderOutcome.success(cls);
        } else {
            /*
             * the object was cached by the class loader but it's not adaptable from {@link Resource} or {@link
             * SlingHttpServletRequest}; attempt to load it like a regular POJO that optionally could implement {@link Use}
             */
            Object javaUseResult = cls.getDeclaredConstructor().newInstance();
            if (javaUseResult instanceof Use) {
                ((Use) javaUseResult).init(BindingsUtils.merge(globalBindings, arguments));
            }
            return ProviderOutcome.notNullOrFailure(javaUseResult);
        }
    }