You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2015/02/12 14:29:57 UTC

svn commit: r1659248 - in /sling/trunk/contrib/scripting/sightly: engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/ engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ engine/src/main/java/org/apache/...

Author: radu
Date: Thu Feb 12 13:29:57 2015
New Revision: 1659248

URL: http://svn.apache.org/r1659248
Log:
SLING-4400 - The Use-API should return a falsy value if no Use-provider was able to solve the requested object

* return null when no UseProvider was able to provide an object (an error is logged in this case)

Modified:
    sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerService.java
    sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ClassUseProvider.java
    sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/PojoUseProvider.java
    sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
    sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
    sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java
    sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java

Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerService.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerService.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerService.java (original)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/SightlyJavaCompilerService.java Thu Feb 12 13:29:57 2015
@@ -220,16 +220,14 @@ public class SightlyJavaCompilerService
     private Object loadObject(String className) {
         try {
             readLock.lock();
-            try {
-                if (classLoaderWriter != null) {
-                    return classLoaderWriter.getClassLoader().loadClass(className).newInstance();
-                }
-            } finally {
-                readLock.unlock();
+            if (classLoaderWriter != null) {
+                return classLoaderWriter.getClassLoader().loadClass(className).newInstance();
             }
             return Class.forName(className).newInstance();
-        } catch (Exception e) {
-            throw new CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, e);
+        } catch (Throwable t) {
+            throw new CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, t);
+        } finally {
+            readLock.unlock();
         }
     }
 
@@ -256,6 +254,8 @@ public class SightlyJavaCompilerService
                 LOG.debug("compilation took {}ms", end - start);
             }
             return compilationResult.loadCompiledClass(compilationUnit.getMainClassName()).newInstance();
+        } catch (Throwable t) {
+            throw new CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, t);
         } finally {
             writeLock.unlock();
         }

Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ClassUseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ClassUseProvider.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ClassUseProvider.java (original)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ClassUseProvider.java Thu Feb 12 13:29:57 2015
@@ -21,6 +21,7 @@ package org.apache.sling.scripting.sight
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.regex.Pattern;
 
 import javax.script.Bindings;
 import javax.servlet.ServletRequest;
@@ -38,6 +39,8 @@ import org.apache.sling.scripting.sightl
 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;
 
 /**
  * Interprets the identifier as a class name and tries to load that class
@@ -62,8 +65,15 @@ import org.osgi.framework.Constants;
 })
 public class ClassUseProvider implements UseProvider {
 
+    private static final Logger LOG = LoggerFactory.getLogger(ClassUseProvider.class);
+    private static final Pattern JAVA_PATTERN = Pattern.compile("([[\\p{L}&&[^\\p{Lu}]]_$][\\p{L}\\p{N}_$]*\\.)*[\\p{Lu}_$][\\p{L}\\p{N}_$]*");
+
     @Override
     public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
+        if (!JAVA_PATTERN.matcher(identifier).matches()) {
+            LOG.debug("Identifier {} does not match a Java class name pattern.", identifier);
+            return ProviderOutcome.failure();
+        }
         Bindings globalBindings = renderContext.getBindings();
         Bindings bindings = UseProviderUtils.merge(globalBindings, arguments);
         SlingScriptHelper sling = (SlingScriptHelper) bindings.get(SlingBindings.SLING);
@@ -79,12 +89,12 @@ public class ClassUseProvider implements
             if (obj == null) {
                 obj = request.adaptTo(cls);
             }
+            return ProviderOutcome.success(obj);
         } catch (ClassNotFoundException e) {
-            obj = null;
+            return ProviderOutcome.failure(e);
         } finally {
             resetRequestAttribute(request, overrides);
         }
-        return ProviderOutcome.notNullOrFailure(obj);
     }
 
     private Map<String, Object> setRequestAttributes(ServletRequest request, Bindings arguments) {

Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/PojoUseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/PojoUseProvider.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/PojoUseProvider.java (original)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/PojoUseProvider.java Thu Feb 12 13:29:57 2015
@@ -32,6 +32,7 @@ import org.apache.sling.api.resource.Res
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.scripting.SlingScriptHelper;
 import org.apache.sling.scripting.sightly.ResourceResolution;
+import org.apache.sling.scripting.sightly.impl.compiler.CompilerException;
 import org.apache.sling.scripting.sightly.impl.compiler.SightlyJavaCompilerService;
 import org.apache.sling.scripting.sightly.pojo.Use;
 import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -63,16 +64,15 @@ import org.slf4j.LoggerFactory;
 })
 public class PojoUseProvider implements UseProvider {
 
-    private final Logger LOG = LoggerFactory.getLogger(PojoUseProvider.class);
-
-    private static final Pattern javaPattern = Pattern.compile("([[\\p{L}&&[^\\p{Lu}]]_$][\\p{L}\\p{N}_$]*\\.)*[\\p{Lu}_$][\\p{L}\\p{N}_$]*");
+    private static final Logger LOG = LoggerFactory.getLogger(PojoUseProvider.class);
+    private static final Pattern JAVA_PATTERN = Pattern.compile("([[\\p{L}&&[^\\p{Lu}]]_$][\\p{L}\\p{N}_$]*\\.)*[\\p{Lu}_$][\\p{L}\\p{N}_$]*");
 
     @Reference
     private SightlyJavaCompilerService sightlyJavaCompilerService = null;
 
     @Override
     public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
-        if (!javaPattern.matcher(identifier).matches()) {
+        if (!JAVA_PATTERN.matcher(identifier).matches()) {
             LOG.debug("Identifier {} does not match a Java class name pattern.", identifier);
             return ProviderOutcome.failure();
         }
@@ -87,9 +87,13 @@ public class PojoUseProvider implements
             if (result instanceof Use) {
                 ((Use) result).init(bindings);
             }
-            return ProviderOutcome.notNullOrFailure(result);
+            return ProviderOutcome.success(result);
         } catch (Exception e) {
-            return ProviderOutcome.failure(e);
+            if (e instanceof CompilerException) {
+                return ProviderOutcome.failure(e);
+            } else {
+                return ProviderOutcome.failure();
+            }
         }
     }
 }

Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java (original)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java Thu Feb 12 13:29:57 2015
@@ -70,7 +70,7 @@ public class RenderUnitProvider implemen
             Bindings globalBindings = renderContext.getBindings();
             Resource renderUnitResource = locateResource(globalBindings, identifier, renderContext);
             RenderUnit renderUnit = unitLoader.createUnit(renderUnitResource, globalBindings, (RenderContextImpl) renderContext);
-            return ProviderOutcome.notNullOrFailure(renderUnit);
+            return ProviderOutcome.success(renderUnit);
         }
         return ProviderOutcome.failure();
     }

Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java (original)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/UseRuntimeExtension.java Thu Feb 12 13:29:57 2015
@@ -44,6 +44,8 @@ import org.apache.sling.scripting.sightl
 import org.apache.sling.scripting.sightly.use.UseProvider;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Runtime extension for the USE plugin
@@ -61,6 +63,8 @@ import org.osgi.framework.ServiceReferen
 )
 public class UseRuntimeExtension implements RuntimeExtension {
 
+    private static final Logger LOG = LoggerFactory.getLogger(UseRuntimeExtension.class);
+
     private final Map<ServiceReference, UseProvider> providersMap = new ConcurrentSkipListMap<ServiceReference, UseProvider>();
 
     @Override
@@ -83,11 +87,12 @@ public class UseRuntimeExtension impleme
             ProviderOutcome outcome = provider.provide(identifier, renderContext, useArguments);
             if (outcome.isSuccess()) {
                 return outcome.getResult();
-            } else if (outcome.getCause() != null) {
-                failureCause = outcome.getCause();
+            } else if ((failureCause = outcome.getCause()) != null) {
+                throw new SightlyException("Identifier " + identifier + " cannot be correctly instantiated by the Use API", failureCause);
             }
         }
-        throw new SightlyException("No use provider could resolve identifier: " + identifier, failureCause);
+        LOG.error("No use provider could resolve identifier " + identifier);
+        return null;
     }
 
     // OSGi ################################################################################################################################

Modified: sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java (original)
+++ sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/use/ProviderOutcome.java Thu Feb 12 13:29:57 2015
@@ -24,6 +24,9 @@ package org.apache.sling.scripting.sight
  */
 public final class ProviderOutcome {
 
+    // a generic failure without a cause returned by #failure()
+    private static final ProviderOutcome GENERIC_FAILURE = new ProviderOutcome(false, null, null);
+
     // whether this is a success or failure
     private final boolean success;
 
@@ -33,8 +36,18 @@ public final class ProviderOutcome {
     // the reason for failure in case of failure (may be null)
     private final Throwable cause;
 
-    // a generic failure without a cause returned by #failure()
-    private static final ProviderOutcome GENERIC_FAILURE = new ProviderOutcome(false, null, null);
+    /**
+     * Creates an outcome instance
+     *
+     * @param success {@code true} to indicate success or {@code false} to indicate failure
+     * @param result  optional result value in case of success, may be {@code null}
+     * @param cause   optional cause in case of failure, may be {@code null}
+     */
+    private ProviderOutcome(boolean success, Object result, Throwable cause) {
+        this.success = success;
+        this.result = result;
+        this.cause = cause;
+    }
 
     /**
      * Create a successful outcome
@@ -47,7 +60,9 @@ public final class ProviderOutcome {
     }
 
     /**
-     * Create a failed outcome without a specific {@link #getCause() cause}
+     * Create a failed outcome without a specific {@link #getCause() cause}. This method must be used for creating outcomes that don't
+     * signal an error but rather the fact that the {@link UseProvider} is not capable of fulfilling the request.
+     *
      * @return a failed outcome
      */
     public static ProviderOutcome failure() {
@@ -55,10 +70,10 @@ public final class ProviderOutcome {
     }
 
     /**
-     * Create a failed outcome with the given {@link #getCause() cause}
+     * Create a failed outcome with the given {@link #getCause() cause}. This method must be used when the {@link UseProvider} is
+     * capable of fulfilling the request but an error condition prevents the provider from doing so.
      *
      * @param cause The reason for this failure, which may be {@code null}
-     *
      * @return a failed outcome
      */
     public static ProviderOutcome failure(Throwable cause) {
@@ -66,9 +81,8 @@ public final class ProviderOutcome {
     }
 
     /**
-     * If the given obj is not {@code null} return a {@link #success(Object)
-     * successful outcome}, with the given result. Otherwise, return
-     * {@link #failure()}
+     * If the given obj is not {@code null} return a {@link #success(Object) successful outcome}, with the given result. Otherwise, return
+     * {@link #failure()}.
      *
      * @param obj the result
      * @return an outcome based on whether the parameter is null or not
@@ -78,21 +92,6 @@ public final class ProviderOutcome {
     }
 
     /**
-     * Creates an outcome instance
-     *
-     * @param success {@code true} to indicate success or {@code false} to
-     *            indicate failure
-     * @param result optional result value in case of success, may be
-     *            {@code null}
-     * @param cause optional cause in case of failure, may be {@code null}
-     */
-    private ProviderOutcome(boolean success, Object result, Throwable cause) {
-        this.success = success;
-        this.result = result;
-        this.cause = cause;
-    }
-
-    /**
      * Check if the outcome has been successful
      *
      * @return the outcome success status
@@ -111,7 +110,7 @@ public final class ProviderOutcome {
     }
 
     /**
-     * Get the result in this outcome
+     * Get the result in this outcome.
      *
      * @return the result of the container
      * @throws IllegalStateException if the outcome is a failure
@@ -124,8 +123,7 @@ public final class ProviderOutcome {
     }
 
     /**
-     * Returns the cause for this failure outcome or {@code null} if this
-     * outcome is a success or no cause has been defined with the
+     * Returns the cause for this failure outcome or {@code null} if this outcome is a success or no cause has been defined with the
      * {@link #failure(Throwable)} method.
      *
      * @return the cause for this failure outcome.

Modified: sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java?rev=1659248&r1=1659247&r2=1659248&view=diff
==============================================================================
--- sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java (original)
+++ sling/trunk/contrib/scripting/sightly/js-use-provider/src/main/java/org/apache/sling/scripting/sightly/js/impl/JsUseProvider.java Thu Feb 12 13:29:57 2015
@@ -27,11 +27,14 @@ import org.apache.felix.scr.annotations.
 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.SlingException;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.scripting.SlingScriptHelper;
+import org.apache.sling.scripting.sightly.SightlyException;
+import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
 import org.apache.sling.scripting.sightly.js.impl.async.AsyncContainer;
 import org.apache.sling.scripting.sightly.js.impl.async.AsyncExtractor;
 import org.apache.sling.scripting.sightly.js.impl.jsapi.SlyBindingsValuesProvider;
@@ -73,9 +76,6 @@ public class JsUseProvider implements Us
     private ScriptEngineManager scriptEngineManager = null;
 
     @Reference
-    private ResourceResolverFactory rrf = null;
-
-    @Reference
     private SlyBindingsValuesProvider slyBindingsValuesProvider = null;
 
     @Override
@@ -85,46 +85,17 @@ public class JsUseProvider implements Us
         if (!Utils.isJsScript(identifier)) {
             return ProviderOutcome.failure();
         }
-        ScriptEngine jsEngine = obtainEngine();
+        ScriptEngine jsEngine = scriptEngineManager.getEngineByName(JS_ENGINE_NAME);
         if (jsEngine == null) {
-            log.warn("No JavaScript engine defined");
-            return ProviderOutcome.failure();
+            return ProviderOutcome.failure(new SightlyException("No JavaScript engine was defined."));
         }
         SlingScriptHelper scriptHelper = Utils.getHelper(globalBindings);
-        JsEnvironment environment = null;
-        ResourceResolver adminResolver = null;
-        try {
-            environment = new JsEnvironment(jsEngine);
-            environment.initialize();
-            String callerPath = scriptHelper.getScript().getScriptResource().getPath();
-            boolean allowedExecutablePath = false;
-            adminResolver = rrf.getAdministrativeResourceResolver(null);
-            for (String path : adminResolver.getSearchPath()) {
-                if (callerPath.startsWith(path)) {
-                    allowedExecutablePath = true;
-                    break;
-                }
-            }
-            if (allowedExecutablePath) {
-                Resource caller = adminResolver.getResource(callerPath);
-                AsyncContainer asyncContainer = environment.run(caller, identifier, globalBindings, arguments);
-                return ProviderOutcome.success(jsValueAdapter.adapt(asyncContainer));
-            }
-            return ProviderOutcome.failure();
-        } catch (LoginException e) {
-            log.error("Unable to load JS script " + identifier, e);
-        } finally {
-            if (environment != null) {
-                environment.cleanup();
-            }
-            if (adminResolver != null) {
-                adminResolver.close();
-            }
-        }
-        return ProviderOutcome.failure();
-    }
-
-    private ScriptEngine obtainEngine() {
-        return scriptEngineManager.getEngineByName(JS_ENGINE_NAME);
+        JsEnvironment environment = new JsEnvironment(jsEngine);
+        environment.initialize();
+        String callerPath = scriptHelper.getScript().getScriptResource().getPath();
+        ResourceResolver adminResolver = renderContext.getScriptResourceResolver();
+        Resource caller = adminResolver.getResource(callerPath);
+        AsyncContainer asyncContainer = environment.run(caller, identifier, globalBindings, arguments);
+        return ProviderOutcome.success(jsValueAdapter.adapt(asyncContainer));
     }
 }