On 6 July 2011 16:37, Mark Proctor <mproctor(a)codehaus.org> wrote:
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.
Here are the Java classes a user might write, using class TripleSet as
provided by the support for duck typing:
public class Person extends TripleSet {
String name;
int age;
Gender gender; // enum Gender { MALE, FEMALE }
}
public interface EatingHabits {
String getLikes();
void setLikes( String value );
String getDislikes();
void setDislikes( String value );
}
public interface FussyEater {
}
Class SessionManager which wraps a StatefulKnowledgeSession provides a
little "glue" for performing "dons" in various forms. It should also
be
available as a global.
public class SessionManager {
public SessionManager( StatefulKnowledgeSession kSession ){...}
public FactHandle insert( Object object ){...}
public Object dons( TripleSet tripleSet, Class<?>... interfaces
){...}
public FactHandle insert( TripleSet tripleSet, Class... interfaces
){...}
public void insertLogical( RuleContext rContext, TripleSet tripleSet,
Class... interfaces ){...}
}
We can insert a Person and don it with EatingHabits:
Person p1 = new Person( "John", 12, Gender.MALE );
EatingHabits ehp1 = (EatingHabits)sessionMgr.dons( p1,
EatingHabits.class );
ehp1.setLikes( "cheese" );
ehp1.setDislikes( "spinach" );
sessionMgr.insert( p1 );
sessionMgr.insert( ehp1 );
And here is some DRL code, followed by the resulting output:
function String isa( Object object, java.lang.Class clazz ){
return object.toString() +
(clazz.isInstance( object ) ? " implements " : " doesn't
implement " ) +
clazz.getSimpleName();
}
rule showPerson
salience 100
when
$p: Person()
then
System.out.println( "Person name: " + $p.toString() );
System.out.println( isa( $p, EatingHabits.class ) );
System.out.println( isa( $p, FussyEater.class ) );
end
rule showLikes
when
$l: EatingHabits( likes == "cheese" )
$p: Person( this == $l )
then
System.out.println( $p.getName() + " likes cheese" );
end
rule showDislikes
when
$d: EatingHabits( dislikes != null )
$p: Person( this == $d )
then
System.out.println( $p.getName() + " dislikes " + $d.getDislikes() );
sessionMgr.insertLogical( kcontext, $p, FussyEater.class );
end
rule gotFussyEater
when
$d: FussyEater()
$p: Person( this == $d )
then
System.out.println( $p.getName() + " is a fussy eater" );
end
rule notFussyEater
when
$p: Person()
not FussyEater( this == $p )
then
System.out.println( $p.getName() + " is not a fussy eater" );
end
rule removeDislikes
salience -100
no-loop true
when
$d: EatingHabits()
then
modify( $d ){ setDislikes( null ) }
end
=======================================================
Person name: Person<John,12,MALE>
Person<John,12,MALE> doesn't implement EatingHabits
Person<John,12,MALE> doesn't implement FussyEater
John dislikes spinach
John is a fussy eater
John likes cheese
John is not a fussy eater
John likes cheese