private ProviderOutcome loadObject()

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


    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.isModelClass(cls)) {
                try {
                    // Attempt to instantiate via sling models
                    // first, try to use the provided adaptable
                    if (adaptable != null && modelFactory.canCreateFromAdaptable(adaptable, cls)) {
                        LOG.debug("Trying to instantiate class {} as Sling Model from provided adaptable.", cls);
                        return ProviderOutcome.notNullOrFailure(modelFactory.createModel(adaptable, cls));
                    }
                    // then, try to use the request
                    if (request != null && modelFactory.canCreateFromAdaptable(request, cls)) {
                        LOG.debug("Trying to instantiate class {} as Sling Model from request.", cls);
                        return ProviderOutcome.notNullOrFailure(modelFactory.createModel(request, cls));
                    }
                    // finally, try to use the resource
                    if (resource != null && modelFactory.canCreateFromAdaptable(resource, cls)) {
                        LOG.debug("Trying to instantiate class {} as Sling Model from resource.", cls);
                        return ProviderOutcome.notNullOrFailure(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);
            }
    }