Author: fmeschbe
Date: Mon Dec 15 13:27:00 2014
New Revision: 1645651

URL: http://svn.apache.org/r1645651
Log:
SLING-4240 SlightlyScriptEngine improvements

* Share ResourceResolver for locating script resources with the script
   execution environment instead of recreating each time
* Improve compiler error reporting
* Improvide discovery of script changes to limit recompilation and
   leverage caching of loaded classes in the DynamicClassloader
   
(applied slightly modified patch by Radu Cotescu; thanks a lot)

Added:
    
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java
   (with props)
Modified:
    
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerException.java
    
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/compiler/optimization/reduce/EvalResult.java
    
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
    
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitLoader.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/ScriptUseProvider.java
    
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java

Modified: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerException.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerException.java?rev=1645651&r1=1645650&r2=1645651&view=diff
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerException.java
 (original)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/CompilerException.java
 Mon Dec 15 13:27:00 2014
@@ -20,19 +20,32 @@ package org.apache.sling.scripting.sight
 
 public class CompilerException extends RuntimeException {
 
-    public CompilerException() {
-        super();
-    }
+    private CompilerExceptionCause cause;
 
     public CompilerException(String message) {
         super(message);
     }
 
-    public CompilerException(String message, Throwable throwable) {
-        super(message, throwable);
+    public CompilerException(CompilerExceptionCause cause) {
+        super();
+        this.cause = cause;
+    }
+
+    public CompilerException(CompilerExceptionCause cause, String message) {
+        super(message);
     }
 
-    public CompilerException(Throwable throwable) {
+    public CompilerException(CompilerExceptionCause cause, Throwable 
throwable) {
         super(throwable);
+        this.cause = cause;
+    }
+
+    public CompilerExceptionCause getFailureCause() {
+        return cause;
+    }
+
+    public enum CompilerExceptionCause {
+        MISSING_REPO_POJO,
+        COMPILER_ERRORS
     }
 }

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=1645651&r1=1645650&r2=1645651&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
 Mon Dec 15 13:27:00 2014
@@ -30,10 +30,8 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.Service;
-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.commons.classloader.ClassLoaderWriter;
 import org.apache.sling.commons.compiler.CompilationResult;
 import org.apache.sling.commons.compiler.CompilationUnit;
@@ -41,6 +39,7 @@ import org.apache.sling.commons.compiler
 import org.apache.sling.commons.compiler.Options;
 import org.apache.sling.jcr.compiler.JcrJavaCompiler;
 import org.apache.sling.scripting.sightly.ResourceResolution;
+import org.apache.sling.scripting.sightly.impl.engine.UnitChangeMonitor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -63,7 +62,7 @@ public class SightlyJavaCompilerService
     private JcrJavaCompiler jcrJavaCompiler = null;
 
     @Reference
-    private ResourceResolverFactory rrf = null;
+    private UnitChangeMonitor unitChangeMonitor = null;
 
     private Options options;
 
@@ -87,45 +86,28 @@ public class SightlyJavaCompilerService
 
         // assume fully qualified class name
         if (className.contains(".")) {
-            Resource pojoResource = checkIfPojoIsInRepo(className);
-            if (pojoResource != null) {
-                return compileSource(pojoResource, className);
-            } else {
-                LOG.debug("fully qualified classname provided, loading object 
directly");
-                return loadObject(className);
-            }
-        }
-
-        LOG.debug("trying to find Java source based on resource: {}", 
resource.getPath());
-
-        // try to find Java source in JCR
-        // use the servlet resolver to do all the magic lookup (resource type 
hierarchy and search path) for us
-
-        Resource scriptResource = ResourceResolution
-                .resolveComponentRelative(resource.getResourceResolver(), 
resource, className + ".java");
-        if (scriptResource != null) {
-            LOG.debug("found Java bean script resource: " + 
scriptResource.getPath());
             try {
-                return compileJavaResource(new 
SlingResourceCompilationUnit(scriptResource), scriptResource.getPath());
-            } catch (Exception e) {
-                throw new CompilerException(e);
+                String pojoPath = getPathFromJavaName(className);
+                return loadPOJOFromRepo(resource.getResourceResolver(), 
className, pojoPath);
+            } catch (CompilerException e1) {
+                if (e1.getFailureCause() == 
CompilerException.CompilerExceptionCause.MISSING_REPO_POJO) {
+                    // the POJO might have been loaded once and come from a 
bundle
+                    return loadObject(className);
+                }
+                throw e1;
             }
         } else {
-            // not found in JCR, try to load from bundle using current 
resource type package
-            // /apps/project/components/foo => 
apps.project.components.foo.<scriptName>
-            Resource resourceType = 
resource.getResourceResolver().getResource(resource.getResourceType());
-
-            if (resourceType == null) {
-                resourceType = resource;
+            LOG.debug("trying to find Java source based on resource: {}", 
resource.getPath());
+            // try to find Java source in JCR from a non-fully qualified class 
name
+            Resource scriptResource = ResourceResolution
+                    .resolveComponentRelative(resource.getResourceResolver(), 
resource, className + ".java");
+            if (scriptResource != null) {
+                String pojoPath = scriptResource.getPath();
+                LOG.debug("found Java bean script resource: " + 
scriptResource.getPath());
+                return loadPOJOFromRepo(resource.getResourceResolver(), 
getJavaNameFromPath(pojoPath), pojoPath);
+            } else {
+                return loadPOJOFromBundle(resource, className);
             }
-
-            String resourceTypeDir = resourceType.getPath();
-            className = getJavaNameFromPath(resourceTypeDir) + "." + className;
-
-            LOG.debug("Java bean source not found, trying to locate using" + " 
component directory as packagename: {}", resourceTypeDir);
-
-            LOG.debug("loading Java class: " + className);
-            return loadObject(className);
         }
     }
 
@@ -143,10 +125,48 @@ public class SightlyJavaCompilerService
             CompilationUnit compilationUnit = new 
SightlyCompilationUnit(javaResource, fqcn);
             return compileJavaResource(compilationUnit, 
javaResource.getPath());
         } catch (Exception e) {
-            throw new CompilerException(e);
+            throw new 
CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, e);
         }
     }
 
+    private Object loadPOJOFromRepo(ResourceResolver resolver, String 
className, String pojoPath) {
+        if (unitChangeMonitor.getLastModifiedDateForJavaUseObject(pojoPath) > 
0) {
+            Resource pojoResource = resolver.getResource(pojoPath);
+            if (pojoResource != null) {
+                // remove it from the monitor so that next time we load it 
from the classloader's cache
+                unitChangeMonitor.clearJavaUseObject(pojoPath);
+                return compileSource(pojoResource, className);
+            } else {
+                throw new 
CompilerException(CompilerException.CompilerExceptionCause.MISSING_REPO_POJO, 
String.format("Resource %s " +
+                        "identifying class %s has been removed.", pojoPath, 
className));
+            }
+        } else {
+            try {
+                // the POJO was compiled but not cached by the 
unitChangeMonitor
+                return loadObject(className);
+            } catch (CompilerException e) {
+                // the POJO was never compiled, nor cached by unitChangeMonitor
+                Resource pojoResource = resolver.getResource(pojoPath);
+                if (pojoResource != null) {
+                    return compileSource(pojoResource, className);
+                }
+                throw new 
CompilerException(CompilerException.CompilerExceptionCause.MISSING_REPO_POJO);
+            }
+        }
+    }
+
+    private Object loadPOJOFromBundle(Resource resource, String className) {
+        Resource resourceType = 
resource.getResourceResolver().getResource(resource.getResourceType());
+        if (resourceType == null) {
+            resourceType = resource;
+        }
+        String resourceTypeDir = resourceType.getPath();
+        String  fullyQualifiedClassName = getJavaNameFromPath(resourceTypeDir) 
+ "." + className;
+        LOG.debug("Java bean source not found, trying to locate using" + " 
component directory as packagename: {}", resourceTypeDir);
+        LOG.debug("loading Java class: " + fullyQualifiedClassName);
+        return loadObject(fullyQualifiedClassName);
+    }
+
     /**
      * Instantiate and return an instance of a class.
      *
@@ -155,29 +175,18 @@ public class SightlyJavaCompilerService
      */
     private Object loadObject(String className) {
         try {
-            return loadClass(className).newInstance();
-        } catch (Exception e) {
-            throw new CompilerException(e);
-        }
-    }
-
-    /**
-     * Retrieve a class from the ClassLoaderWriter service.
-     *
-     * @param name name of class to load
-     * @return Class
-     * @throws ClassNotFoundException
-     */
-    private Class loadClass(String name) throws ClassNotFoundException {
-        readLock.lock();
-        try {
-            if (classLoaderWriter != null) {
-                return classLoaderWriter.getClassLoader().loadClass(name);
+            readLock.lock();
+            try {
+                if (classLoaderWriter != null) {
+                    return 
classLoaderWriter.getClassLoader().loadClass(className).newInstance();
+                }
+            } finally {
+                readLock.unlock();
             }
-        } finally {
-            readLock.unlock();
+            return Class.forName(className).newInstance();
+        } catch (Exception e) {
+            throw new 
CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, e);
         }
-        return Class.forName(name);
     }
 
     /**
@@ -196,7 +205,7 @@ public class SightlyJavaCompilerService
             long end = System.currentTimeMillis();
             List<CompilerMessage> errors = compilationResult.getErrors();
             if (errors != null && errors.size() > 0) {
-                throw new CompilerException(createErrorMsg(errors));
+                throw new 
CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, 
createErrorMsg(errors));
             }
             if (LOG.isDebugEnabled()) {
                 LOG.debug("script compiled: {}", 
compilationResult.didCompile());
@@ -222,37 +231,6 @@ public class SightlyJavaCompilerService
     }
 
     //---------------------------------- private 
-----------------------------------
-
-    /**
-     * Checks is a POJO class name is represented by a resource from the 
repository.
-     *
-     * @param className the class name
-     * @return the Resource in which the class is defined, {@code null} if the 
POJO was not found in the repository
-     */
-    private Resource checkIfPojoIsInRepo(String className) {
-        // POJOs will always be loaded through the compiler (prevents stale 
class loader issues)
-        String pojoPath = "/" + className.replaceAll("\\.", "/") + ".java";
-        ResourceResolver rr = null;
-        try {
-            rr = rrf.getAdministrativeResourceResolver(null);
-            Resource pojoResource = rr.getResource(pojoPath);
-            if (pojoResource != null) {
-                for (String s : rr.getSearchPath()) {
-                    if (pojoPath.startsWith(s)) {
-                        return pojoResource;
-                    }
-                }
-            }
-        } catch (LoginException le) {
-            LOG.error("Cannot search repository for POJO.", le);
-        } finally {
-            if (rr != null) {
-                rr.close();
-            }
-        }
-        return null;
-    }
-
     private String getJavaNameFromPath(String path) {
         if (path.endsWith(".java")) {
             path = path.substring(0, path.length() - 5);
@@ -260,6 +238,10 @@ public class SightlyJavaCompilerService
         return path.substring(1).replace("/", ".").replace("-", "_");
     }
 
+    private String getPathFromJavaName(String className) {
+        return "/" + className.replaceAll("\\.", "/") + ".java";
+    }
+
     private String createErrorMsg(List<CompilerMessage> errors) {
         final StringBuilder buffer = new StringBuilder();
         buffer.append("Compilation errors in ");

Modified: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java?rev=1645651&r1=1645650&r2=1645651&view=diff
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java
 (original)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/compiler/optimization/reduce/EvalResult.java
 Mon Dec 15 13:27:00 2014
@@ -59,7 +59,8 @@ public final class EvalResult {
 
     public Object getValue() {
         if (!isConstant()) {
-            throw new CompilerException(new 
UnsupportedOperationException("Cannot get constant value from non-constant 
result"));
+            throw new 
CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, new 
UnsupportedOperationException
+                    ("Cannot get constant value from non-constant result."));
         }
         return value;
     }
@@ -89,7 +90,8 @@ public final class EvalResult {
         if (value == null) {
             return NullLiteral.INSTANCE;
         }
-        throw new CompilerException(new UnsupportedOperationException("Cannot 
transform to literal: " + value));
+        throw new 
CompilerException(CompilerException.CompilerExceptionCause.COMPILER_ERRORS, new 
UnsupportedOperationException("Cannot " +
+                "transform to literal: " + value));
     }
 
     private static MapLiteral asMapLiteral(Map<String, Object> map) {

Modified: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java?rev=1645651&r1=1645650&r2=1645651&view=diff
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
 (original)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/SightlyScriptEngine.java
 Mon Dec 15 13:27:00 2014
@@ -29,15 +29,12 @@ import javax.script.ScriptException;
 import javax.script.SimpleBindings;
 
 import org.apache.sling.api.SlingHttpServletRequest;
-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.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptConstants;
 import org.apache.sling.api.scripting.SlingScriptHelper;
-import org.apache.sling.commons.classloader.DynamicClassLoader;
 import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
-import org.apache.sling.scripting.sightly.SightlyException;
 import 
org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
 import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit;
 import org.slf4j.Logger;
@@ -71,7 +68,6 @@ public class SightlyScriptEngine extends
         Bindings bindings = 
scriptContext.getBindings(ScriptContext.ENGINE_SCOPE);
         SlingScriptHelper slingScriptHelper = (SlingScriptHelper) 
bindings.get(SlingBindings.SLING);
         Resource scriptResource = 
slingScriptHelper.getScript().getScriptResource();
-
         final SlingBindings slingBindings = new SlingBindings();
         slingBindings.putAll(bindings);
 
@@ -79,9 +75,12 @@ public class SightlyScriptEngine extends
 
         final SlingHttpServletRequest request = slingBindings.getRequest();
         final Object oldValue = 
request.getAttribute(SlingBindings.class.getName());
+        final ResourceResolver scriptResourceResolver = (ResourceResolver) 
scriptContext.getAttribute(
+            SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER, 
SlingScriptConstants.SLING_SCOPE);
+
         try {
             request.setAttribute(SlingBindings.class.getName(), slingBindings);
-            evaluateScript(scriptResource, globalBindings);
+            evaluateScript(scriptResource, globalBindings, 
scriptResourceResolver);
         } finally {
             request.setAttribute(SlingBindings.class.getName(), oldValue);
             Thread.currentThread().setContextClassLoader(old);
@@ -90,51 +89,10 @@ public class SightlyScriptEngine extends
         return null;
     }
 
-    private void evaluateScript(Resource scriptResource, Bindings bindings) {
-        ResourceResolver resourceResolver = null;
-        RenderContextImpl renderContext = new RenderContextImpl(bindings, 
extensionRegistryService.extensions());
+    private void evaluateScript(Resource scriptResource, Bindings bindings, 
ResourceResolver scriptResourceResolver) {
+        RenderContextImpl renderContext = new RenderContextImpl(bindings, 
extensionRegistryService.extensions(), scriptResourceResolver);
         RenderUnit renderUnit = unitLoader.createUnit(scriptResource, 
bindings, renderContext);
-        try {
-            resourceResolver = getAdminResourceResolver(bindings);
-            renderUnit.render(renderContext, EMPTY_BINDINGS);
-        } catch (NoClassDefFoundError defFoundError) {
-            if (renderContext != null) {
-                ClassLoader dcl = 
renderUnit.getClass().getClassLoader().getParent();
-                if (dcl instanceof DynamicClassLoader && 
!((DynamicClassLoader) dcl).isLive()) {
-                    boolean defError = true;
-                    int retries = 0;
-                    while (defError) {
-                        try {
-                            renderUnit = unitLoader.createUnit(scriptResource, 
bindings, renderContext);
-                            renderUnit.render(renderContext, EMPTY_BINDINGS);
-                            defError = false;
-                        } catch (Throwable t) {
-                            if (!(t instanceof NoClassDefFoundError)) {
-                                // break immediately if there's a different 
error than a classloader one
-                                if (t instanceof Error) {
-                                    throw (Error) t;
-                                }
-                                throw (RuntimeException) t;
-                            }
-                            retries++;
-                            if (retries > MAX_CLASSLOADER_RETRIES) {
-                                LOG.error("Max number of retries (" + 
MAX_CLASSLOADER_RETRIES +
-                                        ") for obtaining a valid RenderUnit 
was exceeded.");
-                                throw defFoundError;
-                            }
-                        }
-                    }
-                } else {
-                    // if we can't recover from this just throw the original 
exception
-                    throw defFoundError;
-                }
-            }
-        }
-        finally {
-            if (resourceResolver != null) {
-                resourceResolver.close();
-            }
-        }
+        renderUnit.render(renderContext, EMPTY_BINDINGS);
     }
 
     private void checkArguments(Reader reader, ScriptContext scriptContext) {
@@ -145,14 +103,4 @@ public class SightlyScriptEngine extends
             throw new NullPointerException("ScriptContext cannot be null");
         }
     }
-
-    private ResourceResolver getAdminResourceResolver(Bindings bindings) {
-        SlingScriptHelper sling = (SlingScriptHelper) 
bindings.get(SlingBindings.SLING);
-        ResourceResolverFactory rrf = 
sling.getService(ResourceResolverFactory.class);
-        try {
-            return rrf.getAdministrativeResourceResolver(null);
-        } catch (LoginException e) {
-            throw new SightlyException(e);
-        }
-    }
 }

Added: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java?rev=1645651&view=auto
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java
 (added)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java
 Mon Dec 15 13:27:00 2014
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * 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.impl.engine;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.settings.SlingSettingsService;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventConstants;
+import org.osgi.service.event.EventHandler;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component
+@Service(UnitChangeMonitor.class)
+public class UnitChangeMonitor {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(UnitChangeMonitor.class);
+
+    private Map<String, Long> slyScriptsMap = new ConcurrentHashMap<String, 
Long>();
+    private Map<String, Long> slySourcesMap = new ConcurrentHashMap<String, 
Long>();
+    private Map<String, Long> slyJavaUseMap = new ConcurrentHashMap<String, 
Long>();
+    private ServiceRegistration eventHandlerServiceRegistration;
+    private String[] searchPaths;
+
+    @Reference
+    private ResourceResolverFactory rrf = null;
+
+    @Reference
+    private SlingSettingsService slingSettings = null;
+
+    public long getLastModifiedDateForScript(String script) {
+        Long date = slyScriptsMap.get(script);
+        return date != null ? date : 0;
+    }
+
+    public long getLastModifiedDateForJavaSourceFile(String file) {
+        Long date = slySourcesMap.get(file);
+        return date != null ? date : 0;
+    }
+
+    public long getLastModifiedDateForJavaUseObject(String path) {
+        Long date = slyJavaUseMap.get(path);
+        return date != null ? date : 0;
+    }
+
+
+    public void touchScript(String script) {
+        slyScriptsMap.put(script, System.currentTimeMillis());
+    }
+
+    public void clearJavaUseObject(String path) {
+        slyJavaUseMap.remove(path);
+    }
+
+    @Activate
+    protected void activate(ComponentContext componentContext) {
+        ResourceResolver adminResolver = null;
+        try {
+            adminResolver = rrf.getAdministrativeResourceResolver(null);
+            StringBuilder eventHandlerFilteredPaths = new StringBuilder("(|");
+            searchPaths = adminResolver.getSearchPath();
+            for (String sp : searchPaths) {
+                // Sightly script changes
+                
eventHandlerFilteredPaths.append("(path=").append(sp).append("**/*.").append(SightlyScriptEngineFactory.EXTENSION).append(
+                        ")");
+                // Sightly Java Use-API objects
+                
eventHandlerFilteredPaths.append("(path=").append(sp).append("**/*.java").append(")");
+            }
+            String basePath = UnitLoader.DEFAULT_REPO_BASE_PATH + "/" + 
slingSettings.getSlingId() + "/sightly/";
+            
eventHandlerFilteredPaths.append("(path=").append(basePath).append("**/*.java))");
+            Dictionary eventHandlerProperties = new Hashtable();
+            eventHandlerProperties.put(EventConstants.EVENT_FILTER, 
eventHandlerFilteredPaths.toString());
+            eventHandlerProperties.put(EventConstants.EVENT_TOPIC, new 
String[]{SlingConstants.TOPIC_RESOURCE_ADDED, SlingConstants
+                    .TOPIC_RESOURCE_CHANGED, 
SlingConstants.TOPIC_RESOURCE_REMOVED});
+            eventHandlerServiceRegistration = 
componentContext.getBundleContext().registerService(
+                    EventHandler.class.getName(),
+                    new EventHandler() {
+                        @Override
+                        public void handleEvent(Event event) {
+                            processEvent(event);
+                        }
+                    },
+                    eventHandlerProperties
+            );
+        } catch (LoginException e) {
+            LOG.error("Unable to listen for change events.", e);
+        } finally {
+            if (adminResolver != null) {
+                adminResolver.close();
+            }
+        }
+
+    }
+
+    @Deactivate
+    protected void deactivate(ComponentContext componentContext) {
+        if (eventHandlerServiceRegistration != null) {
+            eventHandlerServiceRegistration.unregister();
+        }
+    }
+
+    private void processEvent(Event event) {
+        String path = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
+        String topic = event.getTopic();
+        if (SlingConstants.TOPIC_RESOURCE_ADDED.equals(topic) || 
SlingConstants.TOPIC_RESOURCE_CHANGED.equals(topic)) {
+            if (path.startsWith(UnitLoader.DEFAULT_REPO_BASE_PATH)) {
+                slySourcesMap.put(path, System.currentTimeMillis());
+            } else {
+                for (String searchPath :searchPaths) {
+                    if (path.startsWith(searchPath)) {
+                        slyJavaUseMap.put(path, System.currentTimeMillis());
+                        return;
+                    }
+                }
+                slyScriptsMap.put(path, System.currentTimeMillis());
+            }
+        } else if (SlingConstants.TOPIC_RESOURCE_REMOVED.equals(topic)) {
+            if (path.startsWith(UnitLoader.DEFAULT_REPO_BASE_PATH)) {
+                slySourcesMap.remove(path);
+            } else {
+                for (String searchPath : searchPaths) {
+                    if (path.startsWith(searchPath)) {
+                        slyJavaUseMap.remove(path);
+                        return;
+                    }
+                }
+                slyScriptsMap.remove(path);
+            }
+        }
+    }
+
+}

Propchange: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitChangeMonitor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitLoader.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitLoader.java?rev=1645651&r1=1645650&r2=1645651&view=diff
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitLoader.java
 (original)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/UnitLoader.java
 Mon Dec 15 13:27:00 2014
@@ -25,7 +25,6 @@ import java.net.URL;
 import java.util.Calendar;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -36,26 +35,22 @@ import org.apache.commons.lang.StringEsc
 import org.apache.commons.lang.StringUtils;
 import org.apache.felix.scr.annotations.Activate;
 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;
-import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.resource.ResourceUtil;
-import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.scripting.sightly.SightlyException;
 import org.apache.sling.scripting.sightly.impl.compiled.CompilationOutput;
 import org.apache.sling.scripting.sightly.impl.compiled.JavaClassBackend;
+import org.apache.sling.scripting.sightly.impl.compiler.SightlyCompilerService;
 import 
org.apache.sling.scripting.sightly.impl.compiler.SightlyJavaCompilerService;
 import 
org.apache.sling.scripting.sightly.impl.compiler.SightlyParsingException;
-import org.apache.sling.scripting.sightly.impl.compiler.SightlyCompilerService;
 import 
org.apache.sling.scripting.sightly.impl.compiler.util.GlobalShadowCheckBackend;
 import 
org.apache.sling.scripting.sightly.impl.engine.compiled.JavaClassTemplate;
 import 
org.apache.sling.scripting.sightly.impl.engine.compiled.SourceIdentifier;
@@ -64,9 +59,6 @@ import org.apache.sling.scripting.sightl
 import 
org.apache.sling.scripting.sightly.impl.engine.runtime.SightlyRenderException;
 import org.apache.sling.settings.SlingSettingsService;
 import org.osgi.service.component.ComponentContext;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventConstants;
-import org.osgi.service.event.EventHandler;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -74,19 +66,8 @@ import org.slf4j.LoggerFactory;
  * Create rendering units from resources.
  */
 @Component
-@Service({UnitLoader.class, EventHandler.class})
-@Properties({
-        @Property(
-                name = EventConstants.EVENT_TOPIC,
-                value = {SlingConstants.TOPIC_RESOURCE_ADDED, 
SlingConstants.TOPIC_RESOURCE_CHANGED, SlingConstants.TOPIC_RESOURCE_REMOVED}
-        ),
-        @Property(
-                name = EventConstants.EVENT_FILTER,
-                value = "(|(" + SlingConstants.PROPERTY_PATH + "=/apps/**/*." 
+ SightlyScriptEngineFactory.EXTENSION + ")(" +
-                        SlingConstants.PROPERTY_PATH + "=/libs/**/*." + 
SightlyScriptEngineFactory.EXTENSION + "))"
-        )
-})
-public class UnitLoader implements EventHandler {
+@Service(UnitLoader.class)
+public class UnitLoader {
 
     public static final String DEFAULT_REPO_BASE_PATH = "/var/classes";
     private static final Logger log = 
LoggerFactory.getLogger(UnitLoader.class);
@@ -101,11 +82,9 @@ public class UnitLoader implements Event
     private static final String JCR_CONTENT = "jcr:content";
     private static final String JCR_DATA = "jcr:data";
     private static final String JCR_LASTMODIFIED = "jcr:lastModified";
-    private static final String JCR_ENCODING = "jcr:encoding";
 
     private String mainTemplate;
     private String childTemplate;
-    private Map<String, Long> slyScriptsMap = new ConcurrentHashMap<String, 
Long>();
 
     private final Map<String, Lock> activeWrites = new HashMap<String, Lock>();
 
@@ -124,37 +103,8 @@ public class UnitLoader implements Event
     @Reference
     private SlingSettingsService slingSettings = null;
 
-    private static long getLastModifiedDate(ResourceResolver resolver, String 
path) {
-        try {
-            Resource ntResource = getNtResource(resolver, path);
-            if (ntResource != null) {
-                ValueMap ntResourceProperties = 
ntResource.adaptTo(ValueMap.class);
-                /**
-                 * make sure to use 0L for the default value; otherwise we get 
an Integer
-                 * overflow due to the long value stored in JCR
-                 */
-                return ntResourceProperties.get(JCR_LASTMODIFIED, 0L);
-            }
-        } catch (Exception e) {
-            log.error("Error while reading last modification date: ", e);
-        }
-        return 0L;
-    }
-
-    private static Resource getNtResource(ResourceResolver resolver, String 
path) {
-        Resource resource = resolver.getResource(path);
-        if (resource != null) {
-            if (path.endsWith(JCR_CONTENT) && 
resource.isResourceType(NT_RESOURCE)) {
-                return resource;
-            } else {
-                Resource ntResource = resource.getChild(JCR_CONTENT);
-                if (ntResource != null && 
ntResource.isResourceType(NT_RESOURCE)) {
-                    return ntResource;
-                }
-            }
-        }
-        return null;
-    }
+    @Reference
+    private UnitChangeMonitor unitChangeMonitor = null;
 
     /**
      * Create a render unit from the given resource
@@ -166,16 +116,18 @@ public class UnitLoader implements Event
      */
     public RenderUnit createUnit(Resource scriptResource, Bindings bindings, 
RenderContextImpl renderContext) {
         Lock lock = null;
-        ResourceResolver adminResolver = null;
         try {
             SourceIdentifier sourceIdentifier = 
obtainIdentifier(scriptResource);
-            adminResolver = rrf.getAdministrativeResourceResolver(null);
             Object obj;
-            ValueMap templateProperties = 
adminResolver.getResource(scriptResource.getPath()).getChild(JCR_CONTENT).adaptTo(ValueMap.class);
-            String encoding = templateProperties.get(JCR_ENCODING, 
sightlyEngineConfiguration.getEncoding());
+            ResourceMetadata resourceMetadata = 
scriptResource.getResourceMetadata();
+            String encoding = resourceMetadata.getCharacterEncoding();
+            if (encoding == null) {
+                encoding = sightlyEngineConfiguration.getEncoding();
+            }
             SlingHttpServletResponse response = (SlingHttpServletResponse) 
bindings.get(SlingBindings.RESPONSE);
             response.setCharacterEncoding(encoding);
-            if (needsUpdate(adminResolver, sourceIdentifier)) {
+            ResourceResolver adminResolver = 
renderContext.getScriptResourceResolver();
+            if (needsUpdate(sourceIdentifier)) {
                 synchronized (activeWrites) {
                     String sourceFullPath = 
sourceIdentifier.getSourceFullPath();
                     lock = activeWrites.get(sourceFullPath);
@@ -196,29 +148,13 @@ public class UnitLoader implements Event
                 throw new SightlyRenderException("Class is not a RenderUnit 
instance");
             }
             return (RenderUnit) obj;
-        } catch (LoginException e) {
-            throw new SightlyRenderException("Unable to create a RenderUnit.", 
e);
         } finally {
-            if (adminResolver != null) {
-                adminResolver.close();
-            }
             if (lock != null) {
                 lock.unlock();
             }
         }
     }
 
-    @Override
-    public void handleEvent(Event event) {
-        String path = (String) event.getProperty(SlingConstants.PROPERTY_PATH);
-        String topic = event.getTopic();
-        if (SlingConstants.TOPIC_RESOURCE_ADDED.equals(topic) || 
SlingConstants.TOPIC_RESOURCE_CHANGED.equals(topic)) {
-            slyScriptsMap.put(path, Calendar.getInstance().getTimeInMillis());
-        } else if (SlingConstants.TOPIC_RESOURCE_REMOVED.equals(topic)) {
-            slyScriptsMap.remove(path);
-        }
-    }
-
     @Activate
     @SuppressWarnings("unused")
     protected void activate(ComponentContext componentContext) {
@@ -372,26 +308,24 @@ public class UnitLoader implements Event
         return ++line;
     }
 
-    private boolean needsUpdate(ResourceResolver resolver, SourceIdentifier 
sourceIdentifier) {
+    private boolean needsUpdate(SourceIdentifier sourceIdentifier) {
         if (sightlyEngineConfiguration.isDevMode()) {
             return true;
         }
-        String javaPath = sourceIdentifier.getSourceFullPath();
         String slyPath = sourceIdentifier.getResource().getPath();
-        Long javaFileDate = getLastModifiedDate(resolver, javaPath);
+        long javaFileDate = 
unitChangeMonitor.getLastModifiedDateForJavaSourceFile(sourceIdentifier.getSourceFullPath());
         if (javaFileDate != 0) {
-
-            Long slyScriptChangeDate = slyScriptsMap.get(slyPath);
-            if (slyScriptChangeDate != null) {
+            long slyScriptChangeDate = 
unitChangeMonitor.getLastModifiedDateForScript(slyPath);
+            if (slyScriptChangeDate != 0) {
                 if (slyScriptChangeDate < javaFileDate) {
                     return false;
                 }
             } else {
-                slyScriptsMap.put(slyPath, 
Calendar.getInstance().getTimeInMillis());
+                unitChangeMonitor.touchScript(slyPath);
             }
             return true;
         }
-        slyScriptsMap.put(slyPath, Calendar.getInstance().getTimeInMillis());
+        unitChangeMonitor.touchScript(slyPath);
         return true;
     }
 

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=1645651&r1=1645650&r2=1645651&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
 Mon Dec 15 13:27:00 2014
@@ -30,10 +30,11 @@ import org.apache.felix.scr.annotations.
 import org.apache.felix.scr.annotations.Service;
 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.ResourceResolution;
 import 
org.apache.sling.scripting.sightly.impl.compiler.SightlyJavaCompilerService;
+import 
org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import 
org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
 import org.apache.sling.scripting.sightly.pojo.Use;
 import org.apache.sling.scripting.sightly.render.RenderContext;
 import org.apache.sling.scripting.sightly.use.ProviderOutcome;
@@ -81,10 +82,8 @@ public class PojoUseProvider implements
         Bindings globalBindings = renderContext.getBindings();
         Bindings bindings = UseProviderUtils.merge(globalBindings, arguments);
         SlingScriptHelper sling = UseProviderUtils.getHelper(bindings);
-        ResourceResolverFactory rrf = 
sling.getService(ResourceResolverFactory.class);
-        ResourceResolver adminResolver = null;
         try {
-            adminResolver = rrf.getAdministrativeResourceResolver(null);
+            ResourceResolver adminResolver = 
RenderContextImpl.getScriptResourceResolver(renderContext);
             Resource resource = 
ResourceResolution.resolveComponentForRequest(adminResolver, 
sling.getRequest());
             Object result = sightlyJavaCompilerService.getInstance(resource, 
identifier);
             if (result instanceof Use) {
@@ -94,10 +93,6 @@ public class PojoUseProvider implements
         } catch (Exception e) {
             LOG.error(String.format("Can't instantiate %s POJO.", identifier), 
e);
             return ProviderOutcome.failure();
-        } finally {
-            if (adminResolver != null) {
-                adminResolver.close();
-            }
         }
     }
 }

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=1645651&r1=1645650&r2=1645651&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
 Mon Dec 15 13:27:00 2014
@@ -27,10 +27,8 @@ import org.apache.felix.scr.annotations.
 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.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.SlingBindings;
 import org.apache.sling.api.scripting.SlingScriptHelper;
 import org.apache.sling.scripting.sightly.ResourceResolution;
@@ -40,7 +38,6 @@ import org.apache.sling.scripting.sightl
 import org.apache.sling.scripting.sightly.impl.engine.runtime.RenderUnit;
 import org.apache.sling.scripting.sightly.render.RenderContext;
 import org.apache.sling.scripting.sightly.use.ProviderOutcome;
-import org.apache.sling.scripting.sightly.use.SightlyUseException;
 import org.apache.sling.scripting.sightly.use.UseProvider;
 import org.osgi.framework.Constants;
 
@@ -68,38 +65,26 @@ public class RenderUnitProvider implemen
     @Reference
     private UnitLoader unitLoader = null;
 
-    @Reference
-    private ResourceResolverFactory rrf = null;
-
     @Override
     public ProviderOutcome provide(String identifier, RenderContext 
renderContext, Bindings arguments) {
         if (identifier.endsWith("." + SightlyScriptEngineFactory.EXTENSION)) {
             Bindings globalBindings = renderContext.getBindings();
-            Resource renderUnitResource = locateResource(globalBindings, 
identifier);
+            Resource renderUnitResource = locateResource(globalBindings, 
identifier, renderContext);
             RenderUnit renderUnit = unitLoader.createUnit(renderUnitResource, 
globalBindings, (RenderContextImpl) renderContext);
             return ProviderOutcome.notNullOrFailure(renderUnit);
         }
         return ProviderOutcome.failure();
     }
 
-    private Resource locateResource(Bindings bindings, String script) {
-        ResourceResolver adminResolver = null;
-        try {
-            adminResolver = rrf.getAdministrativeResourceResolver(null);
-            SlingHttpServletRequest request = (SlingHttpServletRequest) 
bindings.get(SlingBindings.REQUEST);
-            SlingScriptHelper ssh = (SlingScriptHelper) 
bindings.get(SlingBindings.SLING);
-            Resource resource = 
ResourceResolution.resolveComponentForRequest(adminResolver, request);
-            if (resource != null) {
-                return 
ResourceResolution.resolveComponentRelative(adminResolver, resource, script);
-            } else {
-                return 
ResourceResolution.resolveComponentRelative(adminResolver, 
ssh.getScript().getScriptResource(), script);
-            }
-        } catch (LoginException e) {
-            throw new SightlyUseException(e);
-        } finally {
-            if (adminResolver != null) {
-                adminResolver.close();
-            }
+    private Resource locateResource(Bindings bindings, String script, 
RenderContext renderContext) {
+        ResourceResolver adminResolver = 
RenderContextImpl.getScriptResourceResolver(renderContext);
+        SlingHttpServletRequest request = (SlingHttpServletRequest) 
bindings.get(SlingBindings.REQUEST);
+        SlingScriptHelper ssh = (SlingScriptHelper) 
bindings.get(SlingBindings.SLING);
+        Resource resource = 
ResourceResolution.resolveComponentForRequest(adminResolver, request);
+        if (resource != null) {
+            return ResourceResolution.resolveComponentRelative(adminResolver, 
resource, script);
+        } else {
+            return ResourceResolution.resolveComponentRelative(adminResolver, 
ssh.getScript().getScriptResource(), script);
         }
     }
 }

Modified: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.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/ScriptUseProvider.java?rev=1645651&r1=1645650&r2=1645651&view=diff
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
 (original)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/ScriptUseProvider.java
 Mon Dec 15 13:27:00 2014
@@ -25,19 +25,16 @@ import org.apache.commons.lang.StringUti
 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;
-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.SlingBindings;
 import org.apache.sling.api.scripting.SlingScript;
 import org.apache.sling.api.scripting.SlingScriptHelper;
 import 
org.apache.sling.scripting.sightly.impl.engine.SightlyScriptEngineFactory;
+import 
org.apache.sling.scripting.sightly.impl.engine.runtime.RenderContextImpl;
 import org.apache.sling.scripting.sightly.render.RenderContext;
 import org.apache.sling.scripting.sightly.use.ProviderOutcome;
-import org.apache.sling.scripting.sightly.use.SightlyUseException;
 import org.apache.sling.scripting.sightly.use.UseProvider;
 import org.osgi.framework.Constants;
 import org.slf4j.Logger;
@@ -71,9 +68,6 @@ public class ScriptUseProvider implement
 
     private static final Logger log = 
LoggerFactory.getLogger(ScriptUseProvider.class);
 
-    @Reference
-    private ResourceResolverFactory rrf = null;
-
     @Override
     public ProviderOutcome provide(String scriptName, RenderContext 
renderContext, Bindings arguments) {
         Bindings globalBindings = renderContext.getBindings();
@@ -83,27 +77,17 @@ public class ScriptUseProvider implement
             return ProviderOutcome.failure();
         }
         SlingScriptHelper sling = (SlingScriptHelper) 
bindings.get(SlingBindings.SLING);
-        ResourceResolver adminResolver = null;
-        try {
-            adminResolver = rrf.getAdministrativeResourceResolver(null);
-            if (adminResolver == null) {
-                log.warn("Cannot obtain administrative resource resolver for " 
+ scriptName);
-                return ProviderOutcome.failure();
-            }
-            Resource scriptResource = 
UseProviderUtils.locateScriptResource(adminResolver, sling, scriptName);
-            if (scriptResource == null) {
-                log.debug("Path does not match an existing resource: {}", 
scriptName);
-                return ProviderOutcome.failure();
-            }
-            return evalScript(scriptResource, bindings);
-        } catch (LoginException e) {
-            throw new SightlyUseException(e);
-        } finally {
-            if (adminResolver != null) {
-                adminResolver.close();
-            }
+        ResourceResolver adminResolver = 
RenderContextImpl.getScriptResourceResolver(renderContext);
+        if (adminResolver == null) {
+            log.warn("Cannot obtain administrative resource resolver for " + 
scriptName);
+            return ProviderOutcome.failure();
         }
-
+        Resource scriptResource = 
UseProviderUtils.locateScriptResource(adminResolver, sling, scriptName);
+        if (scriptResource == null) {
+            log.debug("Path does not match an existing resource: {}", 
scriptName);
+            return ProviderOutcome.failure();
+        }
+        return evalScript(scriptResource, bindings);
     }
 
     private ProviderOutcome evalScript(Resource scriptResource, Bindings 
bindings) {

Modified: 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
URL: 
http://svn.apache.org/viewvc/sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java?rev=1645651&r1=1645650&r2=1645651&view=diff
==============================================================================
--- 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
 (original)
+++ 
sling/trunk/contrib/scripting/sightly/engine/src/main/java/org/apache/sling/scripting/sightly/impl/engine/runtime/RenderContextImpl.java
 Mon Dec 15 13:27:00 2014
@@ -38,8 +38,10 @@ import javax.script.Bindings;
 
 import org.apache.commons.lang.StringUtils;
 import org.apache.sling.api.adapter.Adaptable;
+import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.scripting.sightly.Record;
+import org.apache.sling.scripting.sightly.SightlyException;
 import org.apache.sling.scripting.sightly.extension.ExtensionInstance;
 import org.apache.sling.scripting.sightly.extension.RuntimeExtension;
 import org.apache.sling.scripting.sightly.render.RenderContext;
@@ -57,14 +59,27 @@ public class RenderContextImpl implement
     public static final String STRING_COERCE = "toString";
     public static final String BOOLEAN_COERCE = "toBoolean";
 
-
     private final Bindings bindings;
     private final Map<String, RuntimeExtension> mapping;
+    private final ResourceResolver scriptResourceResolver;
     private final Map<String, ExtensionInstance> instanceCache = new 
HashMap<String, ExtensionInstance>();
 
-    public RenderContextImpl(Bindings bindings, Map<String, RuntimeExtension> 
mapping) {
+    public static ResourceResolver getScriptResourceResolver(RenderContext 
renderContext) {
+        if (renderContext instanceof RenderContextImpl) {
+            return ((RenderContextImpl) 
renderContext).getScriptResourceResolver();
+        }
+
+        throw new SightlyException("Cannot retrieve Script ResourceResovler 
from RenderContext " + renderContext);
+    }
+
+    public RenderContextImpl(Bindings bindings, Map<String, RuntimeExtension> 
mapping, ResourceResolver scriptResourceResolver) {
         this.bindings = bindings;
         this.mapping = mapping;
+        this.scriptResourceResolver = scriptResourceResolver;
+    }
+
+    public ResourceResolver getScriptResourceResolver() {
+        return scriptResourceResolver;
     }
 
     /**
@@ -308,25 +323,23 @@ public class RenderContextImpl implement
     }
 
     private Method findMethod(Class<?> cls, String baseName) {
-        Method method;
+        Method[] publicMethods = cls.getMethods();
         String capitalized = StringUtils.capitalize(baseName);
-        method = tryMethod(cls, "get" + capitalized);
-        if (method != null) return method;
-        method = tryMethod(cls, "is" + capitalized);
-        if (method != null) return method;
-        method = tryMethod(cls, baseName);
-        return method;
-    }
-
-
-    private Method tryMethod(Class<?> cls, String name) {
-        try {
-            Method m = cls.getMethod(name);
-            Class<?> declaringClass = m.getDeclaringClass();
-            return (isMethodAllowed(m)) ? m : null;
-        } catch (NoSuchMethodException e) {
-            return null;
+        for (Method m : publicMethods) {
+            if (m.getParameterTypes().length == 0) {
+                String methodName = m.getName();
+                if (baseName.equals(methodName)) {
+                    return (isMethodAllowed(m)) ? m : null;
+                }
+                if (("get" + capitalized).equals(methodName)) {
+                    return (isMethodAllowed(m)) ? m : null;
+                }
+                if (("is" + capitalized).equals(methodName)) {
+                    return (isMethodAllowed(m)) ? m : null;
+                }
+            }
         }
+        return null;
     }
 
     private boolean isMethodAllowed(Method method) {


Reply via email to