On 6 July 2011 16:37, Mark Proctor <span dir="ltr"><<a href="mailto:mproctor@codehaus.org">mproctor@codehaus.org</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<a href="http://blog.athico.com/2011/07/traits-duck-typing-and-dynamic-semantic.html" target="_blank">http://blog.athico.com/2011/07/traits-duck-typing-and-dynamic-semantic.html</a><br></blockquote><div><br>Duck typing is available in Java, and therefore it can be used in Drools even today, although without the syntactic sugar described by Mark. Nevertheless, a purely Java-based implementation helps to understand issues and develop a feeling about the usefulness of the proposed feature. <br>
<br>Here are the Java classes a user might write, using class TripleSet as provided by the support for duck typing:<br><br>public class Person extends TripleSet {<br> String name;<br> int age;<br> Gender gender; // enum Gender { MALE, FEMALE }<br>
}<br><br>public interface EatingHabits {<br> String getLikes();<br> void setLikes( String value );<br> String getDislikes();<br> void setDislikes( String value );<br>}<br><br>public interface FussyEater {<br>}<br>
<br>Class SessionManager which wraps a StatefulKnowledgeSession provides a little "glue" for performing "dons" in various forms. It should also be available as a global.<br><br>public class SessionManager {<br>
public SessionManager( StatefulKnowledgeSession kSession ){...}<br> public FactHandle insert( Object object ){...}<br> public Object dons( TripleSet tripleSet, Class<?>... interfaces ){...} <br> public FactHandle insert( TripleSet tripleSet, Class... interfaces ){...}<br>
public void insertLogical( RuleContext rContext, TripleSet tripleSet, Class... interfaces ){...}<br>}<br><br>We can insert a Person and don it with EatingHabits:<br><br> Person p1 = new Person( "John", 12, Gender.MALE );<br>
EatingHabits ehp1 = (EatingHabits)sessionMgr.dons( p1, EatingHabits.class );<br> ehp1.setLikes( "cheese" );<br> ehp1.setDislikes( "spinach" );<br> sessionMgr.insert( p1 ); <br> sessionMgr.insert( ehp1 ); <br>
<br>And here is some DRL code, followed by the resulting output:<br><br>function String isa( Object object, java.lang.Class clazz ){<br> return object.toString() +<br> (clazz.isInstance( object ) ? " implements " : " doesn't implement " ) +<br>
clazz.getSimpleName();<br>}<br><br>rule showPerson<br>salience 100<br>when<br> $p: Person()<br>then<br> System.out.println( "Person name: " + $p.toString() );<br> System.out.println( isa( $p, EatingHabits.class ) );<br>
System.out.println( isa( $p, FussyEater.class ) );<br>end<br><br>rule showLikes<br>when<br> $l: EatingHabits( likes == "cheese" )<br> $p: Person( this == $l )<br>then<br> System.out.println( $p.getName() + " likes cheese" );<br>
end<br><br>rule showDislikes<br>when<br> $d: EatingHabits( dislikes != null )<br> $p: Person( this == $d )<br>then<br> System.out.println( $p.getName() + " dislikes " + $d.getDislikes() );<br> sessionMgr.insertLogical( kcontext, $p, FussyEater.class );<br>
end<br><br>rule gotFussyEater<br>when<br> $d: FussyEater()<br> $p: Person( this == $d )<br>then<br> System.out.println( $p.getName() + " is a fussy eater" );<br>end<br><br>rule notFussyEater<br>when<br>
$p: Person()<br> not FussyEater( this == $p )<br>then<br> System.out.println( $p.getName() + " is not a fussy eater" );<br>end<br><br>rule removeDislikes<br>salience -100<br>no-loop true<br>when<br> $d: EatingHabits()<br>
then<br> modify( $d ){ setDislikes( null ) }<br>end<br><br>=======================================================<br>Person name: Person<John,12,MALE><br>Person<John,12,MALE> doesn't implement EatingHabits<br>
Person<John,12,MALE> doesn't implement FussyEater<br>John dislikes spinach<br>John is a fussy eater<br>John likes cheese<br>John is not a fussy eater<br>John likes cheese<br><br><br></div></div>