Author: danielf Date: Sat Jan 15 04:57:55 2005 New Revision: 125262 URL: http://svn.apache.org/viewcvs?view=rev&rev=125262 Log: String template parsing moved to Substitutions. Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Substitutions.java Modified: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java
Modified: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java?view=diff&rev=125262&p1=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java&r1=125261&p2=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java&r2=125262 ============================================================================== --- cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java (original) +++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Literal.java Sat Jan 15 04:57:55 2005 @@ -15,14 +15,27 @@ */ package org.apache.cocoon.template.jxtg.expression; +/* + From efficiency reasons it might be better to split this class in + two, one that represent attribute content that are strings and one + for Character content that are handled as char arrays. Here the + content is stored as a char array as there in most cases will be + much more content in elements than in attributes, so it is better to + avoid copying there. +*/ + public class Literal extends Subst { public Literal(String val) { - this.value = val; + this.value = val.toCharArray(); } public String getValue() { + return new String(this.value); + } + + public char[] getCharArray() { return value; } - private final String value; -} \ No newline at end of file + private final char[] value; +} Added: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Substitutions.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Substitutions.java?view=auto&rev=125262 ============================================================================== --- (empty file) +++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/expression/Substitutions.java Sat Jan 15 04:57:55 2005 @@ -0,0 +1,134 @@ +/* + * Copyright 1999-2004 The Apache Software Foundation. + * + * Licensed 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.cocoon.template.jxtg.expression; + +import java.io.CharArrayReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import org.apache.cocoon.template.jxtg.environment.ErrorHolder; + +public class Substitutions { + + final private List substitutions; + final private boolean hasSubstitutions; + + public Substitutions(Locator location, String stringTemplate) throws SAXException { + this(location, new StringReader(stringTemplate)); + } + + public Substitutions(Locator location, char[] chars, int start, int length) + throws SAXException { + this(location, new CharArrayReader(chars, start, length)); + } + + private Substitutions(Locator location, Reader in) throws SAXException { + LinkedList substitutions = new LinkedList(); + StringBuffer buf = new StringBuffer(); + buf.setLength(0); + int ch; + boolean inExpr = false; + boolean xpath = false; + try { + top: + while ((ch = in.read()) != -1) { + // column++; + char c = (char) ch; + processChar: + while (true) { + if (inExpr) { + if (c == '\\') { + ch = in.read(); + buf.append(ch == -1 ? '\\' : (char) ch); + } else if (c == '}') { + String str = buf.toString(); + JXTExpression compiledExpression; + try { + compiledExpression = JXTExpression.compile(str, xpath); + } catch (Exception exc) { + throw new SAXParseException(exc.getMessage(), + location, exc); + } catch (Error err) { + throw new SAXParseException(err.getMessage(), + location, + new ErrorHolder(err)); + } + substitutions.add(compiledExpression); + buf.setLength(0); + inExpr = false; + } else { + buf.append(c); + } + } else if (c == '$' || c == '#') { + ch = in.read(); + if (ch == '{') { + xpath = c == '#'; + inExpr = true; + if (buf.length() > 0) { + substitutions.add(new Literal(buf.toString())); + buf.setLength(0); + } + continue top; + } + buf.append(c); + if (ch != -1) { + c = (char) ch; + continue processChar; + } + } else { + buf.append(c); + } + break; + } + } + } catch (IOException ignored) { + // won't happen + ignored.printStackTrace(); + } + if (inExpr) { + // unclosed #{} or ${} + String msg = "Unterminated " + (xpath ? "#" : "$") + "{"; + throw new SAXParseException(msg, location, null); + } + substitutions.add(new Literal(buf.toString())); + + this.substitutions = substitutions; + this.hasSubstitutions = !substitutions.isEmpty(); + } + + public boolean hasSubstitutions() { + return this.hasSubstitutions; + } + + public Iterator iterator() { + return this.substitutions.iterator(); + } + + public int size() { + return this.substitutions.size(); + } + + public Object get(int pos) { + return this.substitutions.get(pos); + } +} Modified: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java?view=diff&rev=125262&p1=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java&r1=125261&p2=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java&r2=125262 ============================================================================== --- cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java (original) +++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/Invoker.java Sat Jan 15 04:57:55 2005 @@ -72,10 +72,10 @@ TextEvent text = (TextEvent) ev; Iterator iter = text.getSubstitutions().iterator(); while (iter.hasNext()) { - Object subst = iter.next(); + Subst subst = (Subst)iter.next(); char[] chars; - if (subst instanceof char[]) { - chars = (char[]) subst; + if (subst instanceof Literal) { + chars = ((Literal)subst).getCharArray(); } else { JXTExpression expr = (JXTExpression) subst; try { @@ -707,8 +707,8 @@ while (iter.hasNext()) { Object subst = iter.next(); char[] chars; - if (subst instanceof char[]) { - chars = (char[]) subst; + if (subst instanceof Literal) { + chars = ((Literal) subst).getCharArray(); } else { JXTExpression expr = (JXTExpression) subst; try { Modified: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java?view=diff&rev=125262&p1=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java&r1=125261&p2=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java&r2=125262 ============================================================================== --- cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java (original) +++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/StartElement.java Sat Jan 15 04:57:55 2005 @@ -15,18 +15,13 @@ */ package org.apache.cocoon.template.jxtg.script.event; -import java.io.IOException; -import java.io.StringReader; import java.util.LinkedList; import java.util.List; -import org.apache.cocoon.template.jxtg.environment.ErrorHolder; -import org.apache.cocoon.template.jxtg.expression.JXTExpression; -import org.apache.cocoon.template.jxtg.expression.Literal; +import org.apache.cocoon.template.jxtg.expression.Substitutions; import org.xml.sax.Attributes; import org.xml.sax.Locator; import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; import org.xml.sax.helpers.AttributesImpl; public class StartElement extends Event { @@ -37,7 +32,6 @@ this.localName = localName; this.raw = raw; this.qname = "{" + namespaceURI + "}" + localName; - StringBuffer buf = new StringBuffer(); int len = attrs.getLength(); for (int i = 0; i < len; i++) { String uri = attrs.getURI(i); @@ -45,90 +39,12 @@ String qname = attrs.getQName(i); String type = attrs.getType(i); String value = attrs.getValue(i); - StringReader in = new StringReader(value); - int ch; - buf.setLength(0); - boolean inExpr = false; - List substEvents = new LinkedList(); - boolean xpath = false; - try { - top: while ((ch = in.read()) != -1) { - char c = (char) ch; - processChar: while (true) { - if (inExpr) { - if (c == '\\') { - ch = in.read(); - buf.append(ch == -1 ? '\\' : (char) ch); - } else if (c == '}') { - String str = buf.toString(); - JXTExpression compiledExpression; - try { - compiledExpression = JXTExpression.compile(str, - xpath); - } catch (Exception exc) { - throw new SAXParseException(exc - .getMessage(), location, exc); - } catch (Error err) { - throw new SAXParseException(err - .getMessage(), location, - new ErrorHolder(err)); - } - substEvents.add(compiledExpression); - buf.setLength(0); - inExpr = false; - } else { - buf.append(c); - } - } else if (c == '$' || c == '#') { - ch = in.read(); - if (ch == '{') { - if (buf.length() > 0) { - substEvents - .add(new Literal(buf.toString())); - buf.setLength(0); - } - inExpr = true; - xpath = c == '#'; - continue top; - } - buf.append(c); - if (ch != -1) { - c = (char) ch; - continue processChar; - } - } else { - buf.append(c); - } - break; - } - } - } catch (IOException ignored) { - ignored.printStackTrace(); - } - if (inExpr) { - // unclosed #{} or ${} - String msg = "Unterminated " + (xpath ? "#" : "$") + "{"; - throw new SAXParseException(msg, location, null); - } - if (buf.length() > 0) { - if (substEvents.size() == 0) { - getAttributeEvents().add( - new CopyAttribute(uri, local, qname, type, value)); - } else { - substEvents.add(new Literal(buf.toString())); - getAttributeEvents().add( - new SubstituteAttribute(uri, local, qname, type, - substEvents)); - } + Substitutions substitutions = new Substitutions(getLocation(), value); + if (substitutions.hasSubstitutions()) { + getAttributeEvents().add(new SubstituteAttribute(uri, local, qname, type, + substitutions)); } else { - if (substEvents.size() > 0) { - getAttributeEvents().add( - new SubstituteAttribute(uri, local, qname, type, - substEvents)); - } else { - getAttributeEvents().add( - new CopyAttribute(uri, local, qname, type, "")); - } + getAttributeEvents().add(new CopyAttribute(uri, local, qname, type, value)); } } this.attributes = new AttributesImpl(attrs); Modified: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java?view=diff&rev=125262&p1=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java&r1=125261&p2=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java&r2=125262 ============================================================================== --- cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java (original) +++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/SubstituteAttribute.java Sat Jan 15 04:57:55 2005 @@ -15,19 +15,18 @@ */ package org.apache.cocoon.template.jxtg.script.event; -import java.util.List; - +import org.apache.cocoon.template.jxtg.expression.Substitutions; public class SubstituteAttribute extends AttributeEvent { public SubstituteAttribute(String namespaceURI, String localName, - String raw, String type, List substs) { + String raw, String type, Substitutions substs) { super(namespaceURI, localName, raw, type); this.substitutions = substs; } - public List getSubstitutions() { + public Substitutions getSubstitutions() { return substitutions; } - private final List substitutions; -} \ No newline at end of file + private final Substitutions substitutions; +} Modified: cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java Url: http://svn.apache.org/viewcvs/cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java?view=diff&rev=125262&p1=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java&r1=125261&p2=cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java&r2=125262 ============================================================================== --- cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java (original) +++ cocoon/trunk/src/blocks/template/java/org/apache/cocoon/template/jxtg/script/event/TextEvent.java Sat Jan 15 04:57:55 2005 @@ -15,118 +15,27 @@ */ package org.apache.cocoon.template.jxtg.script.event; -import java.io.CharArrayReader; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; - -import org.apache.cocoon.template.jxtg.environment.ErrorHolder; -import org.apache.cocoon.template.jxtg.expression.JXTExpression; -import org.apache.commons.jexl.ExpressionFactory; -import org.apache.commons.jxpath.JXPathContext; -import org.apache.commons.lang.ArrayUtils; +import org.apache.cocoon.template.jxtg.expression.Substitutions; import org.xml.sax.Locator; import org.xml.sax.SAXException; -import org.xml.sax.SAXParseException; public class TextEvent extends Event { public TextEvent(Locator location, char[] chars, int start, int length) throws SAXException { super(location); - StringBuffer buf = new StringBuffer(); this.raw = new char[length]; System.arraycopy(chars, start, this.raw, 0, length); - CharArrayReader in = new CharArrayReader(chars, start, length); - int ch; - boolean inExpr = false; - boolean xpath = false; - try { - top: while ((ch = in.read()) != -1) { - // column++; - char c = (char) ch; - processChar: while (true) { - if (inExpr) { - if (c == '\\') { - ch = in.read(); - buf.append(ch == -1 ? '\\' : (char) ch); - } else if (c == '}') { - String str = buf.toString(); - Object compiledExpression; - try { - if (xpath) { - compiledExpression = JXPathContext - .compile(str); - } else { - compiledExpression = ExpressionFactory - .createExpression(str); - } - } catch (Exception exc) { - throw new SAXParseException(exc.getMessage(), - this.getLocation(), exc); - } catch (Error err) { - throw new SAXParseException(err.getMessage(), - this.getLocation(), - new ErrorHolder(err)); - - } - substitutions.add(new JXTExpression(str, - compiledExpression)); - buf.setLength(0); - inExpr = false; - } else { - buf.append(c); - } - } else if (c == '$' || c == '#') { - ch = in.read(); - if (ch == '{') { - xpath = c == '#'; - inExpr = true; - if (buf.length() > 0) { - char[] charArray = new char[buf.length()]; - - buf.getChars(0, buf.length(), charArray, 0); - substitutions.add(charArray); - buf.setLength(0); - } - continue top; - } - buf.append(c); - if (ch != -1) { - c = (char) ch; - continue processChar; - } - } else { - buf.append(c); - } - break; - } - } - } catch (IOException ignored) { - // won't happen - ignored.printStackTrace(); - } - if (inExpr) { - // unclosed #{} or ${} - buf.insert(0, (xpath ? "#" : "$") + "{"); - } - if (buf.length() > 0) { - char[] charArray = new char[buf.length()]; - - buf.getChars(0, buf.length(), charArray, 0); - substitutions.add(charArray); - } else if (substitutions.isEmpty()) { - substitutions.add(ArrayUtils.EMPTY_CHAR_ARRAY); - } + this.substitutions = new Substitutions(getLocation(), chars, start, length); } - final List substitutions = new LinkedList(); + final Substitutions substitutions; final char[] raw; public char[] getRaw() { return raw; } - public List getSubstitutions() { + public Substitutions getSubstitutions() { return substitutions; } -} \ No newline at end of file +}