[jboss-svn-commits] JBL Code SVN: r24039 - in labs/jbossrules/trunk: drools-compiler/src/main/java/org/drools/rule/builder and 4 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Nov 21 12:22:31 EST 2008


Author: tirelli
Date: 2008-11-21 12:22:30 -0500 (Fri, 21 Nov 2008)
New Revision: 24039

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_literal_with_escapes.drl
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MatchesNotMatches.drl
   labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/StringUtils.java
Log:
JBRULES-1858: unquoting strings in DRL files

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java	2008-11-21 17:20:18 UTC (rev 24038)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilderConfiguration.java	2008-11-21 17:22:30 UTC (rev 24039)
@@ -68,6 +68,8 @@
  * drools.accumulate.function.min = org.drools.base.accumulators.MinAccumulateFunction
  * drools.accumulate.function.count = org.drools.base.accumulators.CountAccumulateFunction
  * drools.accumulate.function.sum = org.drools.base.accumulators.SumAccumulateFunction
+ * 
+ * drools.parser.processStringEscapes = true|false
  */
 public class PackageBuilderConfiguration implements KnowledgeBuilderConfiguration {
 
@@ -75,6 +77,8 @@
 
     private static final String        EVALUATOR_DEFINITION_PREFIX = "drools.evaluator.";
 
+    private static final String        DROOLS_PARSER_PROCESS_STRING_ESCAPES = "drools.parser.processStringEscapes";
+
     private Map                        dialectConfigurations;
 
     private String                     defaultDialect;
@@ -94,6 +98,8 @@
     private File                       dumpDirectory;
 
     private boolean					   allowMultipleNamespaces = true;
+    
+    private boolean                    processStringEscapes = true;
 
     public boolean isAllowMultipleNamespaces() {
 		return allowMultipleNamespaces;
@@ -168,6 +174,9 @@
         buildEvaluatorRegistry();
 
         buildDumpDirectory();
+        
+        setProperty( DROOLS_PARSER_PROCESS_STRING_ESCAPES, 
+                     this.chainedProperties.getProperty( DROOLS_PARSER_PROCESS_STRING_ESCAPES, "true" ) );
     }
     
     public void setProperty(String name, String value) {
@@ -180,10 +189,12 @@
             setDefaultDialect( value );    
         } else if ( name.startsWith( "drools.accumulate.function" ) ) {
             addAccumulateFunction( name.substring( name.lastIndexOf( '.' ) ), value );
-        }else if ( name.startsWith( "drools.evaluator." ) ) {
+        } else if ( name.startsWith( "drools.evaluator." ) ) {
             this.evaluatorRegistry.addEvaluatorDefinition( value );
         } else if ( name.equals(  "drools.dump.dir" ) ) {
             buildDumpDirectory( value );
+        } else if ( name.equals(  DROOLS_PARSER_PROCESS_STRING_ESCAPES ) ) {
+            setProcessStringEscapes( Boolean.parseBoolean( value ) );
         }
     }
     
@@ -201,6 +212,8 @@
             return this.evaluatorRegistry.getEvaluatorDefinition( name.substring( name.lastIndexOf( '.' ) ) ).getClass().getName();
         } else if ( name.equals(  "drools.dump.dir" ) ) {
             return Boolean.toString( this.dumpDirectory != null ); 
+        } else if ( name.equals(  DROOLS_PARSER_PROCESS_STRING_ESCAPES ) ) {
+            return String.valueOf( isProcessStringEscapes() );
         }
         return null;
     }
@@ -558,4 +571,14 @@
         this.dumpDirectory = dumpDir;
     }
 
+
+    public boolean isProcessStringEscapes() {
+        return processStringEscapes;
+    }
+
+
+    public void setProcessStringEscapes(boolean processStringEscapes) {
+        this.processStringEscapes = processStringEscapes;
+    }
+
 }
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java	2008-11-21 17:20:18 UTC (rev 24038)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/rule/builder/PatternBuilder.java	2008-11-21 17:22:30 UTC (rev 24039)
@@ -21,6 +21,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
+import java.util.regex.Matcher;
 
 import org.drools.base.ClassObjectType;
 import org.drools.base.FieldFactory;
@@ -80,6 +81,7 @@
 import org.drools.spi.PatternExtractor;
 import org.drools.spi.Restriction;
 import org.drools.spi.Constraint.ConstraintType;
+import org.drools.util.StringUtils;
 import org.mvel2.ParserContext;
 import org.mvel2.compiler.ExpressionCompiler;
 
@@ -767,7 +769,13 @@
                                                 final LiteralRestrictionDescr literalRestrictionDescr) {
         FieldValue field = null;
         try {
-            field = FieldFactory.getFieldValue( literalRestrictionDescr.getValue(),
+            Object value = literalRestrictionDescr.getValue();
+            if( literalRestrictionDescr.getType() == LiteralRestrictionDescr.TYPE_STRING &&
+                context.getConfiguration().isProcessStringEscapes() ) {
+                value = StringUtils.unescapeJava( (String) value );
+            }
+            
+            field = FieldFactory.getFieldValue( value,
                                                 extractor.getValueType() );
         } catch ( final Exception e ) {
             context.getErrors().add( new DescrBuildError( context.getParentDescr(),

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2008-11-21 17:20:18 UTC (rev 24038)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/MiscTest.java	2008-11-21 17:22:30 UTC (rev 24039)
@@ -1167,6 +1167,33 @@
                       ((List) session.getGlobal( "list" )).get( 0 ) );
     }
 
+    public void testLiteralWithEscapes() throws Exception {
+        final PackageBuilder builder = new PackageBuilder();
+        builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_literal_with_escapes.drl" ) ) );
+        final Package pkg = builder.getPackage();
+
+        RuleBase ruleBase = getRuleBase();
+        ruleBase.addPackage( pkg );
+        ruleBase = SerializationHelper.serializeObject( ruleBase );
+        StatefulSession session = ruleBase.newStatefulSession();
+
+        final List list = new ArrayList();
+        session.setGlobal( "list",
+                           list );
+
+        String expected = "s\tti\"lto\nn";
+        final Cheese stilton = new Cheese( expected,
+                                           5 );
+        session.insert( stilton );
+        session = SerializationHelper.getSerialisedStatefulSession( session,
+                                                                    ruleBase );
+
+        session.fireAllRules();
+
+        assertEquals( expected,
+                      ((List) session.getGlobal( "list" )).get( 0 ) );
+    }
+
     public void testLiteralWithBoolean() throws Exception {
         final PackageBuilder builder = new PackageBuilder();
         builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "literal_with_boolean.drl" ) ) );

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java	2008-11-21 17:20:18 UTC (rev 24038)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/lang/RuleParserTest.java	2008-11-21 17:22:30 UTC (rev 24039)
@@ -425,6 +425,18 @@
 		assertNotNull(pattern);
 	}
 
+    public void testRuleParseLhsWithStringQuotes() throws Exception {
+        final String text = "Person( location==\"atlanta\\\"\")\n";
+        PatternDescr pattern = (PatternDescr) parse("lhs_pattern",
+                "lhs_pattern", text);
+        assertNotNull(pattern);
+        
+        FieldConstraintDescr field = (FieldConstraintDescr) pattern.getDescrs().get( 0 ); 
+        assertEquals( "location", field.getFieldName() );
+        System.out.println(field.getRestriction().getRestrictions().get( 0 ).getText());
+        assertEquals( "atlanta\\\"", field.getRestriction().getRestrictions().get( 0 ).getText() );
+    }
+
 	public void testLiteralBoolAndNegativeNumbersRule() throws Exception {
 		final RuleDescr rule = (RuleDescr) parseResource("rule", "rule",
 				"literal_bool_and_negative.drl");

Modified: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MatchesNotMatches.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MatchesNotMatches.drl	2008-11-21 17:20:18 UTC (rev 24038)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_MatchesNotMatches.drl	2008-11-21 17:22:30 UTC (rev 24039)
@@ -14,7 +14,7 @@
 
 rule "Cheese not matches"
     when
-        brie : Cheese( type not matches "(stil.*|mu\w*|brie\d|aged.*|.*prov.*)" )
+        brie : Cheese( type not matches "(stil.*|mu\\w*|brie\\d|aged.*|.*prov.*)" )
     then
 		list.add( brie );
 end   
@@ -30,7 +30,7 @@
 rule "Cheese matches with ^ and escaped s"
 	salience -20
     when
-        prov : Cheese( type matches "^provolone\s*" )
+        prov : Cheese( type matches "^provolone\\s*" )
     then
 		list.add( prov );
 end   

Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_literal_with_escapes.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_literal_with_escapes.drl	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_literal_with_escapes.drl	2008-11-21 17:22:30 UTC (rev 24039)
@@ -0,0 +1,12 @@
+package org.drools.test;
+
+import org.drools.Cheese;
+
+global java.util.List list;
+
+rule "literal test rule"
+    when
+        Cheese( $x: type == "s\tti\"lto\nn" )
+    then
+		list.add( $x );        
+end    
\ No newline at end of file

Modified: labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/StringUtils.java
===================================================================
--- labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/StringUtils.java	2008-11-21 17:20:18 UTC (rev 24038)
+++ labs/jbossrules/trunk/drools-core/src/main/java/org/drools/util/StringUtils.java	2008-11-21 17:22:30 UTC (rev 24039)
@@ -19,6 +19,8 @@
 
 import java.io.IOException;
 import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -771,4 +773,128 @@
             throw new RuntimeException( e );
         }
     }
+    
+    /**
+     * <p>Unescapes any Java literals found in the <code>String</code>.
+     * For example, it will turn a sequence of <code>'\'</code> and
+     * <code>'n'</code> into a newline character, unless the <code>'\'</code>
+     * is preceded by another <code>'\'</code>.</p>
+     * 
+     * @param str  the <code>String</code> to unescape, may be null
+     * @return a new unescaped <code>String</code>, <code>null</code> if null string input
+     */
+    public static String unescapeJava(String str) {
+        if (str == null) {
+            return null;
+        }
+        try {
+            StringWriter writer = new StringWriter(str.length());
+            unescapeJava(writer, str);
+            return writer.toString();
+        } catch (IOException ioe) {
+            // this should never ever happen while writing to a StringWriter
+            throw new RuntimeException(ioe);
+        }
+    }
+
+    /**
+     * <p>Unescapes any Java literals found in the <code>String</code> to a
+     * <code>Writer</code>.</p>
+     *
+     * <p>For example, it will turn a sequence of <code>'\'</code> and
+     * <code>'n'</code> into a newline character, unless the <code>'\'</code>
+     * is preceded by another <code>'\'</code>.</p>
+     * 
+     * <p>A <code>null</code> string input has no effect.</p>
+     * 
+     * @param out  the <code>Writer</code> used to output unescaped characters
+     * @param str  the <code>String</code> to unescape, may be null
+     * @throws IllegalArgumentException if the Writer is <code>null</code>
+     * @throws IOException if error occurs on underlying Writer
+     */
+    public static void unescapeJava(Writer out, String str) throws IOException {
+        if (out == null) {
+            throw new IllegalArgumentException("The Writer must not be null");
+        }
+        if (str == null) {
+            return;
+        }
+        int sz = str.length();
+        StringBuffer unicode = new StringBuffer(4);
+        boolean hadSlash = false;
+        boolean inUnicode = false;
+        for (int i = 0; i < sz; i++) {
+            char ch = str.charAt(i);
+            if (inUnicode) {
+                // if in unicode, then we're reading unicode
+                // values in somehow
+                unicode.append(ch);
+                if (unicode.length() == 4) {
+                    // unicode now contains the four hex digits
+                    // which represents our unicode character
+                    try {
+                        int value = Integer.parseInt(unicode.toString(), 16);
+                        out.write((char) value);
+                        unicode.setLength(0);
+                        inUnicode = false;
+                        hadSlash = false;
+                    } catch (NumberFormatException nfe) {
+                        throw new RuntimeException("Unable to parse unicode value: " + unicode, nfe);
+                    }
+                }
+                continue;
+            }
+            if (hadSlash) {
+                // handle an escaped value
+                hadSlash = false;
+                switch (ch) {
+                    case '\\':
+                        out.write('\\');
+                        break;
+                    case '\'':
+                        out.write('\'');
+                        break;
+                    case '\"':
+                        out.write('"');
+                        break;
+                    case 'r':
+                        out.write('\r');
+                        break;
+                    case 'f':
+                        out.write('\f');
+                        break;
+                    case 't':
+                        out.write('\t');
+                        break;
+                    case 'n':
+                        out.write('\n');
+                        break;
+                    case 'b':
+                        out.write('\b');
+                        break;
+                    case 'u':
+                        {
+                            // uh-oh, we're in unicode country....
+                            inUnicode = true;
+                            break;
+                        }
+                    default :
+                        out.write(ch);
+                        break;
+                }
+                continue;
+            } else if (ch == '\\') {
+                hadSlash = true;
+                continue;
+            }
+            out.write(ch);
+        }
+        if (hadSlash) {
+            // then we're in the weird case of a \ at the end of the
+            // string, let's output it anyway.
+            out.write('\\');
+        }
+    }
+    
+    
 }
\ No newline at end of file




More information about the jboss-svn-commits mailing list