Author: julien_viet
Date: 2009-11-01 06:24:58 -0500 (Sun, 01 Nov 2009)
New Revision: 467
Added:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyCompilationException.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScript.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/Position.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompilationException.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateRuntimeException.java
Removed:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java
Log:
GTNPORTAL-146 : Contextual error reporting of Groovy templates runtime exception
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/BaseScript.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -22,6 +22,8 @@
import java.io.IOException;
/**
+ * The internal base script of a Groovy script as seen by the Groovy world.
+ *
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
*/
Added:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyCompilationException.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyCompilationException.java
(rev 0)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyCompilationException.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class GroovyCompilationException extends TemplateCompilationException
+{
+
+ /** . */
+ private final String groovyText;
+
+ public GroovyCompilationException(Throwable cause, String templateText, String
groovyText)
+ {
+ super(cause, templateText);
+
+ //
+ this.groovyText = groovyText;
+ }
+
+ public String getGroovyText()
+ {
+ return groovyText;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ return "Groovy compilation exception\n" +
+ "template: " +
+ getTemplateText() + "\n" +
+ "compiled to Groovy: " +
+ getGroovyText() + "\n";
+ }
+}
Added:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScript.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScript.java
(rev 0)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScript.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+import groovy.lang.Binding;
+import org.codehaus.groovy.runtime.InvokerHelper;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * A wrapper for a Groovy script and its meta data.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class GroovyScript
+{
+
+ /** . */
+ private final String groovyText;
+
+ /** . */
+ private final Class<?> scriptClass;
+
+ /** . */
+ private final Map<Integer, TextItem> lineTable;
+
+ public GroovyScript(String groovyText, Class<?> scriptClass, Map<Integer,
TextItem> lineTable)
+ {
+ this.groovyText = groovyText;
+ this.scriptClass = scriptClass;
+ this.lineTable = lineTable;
+ }
+
+ public String getGroovyText()
+ {
+ return groovyText;
+ }
+
+ public Class<?> getScriptClass()
+ {
+ return scriptClass;
+ }
+
+ public Map<Integer, TextItem> getLineTable()
+ {
+ return lineTable;
+ }
+
+ public void render(Map context, GroovyPrinter writer) throws IOException,
TemplateRuntimeException
+ {
+ Binding binding = context != null ? new Binding(context) : new Binding();
+
+ //
+ BaseScript script = (BaseScript)InvokerHelper.createScript(scriptClass, binding);
+ script.printer = writer;
+ script.setProperty("out", script.printer);
+
+ //
+ try
+ {
+ script.run();
+ }
+ catch (Exception e)
+ {
+ if (e instanceof IOException)
+ {
+ throw (IOException)e;
+ }
+ else
+ {
+ TextItem textItem = findOut(e);
+ throw new TemplateRuntimeException(textItem, e);
+ }
+ }
+ catch (Throwable e)
+ {
+ if (e instanceof Error)
+ {
+ throw ((Error)e);
+ }
+ TextItem textItem = findOut(e);
+ throw new TemplateRuntimeException(textItem, e);
+ }
+
+ //
+ script.flush();
+ }
+
+ private TextItem findOut(Throwable t)
+ {
+ StackTraceElement[] elements = t.getStackTrace();
+
+ // The index of the script based on the current stack trace
+ int index = elements.length - Thread.currentThread().getStackTrace().length + 1;
+
+ // Try to find the groovy script line
+ if (index >= 0 && index < elements.length)
+ {
+ int groovyLineNumber = elements[index].getLineNumber();
+ return lineTable.get(groovyLineNumber);
+ }
+ else
+ {
+ return null;
+ }
+ }
+}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyScriptBuilder.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -16,8 +16,19 @@
*/
package org.exoplatform.groovyscript;
+import groovy.lang.GroovyClassLoader;
+import groovy.lang.GroovyCodeSource;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.control.CompilerConfiguration;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
@@ -27,6 +38,12 @@
{
/** . */
+ private final String name;
+
+ /** . */
+ private final String templateText;
+
+ /** . */
private SectionType currentType = null;
/** . */
@@ -35,12 +52,22 @@
/** . */
private Script script = new Script();
- public void begin(SectionType sectionType)
+ public GroovyScriptBuilder(String name, String templateText)
{
+ this.name = name;
+ this.templateText = templateText;
+ }
+
+ private void begin(SectionType sectionType, Position pos)
+ {
if (sectionType == null)
{
throw new NullPointerException();
}
+ if (pos == null)
+ {
+ throw new NullPointerException();
+ }
if (currentType != null)
{
throw new IllegalStateException();
@@ -60,39 +87,48 @@
}
}
- public void append(String text)
+ private void append(SectionItem item)
{
- switch (currentType)
+ if (item instanceof TextItem)
{
- case STRING:
- accumulatedText.append(text);
- break;
- case SCRIPTLET:
- script.appendGroovy(text);
- break;
- case EXPR:
- script.appendGroovy(text);
- break;
+ TextItem textItem = (TextItem)item;
+ String text = textItem.getData();
+ switch (currentType)
+ {
+ case STRING:
+ accumulatedText.append(text);
+ break;
+ case SCRIPTLET:
+ script.appendGroovy(text);
+ script.positionTable.put(script.lineNumber, textItem);
+ break;
+ case EXPR:
+ script.appendGroovy(text);
+ script.positionTable.put(script.lineNumber, textItem);
+ break;
+ }
}
- }
-
- public void lineBreak()
- {
- switch (currentType)
+ else if (item instanceof LineBreakItem)
{
- case STRING:
- accumulatedText.append("\n");
- break;
- case SCRIPTLET:
- script.appendGroovy("\n");
- break;
- case EXPR:
- script.appendGroovy("\n");
- break;
+ switch (currentType)
+ {
+ case STRING:
+ accumulatedText.append("\n");
+ break;
+ case SCRIPTLET:
+ case EXPR:
+ script.appendGroovy("\n");
+ script.lineNumber++;
+ break;
+ }
}
+ else
+ {
+ throw new AssertionError();
+ }
}
- public void end()
+ private void end()
{
if (currentType == null)
{
@@ -110,10 +146,13 @@
}
break;
case SCRIPTLET:
+ // We append a line break because we want that any line comment does not
affect the template
script.appendGroovy("\n");
+ script.lineNumber++;
break;
case EXPR:
- script.appendGroovy("}\");");
+ script.appendGroovy("}\");\n");
+ script.lineNumber++;
break;
}
@@ -121,13 +160,65 @@
this.currentType = null;
}
- public String getScript()
+ public GroovyScript build() throws TemplateCompilationException
{
- return script.toString();
- }
+ List<TemplateSection> sections = new TemplateParser().parse(templateText);
+ //
+ for (TemplateSection section : sections)
+ {
+ begin(section.getType(), section.getItems().get(0).getPosition());
+ for (SectionItem item : section.getItems())
+ {
+ append(item);
+ }
+ end();
+ }
+ //
+ String groovyText = script.toString();
+ //
+ CompilerConfiguration config = new CompilerConfiguration();
+
+ //
+ byte[] bytes;
+ try
+ {
+ config.setScriptBaseClass(BaseScript.class.getName());
+ bytes = groovyText.getBytes(config.getSourceEncoding());
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new TemplateCompilationException(e, groovyText);
+ }
+
+ //
+ InputStream in = new ByteArrayInputStream(bytes);
+ GroovyCodeSource gcs = new GroovyCodeSource(in, name, "/groovy/shell");
+ GroovyClassLoader loader = new
GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
+ Class<?> scriptClass;
+ try
+ {
+ scriptClass = loader.parseClass(gcs, false);
+ }
+ catch (CompilationFailedException e)
+ {
+ throw new GroovyCompilationException(e, templateText, groovyText);
+ }
+ catch (ClassFormatError e)
+ {
+ throw new GroovyCompilationException(e, templateText, groovyText);
+ }
+
+ return new GroovyScript(
+ script.toString(), scriptClass, Collections.unmodifiableMap(new
HashMap<Integer, TextItem>(script.positionTable))
+ );
+ }
+
+ /**
+ * Internal representation of a script
+ */
private static class Script
{
@@ -140,6 +231,12 @@
/** . */
private int methodCount = 0;
+ /** The line number table. */
+ private Map<Integer, TextItem> positionTable = new HashMap<Integer,
TextItem>();
+
+ /** The current line number. */
+ private int lineNumber = 1;
+
@Override
public String toString()
{
@@ -159,8 +256,9 @@
public void appendText(String text)
{
TextContant m = new TextContant("s" + methodCount++, text);
-
out.append(";out.print(Constants.").append(m.name).append(");\n");
+
out.append("out.print(Constants.").append(m.name).append(");\n");
textMethods.add(m);
+ lineNumber++;
}
public void appendGroovy(String s)
@@ -203,26 +301,6 @@
}
else
{
-/*
- String code = Integer.toHexString(c);
- switch (code.length())
- {
- default:
- throw new AssertionError();
- case 1:
- code = "000" + code;
- break;
- case 2:
- code = "00" + code;
- break;
- case 3:
- code = "0" + code;
- break;
- case 4:
- break;
- }
- builder.append("\\u").append(code);
-*/
builder.append(c);
}
}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplate.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -16,29 +16,21 @@
*/
package org.exoplatform.groovyscript;
-import groovy.lang.Binding;
-import groovy.lang.GroovyClassLoader;
-import groovy.lang.GroovyCodeSource;
-import groovy.lang.Writable;
-import groovy.text.Template;
-import org.codehaus.groovy.control.CompilationFailedException;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.runtime.InvokerHelper;
import org.exoplatform.commons.utils.OutputStreamPrinter;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
/**
+ * A Groovy template.
+ *
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
*/
-public class GroovyTemplate implements Template
+public class GroovyTemplate
{
private static String read(Reader reader) throws IOException
@@ -52,34 +44,31 @@
return builder.toString();
}
- /** . */
+ /** The name of the template. */
private final String name;
- /** . */
- private final String scriptText;
+ /** The text of the template. */
+ private final String templateText;
- /** . */
- private final String groovyText;
+ /** The groovy script. */
+ private final GroovyScript script;
- /** . */
- private final Class<?> scriptClass;
-
- public GroovyTemplate(String name, Reader scriptReader) throws IOException
+ public GroovyTemplate(String name, Reader scriptReader) throws IOException,
TemplateCompilationException
{
this(name, read(scriptReader));
}
- public GroovyTemplate(Reader scriptReader) throws IOException
+ public GroovyTemplate(Reader scriptReader) throws IOException,
TemplateCompilationException
{
this(read(scriptReader));
}
- public GroovyTemplate(String scriptText) throws IOException
+ public GroovyTemplate(String templateText) throws TemplateCompilationException
{
- this(null, scriptText);
+ this(null, templateText);
}
- public GroovyTemplate(String name, String scriptText) throws IOException
+ public GroovyTemplate(String name, String templateText) throws
TemplateCompilationException
{
if (name == null)
{
@@ -87,38 +76,12 @@
}
//
- TemplateCompiler compiler = new TemplateCompiler();
- String groovyText = compiler.compile(scriptText);
+ GroovyScriptBuilder compiler = new GroovyScriptBuilder(name, templateText);
//
- CompilerConfiguration config = new CompilerConfiguration();
- config.setScriptBaseClass(BaseScript.class.getName());
- byte[] bytes = groovyText.getBytes(config.getSourceEncoding());
- InputStream in = new ByteArrayInputStream(bytes);
- GroovyCodeSource gcs = new GroovyCodeSource(in, name, "/groovy/shell");
- GroovyClassLoader loader = new
GroovyClassLoader(Thread.currentThread().getContextClassLoader(), config);
-
- Class<?> scriptClass;
- try
- {
- scriptClass = loader.parseClass(gcs, false);
- }
- catch (CompilationFailedException e)
- {
- System.out.println("Could not compile script <<<" +
groovyText + ">>>");
- throw e;
- }
- catch (ClassFormatError e)
- {
- System.out.println("Could not compile script <<<" +
groovyText + ">>>");
- throw e;
- }
-
- //
this.name = name;
- this.scriptText = scriptText;
- this.groovyText = groovyText;
- this.scriptClass = scriptClass;
+ this.script = compiler.build();
+ this.templateText = templateText;
}
public String getName()
@@ -126,33 +89,41 @@
return name;
}
- public String getScriptText()
+ public String getTemplateText()
{
- return scriptText;
+ return templateText;
}
public String getGroovyText()
{
- return groovyText;
+ return script.getGroovyText();
}
- public void render(GroovyPrinter writer) throws IOException
+ public void render(Writer writer) throws IOException, TemplateRuntimeException
{
render(writer, null);
}
- public void render(GroovyPrinter writer, Map binding) throws IOException
+ public void render(Writer writer, Map binding) throws IOException,
TemplateRuntimeException
{
- Writable writable = make(binding);
- writable.writeTo(writer);
+ GroovyPrinter printer;
+ if (writer instanceof OutputStreamPrinter)
+ {
+ printer = new OutputStreamWriterGroovyPrinter((OutputStreamPrinter)writer);
+ }
+ else
+ {
+ printer = new WriterGroovyPrinter(writer);
+ }
+ script.render(binding, printer);
}
- public String render() throws IOException
+ public String render() throws IOException, TemplateRuntimeException
{
return render((Map)null);
}
- public String render(Map binding) throws IOException
+ public String render(Map binding) throws IOException, TemplateRuntimeException
{
StringWriter buffer = new StringWriter();
WriterGroovyPrinter printer = new WriterGroovyPrinter(buffer);
@@ -160,47 +131,4 @@
printer.close();
return buffer.toString();
}
-
- public Writable make()
- {
- return make(null);
- }
-
- public Writable make(final Map binding)
- {
- Writable writable = new Writable()
- {
- /**
- * Write the template document with the set binding applied to the writer.
- *
- * @see groovy.lang.Writable#writeTo(java.io.Writer)
- */
- public Writer writeTo(Writer writer)
- {
- Binding context;
- if (binding == null)
- context = new Binding();
- else
- context = new Binding(binding);
-
- //
- BaseScript script = (BaseScript)InvokerHelper.createScript(scriptClass,
context);
- if (writer instanceof OutputStreamPrinter)
- {
- script.printer = new
OutputStreamWriterGroovyPrinter((OutputStreamPrinter)writer);
- }
- else
- {
- script.printer = new WriterGroovyPrinter(writer);
- }
- script.setProperty("out", script.printer);
- script.run();
- script.flush();
- return writer;
- }
- };
-
- //
- return writable;
- }
}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/GroovyTemplateEngine.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -16,23 +16,14 @@
*/
package org.exoplatform.groovyscript;
-import groovy.text.Template;
-import groovy.text.TemplateEngine;
-import org.codehaus.groovy.control.CompilationFailedException;
-
-import java.io.IOException;
-import java.io.Reader;
-
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
* @version $Revision$
*/
-public class GroovyTemplateEngine extends TemplateEngine
+public class GroovyTemplateEngine
{
-
- @Override
- public Template createTemplate(Reader reader) throws CompilationFailedException,
ClassNotFoundException, IOException
+ public GroovyTemplate createTemplate(String text) throws TemplateCompilationException
{
- return new GroovyTemplate(reader);
+ return new GroovyTemplate(text);
}
}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/LineBreakItem.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -23,14 +23,15 @@
public class LineBreakItem extends SectionItem
{
- public LineBreakItem()
+ public LineBreakItem(Position pos)
{
+ super(pos);
}
@Override
public String toString()
{
- return "LineBreak[]";
+ return "LineBreak[position=" + getPosition() + "]";
}
@Override
Added:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/Position.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/Position.java
(rev 0)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/Position.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class Position
+{
+
+ /** . */
+ private final int col;
+
+ /** . */
+ private final int line;
+
+ public Position(int col, int line)
+ {
+ if (col < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+ if (line < 0)
+ {
+ throw new IllegalArgumentException();
+ }
+
+ //
+ this.col = col;
+ this.line = line;
+ }
+
+ public int getCol()
+ {
+ return col;
+ }
+
+ public int getLine()
+ {
+ return line;
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj instanceof Position)
+ {
+ Position that = (Position)obj;
+ return col == that.col && line == that.line;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "Position[col=" + col + ",line=" + line +
"]";
+ }
+}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/SectionItem.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -22,4 +22,21 @@
*/
public abstract class SectionItem
{
+
+ /** . */
+ private final Position pos;
+
+ protected SectionItem(Position pos)
+ {
+ if (pos == null)
+ {
+ throw new NullPointerException("No null position accepted");
+ }
+ this.pos = pos;
+ }
+
+ public Position getPosition()
+ {
+ return pos;
+ }
}
Added:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompilationException.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompilationException.java
(rev 0)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompilationException.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class TemplateCompilationException extends Exception
+{
+
+ /** . */
+ private final String templateText;
+
+ public TemplateCompilationException(Throwable cause, String templateText)
+ {
+ super(cause);
+
+ //
+ this.templateText = templateText;
+ }
+
+ public String getTemplateText()
+ {
+ return templateText;
+ }
+}
Deleted:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateCompiler.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2003-2007 eXo Platform SAS.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation; either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not,
see<http://www.gnu.org/licenses/>.
- */
-package org.exoplatform.groovyscript;
-
-import java.io.IOException;
-import java.util.List;
-
-/**
- * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
- * @version $Revision$
- */
-public class TemplateCompiler
-{
-
- public String compile(String script) throws IOException
- {
- List<TemplateSection> sections = new TemplateParser().parse(script);
- return compile(sections);
- }
-
- public String compile(List<TemplateSection> sections)
- {
- GroovyScriptBuilder scriptBuilder = new GroovyScriptBuilder();
- for (TemplateSection section : sections)
- {
- scriptBuilder.begin(section.getType());
- for (SectionItem item : section.getItems())
- {
- if (item instanceof TextItem)
- {
- scriptBuilder.append(((TextItem)item).getData());
- }
- else
- {
- scriptBuilder.lineBreak();
- }
- }
- scriptBuilder.end();
- }
- return scriptBuilder.getScript();
- }
-}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateParser.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -16,8 +16,10 @@
*/
package org.exoplatform.groovyscript;
-import java.io.BufferedReader;
+import org.exoplatform.commons.utils.UndeclaredIOException;
+
import java.io.IOException;
+import java.io.PushbackReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
@@ -54,27 +56,68 @@
GSTRING_EXPR
}
- public List<TemplateSection> parse(String s) throws IOException
+ public List<TemplateSection> parse(String s)
{
- return parse(new StringReader(s));
+ try
+ {
+ return parse(new StringReader(s));
+ }
+ catch (IOException e)
+ {
+ throw new UndeclaredIOException(e);
+ }
}
- public List<TemplateSection> parse(Reader reader) throws IOException
+ public List<TemplateSection> parse(Reader tmp) throws IOException
{
- if (!reader.markSupported())
- {
- reader = new BufferedReader(reader);
- }
+ PushbackReader reader = new PushbackReader(tmp);
+
//
ArrayList<TemplateSection> sections = new
ArrayList<TemplateSection>();
StringBuilder accumulator = new StringBuilder();
//
+ int lineNumber = 1;
+ int colNumber = 1;
+ Position pos = new Position(1, 1);
Status status = Status.TEXT;
- int c;
- while ((c = reader.read()) != -1)
+ int i;
+ while ((i = reader.read()) != -1)
{
+ char c = (char)i;
+
+ //
+ if (c == '\r')
+ {
+ // On Windows, "\r\n" is a new line
+ int j = reader.read();
+ if (j != -1)
+ {
+ char c2 = (char)j;
+ if (c2 == '\n')
+ {
+ c = '\n';
+ }
+ else
+ {
+ reader.unread(j);
+ }
+ }
+ }
+
+ // Update current position
+ if (c == '\n')
+ {
+ colNumber = 1;
+ lineNumber++;
+ }
+ else
+ {
+ colNumber++;
+ }
+
+ //
switch (status)
{
case TEXT:
@@ -88,7 +131,7 @@
}
else
{
- accumulator.append((char)c);
+ accumulator.append(c);
}
break;
case EXPR:
@@ -98,7 +141,7 @@
}
else
{
- accumulator.append((char)c);
+ accumulator.append(c);
}
break;
case SCRIPTLET:
@@ -108,7 +151,7 @@
}
else
{
- accumulator.append((char)c);
+ accumulator.append(c);
}
break;
case START_ANGLE:
@@ -119,14 +162,15 @@
else
{
status = Status.TEXT;
- accumulator.append('<').append((char)c);
+ accumulator.append('<').append(c);
}
break;
case SCRIPLET_OR_EXPR:
if (accumulator.length() > 0)
{
- sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString(), pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
}
if (c == '=')
{
@@ -139,15 +183,18 @@
else
{
status = Status.SCRIPTLET;
- accumulator.append((char)c);
+ accumulator.append(c);
}
break;
case MAYBE_SCRIPLET_END:
if (c == '>')
{
+ sections.add(new TemplateSection(SectionType.SCRIPTLET,
accumulator.toString(), pos));
+ accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
+
+ //
status = Status.TEXT;
- sections.add(new TemplateSection(SectionType.SCRIPTLET,
accumulator.toString()));
- accumulator.setLength(0);
}
else if (c == '%')
{
@@ -156,15 +203,18 @@
else
{
status = Status.SCRIPTLET;
- accumulator.append('%').append((char)c);
+ accumulator.append('%').append(c);
}
break;
case MAYBE_EXPR_END:
if (c == '>')
{
+ sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString(), pos));
+ accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
+
+ //
status = Status.TEXT;
- sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString()));
- accumulator.setLength(0);
}
else if (c == '%')
{
@@ -173,7 +223,7 @@
else
{
status = Status.EXPR;
- accumulator.append('%').append((char)c);
+ accumulator.append('%').append(c);
}
break;
case MAYBE_GSTRING_EXPR:
@@ -181,49 +231,57 @@
{
if (accumulator.length() > 0)
{
- sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString(), pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
}
status = Status.GSTRING_CURLY_EXPR;
}
- else if (Character.isJavaIdentifierStart((char)c))
+ else if (Character.isJavaIdentifierStart(c))
{
if (accumulator.length() > 0)
{
- sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString(), pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
}
status = Status.GSTRING_EXPR;
- accumulator.append((char)c);
+ accumulator.append(c);
}
else
{
- accumulator.append('$').append((char)c);
+ accumulator.append('$').append(c);
}
break;
case GSTRING_CURLY_EXPR:
if (c == '}')
{
- sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString(), pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
+
+ //
status = Status.TEXT;
}
else
{
- accumulator.append((char)c);
+ accumulator.append(c);
}
break;
case GSTRING_EXPR:
- if (c == '.' || Character.isJavaIdentifierPart((char)c))
+ if (c == '.' || Character.isJavaIdentifierPart(c))
{
- accumulator.append((char)c);
+ accumulator.append(c);
}
else
{
- sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString(), pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
+
+ //
status = Status.TEXT;
- accumulator.append((char)c);
+ accumulator.append(c);
}
break;
default:
@@ -237,12 +295,14 @@
switch (status)
{
case TEXT:
- sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.STRING,
accumulator.toString(), pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
break;
case GSTRING_EXPR:
- sections.add(new TemplateSection(SectionType.EXPR,
accumulator.toString()));
+ sections.add(new TemplateSection(SectionType.EXPR, accumulator.toString(),
pos));
accumulator.setLength(0);
+ pos = new Position(colNumber, lineNumber);
break;
default:
throw new AssertionError();
Added:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateRuntimeException.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateRuntimeException.java
(rev 0)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateRuntimeException.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2003-2007 eXo Platform SAS.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Affero General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not,
see<http://www.gnu.org/licenses/>.
+ */
+package org.exoplatform.groovyscript;
+
+/**
+ * A *checked* exception that denotes a Groovy runtime exception.
+ *
+ * @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
+ * @version $Revision$
+ */
+public class TemplateRuntimeException extends Exception
+{
+
+ /** . */
+ private final TextItem textItem;
+
+ public TemplateRuntimeException(TextItem textItem, String message, Throwable cause)
+ {
+ super(message, cause);
+
+ //
+ this.textItem = textItem;
+ }
+
+ public TemplateRuntimeException(TextItem textItem, Throwable cause)
+ {
+ super(cause);
+
+ //
+ this.textItem = textItem;
+ }
+
+ public TextItem getTextItem()
+ {
+ return textItem;
+ }
+
+ public Integer getLineNumber()
+ {
+ return textItem != null ? textItem.getPosition().getLine() : null;
+ }
+
+ public String getText()
+ {
+ return textItem != null ? textItem.getData() : null;
+ }
+
+ @Override
+ public String getMessage()
+ {
+ return textItem != null ? ("Groovy template exception at " + textItem) :
"Groovy template exception";
+ }
+}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TemplateSection.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -35,6 +35,16 @@
public TemplateSection(SectionType type, String text)
{
+ this(type, text, 0, 0);
+ }
+
+ public TemplateSection(SectionType type, String text, Position pos)
+ {
+ this(type, text, pos.getCol(), pos.getLine());
+ }
+
+ public TemplateSection(SectionType type, String text, int colNumber, int lineNumber)
+ {
if (type == null)
{
throw new NullPointerException();
@@ -44,13 +54,9 @@
throw new NullPointerException();
}
- //
// Now we process the line breaks
ArrayList<SectionItem> sections = new ArrayList<SectionItem>();
- // on Windows, "\r\n" is a new line
- text = text.replaceAll("\r\n", "\n");
-
//
int from = 0;
while (true)
@@ -61,14 +67,20 @@
if (to != -1)
{
String chunk = text.substring(from, to);
- sections.add(new TextItem(chunk));
- sections.add(new LineBreakItem());
+ sections.add(new TextItem(new Position(colNumber, lineNumber), chunk));
+
+ //
+ sections.add(new LineBreakItem(new Position(colNumber + (to - from),
lineNumber)));
+
+ //
from = to + 1;
+ lineNumber++;
+ colNumber = 0;
}
else
{
String chunk = text.substring(from);
- sections.add(new TextItem(chunk));
+ sections.add(new TextItem(new Position(colNumber, lineNumber), chunk));
break;
}
}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/TextItem.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -26,8 +26,11 @@
/** . */
private final String data;
- public TextItem(String data)
+ public TextItem(Position pos, String data)
{
+ super(pos);
+
+ //
if (data == null)
{
throw new NullPointerException();
@@ -60,6 +63,6 @@
@Override
public String toString()
{
- return "DataText[data=" + data + "]";
+ return "DataText[pos=" + getPosition() + ",data=" + data +
"]";
}
}
Modified:
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java
===================================================================
---
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/main/java/org/exoplatform/groovyscript/text/TemplateService.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -22,9 +22,9 @@
import groovy.lang.Writable;
import groovy.text.Template;
-import groovy.text.TemplateEngine;
import org.exoplatform.commons.utils.IOUtil;
import org.exoplatform.container.xml.InitParams;
+import org.exoplatform.groovyscript.GroovyTemplate;
import org.exoplatform.groovyscript.GroovyTemplateEngine;
import org.exoplatform.management.annotations.Managed;
import org.exoplatform.management.annotations.ManagedDescription;
@@ -47,9 +47,9 @@
public class TemplateService
{
- private TemplateEngine engine_;
+ private GroovyTemplateEngine engine_;
- private ExoCache<String, Template> templatesCache_;
+ private ExoCache<String, GroovyTemplate> templatesCache_;
private TemplateStatisticService statisticService;
@@ -68,11 +68,10 @@
{
long startTime = System.currentTimeMillis();
- Template template = getTemplate(name, context.getResourceResolver());
+ GroovyTemplate template = getTemplate(name, context.getResourceResolver());
context.put("_ctx", context);
context.setGroovyTemplateService(this);
- Writable writable = template.make(context);
- writable.writeTo(context.getWriter());
+ template.render(context.getWriter(), context);
long endTime = System.currentTimeMillis();
@@ -95,24 +94,22 @@
if (context == null)
throw new Exception("Binding cannot be null");
context.put("_ctx", context);
- Template template = getTemplate(name, context.getResourceResolver());
- Writable writable = template.make(context);
- writable.writeTo(context.getWriter());
-
+ GroovyTemplate template = getTemplate(name, context.getResourceResolver());
+ template.render(context.getWriter(), context);
}
- final public Template getTemplate(String name, ResourceResolver resolver) throws
Exception
+ final public GroovyTemplate getTemplate(String name, ResourceResolver resolver) throws
Exception
{
return getTemplate(name, resolver, cacheTemplate_);
}
- final public Template getTemplate(String url, ResourceResolver resolver, boolean
cacheable) throws Exception
+ final public GroovyTemplate getTemplate(String url, ResourceResolver resolver, boolean
cacheable) throws Exception
{
- Template template = null;
+ GroovyTemplate template = null;
if (cacheable)
{
String resourceId = resolver.createResourceId(url);
- template = (Template)getTemplatesCache().get(resourceId);
+ template = getTemplatesCache().get(resourceId);
}
if (template != null)
return template;
@@ -140,13 +137,8 @@
getTemplatesCache().remove(resourceId);
}
- public void setTemplatesCache(ExoCache<String, Template> templatesCache_)
+ public ExoCache<String, GroovyTemplate> getTemplatesCache()
{
- this.templatesCache_ = templatesCache_;
- }
-
- public ExoCache<String, Template> getTemplatesCache()
- {
return templatesCache_;
}
Modified:
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java
===================================================================
---
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateCompiler.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -17,7 +17,6 @@
package org.exoplatform.groovyscript;
import junit.framework.TestCase;
-import org.exoplatform.groovyscript.TemplateCompiler;
import java.io.IOException;
@@ -29,7 +28,7 @@
{
/** . */
- private final TemplateCompiler compiler = new TemplateCompiler();
+// private final TemplateCompiler compiler = new TemplateCompiler();
public void testFoo() throws IOException
{
Modified:
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java
===================================================================
---
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateParser.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -24,6 +24,7 @@
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
+import java.util.List;
/**
* @author <a href="mailto:julien.viet@exoplatform.com">Julien
Viet</a>
@@ -102,4 +103,20 @@
new TemplateSection(SectionType.STRING, "c")
), parser.parse("a<%=b%>c"));
}
+
+ public void testWindowsLineBreak() throws IOException
+ {
+
+ }
+
+ public void testPosition() throws IOException
+ {
+ List<TemplateSection> sections = parser.parse("a\nb<%= foo
%>d");
+ assertEquals(new Position(0, 0), sections.get(0).getItems().get(0).getPosition());
+ assertEquals(new Position(1, 0), sections.get(0).getItems().get(1).getPosition());
+ assertEquals(new Position(0, 1), sections.get(0).getItems().get(2).getPosition());
+ assertEquals(new Position(4, 1), sections.get(1).getItems().get(0).getPosition());
+ assertEquals(new Position(11, 1),
sections.get(2).getItems().get(0).getPosition());
+
+ }
}
Modified:
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java
===================================================================
---
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java 2009-10-30
21:04:13 UTC (rev 466)
+++
portal/branches/performance/component/scripting/src/test/java/org/exoplatform/groovyscript/TestTemplateRendering.java 2009-11-01
11:24:58 UTC (rev 467)
@@ -19,11 +19,12 @@
import junit.framework.TestCase;
import org.exoplatform.commons.utils.CharsetTextEncoder;
import org.exoplatform.commons.utils.OutputStreamPrinter;
-import org.exoplatform.groovyscript.GroovyTemplate;
-import org.exoplatform.groovyscript.OutputStreamWriterGroovyPrinter;
+import java.awt.*;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.InputStream;
+import java.util.EmptyStackException;
import java.util.HashMap;
import java.util.Map;
@@ -156,4 +157,105 @@
String gtmpl = baos.toString("UTF-8");
GroovyTemplate template = new GroovyTemplate(gtmpl);
}
+
+ public void testException() throws Exception
+ {
+ GroovyTemplate template = new GroovyTemplate("<% throw new
java.awt.AWTException(); %>");
+ try
+ {
+ template.render();
+ fail();
+ }
+ catch (TemplateRuntimeException e)
+ {
+ assertTrue(e.getCause() instanceof AWTException);
+ }
+ }
+
+ public void testRuntimeException() throws Exception
+ {
+ GroovyTemplate template = new GroovyTemplate("<% throw new
java.util.EmptyStackException(); %>");
+ try
+ {
+ template.render();
+ fail();
+ }
+ catch (TemplateRuntimeException e)
+ {
+ assertTrue(e.getCause() instanceof EmptyStackException);
+ }
+ }
+
+ public void testIOException() throws Exception
+ {
+ GroovyTemplate template = new GroovyTemplate("<% throw new
java.io.IOException(); %>");
+ try
+ {
+ template.render();
+ fail();
+ }
+ catch (IOException e)
+ {
+ }
+ }
+
+ public void testError() throws Exception
+ {
+ GroovyTemplate template = new GroovyTemplate("<% throw new
java.awt.AWTError(); %>");
+ try
+ {
+ template.render();
+ fail();
+ }
+ catch (AWTError e)
+ {
+ }
+ }
+
+ public void testThrowable() throws Exception
+ {
+ GroovyTemplate template = new GroovyTemplate("<% throw new Throwable();
%>");
+ try
+ {
+ template.render();
+ fail();
+ }
+ catch (Throwable t)
+ {
+ }
+ }
+
+ public void testScriptLineNumber() throws Exception
+ {
+ testLineNumber("<%");
+ assertLineNumber(2, "throw new Exception('e')",
"<%\nthrow new Exception('e')%>");
+ }
+
+ public void testExpressionLineNumber() throws Exception
+ {
+ testLineNumber("<%=");
+ }
+
+ private void testLineNumber(String prolog) throws Exception
+ {
+ assertLineNumber(1, "throw new Exception('a')", prolog +
"throw new Exception('a')%>");
+ assertLineNumber(1, "throw new Exception('b')", "foo" +
prolog + "throw new Exception('b')%>");
+ assertLineNumber(2, "throw new Exception('c')", "foo\n"
+ prolog + "throw new Exception('c')%>");
+ assertLineNumber(1, "throw new Exception('d')",
"<%;%>foo" + prolog + "throw new Exception('d')%>");
+ }
+
+ private void assertLineNumber(int expectedLineNumber, String expectedText, String
script) throws TemplateCompilationException, IOException
+ {
+ try
+ {
+ new GroovyTemplate(script).render();
+ fail();
+ }
+ catch (TemplateRuntimeException t)
+ {
+ assertEquals(expectedText, t.getText());
+ assertEquals(expectedLineNumber, (Object)t.getLineNumber());
+ }
+ }
+
}