You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:11:42 UTC
[sling-org-apache-sling-scripting-sightly-models-provider] 09/15:
SLING-5036 - Optimise the ModelsFactoryUseProvider to fail as early as
possible if it cannot provide an object
This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to annotated tag org.apache.sling.scripting.sightly.models.provider-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-sightly-models-provider.git
commit 61deecdf19370b31bfafd2c0d2f8b793c72fc1e6
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Thu Sep 17 14:07:19 2015 +0000
SLING-5036 - Optimise the ModelsFactoryUseProvider to fail as early as possible if it cannot provide an object
* renamed ModelsFactoryUseProvider to SlingModelsUseProvider
* delayed all bindings retrievals until they're absolutely necessary
* removed bindings merging - models can get their arguments through request attributes if they're adaptable from SlingHttpServletRequest
* updated the test setup to take into account the SlingModelsUseProvider (both IT and performance)
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/scripting/sightly/models-use-provider@1703629 13f79535-47bb-0310-9956-ffa450edef68
---
...seProvider.java => SlingModelsUseProvider.java} | 124 +++++++++++----------
1 file changed, 67 insertions(+), 57 deletions(-)
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/SlingModelsUseProvider.java
similarity index 61%
rename from src/main/java/org/apache/sling/scripting/sightly/models/impl/ModelFactoryUseProvider.java
rename to src/main/java/org/apache/sling/scripting/sightly/models/impl/SlingModelsUseProvider.java
index 6c81d92..cf8fa3d 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/models/impl/ModelFactoryUseProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/models/impl/SlingModelsUseProvider.java
@@ -1,30 +1,29 @@
-/*
+/*******************************************************************************
* 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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 java.util.regex.Pattern;
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.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
@@ -41,83 +40,104 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
+ * <p>
* 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}
+ * </p>
+ * <p>
+ * 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>
+ * <li>the given identifier specifies a class which can be loaded by a {@link org.apache.sling.commons.classloader.DynamicClassLoader}</li>
+ * <li>the loaded class has a {@link org.apache.sling.models.annotations.Model} annotation</li>
* </ol>
- * In case any of those preconditions are not fulfilled the other registered UseProviders are used!
+ * </p>
+ * <p>
+ * <p>
+ * In case any of those preconditions are not fulfilled the other registered {@link UseProvider}s will be queried.
+ * </p>
*/
@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 {
+@Properties({
+ @Property(
+ name = Constants.SERVICE_RANKING,
+ label = "Service Ranking",
+ description =
+ "The Service Ranking value acts as the priority with which this Use Provider is queried to return an Use-object. A" +
+ "higher value represents a higher priority.",
+ /**
+ * Must have a higher priority than {@link org.apache.sling.scripting.sightly.impl.engine.extension.use.JavaUseProvider} but lower
+ * than {@link org.apache.sling.scripting.sightly.impl.engine.extension.use.RenderUnitProvider} to kick in before the
+ * JavaUseProvider but after the RenderUnitProvider.
+ */
+ intValue = 95
+ )
+})
+public class SlingModelsUseProvider implements UseProvider {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SlingModelsUseProvider.class);
+ private static final Pattern JAVA_PATTERN = Pattern.compile(
+ "([[\\p{L}&&[^\\p{Lu}]]_$][\\p{L}\\p{N}_$]*\\.)*[\\p{Lu}_$][\\p{L}\\p{N}_$]*");
+
- private static final Logger log = LoggerFactory.getLogger(ModelFactoryUseProvider.class);
-
@Reference
- ModelFactory modelFactory;
-
+ private ModelFactory modelFactory = null;
+
@Reference
private DynamicClassLoaderManager dynamicClassLoaderManager = null;
-
+
@Override
public ProviderOutcome provide(final String identifier, final RenderContext renderContext, final Bindings arguments) {
+ if (!JAVA_PATTERN.matcher(identifier).matches()) {
+ LOGGER.debug("Identifier {} does not match a Java class name pattern.", identifier);
+ return ProviderOutcome.failure();
+ }
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());
+ } catch (ClassNotFoundException e) {
+ LOGGER.debug("Could not find class with the given name {}: {}", identifier, e.getMessage());
// next use provider will be queried
return ProviderOutcome.failure();
}
if (!modelFactory.isModelClass(cls)) {
- log.debug("{} is no Sling Model (because it lacks the according Model annotation or is not being picked up by the Bundle Listener)!");
+ LOGGER.debug("{} is not a Sling Model.");
// 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);
+ SlingHttpServletRequest request = (SlingHttpServletRequest) globalBindings.get(SlingBindings.REQUEST);
if (request == null) {
- return ProviderOutcome.failure(new IllegalStateException("Could not get request from bindings"));
+ 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 {
// try to instantiate class via Sling Models (first via request, then via resource)
if (modelFactory.canCreateFromAdaptable(request, cls)) {
- obj = modelFactory.createModel(request, cls);
- } else if (modelFactory.canCreateFromAdaptable(resource, cls)) {
- obj = modelFactory.createModel(resource, cls);
- } else {
- return ProviderOutcome.failure(new IllegalStateException("Could not adapt the given Sling Model from neither resource nor request: " + cls));
+ return ProviderOutcome.notNullOrFailure(modelFactory.createModel(request, cls));
+ }
+ Resource resource = (Resource) globalBindings.get(SlingBindings.RESOURCE);
+ if (resource == null) {
+ return ProviderOutcome.failure(new IllegalStateException("Could not get resource from bindings."));
}
+ if (modelFactory.canCreateFromAdaptable(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 (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) {
+ 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();
@@ -125,8 +145,7 @@ public class ModelFactoryUseProvider implements UseProvider {
Object oldValue = request.getAttribute(key);
if (oldValue != null) {
overrides.put(key, oldValue);
- }
- else {
+ } else {
overrides.put(key, null);
}
request.setAttribute(key, value);
@@ -134,24 +153,15 @@ public class ModelFactoryUseProvider implements UseProvider {
return overrides;
}
- private void resetRequestAttribute(final ServletRequest request,
- final Map<String, Object> 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 {
+ } 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
"commits@sling.apache.org" <co...@sling.apache.org>.