aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src
diff options
context:
space:
mode:
authorClaude Brisson <cbrisson@apache.org>2019-06-06 16:13:47 +0000
committerClaude Brisson <cbrisson@apache.org>2019-06-06 16:13:47 +0000
commit9bb2aff849e54af3e3608b5320d159bccda3d27f (patch)
tree97e9b7da90e3de491e4b66b9b6b33391ca96bc95 /velocity-engine-core/src
parent59adf613d64b16683e5f959297531fcfac7493ee (diff)
downloadapache-velocity-engine-9bb2aff849e54af3e3608b5320d159bccda3d27f.tar.gz
[engine][VELOCITY-917] Compile-time configurable parser : working StandardParser
git-svn-id: https://svn.apache.org/repos/asf/velocity/engine/branches/parser_experiments@1860722 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'velocity-engine-core/src')
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeConstants.java36
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/RuntimeInstance.java55
-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.java15
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/ASTDirective.java4
-rw-r--r--velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/node/NodeUtils.java4
-rw-r--r--velocity-engine-core/src/main/parser/Parser.jjt (renamed from velocity-engine-core/src/main/parser/StandardParser.jjt)56
7 files changed, 93 insertions, 101 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 b68631b9..0ac45111 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
@@ -372,6 +372,18 @@ public interface RuntimeConstants extends DeprecatedRuntimeConstants
*/
/**
+ * Property specifying the parser class to use
+ * @since 2.2
+ */
+ String PARSER_CLASS = "parser.class";
+
+ /**
+ * Default parser class
+ * @since 2.2
+ */
+ String DEFAULT_PARSER_CLASS = "org.apache.velocity.runtime.parser.StandardParser";
+
+ /**
* The <code>parser.pool.class</code> property specifies the name of the {@link org.apache.velocity.util.SimplePool}
* implementation to use.
*/
@@ -388,30 +400,6 @@ 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_CHAR_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_CHAR_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_CHAR_AT = "parser.character.at";
-
- /**
- * Set the character (onlysingle byte UTF-8 supported at present) to use instead of '*' for '#* *#' block comments.
- * @since 2.2
- */
- String PARSER_CHAR_ASTERISK = "parser.character.asterisk";
-
/*
* ----------------------------------------------------------------------
* 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
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 929962b9..b3e0923e 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
@@ -62,6 +62,8 @@ import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
@@ -228,6 +230,12 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
private LogContext logContext;
/**
+ * Configured parser class
+ * @since 2.2
+ */
+ private Constructor parserConstructor;
+
+ /**
* Configured '$' character
* @since 2.2
*/
@@ -413,10 +421,6 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
/* init parser behavior */
hyphenAllowedInIdentifiers = getBoolean(PARSER_HYPHEN_ALLOWED, false);
- dollar = getConfiguredCharacter(PARSER_CHAR_DOLLAR, '$');
- hash = getConfiguredCharacter(PARSER_CHAR_HASH, '#');
- at = getConfiguredCharacter(PARSER_CHAR_AT, '@');
- asterisk = getConfiguredCharacter(PARSER_CHAR_ASTERISK, '*');
}
private char getConfiguredCharacter(String configKey, char defaultChar)
@@ -1191,6 +1195,29 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
private void initializeParserPool()
{
/*
+ * First initialize parser class. If it's not valid or not found, it will generate an error
+ * later on in this method when parser creation is tester.
+ */
+ String parserClassName = getString(PARSER_CLASS, DEFAULT_PARSER_CLASS);
+ Class parserClass;
+ try
+ {
+ parserClass = ClassUtils.getClass(parserClassName);
+ }
+ catch (ClassNotFoundException cnfe)
+ {
+ throw new VelocityException("parser class not found: " + parserClassName, cnfe);
+ }
+ try
+ {
+ parserConstructor = parserClass.getConstructor(RuntimeServices.class);
+ }
+ catch (NoSuchMethodException nsme)
+ {
+ throw new VelocityException("parser class must provide a constructor taking a RuntimeServices argument", nsme);
+ }
+
+ /*
* Which parser pool?
*/
String pp = getString(RuntimeConstants.PARSER_POOL_CLASS);
@@ -1239,6 +1266,16 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
parserPool = (ParserPool) o;
parserPool.initialize(this);
+
+ /*
+ * test parser creation and use generated parser to fill up customized characters
+ */
+ Parser parser = parserPool.get();
+ dollar = parser.dollar();
+ hash = parser.hash();
+ at = parser.at();
+ asterisk = parser.asterisk();
+ parserPool.put(parser);
}
else
{
@@ -1264,8 +1301,14 @@ public class RuntimeInstance implements RuntimeConstants, RuntimeServices
public Parser createNewParser()
{
requireInitialization();
-
- return new StandardParser(this);
+ try
+ {
+ return (Parser)parserConstructor.newInstance((RuntimeServices)this);
+ }
+ catch (IllegalAccessException | InstantiationException | InvocationTargetException e)
+ {
+ throw new VelocityException("could not build new parser class", e);
+ }
}
/**
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
deleted file mode 100644
index b48383fe..00000000
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserConstants.java
+++ /dev/null
@@ -1,24 +0,0 @@
-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
deleted file mode 100644
index 4074c982..00000000
--- a/velocity-engine-core/src/main/java/org/apache/velocity/runtime/parser/ParserTokenManager.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.apache.velocity.runtime.parser;
-
-public interface ParserTokenManager
-{
- void clearStateVars();
- void switchTo(int lexState);
- int getCurrentLexicalState();
- boolean stateStackPop();
- boolean stateStackPush();
- public Token getNextToken();
- void setDebugStream(java.io.PrintStream ds);
- boolean isInSet();
- void setInSet(boolean value);
- void ReInit(CharStream charStream);
-}
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 25bcd62a..a8bf65e2 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
@@ -31,7 +31,7 @@ import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.directive.RuntimeMacro;
import org.apache.velocity.runtime.parser.ParseException;
import org.apache.velocity.runtime.parser.Parser;
-import org.apache.velocity.runtime.parser.ParserConstants;
+import org.apache.velocity.runtime.parser.StandardParserConstants;
import org.apache.velocity.runtime.parser.Token;
import org.apache.velocity.util.introspection.Info;
@@ -143,7 +143,7 @@ public class ASTDirective extends SimpleNode
}
t = getFirstToken();
- if (t.kind == ParserConstants.WHITESPACE) t = t.next;
+ if (t.kind == StandardParserConstants.WHITESPACE) t = t.next;
directive.setLocation(t.beginLine, t.beginColumn, getTemplate());
directive.init(rsvc, context, this);
}
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 1146e736..84b735bd 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
@@ -20,7 +20,7 @@ package org.apache.velocity.runtime.parser.node;
*/
import org.apache.velocity.runtime.parser.Parser;
-import org.apache.velocity.runtime.parser.ParserConstants;
+import org.apache.velocity.runtime.parser.StandardParserConstants;
import org.apache.velocity.runtime.parser.Token;
/**
@@ -130,7 +130,7 @@ public class NodeUtils
public static String tokenLiteral( Parser parser, Token t )
{
// Look at kind of token and return "" when it's a block comment
- if (t.kind == ParserConstants.MULTI_LINE_COMMENT)
+ if (t.kind == StandardParserConstants.MULTI_LINE_COMMENT)
{
return "";
}
diff --git a/velocity-engine-core/src/main/parser/StandardParser.jjt b/velocity-engine-core/src/main/parser/Parser.jjt
index ffb44384..ecfef164 100644
--- a/velocity-engine-core/src/main/parser/StandardParser.jjt
+++ b/velocity-engine-core/src/main/parser/Parser.jjt
@@ -78,7 +78,7 @@ options
}
-PARSER_BEGIN(StandardParser)
+PARSER_BEGIN(${parser.name}Parser)
package org.apache.velocity.runtime.parser;
import java.io.*;
@@ -106,9 +106,9 @@ import org.slf4j.Logger;
* @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
* @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
* @author <a href="hps@intermeta.de">Henning P. Schmiedehausen</a>
- * @version $Id$
+ * @version $Id: $
*/
-public class StandardParser implements Parser
+public class ${parser.name}Parser implements Parser
{
/**
* Parser debugging flag.
@@ -121,7 +121,7 @@ public class StandardParser implements Parser
{
try
{
- StandardParser.class.getDeclaredMethod("trace_call", String.class);
+ ${parser.name}Parser.class.getDeclaredMethod("trace_call", String.class);
debugParser = true;
}
catch(NoSuchMethodException nsfe)
@@ -180,7 +180,7 @@ public class StandardParser implements Parser
* object, we satisfy the requirement of an InputStream
* by using a newline character as an input stream.
*/
- public StandardParser( RuntimeServices rs)
+ public ${parser.name}Parser( RuntimeServices rs)
{
/*
* need to call the CTOR first thing.
@@ -217,10 +217,10 @@ public class StandardParser implements Parser
/*
* then initialize customizable characters
*/
- dollar = rsvc.dollar();
- hash = rsvc.hash();
- at = rsvc.at();
- asterisk = rsvc.asterisk();
+ dollar = '${parser.char.dollar}';
+ hash = '${parser.char.hash}';
+ at = '${parser.char.at}';
+ asterisk = '${parser.char.asterisk}';
}
/**
@@ -549,7 +549,7 @@ public class StandardParser implements Parser
private char asterisk = '*';
}
-PARSER_END(StandardParser)
+PARSER_END(${parser.name}Parser)
TOKEN_MGR_DECLS:
{
@@ -569,7 +569,7 @@ TOKEN_MGR_DECLS:
*/
public static void trace(String message)
{
- StandardParser.trace(message);
+ ${parser.name}Parser.trace(message);
}
/**
@@ -906,7 +906,7 @@ TOKEN:
* for disaster, another long night with Mr. Parser, or both.
*/
- <ESCAPE_DIRECTIVE : (<DOUBLE_ESCAPE>)* "\\#" (<WORD> | <BRACKETED_WORD>) >
+ <ESCAPE_DIRECTIVE : (<DOUBLE_ESCAPE>)* "\\${parser.char.hash}" (<WORD> | <BRACKETED_WORD>) >
}
@@ -925,7 +925,7 @@ TOKEN:
<DEFAULT, PRE_REFERENCE, PRE_OLD_REFERENCE, REFERENCE, REFMODIFIER, OLD_REFMODIFIER, REFMOD2, REFMOD3>
TOKEN:
{
- <SET_DIRECTIVE: ("#set" | "#{set}") (" "|"\t")* "(">
+ <SET_DIRECTIVE: ("${parser.char.hash}set" | "${parser.char.hash}{set}") (" "|"\t")* "(">
{
if (! inComment)
{
@@ -962,7 +962,7 @@ MORE :
* Note : DOLLARBANG is a duplicate of DOLLAR. They must be identical.
*/
- <DOLLAR: ("\\")* "$">
+ <DOLLAR: ("\\")* "${parser.char.dollar}">
{
if (! inComment)
{
@@ -989,7 +989,7 @@ MORE :
}
}
-| <DOLLARBANG: ("\\")* "$" ("\\")* "!">
+| <DOLLARBANG: ("\\")* "${parser.char.dollar}" ("\\")* "!">
{
if (! inComment)
{
@@ -1016,7 +1016,7 @@ MORE :
}
}
-| "#[["
+| "${parser.char.hash}[["
{
if (!inComment)
{
@@ -1030,7 +1030,7 @@ MORE :
}
}
-| <"#**" ~["#","\u200B"]>
+| <"${parser.char.hash}${parser.char.asterisk}${parser.char.asterisk}" ~["${parser.char.hash}","\u200B"]>
{
if (!inComment)
{
@@ -1045,7 +1045,7 @@ MORE :
}
}
-| "#*"
+| "${parser.char.hash}${parser.char.asterisk}"
{
if (!inComment)
{
@@ -1059,7 +1059,7 @@ MORE :
}
}
-| <HASH : "#" >
+| <HASH : "${parser.char.hash}" >
{
if (! inComment)
{
@@ -1092,7 +1092,7 @@ MORE :
<DEFAULT,PRE_DIRECTIVE,DIRECTIVE,REFERENCE,PRE_REFERENCE,PRE_OLD_REFERENCE,REFMOD2,REFMOD3,REFMODIFIER,OLD_REFMODIFIER>
TOKEN :
{
- <SINGLE_LINE_COMMENT_START: "##">
+ <SINGLE_LINE_COMMENT_START: "${parser.char.hash}${parser.char.hash}">
{
if (!inComment)
{
@@ -1132,7 +1132,7 @@ TOKEN :
<IN_FORMAL_COMMENT>
TOKEN :
{
- <FORMAL_COMMENT: "*#" >
+ <FORMAL_COMMENT: "${parser.char.asterisk}${parser.char.hash}" >
{
inComment = false;
stateStackPop();
@@ -1147,7 +1147,7 @@ TOKEN :
<IN_MULTI_LINE_COMMENT>
TOKEN :
{
- <MULTI_LINE_COMMENT: "*#" >
+ <MULTI_LINE_COMMENT: "${parser.char.asterisk}${parser.char.hash}" >
{
inComment = false;
stateStackPop();
@@ -1162,7 +1162,7 @@ TOKEN :
<IN_TEXTBLOCK>
TOKEN :
{
- <TEXTBLOCK: "]]#" >
+ <TEXTBLOCK: "]]${parser.char.hash}" >
{
inComment = false;
stateStackPop();
@@ -1375,8 +1375,8 @@ TOKEN:
{
<#LETTER: [ "a"-"z", "A"-"Z" ] >
| <#DIRECTIVE_CHAR: [ "a"-"z", "A"-"Z", "0"-"9", "_" ] >
-| <WORD: ( <LETTER> | ["_"] | ["@"]) (<DIRECTIVE_CHAR>)* >
-| <BRACKETED_WORD: "{" ( <LETTER> | ["_"] | ["@"]) (<DIRECTIVE_CHAR>)* "}" >
+| <WORD: ( <LETTER> | ["_"] | ["${parser.char.at}"]) (<DIRECTIVE_CHAR>)* >
+| <BRACKETED_WORD: "{" ( <LETTER> | ["_"] | ["${parser.char.at}"]) (<DIRECTIVE_CHAR>)* "}" >
}
/* -----------------------------------------------------------------------
@@ -1525,12 +1525,12 @@ TOKEN :
{
<DOUBLE_ESCAPE : "\\\\">
| <ESCAPE: "\\" >
-| <TEXT: (~["$", "#", "\\", "\r", "\n","\u200B"])* (~["$", "#", "\\", "\r", "\n", " ", "\t","\u200B"])+ (~["$", "#", "\\", "\r", "\n","\u200B"])* <NEWLINE> ((~["$", "#", "\\", "\r", "\n","\u200B"])* <NEWLINE>)* >
+| <TEXT: (~["${parser.char.dollar}", "${parser.char.hash}", "\\", "\r", "\n","\u200B"])* (~["${parser.char.dollar}", "${parser.char.hash}", "\\", "\r", "\n", " ", "\t","\u200B"])+ (~["${parser.char.dollar}", "${parser.char.hash}", "\\", "\r", "\n","\u200B"])* <NEWLINE> ((~["${parser.char.dollar}", "${parser.char.hash}", "\\", "\r", "\n","\u200B"])* <NEWLINE>)* >
}
TOKEN :
{
- <INLINE_TEXT: (~["$", "#", "\\", "\r", "\n","\u200B"])+ >
+ <INLINE_TEXT: (~["${parser.char.dollar}", "${parser.char.hash}", "\\", "\r", "\n","\u200B"])+ >
}
/**
@@ -1790,7 +1790,7 @@ boolean Directive(boolean afterNewline) :
{
String directiveName;
int p = id.image.lastIndexOf(hash);
- if (id.kind == ParserConstants.BRACKETED_WORD)
+ if (id.kind == StandardParserConstants.BRACKETED_WORD)
{
directiveName = id.image.substring(p + 2, id.image.length() - 1);
}