You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2007/12/17 13:21:10 UTC

svn commit: r604852 - in /incubator/sling/trunk/microsling/microsling-core/src/main: java/org/apache/sling/microsling/experimental/ java/org/apache/sling/microsling/scripting/ resources/META-INF/ resources/META-INF/services/

Author: fmeschbe
Date: Mon Dec 17 04:21:09 2007
New Revision: 604852

URL: http://svn.apache.org/viewvc?rev=604852&view=rev
Log:
SLING-110 Adapt to modified Sling API regarding scripting and
turn JstSlingScriptEnging into a Java Scripting ScriptEngineFactory
and ScriptEngine

Added:
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngineFactory.java
    incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/
    incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/services/
    incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
Modified:
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngine.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java
    incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptServlet.java

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngine.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngine.java?rev=604852&r1=604851&r2=604852&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngine.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngine.java Mon Dec 17 04:21:09 2007
@@ -19,58 +19,69 @@
 package org.apache.sling.microsling.experimental;
 
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.PrintWriter;
+import java.io.Reader;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map;
 
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.sling.api.HttpStatusCodeException;
 import org.apache.sling.api.SlingException;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.scripting.SlingScript;
-import org.apache.sling.api.scripting.SlingScriptEngine;
+import org.apache.sling.api.resource.ResourceMetadata;
+import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.api.scripting.SlingScriptHelper;
 import org.apache.sling.api.wrappers.SlingRequestPaths;
 import org.apache.sling.commons.json.JSONException;
 import org.apache.sling.microsling.helpers.json.JsonItemWriter;
 import org.apache.sling.microsling.resource.SyntheticResourceData;
 import org.apache.sling.microsling.slingservlets.renderers.DefaultHtmlRenderer;
-import org.apache.sling.scripting.javascript.EspReader;
+import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
+import org.apache.sling.scripting.javascript.helper.EspReader;
 
 /** Experimental JST script engine: converts a JST template (using the 
  *  same templating syntax as ESP) to client-side javascript code
  *  that renders the page.
  */
-public class JstScriptEngine implements SlingScriptEngine {
+public class JstScriptEngine extends AbstractSlingScriptEngine {
 
-    public static final String JST_SCRIPT_EXTENSION = "jst";
     private final List<String> libraryScripts = new LinkedList<String>();
     private final DefaultHtmlRenderer htmlRenderer;
     private final ScriptFilteredCopy copier = new ScriptFilteredCopy();
     
-    public JstScriptEngine() {
+    public JstScriptEngine(ScriptEngineFactory scriptEngineFactory) {
+        super(scriptEngineFactory);
+        
         // TODO hardcoded for now...
         libraryScripts.add("/ujax/ujax.js");
         htmlRenderer = new DefaultHtmlRenderer();
     }
     
-    public void eval(SlingScript script, Map<String, Object> props)
-        throws SlingException, IOException {
+    public Object eval(Reader script, ScriptContext context) throws ScriptException {
         
         // This engine does not really run the script, we simply dump it
         // to the client inside a skeleton HTML document, and let the
         // client run the script
-        final PrintWriter w = (PrintWriter)(props.get(SlingScriptEngine.OUT));
-        final EspReader er = new EspReader(script.getScriptReader());
-        er.setOutInitStatement("out=document;\n");
+        Bindings props = context.getBindings(ScriptContext.ENGINE_SCOPE);
+        
+        final SlingScriptHelper helper = (SlingScriptHelper) props.get(SlingBindings.SLING);
         
         try {
+            final PrintWriter w = helper.getResponse().getWriter();
+            final Reader er = getReader(helper.getScript().getScriptResource());
+
             // access our data (need a Node)
-            final Resource r = (Resource)props.get(SlingScriptEngine.RESOURCE);
+            final Resource r = helper.getRequest().getResource();
             
             // to render we must have either a Node or a SyntheticResourceData
             final Node n = r.adaptTo(Node.class);
@@ -89,7 +100,7 @@
             w.println("</title>");
             
             // library scripts
-            final SlingHttpServletRequest request = (SlingHttpServletRequest)props.get(SlingScriptEngine.REQUEST);
+            final SlingHttpServletRequest request = helper.getRequest(); 
             for(String lib : libraryScripts) {
                 final String fullScriptPath =             
                     SlingRequestPaths.getContextPath(request)
@@ -139,25 +150,35 @@
             // all done
             w.println("</body></html>");
             
+        } catch (IOException ioe) {
+            throw new ScriptException(ioe);
+            
         } catch(RepositoryException re) {
-            throw new SlingException("RepositoryException in JstScriptEngine.eval()",re);
+            throw new ScriptException(re);
             
         } catch(JSONException je) {
-            throw new SlingException("JSONException in JstScriptEngine.eval()",je);
+            throw new ScriptException(je);
             
         }
+        
+        return null;
     }
 
-    public String getEngineName() {
-        return "JST script engine (sling JavaScript Templates)";
-    }
-
-    public String getEngineVersion() {
-        return "0.9";
-    }
-
-    public String[] getExtensions() {
-        return new String [] { JST_SCRIPT_EXTENSION };
+    private Reader getReader(Resource resource) throws IOException {
+        InputStream ins = resource.adaptTo(InputStream.class);
+        if (ins != null) {
+            String enc = (String) resource.getResourceMetadata().get(ResourceMetadata.CHARACTER_ENCODING);
+            if (enc == null) {
+                enc = "UTF-8";
+            }
+            
+            Reader r = new InputStreamReader(ins, enc);
+            EspReader er = new EspReader(r);
+            er.setOutInitStatement("out=document;\n");
+            
+            return er;
+        }
+        
+        return null;
     }
-    
 }

Added: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngineFactory.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngineFactory.java?rev=604852&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngineFactory.java (added)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/JstScriptEngineFactory.java Mon Dec 17 04:21:09 2007
@@ -0,0 +1,53 @@
+/*
+ * 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.microsling.experimental;
+
+import javax.script.ScriptEngine;
+
+import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
+
+public class JstScriptEngineFactory extends AbstractScriptEngineFactory {
+
+    public static final String JST_SCRIPT_EXTENSION = "jst";
+
+    JstScriptEngineFactory() {
+        setExtensions(JST_SCRIPT_EXTENSION);
+    }
+    
+    public ScriptEngine getScriptEngine() {
+        return new JstScriptEngine(this);
+    }
+
+    public String getEngineName() {
+        return "JST script engine (sling JavaScript Templates)";
+    }
+
+    public String getEngineVersion() {
+        return "1.0";
+    }
+
+    public String getLanguageName() {
+        return "JavaScript Templates";
+    }
+
+    public String getLanguageVersion() {
+        return "1.0";
+    }
+
+}

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java?rev=604852&r1=604851&r2=604852&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptResolver.java Mon Dec 17 04:21:09 2007
@@ -21,9 +21,7 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.jcr.Item;
 import javax.jcr.Node;
@@ -31,6 +29,11 @@
 import javax.jcr.Property;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.SimpleScriptContext;
 import javax.servlet.ServletException;
 
 import org.apache.sling.api.SlingException;
@@ -38,9 +41,11 @@
 import org.apache.sling.api.SlingHttpServletResponse;
 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.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScript;
-import org.apache.sling.api.scripting.SlingScriptEngine;
 import org.apache.sling.api.scripting.SlingScriptResolver;
+import org.apache.sling.api.wrappers.SlingHttpServletRequestWrapper;
 import org.apache.sling.microsling.resource.JcrNodeResource;
 import org.apache.sling.microsling.scripting.helpers.ScriptFilenameBuilder;
 import org.apache.sling.microsling.scripting.helpers.ScriptHelper;
@@ -74,70 +79,19 @@
     private final ScriptFilenameBuilder scriptFilenameBuilder = new ScriptFilenameBuilder();
     private final ScriptSearchPathsBuilder scriptSearchPathsBuilder = new ScriptSearchPathsBuilder();
 
-    private Map<String, SlingScriptEngine> scriptEngines;
-
-    private static final String[] DEFAULT_SCRIPT_ENGINES = new String[] {
-          "org.apache.sling.scripting.javascript.RhinoJavasSriptEngine",
-          "org.apache.sling.scripting.velocity.VelocityTemplatesScriptEngine",
-          "org.apache.sling.scripting.freemarker.FreemarkerScriptEngine",
-          "org.apache.sling.scripting.ruby.ErbScriptEngine",
-          "org.apache.sling.microsling.experimental.JstScriptEngine"
-       };
-
+    private final ScriptEngineManager scriptEngineManager;
+    
     public MicroslingScriptResolver() throws SlingException {
-        scriptEngines = new HashMap<String, SlingScriptEngine>();
-        for(String engineName : DEFAULT_SCRIPT_ENGINES) {
-            try {
-                final Class engineClass = this.getClass().getClassLoader().loadClass(engineName);
-                final SlingScriptEngine engine = (SlingScriptEngine)engineClass.newInstance();
-                addScriptEngine(engine);
-            } catch (Exception ignore) {
-                log.warn("Unable to instantiate script engine " + engineName, ignore);
-            }
-        }
-    }
-
-    /**
-     * @param req
-     * @throws ServletException
-     * @throws IOException
-     */
-    public static void evaluateScript(final SlingScript script, final SlingHttpServletRequest req,
-            final SlingHttpServletResponse resp) throws ServletException,
-            IOException {
-        try {
-            // the script helper
-            ScriptHelper helper = new ScriptHelper(req, resp);
-
-            // prepare the properties for the script
-            Map<String, Object> props = new HashMap<String, Object>();
-            props.put(SlingScriptEngine.SLING, helper);
-            props.put(SlingScriptEngine.RESOURCE, helper.getRequest().getResource());
-            props.put(SlingScriptEngine.REQUEST, helper.getRequest());
-            props.put(SlingScriptEngine.RESPONSE, helper.getResponse());
-            props.put(SlingScriptEngine.OUT, helper.getResponse().getWriter());
-            props.put(SlingScriptEngine.LOG, LoggerFactory.getLogger(script.getScriptResource().getURI()));
-
-            resp.setContentType(req.getResponseContentType()
-                + "; charset=UTF-8");
-
-            // evaluate the script now using the ScriptEngine
-            script.getScriptEngine().eval(script, props);
-
-            // ensure data is flushed to the underlying writer in case
-            // anything has been written
-            helper.getResponse().getWriter().flush();
-        } catch (IOException ioe) {
-            throw ioe;
-        } catch (ServletException se) {
-            throw se;
-        } catch (Exception e) {
-            throw new SlingException("Cannot get MicroslingScript: "
-                + e.getMessage(), e);
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = getClass().getClassLoader();
         }
+        
+        scriptEngineManager = new ScriptEngineManager(loader);
     }
 
-    public SlingScript findScript(String path) throws SlingException {
+    public SlingScript findScript(ResourceResolver resourceResolver, String name)
+            throws SlingException {
         // TODO Auto-generated method stub
         return null;
     }
@@ -216,7 +170,7 @@
 
                             String scriptName = scriptNode.getName();
                             String scriptExt = scriptName.substring(scriptExtensionOffset);
-                            SlingScriptEngine scriptEngine = scriptEngines.get(scriptExt);
+                            ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension(scriptExt);
 
                             if (scriptEngine != null) {
                                 MicroslingScript script = new MicroslingScript();
@@ -244,19 +198,11 @@
         return result;
     }
 
-    private void addScriptEngine(SlingScriptEngine scriptEngine) {
-        String[] extensions = scriptEngine.getExtensions();
-        for (String extension : extensions) {
-            log.debug("Adding script engine {} for extension {}.", scriptEngine, extension);
-            scriptEngines.put(extension, scriptEngine);
-        }
-    }
-
     private static class MicroslingScript implements SlingScript {
 
         private Resource scriptResource;
 
-        private SlingScriptEngine scriptEngine;
+        private ScriptEngine scriptEngine;
 
         public Resource getScriptResource() {
             return scriptResource;
@@ -266,11 +212,11 @@
             this.scriptResource = scriptResource;
         }
 
-        public SlingScriptEngine getScriptEngine() {
+        public ScriptEngine getScriptEngine() {
             return scriptEngine;
         }
 
-        void setScriptEngine(SlingScriptEngine scriptEngine) {
+        void setScriptEngine(ScriptEngine scriptEngine) {
             this.scriptEngine = scriptEngine;
         }
 
@@ -298,6 +244,47 @@
             // converting the stream data using UTF-8 encoding, which is
             // the default encoding used
             return new BufferedReader(new InputStreamReader(stream, encoding));
+        }
+        
+        public void eval(SlingBindings props) throws IOException,
+                ServletException {
+            try {
+                
+                SlingHttpServletRequest req = (SlingHttpServletRequest) props.get(SlingBindings.REQUEST);
+                SlingHttpServletResponse res = (SlingHttpServletResponse) props.get(SlingBindings.RESPONSE);
+                
+                // the script helper
+                ScriptHelper helper = new ScriptHelper(req, res);
+
+                // prepare the properties for the script
+                Bindings bindings = getScriptEngine().createBindings();
+                
+                bindings.put(SlingBindings.SLING, helper);
+                bindings.put(SlingBindings.RESOURCE, helper.getRequest().getResource());
+                bindings.put(SlingBindings.REQUEST, helper.getRequest());
+                bindings.put(SlingBindings.RESPONSE, helper.getResponse());
+                bindings.put(SlingBindings.OUT, helper.getResponse().getWriter());
+                bindings.put(SlingBindings.LOG, LoggerFactory.getLogger(getScriptResource().getURI()));
+
+                res.setContentType(req.getResponseContentType()
+                    + "; charset=UTF-8");
+
+                ScriptContext context = new SimpleScriptContext();
+                
+                // evaluate the script now using the ScriptEngine
+                getScriptEngine().eval(getScriptReader(), context);
+
+                // ensure data is flushed to the underlying writer in case
+                // anything has been written
+                helper.getResponse().getWriter().flush();
+            } catch (IOException ioe) {
+                throw ioe;
+//            } catch (ServletException se) {
+//                throw se;
+            } catch (Exception e) {
+                throw new SlingException("Cannot get MicroslingScript: "
+                    + e.getMessage(), e);
+            }
         }
     }
 

Modified: incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptServlet.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptServlet.java?rev=604852&r1=604851&r2=604852&view=diff
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptServlet.java (original)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/scripting/MicroslingScriptServlet.java Mon Dec 17 04:21:09 2007
@@ -26,8 +26,7 @@
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
+import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScript;
 
 public class MicroslingScriptServlet implements Servlet {
@@ -40,8 +39,11 @@
 
     public void service(ServletRequest req, ServletResponse res)
             throws ServletException, IOException {
-        MicroslingScriptResolver.evaluateScript(script,
-            (SlingHttpServletRequest) req, (SlingHttpServletResponse) res);
+
+        SlingBindings bindings = new SlingBindings();
+        bindings.put(SlingBindings.REQUEST, req);
+        bindings.put(SlingBindings.RESPONSE, res);
+        script.eval(bindings);
     }
 
     public ServletConfig getServletConfig() {

Added: incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory?rev=604852&view=auto
==============================================================================
--- incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory (added)
+++ incubator/sling/trunk/microsling/microsling-core/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory Mon Dec 17 04:21:09 2007
@@ -0,0 +1 @@
+org.apache.sling.microsling.experimental.JstScriptEngineFactory
\ No newline at end of file