aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'velocity-engine-core/src/main')
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java56
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java79
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeServices.java28
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Macro.java15
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java7
-rwxr-xr-xvelocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Scope.java3
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/Parser.java54
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserConstants.java24
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserTokenManager.java6
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComment.java4
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java6
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIfStatement.java2
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java10
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java2
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java4
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTText.java4
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java14
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/JJTParserState.java5
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/Node.java7
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/NodeUtils.java15
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ParserTreeConstants.java24
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java17
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/visitor/NodeViewMode.java3
-rw-r--r--velocity-engine-core/src/main/parser/StandardParser.jjt (renamed from velocity-engine-core/src/main/parser/Parser.jjt)87
24 files changed, 398 insertions, 78 deletions
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
index 27782632..545e8f08 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java
@@ -367,22 +367,10 @@ public interface RuntimeConstants extends DeprecatedRuntimeConstants
/*
* ----------------------------------------------------------------------
- * G E N E R A L R U N T I M E C O N F I G U R A T I O N
+ * P A R S E R C O N F I G U R A T I O N
* ----------------------------------------------------------------------
*/
- /** Whether to use string interning. */
- String RUNTIME_STRING_INTERNING = "runtime.string_interning";
-
- /** Switch for the interpolation facility for string literals. */
- String INTERPOLATE_STRINGLITERALS = "runtime.interpolate_string_literals";
-
- /** Switch for ignoring nulls in math equations vs throwing exceptions. */
- String STRICT_MATH = "runtime.strict_math";
-
- /** Key upon which a context should be accessible within itself */
- String CONTEXT_AUTOREFERENCE_KEY = "context.self_reference_key";
-
/**
* The <code>parser.pool.class</code> property specifies the name of the {@link org.apache.velocity.util.SimplePool}
* implementation to use.
@@ -401,6 +389,48 @@ public interface RuntimeConstants extends DeprecatedRuntimeConstants
String PARSER_HYPHEN_ALLOWED = "parser.allow_hyphen_in_identifiers";
/**
+ * Set the character (onlysingle byte UTF-8 supported at present) to use instead of '$' for references.
+ * @since 2.2
+ */
+ String PARSER_DOLLAR = "parser.character.dollar";
+
+ /**
+ * Set the character (onlysingle byte UTF-8 supported at present) to use instead of '#' for directives, macros and comments.
+ * @since 2.2
+ */
+ String PARSER_HASH = "parser.character.hash";
+
+ /**
+ * Set the character (onlysingle byte UTF-8 supported at present) to use instead of '@' for '#@' block macros.
+ * @since 2.2
+ */
+ String PARSER_AROBASE = "parser.character.arobase";
+
+ /**
+ * Set the character (onlysingle byte UTF-8 supported at present) to use instead of '*' for '#* *#' block comments.
+ * @since 2.2
+ */
+ String PARSER_STAR = "parser.character.star";
+
+ /*
+ * ----------------------------------------------------------------------
+ * G E N E R A L R U N T I M E C O N F I G U R A T I O N
+ * ----------------------------------------------------------------------
+ */
+
+ /** Whether to use string interning. */
+ String RUNTIME_STRING_INTERNING = "runtime.string_interning";
+
+ /** Switch for the interpolation facility for string literals. */
+ String INTERPOLATE_STRINGLITERALS = "runtime.interpolate_string_literals";
+
+ /** Switch for ignoring nulls in math equations vs throwing exceptions. */
+ String STRICT_MATH = "runtime.strict_math";
+
+ /** Key upon which a context should be accessible within itself */
+ String CONTEXT_AUTOREFERENCE_KEY = "context.self_reference_key";
+
+ /**
* Space gobbling mode
* @since 2.0
*/
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java
index c72491a6..420529c5 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java
@@ -40,6 +40,7 @@ import org.apache.velocity.runtime.directive.StopCommand;
import org.apache.velocity.runtime.parser.LogContext;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.Parser;
+import org.apache.velocity.runtime.parser.StandardParser;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.SimpleNode;
import org.apache.velocity.runtime.resource.ContentResource;
@@ -61,6 +62,7 @@ import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
+import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
@@ -226,6 +228,31 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
private LogContext logContext;
/**
+ * Configured '$' character
+ * @since 2.2
+ */
+ private char dollar = '$';
+
+ /**
+ * Configured '#' character
+ * @since 2.2
+ */
+ private char hash = '$';
+
+ /**
+ * Configured '@' character
+ * @since 2.2
+ */
+ private char arobase = '$';
+
+ /**
+ * Configured '*' character
+ * @since 2.2
+ */
+ private char star = '$';
+
+
+ /**
* Creates a new RuntimeInstance object.
*/
public RuntimeInstance()
@@ -320,6 +347,10 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
this.runtimeDirectivesShared = null;
this.uberSpect = null;
this.stringInterning = false;
+ this.dollar = '$';
+ this.hash = '#';
+ this.arobase = '@';
+ this.star = '*';
/*
* create a VM factory, introspector, and application attributes
@@ -382,6 +413,24 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
/* init parser behavior */
hyphenAllowedInIdentifiers = getBoolean(PARSER_HYPHEN_ALLOWED, false);
+ dollar = getConfiguredCharacter(PARSER_DOLLAR, '$');
+ hash = getConfiguredCharacter(PARSER_HASH, '#');
+ arobase = getConfiguredCharacter(PARSER_AROBASE, '@');
+ star = getConfiguredCharacter(PARSER_STAR, '*');
+ }
+
+ private char getConfiguredCharacter(String configKey, char defaultChar)
+ {
+ String configuredChar = getString(configKey);
+ if (configuredChar != null)
+ {
+ if (configuredChar.length() != 2 || configuredChar.getBytes(StandardCharsets.UTF_8).length != 1)
+ {
+ throw new RuntimeException(configKey + " must be a single byte UTF-8 character");
+ }
+ return configuredChar.charAt(0);
+ }
+ return defaultChar;
}
/**
@@ -1216,7 +1265,7 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
{
requireInitialization();
- return new Parser(this);
+ return new StandardParser(this);
}
/**
@@ -1264,7 +1313,7 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
if (keepParser)
{
/* drop the parser Template reference to allow garbage collection */
- parser.currentTemplate = null;
+ parser.resetCurrentTemplate();
parserPool.put(parser);
}
@@ -1530,7 +1579,7 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
}
/* now just create the VM call, and use evaluate */
- StringBuilder template = new StringBuilder("#");
+ StringBuilder template = new StringBuilder(String.valueOf(hash));
template.append(vmName);
template.append("(");
for (String param : params)
@@ -1904,4 +1953,28 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
{
return enabledScopeControls.contains(scopeName);
}
+
+ @Override
+ public char dollar()
+ {
+ return dollar;
+ }
+
+ @Override
+ public char hash()
+ {
+ return hash;
+ }
+
+ @Override
+ public char arobase()
+ {
+ return arobase;
+ }
+
+ @Override
+ public char star()
+ {
+ return star;
+ }
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeServices.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeServices.java
index 20f63a3a..588580c5 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeServices.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeServices.java
@@ -489,4 +489,32 @@ public interface RuntimeServices
* @since 2.1
*/
boolean isScopeControlEnabled(String scopeName);
+
+ /**
+ * Get the character configured for '$'
+ * @return configured character for '$', or '$'
+ * @since 2.2
+ */
+ char dollar();
+
+ /**
+ * Get the character configured for '#'
+ * @return configured character for '#', or '#'
+ * @since 2.2
+ */
+ char hash();
+
+ /**
+ * Get the character configured for '@'
+ * @return configured character for '@', or '@'
+ * @since 2.2
+ */
+ char arobase();
+
+ /**
+ * Get the character configured for '*'
+ * @return configured character for '*', or '*'
+ * @since 2.2
+ */
+ char star();
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Macro.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Macro.java
index 36e90adb..c5673f0f 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Macro.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Macro.java
@@ -21,8 +21,10 @@ package org.apache.velocity.runtime.directive;
import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.TemplateInitException;
+import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeServices;
import org.apache.velocity.runtime.parser.ParseException;
+import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.Token;
import org.apache.velocity.runtime.parser.node.Node;
import org.apache.velocity.runtime.parser.node.ParserTreeConstants;
@@ -218,9 +220,9 @@ public class Macro extends Directive
// trim off the leading $ for the args after the macro name.
// saves everyone else from having to do it
- if (i > 0 && macroArg.name.startsWith("$"))
+ if (i > 0 && macroArg.name.startsWith(String.valueOf(rsvc.dollar())))
{
- macroArg.name = macroArg.name.substring(1, macroArg.name.length());
+ macroArg.name = macroArg.name.substring(1);
}
macroArgs.add(macroArg);
@@ -230,7 +232,7 @@ public class Macro extends Directive
{
StringBuilder msg = new StringBuilder("Macro.getArgArray(): nbrArgs=");
msg.append(numArgs).append(": ");
- macroToString(msg, macroArgs);
+ macroToString(msg, macroArgs, rsvc);
rsvc.getLog("macro").debug(msg.toString());
}
@@ -267,15 +269,14 @@ public class Macro extends Directive
* has passed in as buf, this method returns it.
* @since 1.5
*/
- public static StringBuilder macroToString(final StringBuilder buf,
- List<MacroArg> macroArgs)
+ public static StringBuilder macroToString(final StringBuilder buf, List<MacroArg> macroArgs, RuntimeServices rsvc)
{
StringBuilder ret = (buf == null) ? new StringBuilder() : buf;
- ret.append('#').append(macroArgs.get(0).name).append("( ");
+ ret.append(rsvc.hash()).append(macroArgs.get(0).name).append("( ");
for (MacroArg marg : macroArgs)
{
- ret.append("$").append(marg.name);
+ ret.append(rsvc.dollar()).append(marg.name);
if (marg.defaultVal != null)
{
ret.append("=").append(marg.defaultVal);
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
index 9481b05a..da019698 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/RuntimeMacro.java
@@ -30,6 +30,7 @@ import org.apache.velocity.runtime.Renderable;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.RuntimeConstants.SpaceGobbling;
import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.Token;
import org.apache.velocity.runtime.parser.node.ASTDirective;
import org.apache.velocity.runtime.parser.node.Node;
@@ -140,7 +141,7 @@ public class RuntimeMacro extends Directive
*/
// Tokens can be used here since we are in init() and Tokens have not been dropped yet
Token t = node.getLastToken();
- if (t.image.startsWith(")") || t.image.startsWith("#end"))
+ if (t.image.startsWith(")") || t.image.startsWith(rsvc.hash() + "end"))
{
strictRef = rsvc.getBoolean(RuntimeConstants.RUNTIME_REFERENCES_STRICT, false);
}
@@ -194,7 +195,7 @@ public class RuntimeMacro extends Directive
int pos = -1;
while (t != null && t != node.getLastToken())
{
- if (pos == -1) pos = t.image.lastIndexOf('#');
+ if (pos == -1) pos = t.image.lastIndexOf(rsvc.hash());
if (pos != -1)
{
buffer.append(t.image.substring(pos));
@@ -209,7 +210,7 @@ public class RuntimeMacro extends Directive
if (t != null)
{
- if (pos == -1) pos = t.image.lastIndexOf('#');
+ if (pos == -1) pos = t.image.lastIndexOf(rsvc.hash());
if (pos != -1)
{
buffer.append(t.image.substring(pos));
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Scope.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Scope.java
index beedf05f..1938ae79 100755
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Scope.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/directive/Scope.java
@@ -20,6 +20,7 @@ package org.apache.velocity.runtime.directive;
*/
import org.apache.velocity.Template;
+import org.apache.velocity.runtime.parser.Parser;
import java.util.AbstractMap;
import java.util.HashMap;
@@ -326,7 +327,7 @@ public class Scope extends AbstractMap
StringBuilder sb = new StringBuilder();
if (directive != null)
{
- sb.append('#');
+ sb.append('#'); // parser characters substitution is not heandled here
}
sb.append(getName());
sb.append("[type:").append(getType());
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/Parser.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/Parser.java
new file mode 100644
index 00000000..14deca2c
--- /dev/null
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/Parser.java
@@ -0,0 +1,54 @@
+package org.apache.velocity.runtime.parser;
+
+/*
+ * 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.
+ */
+
+import org.apache.velocity.Template;
+import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.directive.Directive;
+import org.apache.velocity.runtime.parser.node.SimpleNode;
+
+import java.io.Reader;
+
+public interface Parser
+{
+ RuntimeServices getRuntimeServices();
+ SimpleNode parse(Reader reader, Template template) throws ParseException;
+ void resetCurrentTemplate();
+ Template getCurrentTemplate();
+ Token getToken(int index);
+ boolean isDirective(String macro);
+ Directive getDirective(String directive);
+ void ReInit(CharStream stream);
+
+ char dollar();
+ char hash();
+ char arobase();
+ char star();
+
+ default String lineComment()
+ {
+ return String.valueOf(hash()) + hash();
+ }
+
+ default String blockComment()
+ {
+ return String.valueOf(hash()) + star();
+ }
+}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserConstants.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserConstants.java
new file mode 100644
index 00000000..b48383fe
--- /dev/null
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserConstants.java
@@ -0,0 +1,24 @@
+package org.apache.velocity.runtime.parser;
+
+/*
+ * 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.
+ */
+
+public interface ParserConstants extends StandardParserConstants
+{
+}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserTokenManager.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
new file mode 100644
index 00000000..d276d506
--- /dev/null
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
@@ -0,0 +1,6 @@
+package org.apache.velocity.runtime.parser;
+
+public interface ParserTokenManager
+{
+
+}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComment.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComment.java
index 6e330761..56a5141c 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComment.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTComment.java
@@ -76,8 +76,8 @@ public class ASTComment extends SimpleNode
{
Token t = getFirstToken();
- int loc1 = t.image.indexOf("##");
- int loc2 = t.image.indexOf("#*");
+ int loc1 = t.image.indexOf(parser.lineComment());
+ int loc2 = t.image.indexOf(parser.blockComment());
if (loc1 == -1 && loc2 == -1)
{
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
index bed5fadc..3cb2f865 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java
@@ -113,7 +113,7 @@ public class ASTDirective extends SimpleNode
*/
t = getFirstToken();
int pos = -1;
- while (t != null && (pos = t.image.lastIndexOf('#')) == -1)
+ while (t != null && (pos = t.image.lastIndexOf(rsvc.hash())) == -1)
{
t = t.next;
}
@@ -148,7 +148,7 @@ public class ASTDirective extends SimpleNode
directive.setLocation(t.beginLine, t.beginColumn, getTemplate());
directive.init(rsvc, context, this);
}
- else if( directiveName.startsWith("@") )
+ else if( directiveName.startsWith(String.valueOf(rsvc.arobase())) )
{
if( this.jjtGetNumChildren() > 0 )
{
@@ -313,7 +313,7 @@ public class ASTDirective extends SimpleNode
{
writer.write(prefix);
writer.write(morePrefix);
- writer.write( "#");
+ writer.write(rsvc.hash());
writer.write(directiveName);
writer.write(postfix);
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIfStatement.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIfStatement.java
index 31e1fbb4..670baa14 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIfStatement.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTIfStatement.java
@@ -93,7 +93,7 @@ public class ASTIfStatement extends SimpleNode
*/
Token t = getFirstToken();
int pos = -1;
- while (t != null && (pos = t.image.lastIndexOf('#')) == -1)
+ while (t != null && (pos = t.image.lastIndexOf(rsvc.hash())) == -1)
{
t = t.next;
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
index 058dff39..238336bc 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTReference.java
@@ -283,7 +283,7 @@ public class ASTReference extends SimpleNode
!context.containsKey(rootString) && !onlyTestingReference))
{
result = EventHandlerUtil.invalidGetMethod(rsvc, context,
- "$" + rootString, null, null, uberInfo);
+ rsvc.dollar() + rootString, null, null, uberInfo);
}
if (result == null && astAlternateValue != null)
@@ -347,7 +347,7 @@ public class ASTReference extends SimpleNode
if (!context.containsKey(rootString) && referenceType != QUIET_REFERENCE && (!onlyTestingReference || numChildren > 0))
{
result = EventHandlerUtil.invalidGetMethod(rsvc, context,
- "$" + rootString, previousResult, null, uberInfo);
+ rsvc.dollar() + rootString, previousResult, null, uberInfo);
}
}
else
@@ -361,7 +361,7 @@ public class ASTReference extends SimpleNode
referenceType != QUIET_REFERENCE &&
(!onlyTestingReference || failedChild < numChildren - 1))
{
- StringBuilder name = new StringBuilder("$").append(rootString);
+ StringBuilder name = new StringBuilder(String.valueOf(rsvc.dollar())).append(rootString);
for (int i = 0; i <= failedChild; i++)
{
Node node = jjtGetChild(i);
@@ -920,7 +920,7 @@ public class ASTReference extends SimpleNode
int i = 0;
int len = t.image.length();
- i = t.image.indexOf('$');
+ i = t.image.indexOf(rsvc.dollar());
if (i == -1)
{
@@ -1004,7 +1004,7 @@ public class ASTReference extends SimpleNode
* last $
*/
- int loc1 = t.image.lastIndexOf('$');
+ int loc1 = t.image.lastIndexOf(rsvc.dollar());
/*
* if we have extra stuff, loc > 0
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java
index 438e7c6e..b01a0348 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTSetDirective.java
@@ -115,7 +115,7 @@ public class ASTSetDirective extends SimpleNode
*/
Token t = getFirstToken();
int pos = -1;
- while (t != null && (pos = t.image.lastIndexOf('#')) == -1)
+ while (t != null && (pos = t.image.lastIndexOf(rsvc.hash())) == -1)
{
t = t.next;
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java
index 2b197d4e..81c3838e 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTStringLiteral.java
@@ -96,8 +96,8 @@ public class ASTStringLiteral extends SimpleNode
interpolate = rsvc.getBoolean(
RuntimeConstants.INTERPOLATE_STRINGLITERALS, true)
&& getFirstToken().image.startsWith("\"")
- && ((getFirstToken().image.indexOf('$') != -1) || (getFirstToken().image
- .indexOf('#') != -1));
+ && ((getFirstToken().image.indexOf(rsvc.dollar()) != -1) || (getFirstToken().image
+ .indexOf(rsvc.hash()) != -1));
/*
* get the contents of the string, minus the '/" at each end
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTText.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTText.java
index ef577dc0..526a1e12 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTText.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTText.java
@@ -96,9 +96,9 @@ public class ASTText extends SimpleNode
Token t = getFirstToken();
for (; t != getLastToken(); t = t.next)
{
- builder.append(NodeUtils.tokenLiteral(t));
+ builder.append(NodeUtils.tokenLiteral(parser, t));
}
- builder.append(NodeUtils.tokenLiteral(t));
+ builder.append(NodeUtils.tokenLiteral(parser, t));
ctext = builder.toString();
cleanupParserAndTokens();
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
index 47f91635..68da9430 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTTextblock.java
@@ -35,25 +35,19 @@ import java.io.Writer;
*/
public class ASTTextblock extends SimpleNode
{
- public static final String START = "#[[";
- public static final String END = "]]#";
+ public final String START;
+ public final String END;
private char[] ctext;
/**
- * @param id
- */
- public ASTTextblock(int id)
- {
- super(id);
- }
-
- /**
* @param p
* @param id
*/
public ASTTextblock(Parser p, int id)
{
super(p, id);
+ START = parser.hash() + "[[";
+ END = "]]" + parser.hash();
}
/**
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/JJTParserState.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/JJTParserState.java
new file mode 100644
index 00000000..9f84bfb0
--- /dev/null
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/JJTParserState.java
@@ -0,0 +1,5 @@
+package org.apache.velocity.runtime.parser.node;
+
+public class JJTParserState extends JJTStandardParserState
+{
+}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/Node.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/Node.java
index f311cb71..cb44c6d2 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/Node.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/Node.java
@@ -26,6 +26,7 @@ import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.TemplateInitException;
import org.apache.velocity.runtime.Renderable;
+import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.Token;
import java.io.IOException;
@@ -221,4 +222,10 @@ public interface Node extends Renderable
* @return the template this node belongs to
*/
Template getTemplate();
+
+ /**
+ * @return the parser which generated this node
+ * @since 2.2
+ */
+ Parser getParser();
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/NodeUtils.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/NodeUtils.java
index afbee2ca..1146e736 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/NodeUtils.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/NodeUtils.java
@@ -19,6 +19,7 @@ package org.apache.velocity.runtime.parser.node;
* under the License.
*/
+import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.ParserConstants;
import org.apache.velocity.runtime.parser.Token;
@@ -43,7 +44,7 @@ public class NodeUtils
* @return StrBuilder with the special tokens.
* @since 2.0.0
*/
- public static StringBuilder getSpecialText(Token t)
+ public static StringBuilder getSpecialText(Parser parser, Token t)
{
StringBuilder sb = new StringBuilder();
@@ -62,7 +63,7 @@ public class NodeUtils
{
char c = st.charAt(i);
- if ( c == '#' || c == '$' )
+ if ( c == parser.hash() || c == parser.dollar() )
{
sb.append( c );
}
@@ -90,7 +91,7 @@ public class NodeUtils
*/
continue;
}
- else if( cc == '$' )
+ else if( cc == parser.dollar() )
{
/*
* a $ ends it correctly
@@ -126,20 +127,20 @@ public class NodeUtils
* @param t
* @return A node literal.
*/
- public static String tokenLiteral( Token t )
+ public static String tokenLiteral( Parser parser, Token t )
{
- // Look at kind of token and return "" when it's a multiline comment
+ // Look at kind of token and return "" when it's a block comment
if (t.kind == ParserConstants.MULTI_LINE_COMMENT)
{
return "";
}
- else if (t.specialToken == null || t.specialToken.image.startsWith("##"))
+ else if (t.specialToken == null || t.specialToken.image.startsWith(parser.lineComment()))
{
return t.image;
}
else
{
- StringBuilder special = getSpecialText(t);
+ StringBuilder special = getSpecialText(parser, t);
if (special.length() > 0)
{
return special.append(t.image).toString();
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ParserTreeConstants.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ParserTreeConstants.java
new file mode 100644
index 00000000..7cc1dc53
--- /dev/null
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ParserTreeConstants.java
@@ -0,0 +1,24 @@
+package org.apache.velocity.runtime.parser.node;
+
+/*
+ * 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.
+ */
+
+public interface ParserTreeConstants extends StandardParserTreeConstants
+{
+}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java
index 59aade33..1c6761bb 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/SimpleNode.java
@@ -128,7 +128,7 @@ public class SimpleNode implements Node
{
this(i);
parser = p;
- template = parser.currentTemplate;
+ template = parser.getCurrentTemplate();
}
/**
@@ -352,16 +352,16 @@ public class SimpleNode implements Node
// buffer allocation. VELOCITY-606
if (first == last)
{
- literal = NodeUtils.tokenLiteral(first);
+ literal = NodeUtils.tokenLiteral(parser, first);
return literal;
}
Token t = first;
- StringBuilder sb = new StringBuilder(NodeUtils.tokenLiteral(t));
+ StringBuilder sb = new StringBuilder(NodeUtils.tokenLiteral(parser, t));
while (t != last)
{
t = t.next;
- sb.append(NodeUtils.tokenLiteral(t));
+ sb.append(NodeUtils.tokenLiteral(parser, t));
}
literal = sb.toString();
return literal;
@@ -570,4 +570,13 @@ public class SimpleNode implements Node
}
public Template getTemplate() { return template; }
+
+ /**
+ * @return the parser which created this node
+ * @since 2.2
+ */
+ public Parser getParser()
+ {
+ return parser;
+ }
}
diff --git a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/visitor/NodeViewMode.java b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/visitor/NodeViewMode.java
index 8e8b57c9..da9441a2 100644
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/visitor/NodeViewMode.java
+++ b/velocity-engine-core/src/main/java/org/apache/velocity/runtime/visitor/NodeViewMode.java
@@ -19,6 +19,7 @@ package org.apache.velocity.runtime.visitor;
* under the License.
*/
+import org.apache.velocity.runtime.parser.Parser;
import org.apache.velocity.runtime.parser.Token;
import org.apache.velocity.runtime.parser.node.*;
@@ -66,7 +67,7 @@ public class NodeViewMode extends BaseVisitor
// TODO: Token reference
t = node.getFirstToken();
- if (t.specialToken != null && ! t.specialToken.image.startsWith("##"))
+ if (t.specialToken != null && ! t.specialToken.image.startsWith(node.getParser().lineComment()))
special = t.specialToken.image;
tokens = " -> " + special + t.image;
diff --git a/velocity-engine-core/src/main/parser/Parser.jjt b/velocity-engine-core/src/main/parser/StandardParser.jjt
index 6f1626bd..06e6fa15 100644
--- a/velocity-engine-core/src/main/parser/Parser.jjt
+++ b/velocity-engine-core/src/main/parser/StandardParser.jjt
@@ -23,8 +23,9 @@
*/
options
{
- /** The default package for this parser kit */
+ /** The default package for this parser kit. This is now done from Maven.
NODE_PACKAGE="org.apache.velocity.runtime.parser";
+ */
/** A source file will be generated for each non-terminal */
MULTI=true;
@@ -73,9 +74,11 @@ options
DEBUG_LOOKAHEAD = true;
DEBUG_TOKEN_MANAGER = true;
*/
+
+
}
-PARSER_BEGIN(Parser)
+PARSER_BEGIN(StandardParser)
package org.apache.velocity.runtime.parser;
import java.io.*;
@@ -105,7 +108,7 @@ import org.slf4j.Logger;
* @author <a href="hps@intermeta.de">Henning P. Schmiedehausen</a>
* @version $Id$
*/
-public class Parser
+public class StandardParser implements Parser
{
/**
* Parser debugging flag.
@@ -118,7 +121,7 @@ public class Parser
{
try
{
- Parser.class.getDeclaredMethod("trace_call", String.class);
+ StandardParser.class.getDeclaredMethod("trace_call", String.class);
debugParser = true;
}
catch(NoSuchMethodException nsfe)
@@ -162,6 +165,7 @@ public class Parser
private RuntimeServices rsvc = null;
+ @Override
public RuntimeServices getRuntimeServices()
{
return rsvc;
@@ -176,7 +180,7 @@ public class Parser
* object, we satisfy the requirement of an InputStream
* by using a newline character as an input stream.
*/
- public Parser( RuntimeServices rs)
+ public StandardParser( RuntimeServices rs)
{
/*
* need to call the CTOR first thing.
@@ -209,6 +213,14 @@ public class Parser
* and save the RuntimeServices
*/
rsvc = rs;
+
+ /*
+ * then initialize customizable characters
+ */
+ dollar = rsvc.dollar();
+ hash = rsvc.hash();
+ arobase = rsvc.arobase();
+ star = rsvc.star();
}
/**
@@ -220,6 +232,7 @@ public class Parser
* method and re-initializing the lexer with
* the new stream that we want parsed.
*/
+ @Override
public SimpleNode parse( Reader reader, Template template )
throws ParseException
{
@@ -281,6 +294,7 @@ public class Parser
/**
* This method gets a Directive from the directives Hashtable
*/
+ @Override
public Directive getDirective(String directive)
{
return (Directive) rsvc.getDirective(directive);
@@ -289,6 +303,7 @@ public class Parser
/**
* This method finds out of the directive exists in the directives Map.
*/
+ @Override
public boolean isDirective(String directive)
{
return rsvc.getDirective(directive) != null;
@@ -491,9 +506,50 @@ public class Parser
return true;
}
+
+ @Override
+ public Template getCurrentTemplate()
+ {
+ return currentTemplate;
+ }
+
+ @Override
+ public void resetCurrentTemplate()
+ {
+ currentTemplate = null;
+ }
+
+ @Override
+ public char dollar()
+ {
+ return dollar;
+ }
+
+ @Override
+ public char hash()
+ {
+ return hash;
+ }
+
+ @Override
+ public char arobase()
+ {
+ return arobase;
+ }
+
+ @Override
+ public char star()
+ {
+ return star;
+ }
+
+ private char dollar = '$';
+ private char hash = '#';
+ private char arobase = '@';
+ private char star = '*';
}
-PARSER_END(Parser)
+PARSER_END(StandardParser)
TOKEN_MGR_DECLS:
{
@@ -507,13 +563,18 @@ TOKEN_MGR_DECLS:
private boolean inComment;
public boolean inSet;
+ public char dollar = '$';
+ public char hash = '#';
+ public char arobase = '@';
+ public char star = '*';
+
/**
* Our own trace method. Use sparsingly in production, since each
* and every call will introduce an execution branch and slow down parsing.
*/
public static void trace(String message)
{
- Parser.trace(message);
+ StandardParser.trace(message);
}
/**
@@ -1718,7 +1779,7 @@ boolean Directive(boolean afterNewline) :
((id = <WORD>) | (id = <BRACKETED_WORD>))
{
String directiveName;
- int p = id.image.lastIndexOf('#');
+ int p = id.image.lastIndexOf(hash);
if (id.kind == ParserConstants.BRACKETED_WORD)
{
directiveName = id.image.substring(p + 2, id.image.length() - 1);
@@ -1916,7 +1977,7 @@ boolean Directive(boolean afterNewline) :
)
#Block
{
- int pos = _else.image.lastIndexOf('#');
+ int pos = _else.image.lastIndexOf(hash);
if (pos > 0)
{
block.setMorePostfix(_else.image.substring(0, pos));
@@ -1948,7 +2009,7 @@ boolean Directive(boolean afterNewline) :
}
]
{
- int pos = end.image.lastIndexOf('#');
+ int pos = end.image.lastIndexOf(hash);
if (pos > 0)
{
block.setMorePostfix(end.image.substring(0, pos));
@@ -2206,7 +2267,7 @@ boolean IfStatement(boolean afterNewline) :
}
]
{
- int pos = end.image.lastIndexOf('#');
+ int pos = end.image.lastIndexOf(hash);
if (pos > 0)
{
lastBlock.setMorePostfix(end.image.substring(0, pos));
@@ -2245,7 +2306,7 @@ ASTBlock ElseStatement(ASTBlock previousBlock, boolean afterNewline) :
)
#Block
{
- int pos = _else.image.lastIndexOf('#');
+ int pos = _else.image.lastIndexOf(hash);
if (pos > 0)
{
previousBlock.setMorePostfix(_else.image.substring(0, pos));
@@ -2285,7 +2346,7 @@ ASTBlock ElseIfStatement(ASTBlock previousBlock, boolean afterNewline) :
)
#Block
{
- int pos = elseif.image.lastIndexOf('#');
+ int pos = elseif.image.lastIndexOf(hash);
if (pos > 0)
{
previousBlock.setMorePostfix(elseif.image.substring(0, pos));