[rules-users] Map errors and quirks

zstlaw zstlawre at akamai.com
Fri Oct 7 17:07:03 EDT 2011


I have a large pool of errors I would like help with but I am breaking them
up by topic since they are so different in nature.  I have made fairly
simple examples to start.

Environment : Using drools 5.2.0.Final on Linux using the openjdk 6 JDK.  

First are some bugs in Map access when using a local variable or a object
variable as key.  This is a very simple case which gets more complicated in
my next example in this email.  The rule file will not compile despite
appearing logically valid to me.

/* simple example class */
package com.sample;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class Mailbox {
	static public final String TEST_EMAIL = "me at test.com";
	public Map<String, Date> recentContacts = new HashMap<String,
Date>();
	public Mailbox() {
		owneremail = TEST_EMAIL;
		
		// create contact for self
		recentContacts.put(owneremail, new Date());
	}

	public Map<String, Date> getRecentContacts() {
		return recentContacts;
	}
}

/* simple rule file */
// this rule is nonsensical but attempts hashmap access via many means to
find out why
// behavior was inconsistant.  Each commented line will cause file to not
compile when uncommented.
// the uncommented lines are present to show what does work.
package com.sample
import java.util.Date;
import java.util.Map;
import com.sample.Mailbox;
rule "check recentContacts hash mvel"
dialect "mvel"
    when
        $m : Mailbox( 
        		// Each commented line will result in the file no longer compiling
if uncommented
			$me : owneremail,
			recentContacts[Mailbox.TEST_EMAIL] != null,
			recentContacts["me at test.com"] != null,
//			recentContacts[owneremail] != null, // HAS ERROR because it checks
HashMap for owneremail
			recentContacts[$me] != null,
			$d1 : recentContacts[Mailbox.TEST_EMAIL],
			$d2 : recentContacts["me at test.com"],
//			$d3 : recentContacts[$me], // HAS ERROR only when doing variable
assignment
			recentContacts.get(owneremail) != null,
			recentContacts.get($me) != null,
//			$d4: recentContacts.get($me), // HAS ERROR only if doing variable
assignment
			$d5 : getRecentContacts(),
			$d6 : getRecentContacts().size,
			0 < 1
        )
    then
        System.out.println( "recentContacts were accessible" );
end



Any suggestions?  Not being able to access objects in a hash is problematic. 
And it gets worse if objects are not base java classes as I find even static
enums getting handled erratically when used as keys.  Some time I need to
use the full name but using a method I can use different expression and have
it work.  Moving to next problem now this is my real problem.  Please note
that I was not initially usign an inner static enum but moved it there to
make example a single file.

/* more complicated version of class */
package com.sample;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Mailbox {
        // taken straight form example code
	static public class Message {
	    public static final int HELLO = 0;
	    public static final int GOODBYE = 1;

	    private String message;
	    private int status;

	    public String getMessage() {
	        return this.message;
	    }

	    public void setMessage(String message) {
	        this.message = message;
	    }

	    public int getStatus() {
	        return this.status;
	    }

	    public void setStatus(int status) {
	        this.status = status;
	    }
	}

	static public enum FolderType {INBOX, SENT, TRASH};
	static public final String TEST_EMAIL = "me at test.com";

	private Map&lt;FolderType, List&lt;Message&gt;> folders = new
HashMap&lt;FolderType, List&lt;Message&gt;>();
	public Map&lt;String, Date&gt; recentContacts = new HashMap&lt;String,
Date&gt;();
	private String owneremail;

	public Mailbox(String username) {
		owneremail = username;
		
		// create contact for self
		recentContacts.put(owneremail, new Date());
		
		// create default folders
		folders.put(FolderType.SENT, new ArrayList<Message>());
		folders.put(FolderType.TRASH, new ArrayList<Message>());
		folders.put(FolderType.INBOX, new ArrayList<Message>());
	}

	/** parameterized accessor */
	public List<Message> getFolder(FolderType t) {
		return folders.get(t);
	}

	public Map&lt;FolderType, List&lt;Message&gt;> getFolders() {
		return folders;
	}

	public Map&lt;String, Date&gt; getRecentContacts() {
		return recentContacts;
	}

	public String getOwneremail() {
		return owneremail;
	}
}

/* more complicated rule */
package com.sample
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.sample.Mailbox;
import com.sample.Mailbox.FolderType;
import com.sample.Mailbox.Message;


rule "check folders hash mvel"
dialect "mvel"
    when
        $m : Mailbox( 
			// Each commented line will result in the file no longer compiling
			$type1 : FolderType.INBOX,
			$type2 : com.sample.Mailbox$FolderType.INBOX,
			$work1 : getFolder(null),
			$work2 : getFolder(com.sample.Mailbox$FolderType.INBOX),
			$work3 : getFolder(com.sample.Mailbox$FolderType.INBOX).size,
//        		getFolder(FolderType.INBOX), // HAS ERROR - unable to resolve
using strict mode
			getFolder($type1) != null,
//        		$err1 : getFolder($type1), // again HAS ERROR only when doing
variable assignment
			getFolder($type2) != null,
//        		$err2 : getFolder($type2), // again HAS ERROR only when doing
variable assignment
			getFolder($type1).size() > 0,
			getFolder($type1).isEmpty(),
//        		$err3 : folders[FolderType.INBOX], // HAS ERROR
//        		$err4 : folders[com.sample.Mailbox.FolderType.INBOX], // HAS
ERROR - bad path syntax obviously
//        		$err5 : folders[com.sample.Mailbox$FolderType.INBOX], // HAS
ERROR
//        		folders[$type1]!=null, // HAS ERROR
//        		folders[$type2]!=null, // HAS ERROR
			$work6 : folders,
			$work7 : folders.size,
			folders.containsKey(com.sample.Mailbox$FolderType.INBOX),
			folders.containsKey($type2),
			!folders.isEmpty,
//        		$err6: folders.size(),  // HAS ERROR
//        		$err7: folders.isEmpty(),  // HAS ERROR
//        		folders.get(FolderType.INBOX)!=null, // HAS ERROR
//         		folders.get(com.sample.Mailbox.FolderType.INBOX)!=null, // HAS
ERROR - bad path syntax obviously
//        		folders.get(com.sample.Mailbox$FolderType.INBOX)!=null, // HAS
ERROR
//        		folders.get($type1)!=null, // HAS ERROR
//        		folders.get($type2)!=null, // HAS ERROR
			$work8 : getFolders(),
			$work9 : getFolders().size,
//        		getFolders().size(), // HAS ERROR
			0 < 1
        )
    then
        System.out.println( "folders were accessible" );
end

Now you can see my real problem.  Dealing with a hash of enum to other
object I get a lot of odd behavior on hash keying depending on how I make
each call and while I really need to store the result to do many comparisons
I can not unless I hardcode the parameter by which I am accessing the data
which would profoundly weaken the rules I am writing.

While I could register every object in the hash the problem then becomes the
profusion of meta objects and the management of them especially given the
memory leaks not fixed until 5.3.Final is released.

Thank you for any assistance!

--
View this message in context: http://drools.46999.n3.nabble.com/Map-errors-and-quirks-tp3404106p3404106.html
Sent from the Drools: User forum mailing list archive at Nabble.com.



More information about the rules-users mailing list