This is an automated email from the ASF dual-hosted git repository. rombert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-models-provider.git
commit 6385660942d8bc724e898573cbcf1a3b35e06b1f Author: Radu Cotescu <[email protected]> AuthorDate: Tue May 12 15:39:47 2015 +0000 SLING-4704 - Move the Sightly scripting engine artifacts from contrib to bundles * moved Sightly artifacts from contrib to bundles * updated SCM info git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1678979 13f79535-47bb-0310-9956-ffa450edef68 --- pom.xml | 132 +++++++++++++++++ .../models/impl/ModelFactoryUseProvider.java | 157 +++++++++++++++++++++ 2 files changed, 289 insertions(+) diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..9b84786 --- /dev/null +++ b/pom.xml @@ -0,0 +1,132 @@ +<?xml version="1.0"?> +<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <!-- ======================================================================= --> + <!-- P A R E N T P R O J E C T --> + <!-- ======================================================================= --> + <parent> + <groupId>org.apache.sling</groupId> + <artifactId>sling</artifactId> + <version>22</version> + <relativePath /> + </parent> + + <!-- ======================================================================= --> + <!-- P R O J E C T --> + <!-- ======================================================================= --> + <artifactId>org.apache.sling.scripting.sightly.models.provider</artifactId> + <version>1.0.0-SNAPSHOT</version> + <packaging>bundle</packaging> + + <name>Apache Sling Scripting Sightly Models Use Provider</name> + + <description> + Apache Sling Scripting Sightly Models Use Provider adds support for accessing Sling Models from Sightly's Use-API leveraging the ModelFactory. + </description> + + <scm> + <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/sightly/models-use-provider</connection> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/sightly/models-use-provider</developerConnection> + <url>http://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/sightly/models-use-provider</url> + </scm> + + <properties> + <sling.java.version>6</sling.java.version> + </properties> + + <!-- ======================================================================= --> + <!-- B U I L D --> + <!-- ======================================================================= --> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-scr-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + </plugin> + </plugins> + </build> + + <!-- ======================================================================= --> + <!-- D E P E N D E N C I E S --> + <!-- ======================================================================= --> + <dependencies> + <!-- OSGI --> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + </dependency> + + <!-- Sling --> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.api</artifactId> + <version>2.4.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.models.api</artifactId> + <version>1.1.1-SNAPSHOT</version> + <scope>provided</scope> + </dependency> + + <!-- Sightly --> + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.scripting.sightly</artifactId> + <version>1.0.0</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.apache.sling</groupId> + <artifactId>org.apache.sling.commons.classloader</artifactId> + <version>1.3.0</version> + <scope>provided</scope> + </dependency> + + <!-- Logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <scope>provided</scope> + </dependency> + + </dependencies> +</project> diff --git a/src/main/java/org/apache/sling/scripting/sightly/models/impl/ModelFactoryUseProvider.java b/src/main/java/org/apache/sling/scripting/sightly/models/impl/ModelFactoryUseProvider.java new file mode 100644 index 0000000..538aca4 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/sightly/models/impl/ModelFactoryUseProvider.java @@ -0,0 +1,157 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.sling.scripting.sightly.models.impl; + + +import java.util.HashMap; +import java.util.Map; + +import javax.script.Bindings; +import javax.script.SimpleBindings; +import javax.servlet.ServletRequest; + +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Property; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.Service; +import org.apache.sling.api.SlingHttpServletRequest; +import org.apache.sling.api.resource.Resource; +import org.apache.sling.api.scripting.SlingBindings; +import org.apache.sling.commons.classloader.DynamicClassLoaderManager; +import org.apache.sling.models.factory.ModelFactory; +import org.apache.sling.scripting.sightly.render.RenderContext; +import org.apache.sling.scripting.sightly.use.ProviderOutcome; +import org.apache.sling.scripting.sightly.use.UseProvider; +import org.osgi.framework.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Sightly {@link UseProvider} which will instantiate a referenced Sling Model. + * For that it tries to use the {@link ModelFactory#createModel(Object, Class)} first with the adaptable {@link Resource} + * then with the adaptable {@link SlingHttpServletRequest}. + * It will always fail with an exception (i.e. no other {@code UseProvider} is asked afterwards and the exception is being rethrown) + * in case the following two preconditions are fulfilled: + * <ol> + * <li>the given identifier specifies a class which can be loaded by the DynamicClassLoader</li> + * <li>the loaded class has a Model annotation</li> + * </ol> + * In case any of those preconditions are not fulfilled the other registered UseProviders are used! + */ +@Component +@Service +/* + * must have a higher priority than org.apache.sling.scripting.sightly.impl.engine.extension.use.JavaUseProvider but lower than + * org.apache.sling.scripting.sightly.impl.engine.extension.use.RenderUnitProvider to kick in + * before the JavaUseProvider but after the RenderUnitProvider + */ +@Property(name = Constants.SERVICE_RANKING, intValue = { 95 }) +public class ModelFactoryUseProvider implements UseProvider { + + private static final Logger log = LoggerFactory.getLogger(ModelFactoryUseProvider.class); + + @Reference + ModelFactory modelFactory; + + @Reference + private DynamicClassLoaderManager dynamicClassLoaderManager = null; + + @Override + public ProviderOutcome provide(final String identifier, final RenderContext renderContext, final Bindings arguments) { + final Class<?> cls; + try { + cls = dynamicClassLoaderManager.getDynamicClassLoader().loadClass(identifier); + } catch(ClassNotFoundException e) { + log.debug("Could not find class with the given name {}: {}", identifier, e.getMessage()); + // next use provider will be queried + return ProviderOutcome.failure(); + } + Bindings globalBindings = renderContext.getBindings(); + Bindings bindings = merge(globalBindings, arguments); + Resource resource = (Resource) bindings.get(SlingBindings.RESOURCE); + if (resource == null) { + return ProviderOutcome.failure(new IllegalStateException("Could not get resource from bindings")); + } + SlingHttpServletRequest request = (SlingHttpServletRequest) bindings.get(SlingBindings.REQUEST); + if (request == null) { + return ProviderOutcome.failure(new IllegalStateException("Could not get request from bindings")); + } + + // pass parameters as request attributes + Map<String, Object> overrides = setRequestAttributes(request, arguments); + Object obj = null; + try { + if (!modelFactory.isModelClass(resource, cls)) { + log.debug("{} is no Sling Model (because it lacks the according Model annotation)!"); + // next use provider will be queried + return ProviderOutcome.failure(); + } + // try to instantiate class via Sling Models (first via resource, then via request) + if (modelFactory.canCreateFromAdaptable(resource, cls)) { + obj = modelFactory.createModel(resource, cls); + } else if (modelFactory.canCreateFromAdaptable(request, cls)) { + obj = modelFactory.createModel(request, cls); + } else { + return ProviderOutcome.failure(new IllegalStateException("Could not adapt the given Sling Model from neither resource nor request: " + cls)); + } + } catch (Throwable e) { + return ProviderOutcome.failure(e); + } finally { + resetRequestAttribute(request, overrides); + } + return ProviderOutcome.notNullOrFailure(obj); + } + + private Map<String, Object> setRequestAttributes(final ServletRequest request, + final Bindings arguments) { + Map<String, Object> overrides = new HashMap<String, Object>(); + for (Map.Entry<String, Object> entry : arguments.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + Object oldValue = request.getAttribute(key); + if (oldValue != null) { + overrides.put(key, oldValue); + } + else { + overrides.put(key, null); + } + request.setAttribute(key, value); + } + return overrides; + } + + private void resetRequestAttribute(final ServletRequest request, + final Map<String, Object> overrides) { + for (Map.Entry<String, Object> entry : overrides.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (value == null) { + request.removeAttribute(key); + } + else { + request.setAttribute(key, value); + } + } + } + + private SimpleBindings merge(Bindings former, Bindings latter) { + SimpleBindings bindings = new SimpleBindings(); + bindings.putAll(former); + bindings.putAll(latter); + return bindings; + } +} -- To stop receiving notification emails like this one, please contact "[email protected]" <[email protected]>.
