You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ad...@apache.org on 2010/02/05 23:34:54 UTC
svn commit: r907117 -
/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java
Author: adrianc
Date: Fri Feb 5 22:34:53 2010
New Revision: 907117
URL: http://svn.apache.org/viewvc?rev=907117&view=rev
Log:
Added JavaDocs and changed some parameter names in FlexibleStringExpander.java. No functional change.
Modified:
ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java
Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java?rev=907117&r1=907116&r2=907117&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/FlexibleStringExpander.java Fri Feb 5 22:34:53 2010
@@ -42,10 +42,11 @@
import bsh.EvalError;
-/** Expands String values that contain Unified Expression Language syntax.
- * Also supports the execution of bsh scripts by using the 'bsh:' prefix.
+/** Expands String values that contain Unified Expression Language (JSR 245)
+ * syntax. This class also supports the execution of bsh scripts by using the
+ * 'bsh:' prefix, and Groovy scripts by using the 'groovy:' prefix.
* Further it is possible to control the output by specifying the suffix
- * '?currency(XXX)' to format the output according the current locale
+ * '?currency(XXX)' to format the output according to the supplied locale
* and specified (XXX) currency.<p>This class extends the UEL by allowing
* nested expressions.</p>
*/
@@ -58,126 +59,163 @@
protected static final UtilCache<String, FlexibleStringExpander> exprCache = UtilCache.createUtilCache("flexibleStringExpander.ExpressionCache");
protected static final FlexibleStringExpander nullExpr = new ConstElem("");
- /** Does on-the-fly parsing and expansion of the original String using
- * variable values from the passed context. A null context argument will
- * return the original String.
- * @param original The original String that will be expanded
- * @param context A context Map containing the variable values
- * @return The original String expanded by replacing varaible place holders.
- */
- public static String expandString(String original, Map<String, ? extends Object> context) {
- return expandString(original, context, null, null);
- }
-
- /** Does on-the-fly parsing and expansion of the original String using
- * variable values from the passed context. A null context argument will
- * return the original String.
- * @param original The original String that will be expanded
- * @param context A context Map containing the variable values
- * @return The original String expanded by replacing varaible place holders.
- */
- public static String expandString(String original, Map<String, ? extends Object> context, Locale locale) {
- return expandString(original, context, null, locale);
- }
-
- /** Does on-the-fly parsing and expansion of the original String using
- * variable values from the passed context. A null context argument will
- * return the original String.
- * @param original The original String that will be expanded
- * @param context A context Map containing the variable values
- * @return The original String expanded by replacing varaible place holders.
- */
- public static String expandString(String original, Map<String, ? extends Object> context, TimeZone timeZone, Locale locale) {
- if (context == null || original == null || !original.contains(openBracket)) {
- return original;
+ /** Evaluate an expression and return the result as a <code>String</code>.
+ * Null expressions return <code>null</code>.
+ * A null <code>context</code> argument will return the original expression.
+ * <p>Note that the behavior of this method is not the same as using
+ * <code>FlexibleStringExpander.getInstance(expression).expandString(context)</code>
+ * because it returns <code>null</code> when given a null <code>expression</code>
+ * argument, and
+ * <code>FlexibleStringExpander.getInstance(expression).expandString(context)</code>
+ * returns an empty <code>String</code>.</p>
+ *
+ * @param expression The original expression
+ * @param context The evaluation context
+ * @return The original expression's evaluation result as a <code>String</code>
+ */
+ public static String expandString(String expression, Map<String, ? extends Object> context) {
+ return expandString(expression, context, null, null);
+ }
+
+ /** Evaluate an expression and return the result as a <code>String</code>.
+ * Null expressions return <code>null</code>.
+ * A null <code>context</code> argument will return the original expression.
+ * <p>Note that the behavior of this method is not the same as using
+ * <code>FlexibleStringExpander.getInstance(expression).expandString(context, locale)</code>
+ * because it returns <code>null</code> when given a null <code>expression</code>
+ * argument, and
+ * <code>FlexibleStringExpander.getInstance(expression).expandString(context, locale)</code>
+ * returns an empty <code>String</code>.</p>
+ *
+ * @param expression The original expression
+ * @param context The evaluation context
+ * @param locale The locale to be used for localization
+ * @return The original expression's evaluation result as a <code>String</code>
+ */
+ public static String expandString(String expression, Map<String, ? extends Object> context, Locale locale) {
+ return expandString(expression, context, null, locale);
+ }
+
+ /** Evaluate an expression and return the result as a <code>String</code>.
+ * Null expressions return <code>null</code>.
+ * A null <code>context</code> argument will return the original expression.
+ * <p>Note that the behavior of this method is not the same as using
+ * <code>FlexibleStringExpander.getInstance(expression).expandString(context, timeZone locale)</code>
+ * because it returns <code>null</code> when given a null <code>expression</code>
+ * argument, and
+ * <code>FlexibleStringExpander.getInstance(expression).expandString(context, timeZone, locale)</code>
+ * returns an empty <code>String</code>.</p>
+ *
+ * @param expression The original expression
+ * @param context The evaluation context
+ * @param timeZone The time zone to be used for localization
+ * @param locale The locale to be used for localization
+ * @return The original expression's evaluation result as a <code>String</code>
+ */
+ public static String expandString(String expression, Map<String, ? extends Object> context, TimeZone timeZone, Locale locale) {
+ if (context == null || expression == null || !expression.contains(openBracket)) {
+ return expression;
}
- FlexibleStringExpander fse = FlexibleStringExpander.getInstance(original);
+ FlexibleStringExpander fse = FlexibleStringExpander.getInstance(expression);
return fse.expandString(context, timeZone, locale);
}
- /** Returns a FlexibleStringExpander instance.
- * @param original The original String expression
- * @return A FlexibleStringExpander instance
+ /** Returns a <code>FlexibleStringExpander</code> object. <p>A null or
+ * empty argument will return a <code>FlexibleStringExpander</code>
+ * object that represents an empty expression. That object is a shared
+ * singleton, so there is no memory or performance penalty in using it.</p>
+ * <p>If the method is passed a <code>String</code> argument that doesn't
+ * contain an expression, the <code>FlexibleStringExpander</code> object
+ * that is returned does not perform any evaluations on the original
+ * <code>String</code> - any methods that return a <code>String</code>
+ * will return the original <code>String</code>. The object returned by
+ * this method is very compact - taking less memory than the original
+ * <code>String</code>.</p>
+ *
+ * @param expression The original expression
+ * @return A <code>FlexibleStringExpander</code> instance
*/
- public static FlexibleStringExpander getInstance(String original) {
- if (UtilValidate.isEmpty(original)) {
+ public static FlexibleStringExpander getInstance(String expression) {
+ if (UtilValidate.isEmpty(expression)) {
return nullExpr;
}
// Remove the next three lines to cache all expressions
- if (!original.contains(openBracket)) {
- return new ConstElem(original);
+ if (!expression.contains(openBracket)) {
+ return new ConstElem(expression);
}
- FlexibleStringExpander fse = exprCache.get(original);
+ FlexibleStringExpander fse = exprCache.get(expression);
if (fse == null) {
synchronized (exprCache) {
- FlexibleStringExpander[] strElems = getStrElems(original);
+ FlexibleStringExpander[] strElems = getStrElems(expression);
if (strElems.length == 1) {
fse = strElems[0];
} else {
- fse = new Elements(original, strElems);
+ fse = new Elements(expression, strElems);
}
- exprCache.put(original, fse);
+ exprCache.put(expression, fse);
}
}
return fse;
}
- /** Protected helper method.
- * @param original
- * @return a list of parsed string elements
+ /** Parses an expression and returns an array of <code>FlexibleStringExpander</code>
+ * instances.
+ * @param expression The expression to be parsed
+ * @return An array of <code>FlexibleStringExpander</code>
+ * instances
*/
- protected static FlexibleStringExpander[] getStrElems(String original) {
- if (UtilValidate.isEmpty(original)) {
+ protected static FlexibleStringExpander[] getStrElems(String expression) {
+ if (UtilValidate.isEmpty(expression)) {
return null;
}
- int origLen = original.length();
+ int origLen = expression.length();
ArrayList<FlexibleStringExpander> strElems = new ArrayList<FlexibleStringExpander>();
- int start = original.indexOf(openBracket);
+ int start = expression.indexOf(openBracket);
if (start == -1) {
- strElems.add(new ConstElem(original));
+ strElems.add(new ConstElem(expression));
strElems.trimToSize();
return strElems.toArray(new FlexibleStringExpander[strElems.size()]);
}
int currentInd = 0;
int end = -1;
while (start != -1) {
- end = original.indexOf(closeBracket, start);
+ end = expression.indexOf(closeBracket, start);
if (end == -1) {
- Debug.logWarning("Found a ${ without a closing } (curly-brace) in the String: " + original, module);
+ Debug.logWarning("Found a ${ without a closing } (curly-brace) in the String: " + expression, module);
break;
}
// Check for escaped expression
- boolean escapedExpression = (start - 1 >= 0 && original.charAt(start - 1) == '\\');
+ boolean escapedExpression = (start - 1 >= 0 && expression.charAt(start - 1) == '\\');
if (start > currentInd) {
// append everything from the current index to the start of the expression
- strElems.add(new ConstElem(original.substring(currentInd, escapedExpression ? start -1 : start)));
+ strElems.add(new ConstElem(expression.substring(currentInd, escapedExpression ? start -1 : start)));
}
- if (original.indexOf("bsh:", start + 2) == start + 2 && !escapedExpression) {
+ if (expression.indexOf("bsh:", start + 2) == start + 2 && !escapedExpression) {
// checks to see if this starts with a "bsh:", if so treat the rest of the expression as a bsh scriptlet
- strElems.add(new BshElem(original.substring(start + 6, end)));
- } else if (original.indexOf("groovy:", start + 2) == start + 2 && !escapedExpression) {
+ strElems.add(new BshElem(expression.substring(start + 6, end)));
+ } else if (expression.indexOf("groovy:", start + 2) == start + 2 && !escapedExpression) {
// checks to see if this starts with a "groovy:", if so treat the rest of the expression as a groovy scriptlet
- strElems.add(new GroovyElem(original.substring(start + 9, end)));
+ strElems.add(new GroovyElem(expression.substring(start + 9, end)));
} else {
// Scan for matching closing bracket
- int ptr = original.indexOf(openBracket, start + 2);
+ int ptr = expression.indexOf(openBracket, start + 2);
while (ptr != -1 && end != -1 && ptr < end) {
- end = original.indexOf(closeBracket, end + 1);
- ptr = original.indexOf(openBracket, ptr + 2);
+ end = expression.indexOf(closeBracket, end + 1);
+ ptr = expression.indexOf(openBracket, ptr + 2);
}
if (end == -1) {
end = origLen;
}
- String expression = original.substring(start + 2, end);
+ String subExpression = expression.substring(start + 2, end);
// Evaluation sequence is important - do not change it
if (escapedExpression) {
- strElems.add(new ConstElem(original.substring(start, end + 1)));
- } else if (expression.contains("?currency(")) {
+ strElems.add(new ConstElem(expression.substring(start, end + 1)));
+ } else if (subExpression.contains("?currency(")) {
strElems.add(new CurrElem(expression));
- } else if (expression.contains(openBracket)) {
- strElems.add(new NestedVarElem(expression));
+ } else if (subExpression.contains(openBracket)) {
+ strElems.add(new NestedVarElem(subExpression));
} else {
- strElems.add(new VarElem(expression));
+ strElems.add(new VarElem(subExpression));
}
}
// reset the current index to after the expression, and the start to the beginning of the next expression
@@ -185,18 +223,16 @@
if (currentInd > origLen) {
currentInd = origLen;
}
- start = original.indexOf(openBracket, currentInd);
+ start = expression.indexOf(openBracket, currentInd);
}
// append the rest of the original string, ie after the last expression
if (currentInd < origLen) {
- strElems.add(new ConstElem(original.substring(currentInd)));
+ strElems.add(new ConstElem(expression.substring(currentInd)));
}
- strElems.trimToSize();
return strElems.toArray(new FlexibleStringExpander[strElems.size()]);
}
- // Note: a character array is used instead of a String to
- // keep the memory footprint small.
+ // Note: a character array is used instead of a String to keep the memory footprint small.
protected final char[] orig;
protected int hint = 20;
@@ -204,16 +240,47 @@
this.orig = original.toCharArray();
}
+ /** Appends this object's expression result to <code>buffer</code>.
+ *
+ * @param buffer The buffer to append to
+ * @param context The evaluation context
+ * @param timeZone The time zone to be used for localization
+ * @param locale The locale to be used for localization
+ */
protected abstract void append(StringBuilder buffer, Map<String, ? extends Object> context, TimeZone timeZone, Locale locale);
+ /** Evaluate this object's expression and return the result as a <code>String</code>.
+ * Null or empty expressions return an empty <code>String</code>.
+ * A <code>null context</code> argument will return the original expression.
+ *
+ * @param context The evaluation context
+ * @return This object's expression result as a <code>String</code>
+ */
public String expandString(Map<String, ? extends Object> context) {
return this.expandString(context, null, null);
}
+ /** Evaluate this object's expression and return the result as a <code>String</code>.
+ * Null or empty expressions return an empty <code>String</code>.
+ * A <code>null context</code> argument will return the original expression.
+ *
+ * @param context The evaluation context
+ * @param locale The locale to be used for localization
+ * @return This object's expression result as a <code>String</code>
+ */
public String expandString(Map<String, ? extends Object> context, Locale locale) {
return this.expandString(context, null, locale);
}
+ /** Evaluate this object's expression and return the result as a <code>String</code>.
+ * Null or empty expressions return an empty <code>String</code>.
+ * A <code>null context</code> argument will return the original expression.
+ *
+ * @param context The evaluation context
+ * @param timeZone The time zone to be used for localization
+ * @param locale The locale to be used for localization
+ * @return This object's expression result as a <code>String</code>
+ */
public String expandString(Map<String, ? extends Object> context, TimeZone timeZone, Locale locale) {
if (context == null) {
return this.toString();
@@ -248,19 +315,34 @@
return buffer.toString();
}
+ /** Returns a copy of the original expression.
+ *
+ * @return The original expression
+ */
public String getOriginal() {
return new String(this.orig);
}
+ /** Returns <code>true</code> if the original expression is empty
+ * or <code>null</code>.
+ *
+ * @return <code>true</code> if the original expression is empty
+ * or <code>null</code>
+ */
public boolean isEmpty() {
return this.orig == null || this.orig.length == 0;
}
+ /** Returns a copy of the original expression.
+ *
+ * @return The original expression
+ */
@Override
public String toString() {
return new String(this.orig);
}
+ /** An object that represents a <code>${bsh:}</code> expression. */
protected static class BshElem extends FlexibleStringExpander {
protected BshElem(String original) {
super(original);
@@ -285,6 +367,7 @@
}
}
+ /** An object that represents a <code>String</code> constant portion of an expression. */
protected static class ConstElem extends FlexibleStringExpander {
protected ConstElem(String original) {
super(original);
@@ -299,6 +382,7 @@
}
}
+ /** An object that represents a currency portion of an expression. */
protected static class CurrElem extends FlexibleStringExpander {
protected final char[] valueStr;
protected final FlexibleStringExpander codeExpr;
@@ -326,6 +410,7 @@
}
}
+ /** A container object that contains expression fragments. */
protected static class Elements extends FlexibleStringExpander {
protected final FlexibleStringExpander[] childElems;
protected Elements(String original, FlexibleStringExpander[] childElems) {
@@ -339,6 +424,7 @@
}
}
+ /** An object that represents a <code>${groovy:}</code> expression. */
protected static class GroovyElem extends FlexibleStringExpander {
protected final Class<?> parsedScript;
protected GroovyElem(String script) {
@@ -368,6 +454,7 @@
}
}
+ /** An object that represents a nested expression. */
protected static class NestedVarElem extends FlexibleStringExpander {
protected final FlexibleStringExpander[] childElems;
protected NestedVarElem(String original) {
@@ -400,6 +487,7 @@
}
}
+ /** An object that represents a simple, non-nested expression. */
protected static class VarElem extends FlexibleStringExpander {
protected final char[] bracketedOriginal;
protected VarElem(String original) {