You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/03/12 17:17:02 UTC

svn commit: r636395 - in /incubator/sling/trunk/scripting/jst: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/scripting/ src/main/java/org/apache/sling/script...

Author: bdelacretaz
Date: Wed Mar 12 09:16:56 2008
New Revision: 636395

URL: http://svn.apache.org/viewvc?rev=636395&view=rev
Log:
SLING-192 - JST script engine (experimental), adapted from microsling code

Added:
    incubator/sling/trunk/scripting/jst/   (with props)
    incubator/sling/trunk/scripting/jst/pom.xml   (with props)
    incubator/sling/trunk/scripting/jst/src/
    incubator/sling/trunk/scripting/jst/src/main/
    incubator/sling/trunk/scripting/jst/src/main/java/
    incubator/sling/trunk/scripting/jst/src/main/java/org/
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java   (with props)
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java   (with props)
    incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java   (with props)
    incubator/sling/trunk/scripting/jst/src/test/
    incubator/sling/trunk/scripting/jst/src/test/java/
    incubator/sling/trunk/scripting/jst/src/test/java/org/
    incubator/sling/trunk/scripting/jst/src/test/java/org/apache/
    incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/
    incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/
    incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/
    incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java   (with props)

Propchange: incubator/sling/trunk/scripting/jst/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Mar 12 09:16:56 2008
@@ -0,0 +1,9 @@
+target
+bin
+*.iml
+*.ipr
+*.iws
+.settings
+.project
+.classpath
+.externalToolBuilders

Added: incubator/sling/trunk/scripting/jst/pom.xml
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst/pom.xml?rev=636395&view=auto
==============================================================================
--- incubator/sling/trunk/scripting/jst/pom.xml (added)
+++ incubator/sling/trunk/scripting/jst/pom.xml Wed Mar 12 09:16:56 2008
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>1-incubator-SNAPSHOT</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.scripting.jst</artifactId>
+    <version>2.0.0-incubator-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Sling - Scripting - JST Support</name>
+    <description>Support for JST scripting</description>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/incubator/sling/trunk/scripting/jst
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/incubator/sling/trunk/scripting/jst
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Private-Package>
+                            org.apache.sling.scripting.jst,
+                            org.apache.sling.scripting.javascript.io.*,
+                            org.apache.sling.servlets.helpers.*
+                        </Private-Package>
+                        
+                        <Import-Package>
+                            org.apache.bsf.*;
+                            sun.misc; resolution:=optional,
+                            *
+                        </Import-Package>
+                        
+                        <ScriptEngine-Name>${pom.name}</ScriptEngine-Name>
+                        <ScriptEngine-Version>${pom.version}</ScriptEngine-Version>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.scripting.javascript</artifactId>
+            <version>${pom.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.scripting.api</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.servlets.default</artifactId>
+            <version>${pom.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.json</artifactId>
+            <version>${pom.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.jcr</groupId>
+            <artifactId>jcr</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+          <groupId>junit</groupId>
+          <artifactId>junit</artifactId>
+          <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>

Propchange: incubator/sling/trunk/scripting/jst/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java?rev=636395&view=auto
==============================================================================
--- incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java (added)
+++ incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java Wed Mar 12 09:16:56 2008
@@ -0,0 +1,174 @@
+/*
+ * 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.jst;
+
+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 javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptException;
+
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+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.commons.json.jcr.JsonItemWriter;
+import org.apache.sling.scripting.api.AbstractSlingScriptEngine;
+import org.apache.sling.scripting.javascript.io.EspReader;
+import org.apache.sling.servlets.helpers.DefaultHtmlRenderer;
+
+/** Experimental JST script engine: converts a JST template (using the
+ *  same templating syntax as ESP) to client-side javascript code
+ *  that renders the page.
+ *  
+ *  THIS IS STILL VERY ROUGH (2008/03/11), CONSIDER EXPERIMENTAL!!
+ */
+public class JstScriptEngine extends AbstractSlingScriptEngine {
+
+    private final List<String> libraryScripts = new LinkedList<String>();
+    private final DefaultHtmlRenderer htmlRenderer;
+    private final ScriptFilteredCopy copier = new ScriptFilteredCopy();
+
+    JstScriptEngine(ScriptEngineFactory scriptEngineFactory) {
+        super(scriptEngineFactory);
+
+        // TODO hardcoded for now...
+        libraryScripts.add("/ujax/ujax.js");
+        htmlRenderer = new DefaultHtmlRenderer();
+    }
+
+    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
+        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 = helper.getRequest().getResource();
+
+            // to render we must have either a Node or a SyntheticResourceData
+            final Node n = r.adaptTo(Node.class);
+            
+            // output HEAD with javascript initializations
+            // TODO we should instead parse (at least minimally) the template file, and inject our
+            // stuff in the right places
+            w.println("<html><head><title id=\"JstPageTitle\">");
+            w.println("JST rendering of " + r.getPath());
+            w.println("</title>");
+
+            // library scripts
+            final SlingHttpServletRequest request = helper.getRequest();
+            for(String lib : libraryScripts) {
+                final String fullScriptPath = 
+                    SlingRequestPaths.getContextPath(request)
+                    + SlingRequestPaths.getServletPath(request)
+                    + lib
+                ;
+                w.println("<script src=\"" + fullScriptPath + "\"></script>");
+            }
+
+            // onLoad method
+            w.println("<script language=\"javascript\">");
+            w.println("function jstOnLoad() { if(typeof onLoad == \"function\") { onLoad(); } }");
+            w.println("</script>");
+
+            // data in JSON format
+            final JsonItemWriter j = new JsonItemWriter(null);
+            final int maxRecursionLevels = 1;
+            w.println("<script language='javascript'>");
+            w.print("var currentNode=");
+            if(n!=null) {
+                j.dump(n, w, maxRecursionLevels);
+            } else {
+                w.print("{}");
+            }
+            w.println(";");
+            w.println("</script>");
+            w.println("</head><body onLoad=\"jstOnLoad()\">");
+
+            // output our parsed script, first in body
+            w.println("<div id=\"JstRenderingScript\">\n<script language='javascript'>");
+            copier.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=\"JstDefaultRendering\">");
+            if(n!=null) {
+                htmlRenderer.render(w, r, n);
+            }
+            w.println("</div>");
+            w.println("<script language=\"javascript\">");
+            w.println("document.getElementById(\"JstDefaultRendering\").setAttribute(\"style\",\"display:none\");");
+            w.println("</script>");
+
+            // all done
+            w.println("</body></html>");
+
+        } catch (IOException ioe) {
+            throw new ScriptException(ioe);
+
+        } catch(RepositoryException re) {
+            throw new ScriptException(re);
+
+        } catch(JSONException je) {
+            throw new ScriptException(je);
+            
+        }
+
+        return null;
+    }
+
+    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;
+    }
+}

Propchange: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngine.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java?rev=636395&view=auto
==============================================================================
--- incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java (added)
+++ incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java Wed Mar 12 09:16:56 2008
@@ -0,0 +1,58 @@
+/*
+ * 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.jst;
+
+import javax.script.ScriptEngine;
+
+import org.apache.sling.scripting.api.AbstractScriptEngineFactory;
+
+/** Defines attributes of the JST script engine */
+public class JstScriptEngineFactory extends AbstractScriptEngineFactory {
+
+    public static final String JST_SCRIPT_EXTENSION = "jst";
+    public final static String JST_MIME_TYPE = "application/x-sling-jst";
+    public final static String SHORT_NAME = "jst";
+
+    public JstScriptEngineFactory() {
+        setExtensions(JST_SCRIPT_EXTENSION);
+        setMimeTypes(JST_MIME_TYPE);
+        setNames(SHORT_NAME);
+    }
+    
+    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";
+    }
+
+}

Propchange: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/JstScriptEngineFactory.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java?rev=636395&view=auto
==============================================================================
--- incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java (added)
+++ incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java Wed Mar 12 09:16:56 2008
@@ -0,0 +1,67 @@
+/*
+ * 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.jst;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+/** Copy the ECT script to the output, filtering <script>
+ *  tags on the way (see SLING-114 comment 10/Dec/07 01:00 AM).
+ *  To simplify things, assumes each out.write statement is on
+ *  its own line in input.  
+ */  
+class ScriptFilteredCopy {
+
+    /** Read r line-by-line, process lines that need to be
+     *  modified, and write results to w
+     */
+    void copy(Reader r, Writer w) throws IOException {
+        final BufferedReader br = new BufferedReader(r);
+        String line = null;
+        while( (line = br.readLine()) != null) {
+            final String toWrite = processLine(line); 
+            w.write(toWrite, 0, toWrite.length());
+            w.write('\n');
+        }
+    }
+
+    /** Transform lines that look like
+     *  <pre>
+     *      out.write("something and a <script> tag");
+     *  </pre>
+     *  
+     *  Into
+     *   <pre>
+     *      out.write("something and a <");
+     *      out.write("script> tag");
+     *   </pre>
+     *   
+     *  To work around browsers problems when they 
+     *  see a </script> tag in a String. 
+     */
+    String processLine(String line) {
+        if(line.startsWith("out.write(") && line.endsWith("\");")) {
+            return line.replaceAll("script>","\");\nout.write(\"script>");
+        } else {
+            return line;
+        }
+    }
+}

Propchange: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/scripting/jst/src/main/java/org/apache/sling/scripting/jst/ScriptFilteredCopy.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL

Added: incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java?rev=636395&view=auto
==============================================================================
--- incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java (added)
+++ incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java Wed Mar 12 09:16:56 2008
@@ -0,0 +1,83 @@
+/*
+ * 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.jst;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+
+/** Test the ScriptFilteredCopy */
+public class ScriptFilteredCopyTest extends TestCase {
+    
+    private final ScriptFilteredCopy sfc = new ScriptFilteredCopy();
+    
+    private void runTest(String input, String expected) throws IOException {
+        final StringWriter sw = new StringWriter();
+        sfc.copy(new StringReader(input), sw);
+        assertEquals(flatten(expected), flatten(sw.toString()));
+    }
+    
+    public void testNoChanges() throws IOException {
+        final String input = "No out.write statements on their own lines";
+        final String expected = input + "\n";
+        runTest(input,expected);
+    }
+    
+    public void testOpenClose() throws IOException {
+        final String input = 
+            "A\n"
+            + "out.write(\"some <script> here </script>\");\n"
+            + "B\n";
+        
+        final String expected = 
+        "A\n"
+        + "out.write(\"some <\");\n"
+        + "out.write(\"script> here </\");\n"
+        + "out.write(\"script>\");\n"
+        + "B\n";
+        
+        runTest(input,expected);
+    }
+    
+    public void testOpenAtStart() throws IOException {
+        final String input = "out.write(\"<script> here\");\n";
+        final String expected = 
+            "out.write(\"<\");\n"
+            + "out.write(\"script> here\");\n"
+        ;
+        
+        runTest(input,expected);
+    }
+
+    public void testOpenAtEnd() throws IOException {
+        final String input = "out.write(\"Here a <script>\");\n";
+        final String expected = 
+            "out.write(\"Here a <\");\n"
+            + "out.write(\"script>\");\n"
+        ;
+        runTest(input,expected);
+    }
+    
+    /** Replace \n with . in strings to make it easier to compare visually for testing */
+    private static String flatten(String str) {
+        return str.replace('\n', '.');
+    }
+}

Propchange: incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/sling/trunk/scripting/jst/src/test/java/org/apache/sling/scripting/jst/ScriptFilteredCopyTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision Rev URL