[jboss-svn-commits] JBL Code SVN: r15396 - in labs/jbossrules/trunk/drools-compiler/src: main/java/org/drools/brms/client/modeldriven/brl and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Thu Sep 27 04:06:00 EDT 2007


Author: michael.neale at jboss.com
Date: 2007-09-27 04:06:00 -0400 (Thu, 27 Sep 2007)
New Revision: 15396

Added:
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngineTest.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/SampleDataSource2.java
Modified:
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/brl/CompositeFieldConstraint.java
   labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/server/util/DataEnumLoader.java
   labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/DataEnumLoaderTest.java
Log:
JBRULES-1228

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java	2007-09-27 06:01:34 UTC (rev 15395)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngine.java	2007-09-27 08:06:00 UTC (rev 15396)
@@ -6,7 +6,10 @@
 import java.util.Set;
 
 import org.drools.brms.client.modeldriven.brl.DSLSentence;
+import org.drools.brms.client.modeldriven.brl.FactPattern;
+import org.drools.brms.client.modeldriven.brl.FieldConstraint;
 import org.drools.brms.client.modeldriven.brl.PortableObject;
+import org.drools.brms.client.modeldriven.brl.SingleFieldConstraint;
 
 /**
  * An suggestion completion processor. This should be usable in both GWT/Web and the IDE.
@@ -98,6 +101,11 @@
     public DSLSentence[]          conditionDSLSentences  = new DSLSentence[0];
     public DSLSentence[]          actionDSLSentences     = new DSLSentence[0];
 
+    /**
+     * This is used to calculate what fields an enum list may depend on. Optional.
+     */
+	private transient Map dataEnumLookupFields;
+
     //    /**
     //     * For bulk loading up the data (from a previous rule save)
     //     *
@@ -224,4 +232,53 @@
         return toStringArray( this.globalTypes.keySet() );
     }
 
+    /**
+     * This returns a list of enums options (values) that can be used
+     * for the given field of the given FactPattern.
+     *
+     * This also takes into account enums that depend on other fields.
+     *
+     */
+	public String[] getEnums(FactPattern pat, String field) {
+
+		Map dataEnumLookupFields = loadDataEnumLookupFields();
+		String typeField = (String) dataEnumLookupFields.get(pat.factType + "." + field );
+
+		if (pat.constraintList != null && pat.constraintList.constraints != null) {
+			FieldConstraint[] cons = pat.constraintList.constraints;
+			for (int i = 0; i < cons.length; i++) {
+				FieldConstraint con = cons[i];
+				if (con instanceof SingleFieldConstraint) {
+					SingleFieldConstraint sfc = (SingleFieldConstraint) con;
+					if ( sfc.fieldName.equals(typeField)) {
+						String key = pat.factType + "." + field + "[" + typeField + "=" + sfc.value + "]";
+						return (String[]) this.dataEnumLists.get(key);
+					}
+				}
+			}
+		}
+
+
+		return (String[]) this.dataEnumLists.get(pat.factType + "." + field);
+	}
+
+	private Map loadDataEnumLookupFields() {
+		if (this.dataEnumLookupFields == null) {
+			this.dataEnumLookupFields = new HashMap();
+		}
+
+		Set keys = this.dataEnumLists.keySet();
+		for (Iterator iter = keys.iterator(); iter.hasNext();) {
+			String key = (String) iter.next();
+			if (key.indexOf('[') != -1) {
+				int ix = key.indexOf('[');
+				String factField = key.substring(0, ix);
+				String predicate = key.substring(ix + 1, key.indexOf(']'));
+				String typeField = predicate.substring(0, predicate.indexOf('='));
+				dataEnumLookupFields.put(factField, typeField);
+			}
+		}
+		return dataEnumLookupFields;
+	}
+
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/brl/CompositeFieldConstraint.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/brl/CompositeFieldConstraint.java	2007-09-27 06:01:34 UTC (rev 15395)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/client/modeldriven/brl/CompositeFieldConstraint.java	2007-09-27 08:06:00 UTC (rev 15396)
@@ -2,40 +2,42 @@
 
 /**
  * This is a field constraint that may span multiple fields.
- * 
+ *
  * @author Michael Neale
  */
 public class CompositeFieldConstraint implements FieldConstraint {
 
-    
+
     /**
      * Means that any of the children can resolve to be true.
      */
     public static final String COMPOSITE_TYPE_OR = "||";
-    
+
     /**
      * Means that ALL of the children constraints must resolve to be true.
      */
     public static final String COMPOSITE_TYPE_AND = "&&";
-    
-    
+
+
     /**
-     * The type of composite that it is. 
+     * The type of composite that it is.
      */
     public String compositeJunctionType = null;
-    
-    
+
+
     /**
      * This is the child field constraints of the composite.
      * They may be single constraints, or composite themselves.
-     * If this composite is it at the "top level"  - then 
-     * there is no need to look at the compositeType property 
+     * If this composite is it at the "top level"  - then
+     * there is no need to look at the compositeType property
      * (as they are all children that are "anded" together anyway in the fact
      * pattern that contains it).
      */
     public FieldConstraint[] constraints = null;
-    
-    
+
+    //Note this is a bit ugly, GWT had some early limitations which required this to kind of work this way.
+    //when generics are available, could probably switch to it, but remember this is persistent stuff
+    //so don't want to break backwards compat (as XStream is used)
     public void addConstraint(final FieldConstraint constraint) {
         if ( this.constraints == null ) {
             this.constraints = new FieldConstraint[1];
@@ -51,9 +53,9 @@
     }
 
     public void removeConstraint(final int idx) {
-        //Unfortunately, this is kinda duplicate code with other methods, 
-        //but with typed arrays, and GWT, its not really possible to do anything "better" 
-        //at this point in time. 
+        //Unfortunately, this is kinda duplicate code with other methods,
+        //but with typed arrays, and GWT, its not really possible to do anything "better"
+        //at this point in time.
         final FieldConstraint[] newList = new FieldConstraint[this.constraints.length - 1];
         int newIdx = 0;
         for ( int i = 0; i < this.constraints.length; i++ ) {
@@ -67,6 +69,6 @@
         this.constraints = newList;
 
     }
-    
-    
+
+
 }

Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/server/util/DataEnumLoader.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/server/util/DataEnumLoader.java	2007-09-27 06:01:34 UTC (rev 15395)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/brms/server/util/DataEnumLoader.java	2007-09-27 08:06:00 UTC (rev 15396)
@@ -31,10 +31,13 @@
         if (mvelSource == null || (mvelSource.trim().equals( "" ))) {
             return Collections.EMPTY_MAP;
         }
-        mvelSource = addCommasForNewLines(mvelSource);
+        if (mvelSource.startsWith("=")) {
+        	mvelSource = mvelSource.substring(1);
+        } else {
+        	mvelSource = "[ " + addCommasForNewLines(mvelSource) + " ]";
+        }
 		final Object mvelData;
 		try {
-		    mvelSource = "[ " + mvelSource + " ]";
 			mvelData = MVEL.eval(mvelSource, new HashMap());
 		} catch (RuntimeException e) {
 			addError("Unable to load enumeration data.");

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngineTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngineTest.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngineTest.java	2007-09-27 08:06:00 UTC (rev 15396)
@@ -0,0 +1,308 @@
+package org.drools.brms.client.modeldriven;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.drools.brms.client.modeldriven.brl.FactPattern;
+import org.drools.brms.client.modeldriven.brl.SingleFieldConstraint;
+import org.drools.brms.server.rules.SuggestionCompletionLoader;
+
+public class SuggestionCompletionEngineTest extends TestCase {
+
+    public void testNestedImports() {
+        String pkg = "package org.test\n import org.drools.brms.client.modeldriven.SuggestionCompletionEngineTest.NestedClass";
+
+        SuggestionCompletionLoader loader = new SuggestionCompletionLoader();
+        SuggestionCompletionEngine engine = loader.getSuggestionEngine( pkg, new ArrayList(), new ArrayList() );
+
+        assertEquals( "String", engine.getFieldType( "SuggestionCompletionEngineTest$NestedClass", "name" ) );
+    }
+
+    public void testStringNonNumeric() {
+        String pkg = "package org.test\n import org.drools.brms.client.modeldriven.Alert";
+
+        SuggestionCompletionLoader loader = new SuggestionCompletionLoader();
+        SuggestionCompletionEngine engine = loader.getSuggestionEngine( pkg, new ArrayList(), new ArrayList() );
+
+        assertEquals( SuggestionCompletionEngine.TYPE_STRING, engine.getFieldType( "Alert", "message" ) );
+
+    }
+
+    public void testDataEnums() {
+        String pkg = "package org.test\n import org.drools.brms.client.modeldriven.SuggestionCompletionEngineTest.NestedClass";
+
+        SuggestionCompletionLoader loader = new SuggestionCompletionLoader();
+
+        List enums = new ArrayList();
+
+        enums.add( "'Person.age' : [42, 43] \n 'Person.sex' : ['M', 'F']");
+        enums.add( "'Driver.sex' : ['M', 'F']" );
+
+
+        SuggestionCompletionEngine engine = loader.getSuggestionEngine( pkg, new ArrayList(), new ArrayList() , enums);
+        assertEquals( "String", engine.getFieldType( "SuggestionCompletionEngineTest$NestedClass", "name" ) );
+
+        assertEquals(3, engine.dataEnumLists.size());
+        String[] items = (String[]) engine.dataEnumLists.get( "Person.age" );
+        assertEquals(2, items.length);
+        assertEquals("42", items[0]);
+        assertEquals("43", items[1]);
+
+        items = engine.getEnums(new FactPattern("Person"), "age");
+        assertEquals(2, items.length);
+        assertEquals("42", items[0]);
+        assertEquals("43", items[1]);
+
+        items = engine.getEnums(new FactPattern("Nothing"), "age");
+        assertNull(items);
+
+
+    }
+
+    public void testCompletions() {
+
+        final SuggestionCompletionEngine com = new SuggestionCompletionEngine();
+
+        com.factTypes = new String[]{"Person", "Vehicle"};
+        com.fieldsForType = new HashMap() {
+            {
+                put( "Person",
+                     new String[]{"age", "name", "rank"} );
+                put( "Vehicle",
+                     new String[]{"type", "make"} );
+            }
+        };
+        com.fieldTypes = new HashMap() {
+            {
+                put( "Person.age",
+                     "Numeric" );
+                put( "Person.rank",
+                     "Comparable" );
+                put( "Person.name",
+                     "String" );
+                put( "Vehicle.make",
+                     "String" );
+                put( "Vehicle.type",
+                     "String" );
+            }
+        };
+        com.globalTypes = new HashMap() {
+            {
+                put( "bar",
+                     "Person" );
+                put( "baz",
+                     "Vehicle" );
+            }
+        };
+
+        String[] c = com.getConditionalElements();
+        assertEquals( "not",
+                      c[0] );
+        assertEquals( "exists",
+                      c[1] );
+        assertEquals( "or",
+                      c[2] );
+
+        c = com.getFactTypes();
+        assertEquals( 2,
+                      c.length );
+        assertContains( "Person",
+                        c );
+        assertContains( "Vehicle",
+                        c );
+
+        c = com.getFieldCompletions( "Person" );
+        assertEquals( "age",
+                      c[0] );
+        assertEquals( "name",
+                      c[1] );
+
+        c = com.getFieldCompletions( "Vehicle" );
+        assertEquals( "type",
+                      c[0] );
+        assertEquals( "make",
+                      c[1] );
+
+        c = com.getOperatorCompletions( "Person",
+                                        "name" );
+        assertEquals( 4,
+                      c.length );
+        assertEquals( "==",
+                      c[0] );
+        assertEquals( "!=",
+                      c[1] );
+        assertEquals( "matches",
+                      c[2] );
+
+        c = com.getOperatorCompletions( "Person",
+                                        "age" );
+        assertEquals( 6,
+                      c.length );
+        assertEquals( c[0],
+                      "==" );
+        assertEquals( c[1],
+                      "!=" );
+        assertEquals( c[2],
+                      "<" );
+        assertEquals( c[3],
+                      ">" );
+
+        c = com.getOperatorCompletions( "Person",
+                                        "rank" );
+        assertEquals( 6,
+                      c.length );
+        assertEquals( c[0],
+                      "==" );
+        assertEquals( c[1],
+                      "!=" );
+        assertEquals( c[2],
+                      "<" );
+        assertEquals( c[3],
+                      ">" );
+
+        c = com.getConnectiveOperatorCompletions( "Vehicle",
+                                                  "make" );
+        assertEquals( 5,
+                      c.length );
+        assertEquals( "|| ==",
+                      c[0] );
+
+        c = com.getGlobalVariables();
+        assertEquals( 2,
+                      c.length );
+        assertEquals( "baz",
+                      c[0] );
+        assertEquals( "bar",
+                      c[1] );
+
+        c = com.getFieldCompletionsForGlobalVariable( "bar" );
+        assertEquals( 3,
+                      c.length );
+        assertEquals( "age",
+                      c[0] );
+        assertEquals( "name",
+                      c[1] );
+
+        c = com.getFieldCompletionsForGlobalVariable( "baz" );
+        assertEquals( 2,
+                      c.length );
+        assertEquals( "type",
+                      c[0] );
+        assertEquals( "make",
+                      c[1] );
+
+        //check that it has default operators for general objects
+        c = com.getOperatorCompletions( "Person",
+                                        "wankle" );
+        assertEquals( 2,
+                      c.length );
+
+        assertEquals("Numeric", com.getFieldType( "Person", "age" ));
+
+    }
+
+    public void testAdd() {
+        final SuggestionCompletionEngine com = new SuggestionCompletionEngine();
+        com.factTypes = new String[]{"Foo"};
+        com.fieldsForType = new HashMap() {
+            {
+                put( "Foo",
+                     new String[]{"a"} );
+            }
+        };
+
+        assertEquals( 1,
+                      com.getFactTypes().length );
+        assertEquals( "Foo",
+                      com.getFactTypes()[0] );
+
+        assertEquals( 1,
+                      com.getFieldCompletions( "Foo" ).length );
+        assertEquals( "a",
+                      com.getFieldCompletions( "Foo" )[0] );
+
+    }
+
+    public void testSmartEnums() {
+    	final SuggestionCompletionEngine sce = new SuggestionCompletionEngine();
+    	sce.dataEnumLists = new HashMap();
+    	sce.dataEnumLists.put("Fact.type", new String[] {"sex", "colour"});
+    	sce.dataEnumLists.put("Fact.value[type=sex]", new String[] {"M", "F"});
+    	sce.dataEnumLists.put("Fact.value[type=colour]", new String[] {"RED", "WHITE", "BLUE"});
+
+    	FactPattern pat = new FactPattern("Fact");
+    	SingleFieldConstraint sfc = new SingleFieldConstraint("type");
+    	sfc.value = "sex";
+    	pat.addConstraint(sfc);
+    	String[] result = sce.getEnums(pat, "value");
+    	assertEquals(2, result.length);
+    	assertEquals("M", result[0]);
+    	assertEquals("F", result[1]);
+
+
+    	pat = new FactPattern("Fact");
+    	sfc = new SingleFieldConstraint("type");
+    	sfc.value = "colour";
+    	pat.addConstraint(sfc);
+
+    	result = sce.getEnums(pat, "value");
+    	assertEquals(3, result.length);
+    	assertEquals("RED", result[0]);
+    	assertEquals("WHITE", result[1]);
+    	assertEquals("BLUE", result[2]);
+
+    	result = sce.getEnums(pat, "type");
+    	assertEquals(2, result.length);
+    	assertEquals("sex", result[0]);
+    	assertEquals("colour", result[1]);
+
+
+    }
+
+    private void assertContains(final String string,
+                                final String[] c) {
+
+        for ( int i = 0; i < c.length; i++ ) {
+            if ( string.equals( c[i] ) ) {
+                return;
+            }
+        }
+        fail( "String array did not contain: " + string );
+
+    }
+
+    public void testGlobalAndFacts() {
+        final SuggestionCompletionEngine com = new SuggestionCompletionEngine();
+
+        com.globalTypes = new HashMap() {
+            {
+                put( "y",
+                     "Foo" );
+            }
+        };
+        com.fieldsForType = new HashMap() {
+            {
+                put( "Foo",
+                     new String[]{"a"} );
+            }
+        };
+
+        assertFalse( com.isGlobalVariable( "x" ) );
+        assertTrue( com.isGlobalVariable( "y" ) );
+    }
+
+    public static class NestedClass {
+        private String name;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+    }
+}


Property changes on: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/client/modeldriven/SuggestionCompletionEngineTest.java
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/DataEnumLoaderTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/DataEnumLoaderTest.java	2007-09-27 06:01:34 UTC (rev 15395)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/DataEnumLoaderTest.java	2007-09-27 08:06:00 UTC (rev 15396)
@@ -70,7 +70,21 @@
 
     }
 
+    public void testLiteralHelperUtilityClass() {
+    	//this shows how you can load it up with a class (which should return a map of keys to List.
+    	DataEnumLoader loader = new DataEnumLoader("=(new org.drools.brms.modeldriven.SampleDataSource2()).loadData()");
 
+    	assertFalse(loader.hasErrors());
+
+        assertEquals(1, loader.getData().size());
+        String[] res = (String[]) loader.getData().get("whee");
+    	assertEquals(2, res.length);
+    	assertEquals("hey", res[0]);
+    	assertEquals("ho", res[1]);
+
+    }
+
+
     public void testNewLines() {
         String s = "yeah yeah, \nyeah \nyeah";
         assertEquals("yeah yeah,\nyeah,\nyeah", DataEnumLoader.addCommasForNewLines( s ));

Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/SampleDataSource2.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/SampleDataSource2.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/SampleDataSource2.java	2007-09-27 08:06:00 UTC (rev 15396)
@@ -0,0 +1,21 @@
+package org.drools.brms.modeldriven;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class SampleDataSource2 {
+
+	public Map loadData() {
+		Map data = new HashMap();
+
+		List d = new ArrayList();
+		d.add("hey");
+		d.add("ho");
+		data.put("whee", d);
+
+		return data;
+	}
+
+}


Property changes on: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/brms/modeldriven/SampleDataSource2.java
___________________________________________________________________
Name: svn:eol-style
   + native




More information about the jboss-svn-commits mailing list