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 2009/05/07 18:30:03 UTC

svn commit: r772699 - in /ofbiz/trunk/framework: base/src/org/ofbiz/base/util/ base/src/org/ofbiz/base/util/string/ widget/src/org/ofbiz/widget/form/

Author: adrianc
Date: Thu May  7 16:30:02 2009
New Revision: 772699

URL: http://svn.apache.org/viewvc?rev=772699&view=rev
Log:
Added XML-friendly operator substitution to BeanShell and Groovy. BeanShell already supported operator substitution, but I extended it to convert apostrophes to quotes.

Modified:
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/GroovyUtil.java
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java
    ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/UelUtil.java
    ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java?rev=772699&r1=772698&r2=772699&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java Thu May  7 16:30:02 2009
@@ -25,9 +25,7 @@
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
-import java.util.Set;
 
 import org.ofbiz.base.location.FlexibleLocation;
 import org.ofbiz.base.util.cache.UtilCache;
@@ -53,6 +51,7 @@
      * Evaluate a BSH condition or expression
      * @param expression The expression to evaluate
      * @param context The context to use in evaluation (re-written)
+     * @see <a href="StringUtil.html#convertOperatorSubstitutions(java.lang.String)">StringUtil.convertOperatorSubstitutions(java.lang.String)</a>
      * @return Object The result of the evaluation
      * @throws EvalError
      */
@@ -62,19 +61,17 @@
             Debug.logError("BSH Evaluation error. Empty expression", module);
             return null;
         }
-
-        if (Debug.verboseOn())
+        if (Debug.verboseOn()) {
             Debug.logVerbose("Evaluating -- " + expression, module);
-        if (Debug.verboseOn())
             Debug.logVerbose("Using Context -- " + context, module);
-
+        }
         try {
             Interpreter bsh = makeInterpreter(context);
             // evaluate the expression
-            o = bsh.eval(expression);
-            if (Debug.verboseOn())
+            o = bsh.eval(StringUtil.convertOperatorSubstitutions(expression));
+            if (Debug.verboseOn()) {
                 Debug.logVerbose("Evaluated to -- " + o, module);
-
+            }
             // read back the context info
             NameSpace ns = bsh.getNameSpace();
             String[] varNames = ns.getVariableNames();

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/GroovyUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/GroovyUtil.java?rev=772699&r1=772698&r2=772699&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/GroovyUtil.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/GroovyUtil.java Thu May  7 16:30:02 2009
@@ -65,6 +65,7 @@
      * Evaluate a Groovy condition or expression
      * @param expression The expression to evaluate
      * @param context The context to use in evaluation (re-written)
+     * @see <a href="StringUtil.html#convertOperatorSubstitutions(java.lang.String)">StringUtil.convertOperatorSubstitutions(java.lang.String)</a>
      * @return Object The result of the evaluation
      * @throws CompilationFailedException
      */
@@ -75,28 +76,23 @@
             Debug.logError("Groovy Evaluation error. Empty expression", module);
             return null;
         }
-
-        if (Debug.verboseOn())
+        if (Debug.verboseOn()) {
             Debug.logVerbose("Evaluating -- " + expression, module);
-        if (Debug.verboseOn())
             Debug.logVerbose("Using Context -- " + context, module);
-
+        }
         try {
             GroovyShell shell = new GroovyShell(getBinding(context));
-            o = shell.evaluate(expression);
-
-            if (Debug.verboseOn())
+            o = shell.evaluate(StringUtil.convertOperatorSubstitutions(expression));
+            if (Debug.verboseOn()) {
                 Debug.logVerbose("Evaluated to -- " + o, module);
-
+            }
             // read back the context info
             Binding binding = shell.getContext();
             context.putAll(binding.getVariables());
-
         } catch (CompilationFailedException e) {
             Debug.logError(e, "Groovy Evaluation error.", module);
             throw e;
         }
-
         return o;
     }
 

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java?rev=772699&r1=772698&r2=772699&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java Thu May  7 16:30:02 2009
@@ -56,6 +56,7 @@
 public class StringUtil {
 
     public static final String module = StringUtil.class.getName();
+    protected static final Map<String, Pattern> substitionPatternMap;
 
     /** OWASP ESAPI canonicalize strict flag; setting false so we only get warnings about double encoding, etc; can be set to true for exceptions and more security */
     public static final boolean esapiCanonicalizeStrict = false;
@@ -66,6 +67,14 @@
         List<Codec> codecList = Arrays.asList(new HTMLEntityCodec(), new PercentCodec());
         defaultWebEncoder = new DefaultEncoder(codecList);
         defaultWebValidator = new DefaultValidator();
+        substitionPatternMap = FastMap.newInstance();
+        substitionPatternMap.put("&&", Pattern.compile("@and", Pattern.LITERAL));
+        substitionPatternMap.put("||", Pattern.compile("@or", Pattern.LITERAL));
+        substitionPatternMap.put("<=", Pattern.compile("@lteq", Pattern.LITERAL));
+        substitionPatternMap.put(">=", Pattern.compile("@gteq", Pattern.LITERAL));
+        substitionPatternMap.put("<", Pattern.compile("@lt", Pattern.LITERAL));
+        substitionPatternMap.put(">", Pattern.compile("@gt", Pattern.LITERAL));
+        substitionPatternMap.put("\"", Pattern.compile("'", Pattern.LITERAL));
     }
 
     public static final SimpleEncoder htmlEncoder = new HtmlEncoder();
@@ -474,6 +483,33 @@
         return outStrBfr.toString();
     }
 
+    /** Converts operator substitutions (@and, @or, etc) back to their original form.
+     * <p>OFBiz script syntax provides special forms of common operators to make
+     * it easier to embed logical expressions in XML:
+     * <table border="1" cellpadding="2">
+     * <tr><td><strong>@and</strong></td><td>&amp;&amp;</td></tr>
+     * <tr><td><strong>@or</strong></td><td>||</td></tr>
+     * <tr><td><strong>@gt</strong></td><td>&gt;</td></tr>
+     * <tr><td><strong>@gteq</strong></td><td>&gt;=</td></tr>
+     * <tr><td><strong>@lt</strong></td><td>&lt;</td></tr>
+     * <tr><td><strong>@lteq</strong></td><td>&lt;=</td></tr>
+     * <tr><td><strong>'</strong></td><td>&quot;</td></tr>
+     * </table></p>
+     * @param expression The <code>String</code> to convert
+     * @return The converted <code>String</code>
+     */
+    public static String convertOperatorSubstitutions(String expression) {
+        String result = expression;
+        if (result != null && result.contains("@")) {
+            Set<String> keys = substitionPatternMap.keySet();
+            for (String replacement : keys) {
+                Pattern pattern = substitionPatternMap.get(replacement);
+                result = pattern.matcher(result).replaceAll(replacement);
+            }
+        }
+        return result;
+    }
+
     /**
      * Uses a black-list approach for necessary characters for HTML.
      * Does not allow various characters (after canonicalization), including "<", ">", "&" (if not followed by a space), and "%" (if not followed by a space).

Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/UelUtil.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/UelUtil.java?rev=772699&r1=772698&r2=772699&view=diff
==============================================================================
--- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/UelUtil.java (original)
+++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/string/UelUtil.java Thu May  7 16:30:02 2009
@@ -27,6 +27,7 @@
 import javolution.util.FastMap;
 
 import org.ofbiz.base.util.Debug;
+import org.ofbiz.base.util.StringUtil;
 import org.ofbiz.base.util.UtilGenerics;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.collections.LocalizedMap;
@@ -368,31 +369,14 @@
 
     /** Prepares an expression for evaluation by UEL.<p>The OFBiz syntax is
      * converted to UEL-compatible syntax and the resulting expression is
-     * returned. OFBiz syntax provides special forms of common operators to make
-     * it easier to embed UEL expressions in XML:
-     * <table border="1" cellpadding="2">
-     * <tr><td><strong>@gt</strong></td><td>&gt;</td></tr>
-     * <tr><td><strong>@lt</strong></td><td>&lt;</td></tr>
-     * <tr><td><strong>@lteq</strong></td><td>&lt;=</td></tr>
-     * <tr><td><strong>@gteq</strong></td><td>&gt;=</td></tr>
-     * <tr><td><strong>@or</strong></td><td>||</td></tr>
-     * <tr><td><strong>@and</strong></td><td>&amp;&amp;</td></tr>
-     * </table></p>
+     * returned.</p>
+     * @see <a href="StringUtil.html#convertOperatorSubstitutions(java.lang.String)">StringUtil.convertOperatorSubstitutions(java.lang.String)</a>
      * @param expression Expression to be converted
      * @return Converted expression
      */
     public static String prepareExpression(String expression) {
-        String result = expression;
+        String result = StringUtil.convertOperatorSubstitutions(expression);
         result = result.replace("[]", "['add']");
-        if (result.contains("@")) {
-            // TODO: create a static Pattern instance and use a Matcher
-            result = result.replace("@or", "||");
-            result = result.replace("@and", "&&");
-            result = result.replace("@lteq", "<=");
-            result = result.replace("@gteq", ">=");
-            result = result.replace("@lt", "<");
-            result = result.replace("@gt", ">");
-        }
         int openBrace = result.indexOf("[+");
         int closeBrace = (openBrace == -1 ? -1 : result.indexOf(']', openBrace));
         if (closeBrace != -1) {

Modified: ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java?rev=772699&r1=772698&r2=772699&view=diff
==============================================================================
--- ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java (original)
+++ ofbiz/trunk/framework/widget/src/org/ofbiz/widget/form/ModelFormField.java Thu May  7 16:30:02 2009
@@ -1131,7 +1131,7 @@
         } else {
             try {
                 Interpreter bsh = this.modelForm.getBshInterpreter(context);
-                Object retVal = bsh.eval(useWhenStr);
+                Object retVal = bsh.eval(StringUtil.convertOperatorSubstitutions(useWhenStr));
                 boolean condTrue = false;
                 // retVal should be a Boolean, if not something weird is up...
                 if (retVal instanceof Boolean) {



Re: svn commit: r772699 - in /ofbiz/trunk/framework: base/src/org/ofbiz/base/util/ base/src/org/ofbiz/base/util/string/ widget/src/org/ofbiz/widget/form/

Posted by Adrian Crum <ad...@hlmksw.com>.
Adam,

Thank you for your review and comments. There might be a more efficient 
way to do this, but this is the best I can come up with. It's an 
improvement over the repeated String replace alls.

-Adrian


Adam Heath wrote:
> adrianc@apache.org wrote:
>> Author: adrianc
>> Date: Thu May  7 16:30:02 2009
>> New Revision: 772699
>>
>> Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java?rev=772699&r1=772698&r2=772699&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java (original)
>> +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java Thu May  7 16:30:02 2009
>> @@ -62,19 +61,17 @@
>>              Debug.logError("BSH Evaluation error. Empty expression", module);
>>              return null;
>>          }
>> -
>> -        if (Debug.verboseOn())
>> +        if (Debug.verboseOn()) {
>>              Debug.logVerbose("Evaluating -- " + expression, module);
>> -        if (Debug.verboseOn())
>>              Debug.logVerbose("Using Context -- " + context, module);
>> -
>> +        }
>>          try {
>>              Interpreter bsh = makeInterpreter(context);
>>              // evaluate the expression
>> -            o = bsh.eval(expression);
>> -            if (Debug.verboseOn())
>> +            o = bsh.eval(StringUtil.convertOperatorSubstitutions(expression));
>> +            if (Debug.verboseOn()) {
>>                  Debug.logVerbose("Evaluated to -- " + o, module);
>> -
>> +            }
>>              // read back the context info
>>              NameSpace ns = bsh.getNameSpace();
>>              String[] varNames = ns.getVariableNames();
> 
> Please try not do do whitespace/formatting changes when altering code
> paths.
> 
>> Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java
>> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java?rev=772699&r1=772698&r2=772699&view=diff
>> ==============================================================================
>> --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java (original)
>> +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java Thu May  7 16:30:02 2009
>> @@ -56,6 +56,7 @@
>>  public class StringUtil {
>>  
>>      public static final String module = StringUtil.class.getName();
>> +    protected static final Map<String, Pattern> substitionPatternMap;
> 
> substitution, you mispelled(sic) the word.
> 
> Additionally, this is not really a map.  It's more a list of
> pattern/replacement pairs.
> 
>>      /** OWASP ESAPI canonicalize strict flag; setting false so we only get warnings about double encoding, etc; can be set to true for exceptions and more security */
>>      public static final boolean esapiCanonicalizeStrict = false;
>> @@ -66,6 +67,14 @@
>>          List<Codec> codecList = Arrays.asList(new HTMLEntityCodec(), new PercentCodec());
>>          defaultWebEncoder = new DefaultEncoder(codecList);
>>          defaultWebValidator = new DefaultValidator();
>> +        substitionPatternMap = FastMap.newInstance();
>> +        substitionPatternMap.put("&&", Pattern.compile("@and", Pattern.LITERAL));
>> +        substitionPatternMap.put("||", Pattern.compile("@or", Pattern.LITERAL));
>> +        substitionPatternMap.put("<=", Pattern.compile("@lteq", Pattern.LITERAL));
>> +        substitionPatternMap.put(">=", Pattern.compile("@gteq", Pattern.LITERAL));
>> +        substitionPatternMap.put("<", Pattern.compile("@lt", Pattern.LITERAL));
>> +        substitionPatternMap.put(">", Pattern.compile("@gt", Pattern.LITERAL));
>> +        substitionPatternMap.put("\"", Pattern.compile("'", Pattern.LITERAL));
>>      }
>>  
>>      public static final SimpleEncoder htmlEncoder = new HtmlEncoder();
>> @@ -474,6 +483,33 @@
>>          return outStrBfr.toString();
>>      }
>>  
>> +    public static String convertOperatorSubstitutions(String expression) {
>> +        String result = expression;
>> +        if (result != null && result.contains("@")) {
>> +            Set<String> keys = substitionPatternMap.keySet();
>> +            for (String replacement : keys) {
> 
> for (Map.Entry<String, Pattern> entry: substitionPatternMap) {
> 
> Don't do a loop, then a separate fetch.  The above is more efficient.
> 
>> +                Pattern pattern = substitionPatternMap.get(replacement);
>> +                result = pattern.matcher(result).replaceAll(replacement);
> 
> There is probably a more efficient way to do this, instead of looping
> over the entire string for each listing pattern/replacement.  Maybe
> combining all the patterns in a (foo|bar) arrangement, looping with
> appendReplacement, then looking up the matched value in the key.  But
> I could be wrong on that.
> 
>> +            }
>> +        }
>> +        return result;
>> +    }
>> +
>>      /**
>>       * Uses a black-list approach for necessary characters for HTML.
>>       * Does not allow various characters (after canonicalization), including "<", ">", "&" (if not followed by a space), and "%" (if not followed by a space).
>>
> 
> 

Re: svn commit: r772699 - in /ofbiz/trunk/framework: base/src/org/ofbiz/base/util/ base/src/org/ofbiz/base/util/string/ widget/src/org/ofbiz/widget/form/

Posted by Adam Heath <do...@brainfood.com>.
adrianc@apache.org wrote:
> Author: adrianc
> Date: Thu May  7 16:30:02 2009
> New Revision: 772699
> 
> Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java?rev=772699&r1=772698&r2=772699&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java (original)
> +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/BshUtil.java Thu May  7 16:30:02 2009
> @@ -62,19 +61,17 @@
>              Debug.logError("BSH Evaluation error. Empty expression", module);
>              return null;
>          }
> -
> -        if (Debug.verboseOn())
> +        if (Debug.verboseOn()) {
>              Debug.logVerbose("Evaluating -- " + expression, module);
> -        if (Debug.verboseOn())
>              Debug.logVerbose("Using Context -- " + context, module);
> -
> +        }
>          try {
>              Interpreter bsh = makeInterpreter(context);
>              // evaluate the expression
> -            o = bsh.eval(expression);
> -            if (Debug.verboseOn())
> +            o = bsh.eval(StringUtil.convertOperatorSubstitutions(expression));
> +            if (Debug.verboseOn()) {
>                  Debug.logVerbose("Evaluated to -- " + o, module);
> -
> +            }
>              // read back the context info
>              NameSpace ns = bsh.getNameSpace();
>              String[] varNames = ns.getVariableNames();

Please try not do do whitespace/formatting changes when altering code
paths.

> Modified: ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java
> URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java?rev=772699&r1=772698&r2=772699&view=diff
> ==============================================================================
> --- ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java (original)
> +++ ofbiz/trunk/framework/base/src/org/ofbiz/base/util/StringUtil.java Thu May  7 16:30:02 2009
> @@ -56,6 +56,7 @@
>  public class StringUtil {
>  
>      public static final String module = StringUtil.class.getName();
> +    protected static final Map<String, Pattern> substitionPatternMap;

substitution, you mispelled(sic) the word.

Additionally, this is not really a map.  It's more a list of
pattern/replacement pairs.

>      /** OWASP ESAPI canonicalize strict flag; setting false so we only get warnings about double encoding, etc; can be set to true for exceptions and more security */
>      public static final boolean esapiCanonicalizeStrict = false;
> @@ -66,6 +67,14 @@
>          List<Codec> codecList = Arrays.asList(new HTMLEntityCodec(), new PercentCodec());
>          defaultWebEncoder = new DefaultEncoder(codecList);
>          defaultWebValidator = new DefaultValidator();
> +        substitionPatternMap = FastMap.newInstance();
> +        substitionPatternMap.put("&&", Pattern.compile("@and", Pattern.LITERAL));
> +        substitionPatternMap.put("||", Pattern.compile("@or", Pattern.LITERAL));
> +        substitionPatternMap.put("<=", Pattern.compile("@lteq", Pattern.LITERAL));
> +        substitionPatternMap.put(">=", Pattern.compile("@gteq", Pattern.LITERAL));
> +        substitionPatternMap.put("<", Pattern.compile("@lt", Pattern.LITERAL));
> +        substitionPatternMap.put(">", Pattern.compile("@gt", Pattern.LITERAL));
> +        substitionPatternMap.put("\"", Pattern.compile("'", Pattern.LITERAL));
>      }
>  
>      public static final SimpleEncoder htmlEncoder = new HtmlEncoder();
> @@ -474,6 +483,33 @@
>          return outStrBfr.toString();
>      }
>  
> +    public static String convertOperatorSubstitutions(String expression) {
> +        String result = expression;
> +        if (result != null && result.contains("@")) {
> +            Set<String> keys = substitionPatternMap.keySet();
> +            for (String replacement : keys) {

for (Map.Entry<String, Pattern> entry: substitionPatternMap) {

Don't do a loop, then a separate fetch.  The above is more efficient.

> +                Pattern pattern = substitionPatternMap.get(replacement);
> +                result = pattern.matcher(result).replaceAll(replacement);

There is probably a more efficient way to do this, instead of looping
over the entire string for each listing pattern/replacement.  Maybe
combining all the patterns in a (foo|bar) arrangement, looping with
appendReplacement, then looking up the matched value in the key.  But
I could be wrong on that.

> +            }
> +        }
> +        return result;
> +    }
> +
>      /**
>       * Uses a black-list approach for necessary characters for HTML.
>       * Does not allow various characters (after canonicalization), including "<", ">", "&" (if not followed by a space), and "%" (if not followed by a space).
>