Author: bdelacretaz
Date: Mon Dec 3 04:50:32 2007
New Revision: 600511
URL: http://svn.apache.org/viewvc?rev=600511&view=rev
Log:
SLING-114 - experimental ECT (Ecmascript Client Templates) script 'engine'
Added:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java
(with props)
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
(with props)
incubator/sling/trunk/microsling/microsling-core/src/test/resources/integration-test/rendering-test.ect
Modified:
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/slingservlets/renderers/DefaultHtmlRendererServlet.java
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SlingResourceTypeRenderingTest.java
Added:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java?rev=600511&view=auto
==============================================================================
---
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java
(added)
+++
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java
Mon Dec 3 04:50:32 2007
@@ -0,0 +1,151 @@
+/*
+ * 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 java.io.IOException;
+import java.io.PrintWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.api.HttpStatusCodeException;
+import org.apache.sling.api.SlingException;
+import org.apache.sling.api.resource.NodeProvider;
+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.commons.json.JSONException;
+import org.apache.sling.microsling.helpers.json.JsonItemWriter;
+import org.apache.sling.microsling.slingservlets.renderers.DefaultHtmlRenderer;
+import org.apache.sling.scripting.javascript.EspReader;
+
+/** Experimental ECT script engine: converts an ECT template (using the
+ * same templating syntax as ESP) to client-side javascript code
+ * that renders the page.
+ */
+public class EctScriptEngine implements SlingScriptEngine {
+
+ public static final String ECT_SCRIPT_EXTENSION = "ect";
+ private final List<String> libraryScripts = new LinkedList<String>();
+ private final DefaultHtmlRenderer htmlRenderer;
+
+ public EctScriptEngine() {
+ // TODO hardcoded for now...
+ libraryScripts.add("/microjax/microjax.js");
+ htmlRenderer = new DefaultHtmlRenderer();
+ }
+
+ public void eval(SlingScript script, Map<String, Object> props)
+ throws SlingException, IOException {
+
+ // 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;");
+
+ try {
+ // access our data (need a Node)
+ final Resource r = (Resource)props.get(SlingScriptEngine.RESOURCE);
+ if( !(r instanceof NodeProvider) ) {
+ throw new HttpStatusCodeException(
+ HttpServletResponse.SC_NOT_FOUND,"Resource is not a
NodeProvider, cannot render");
+ }
+ final Node n = ((NodeProvider)r).getNode();
+
+ // output HEAD with javascript initializations
+ w.println("<html><head><title id=\"EctPageTitle\">");
+ w.println("ECT rendering of " + n.getPath());
+ w.println("</title>");
+
+ // library scripts
+ for(String lib : libraryScripts) {
+ w.println("<script src=\"" + lib + "\"></script>");
+ }
+
+ // onLoad method
+ w.println("<script language=\"javascript\">");
+ w.println("function ectOnLoad() { if(typeof onLoad ==
\"function\") { onLoad(); } }");
+ w.println("</script>");
+
+ // node data in JSON format
+ final JsonItemWriter j = new JsonItemWriter(null);
+ final int maxRecursionLevels = 1;
+ w.println("<script language='javascript'>");
+ w.print("var str='");
+ j.dump(n, w, maxRecursionLevels);
+ w.println("';");
+ w.print("eval(\"var currentNode=\" + str );");
+ w.println("</script>");
+ w.println("</head><body onLoad=\"ectOnLoad()\">");
+
+ // output our parsed script, first in body
+ w.println("<div id=\"EctRenderingScript\">\n<script
language='javascript'>");
+ copy(er,w);
+ w.println("</script>\n</div>");
+
+ // default rendering, turned off automatically from the javascript
that
+ // follows, if javascript is enabled
+ w.println("<div id=\"EctDefaultRendering\">");
+ htmlRenderer.render(w, r, n);
+ w.println("</div>");
+ w.println("<script language=\"javascript\">");
+
w.println("document.getElementById(\"EctDefaultRendering\").setAttribute(\"style\",\"display:none\");");
+ w.println("</script>");
+
+ // all done
+ w.println("</body></html>");
+
+ } catch(RepositoryException re) {
+ throw new SlingException("RepositoryException in
EctScriptEngine.eval()",re);
+
+ } catch(JSONException je) {
+ throw new SlingException("JSONException in
EctScriptEngine.eval()",je);
+
+ }
+ }
+
+ public String getEngineName() {
+ return "ECT script engine (Ecmascript Client Templates)";
+ }
+
+ public String getEngineVersion() {
+ return "0.9";
+ }
+
+ public String[] getExtensions() {
+ return new String [] { ECT_SCRIPT_EXTENSION };
+ }
+
+ private static void copy(Reader r, Writer w) throws IOException {
+ final int bufsize = 16384;
+ final char [] buffer = new char[bufsize];
+ int n = 0;
+ while( (n = r.read(buffer, 0, bufsize)) > 0) {
+ w.write(buffer, 0, n);
+ }
+ }
+}
Propchange:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/experimental/EctScriptEngine.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
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=600511&r1=600510&r2=600511&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 3 04:50:32 2007
@@ -77,7 +77,8 @@
"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.scripting.ruby.ErbScriptEngine",
+ "org.apache.sling.microsling.experimental.EctScriptEngine"
};
public MicroslingScriptResolver() throws SlingException {
Added:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java?rev=600511&view=auto
==============================================================================
---
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
(added)
+++
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
Mon Dec 3 04:50:32 2007
@@ -0,0 +1,74 @@
+/*
+ * 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.slingservlets.renderers;
+
+import java.io.PrintWriter;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Value;
+
+import org.apache.sling.api.resource.Resource;
+
+/** Reusable default HTML rendering of a Node
+ */
+public class DefaultHtmlRenderer {
+
+ public void render(PrintWriter pw, Resource r, Node n) throws
RepositoryException {
+ pw.println("<h1>Node dumped by " + getClass().getSimpleName() +
"</h1>");
+ pw.println("<p>Node path: <b>" + n.getPath() + "</b></p>");
+ pw.println("<p>Resource metadata: <b>" + r.getResourceMetadata() +
"</b></p>");
+
+ pw.println("<h2>Node properties</h2>");
+ for (PropertyIterator pi = n.getProperties(); pi.hasNext();) {
+ final Property p = pi.nextProperty();
+ printPropertyValue(pw, p);
+ }
+ }
+
+ protected void dump(PrintWriter pw, Resource r, Property p) throws
RepositoryException {
+ pw.println("<h2>Property dumped by " + getClass().getSimpleName() +
"</h1>");
+ pw.println("<p>Property path:" + p.getPath() + "</p>");
+ pw.println("<p>Resource metadata: " + r.getResourceMetadata() +
"</p>");
+
+ printPropertyValue(pw, p);
+ }
+
+ protected void printPropertyValue(PrintWriter pw, Property p)
+ throws RepositoryException {
+
+ pw.print(p.getName() + ": <b>");
+
+ if (p.getDefinition().isMultiple()) {
+ Value[] values = p.getValues();
+ pw.print('[');
+ for (int i = 0; i < values.length; i++) {
+ if (i > 0) {
+ pw.print(", ");
+ }
+ pw.print(values[i].getString());
+ }
+ pw.print(']');
+ } else {
+ pw.print(p.getValue().getString());
+ }
+
+ pw.print("</b><br/>");
+ }
+}
Propchange:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRenderer.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java?rev=600511&r1=600510&r2=600511&view=diff
==============================================================================
---
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java
(original)
+++
incubator/sling/trunk/microsling/microsling-core/src/main/java/org/apache/sling/microsling/slingservlets/renderers/DefaultHtmlRendererServlet.java
Mon Dec 3 04:50:32 2007
@@ -20,10 +20,7 @@
import java.io.PrintWriter;
import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.PropertyIterator;
import javax.jcr.RepositoryException;
-import javax.jcr.Value;
import javax.servlet.ServletException;
import org.apache.sling.api.SlingHttpServletRequest;
@@ -38,9 +35,11 @@
private static final long serialVersionUID = -5815904221043005085L;
private final String responseContentType;
+ private final DefaultHtmlRenderer renderer;
public DefaultHtmlRendererServlet(String responseContentTypeHeaderValue) {
this.responseContentType = responseContentTypeHeaderValue;
+ this.renderer = new DefaultHtmlRenderer();
}
@Override
@@ -53,53 +52,11 @@
final PrintWriter pw = resp.getWriter();
try {
pw.println("<html><body>");
- dump(pw, r, node);
+ renderer.render(pw, r, node);
pw.println("</body></html>");
} catch (RepositoryException re) {
throw new ServletException("Cannot dump contents of "
+ req.getResource().getURI(), re);
}
- }
-
- protected void dump(PrintWriter pw, Resource r, Node n) throws
RepositoryException {
- pw.println("<h1>Node dumped by " + getClass().getSimpleName() +
"</h1>");
- pw.println("<p>Node path: <b>" + n.getPath() + "</b></p>");
- pw.println("<p>Resource metadata: <b>" + r.getResourceMetadata() +
"</b></p>");
-
- pw.println("<h2>Node properties</h2>");
- for (PropertyIterator pi = n.getProperties(); pi.hasNext();) {
- final Property p = pi.nextProperty();
- printPropertyValue(pw, p);
- }
- }
-
- protected void dump(PrintWriter pw, Resource r, Property p) throws
RepositoryException {
- pw.println("<h2>Property dumped by " + getClass().getSimpleName() +
"</h1>");
- pw.println("<p>Property path:" + p.getPath() + "</p>");
- pw.println("<p>Resource metadata: " + r.getResourceMetadata() +
"</p>");
-
- printPropertyValue(pw, p);
- }
-
- protected void printPropertyValue(PrintWriter pw, Property p)
- throws RepositoryException {
-
- pw.print(p.getName() + ": <b>");
-
- if (p.getDefinition().isMultiple()) {
- Value[] values = p.getValues();
- pw.print('[');
- for (int i = 0; i < values.length; i++) {
- if (i > 0) {
- pw.print(", ");
- }
- pw.print(values[i].getString());
- }
- pw.print(']');
- } else {
- pw.print(p.getValue().getString());
- }
-
- pw.print("</b><br/>");
}
}
Modified:
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java?rev=600511&r1=600510&r2=600511&view=diff
==============================================================================
---
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java
(original)
+++
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/NodetypeRenderingTest.java
Mon Dec 3 04:50:32 2007
@@ -51,7 +51,7 @@
public void testWithoutScriptHtml() throws IOException {
final String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
- assertTrue("Content includes DefaultHtmlRendererServlet
marker",content.contains("dumped by DefaultHtmlRendererServlet"));
+ assertTrue("Content contains default rendering",content.contains("Node
dumped by DefaultHtmlRenderer"));
}
public void testEspHtml() throws IOException {
Modified:
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SlingResourceTypeRenderingTest.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SlingResourceTypeRenderingTest.java?rev=600511&r1=600510&r2=600511&view=diff
==============================================================================
---
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SlingResourceTypeRenderingTest.java
(original)
+++
incubator/sling/trunk/microsling/microsling-core/src/test/java/org/apache/sling/microsling/integration/SlingResourceTypeRenderingTest.java
Mon Dec 3 04:50:32 2007
@@ -55,7 +55,7 @@
public void testWithoutScriptHtml() throws IOException {
final String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
- assertTrue("Content includes DefaultHtmlRendererServlet
marker",content.contains("dumped by DefaultHtmlRendererServlet"));
+ assertTrue("Content contains default rendering",content.contains("Node
dumped by DefaultHtmlRenderer"));
}
public void testEspHtml() throws IOException {
@@ -64,6 +64,19 @@
final String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
assertTrue("Content includes ESP marker",content.contains("ESP
template"));
assertTrue("Content contains formatted test
text",content.contains("<p>" + testText + "</p>"));
+ } finally {
+ testClient.delete(toDelete);
+ }
+ }
+
+ public void testEctHtml() throws IOException {
+ final String toDelete =
uploadTestScript("rendering-test.ect","html.ect");
+ try {
+ final String content = getContent(displayUrl + ".html",
CONTENT_TYPE_HTML);
+ assertTrue("Content includes ECT marker",content.contains("ECT
template"));
+ assertTrue("Content contains JSON
data",content.contains("\"text\":\"" + testText + "\""));
+ assertTrue("Content contains default
rendering",content.contains("div id=\"EctDefaultRendering"));
+ assertTrue("Content contains javascript rendering
code",content.contains("out.write( currentNode.text )"));
} finally {
testClient.delete(toDelete);
}
Added:
incubator/sling/trunk/microsling/microsling-core/src/test/resources/integration-test/rendering-test.ect
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/microsling/microsling-core/src/test/resources/integration-test/rendering-test.ect?rev=600511&view=auto
==============================================================================
---
incubator/sling/trunk/microsling/microsling-core/src/test/resources/integration-test/rendering-test.ect
(added)
+++
incubator/sling/trunk/microsling/microsling-core/src/test/resources/integration-test/rendering-test.ect
Mon Dec 3 04:50:32 2007
@@ -0,0 +1,11 @@
+<%-- used by ScriptedRenderingTest --%>
+<p>
+ ECT template.
+</p>
+
+<p>
+ <%= currentNode.title %> </b>
+</p>
+<p>
+ <%= currentNode.text %> </em>
+</p>