Skip to content

Commit

Permalink
[DROOLS-832] Logical setters do not work with non-natively traitable …
Browse files Browse the repository at this point in the history
…beans
  • Loading branch information
sotty authored and mariofusco committed Jul 2, 2015
1 parent d88d307 commit d129667
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 3 deletions.
Expand Up @@ -19,8 +19,10 @@
import org.drools.compiler.CommonTestMethodBase;
import org.drools.compiler.integrationtests.SerializationHelper;
import org.drools.core.common.InternalFactHandle;
import org.drools.core.factmodel.traits.CoreWrapper;
import org.drools.core.factmodel.traits.TraitFactory;
import org.drools.core.factmodel.traits.TraitField;
import org.drools.core.factmodel.traits.Traitable;
import org.drools.core.factmodel.traits.TraitableBean;
import org.drools.core.factmodel.traits.VirtualPropertyMode;
import org.junit.Test;
Expand Down Expand Up @@ -492,6 +494,82 @@ public void testInitializationConflictManagementPrimitiveTypes() {
}


@Traitable( logical = true )
public static class Qty {
private Integer num;

public Qty( Integer num ) {
this.num = num;
}

public Integer getNum() {
return num;
}

public void setNum( Integer num ) {
this.num = num;
}
}

@Test
public void testHardGetSetOnLogicallyTraitedField() {
String drl = "package org.drools.test; " +
"import " + Qty.class.getCanonicalName() + "; " +
"" +
"global java.util.List list; " +

"declare Obs @Traitable( logical = true ) value : Qty end " +

"declare trait TObs @Trait( logical = true ) value : TQty end " +
"declare trait TQty @Trait( logical = true ) num : Integer end " +

"rule Init " +
"when " +
"then " +
" Obs o = new Obs( new Qty( 42 ) ); " +
" don( o, TObs.class ); " +
"end " +

"rule Log " +
"when " +
" $o : TObs( $val : value.num ) " +
"then " +
" list.add( $val ); " +
"end " +

"rule Change " +
"when " +
" $s : String() " +
" $o : TObs() " +
"then " +
" delete( $s ); " +
" modify( $o ) { getValue().setNum( 99 ); } " +
"end ";

KnowledgeBase knowledgeBase = loadKnowledgeBaseFromString( drl );
TraitFactory.setMode( mode, knowledgeBase );

StatefulKnowledgeSession knowledgeSession = knowledgeBase.newStatefulKnowledgeSession();
ArrayList list = new ArrayList();
knowledgeSession.setGlobal( "list", list );

knowledgeSession.fireAllRules();
knowledgeSession.insert( "x" );
knowledgeSession.fireAllRules();

boolean found = false;
for ( Object o : knowledgeSession.getObjects( new ClassObjectFilter( Qty.class ) ) ) {
assertEquals( (Integer) 99, ( (Qty) o ).getNum() );
assertEquals( 99, ( (CoreWrapper) o )._getFieldTMS().get( "num", Integer.class ) );
found = true;
}
assertTrue( found );

assertEquals( Arrays.asList( 42, 99 ), list );
knowledgeSession.dispose();
}




@Test
Expand Down
Expand Up @@ -317,7 +317,7 @@ public synchronized <K> CoreWrapper<K> getCoreWrapper( Class<K> coreKlazz , Clas
}

public <K> TraitableBean<K,CoreWrapper<K>> asTraitable( K core, ClassDefinition coreDef) {
if ( coreDef.getDefinedClass() != core.getClass() ) {
if ( coreDef == null || coreDef.getDefinedClass() != core.getClass() ) {
// ensure that a compatible interface cDef is not replaced for the missing actual definition
try {
coreDef = buildClassDefinition( core.getClass(), core.getClass() );
Expand Down
Expand Up @@ -662,7 +662,8 @@ private void buildHardSetter( ClassVisitor cw, FieldDefinition field, String mas
if ( core.isFullTraiting() ) {
// The trait field update will be done by the core setter. However, types may mismatch here
FieldDefinition hardField = core.getFieldByAlias( field.resolveAlias() );
if ( ! field.getType().isPrimitive() && ! field.getTypeName().equals( hardField.getTypeName() ) ) {
boolean isHardField = field.getTypeName().equals( hardField.getTypeName() );
if ( ! field.getType().isPrimitive() && ! isHardField ) {
boolean isCoreTrait = hardField.getType().getAnnotation( Trait.class ) != null;
boolean isTraitTrait = field.getType().getAnnotation( Trait.class ) != null;

Expand Down Expand Up @@ -706,8 +707,13 @@ private void buildHardSetter( ClassVisitor cw, FieldDefinition field, String mas
mv.visitInsn( RETURN );
}
}

if ( isHardField && CoreWrapper.class.isAssignableFrom( core.getDefinedClass() ) ) {
logicalSetter( mv, field, masterName, this.trait, core, true );
}
}


TraitFactory.invokeInjector( mv, masterName, trait, core, field, false, 1 );

mv.visitInsn( RETURN );
Expand Down
Expand Up @@ -851,7 +851,8 @@ protected void buildHardSetter( ClassVisitor cw, FieldDefinition field, String m
if ( core.isFullTraiting() ) {
// The trait field update will be done by the core setter. However, types may mismatch here
FieldDefinition hardField = core.getFieldByAlias( field.resolveAlias() );
if ( ! field.getType().isPrimitive() && ! field.getTypeName().equals( hardField.getTypeName() ) ) {
boolean isHardField = field.getTypeName().equals( hardField.getTypeName() );
if ( ! field.getType().isPrimitive() && ! isHardField ) {
boolean isCoreTrait = hardField.getType().getAnnotation( Trait.class ) != null;
boolean isTraitTrait = field.getType().getAnnotation( Trait.class ) != null;

Expand Down Expand Up @@ -895,6 +896,10 @@ protected void buildHardSetter( ClassVisitor cw, FieldDefinition field, String m
mv.visitInsn( RETURN );
}
}

if ( isHardField && CoreWrapper.class.isAssignableFrom( core.getDefinedClass() ) ) {
logicalSetter( mv, field, masterName, this.trait, core, true );
}
}

TraitFactory.invokeInjector( mv, masterName, trait, core, field, false, 1 );
Expand Down

0 comments on commit d129667

Please sign in to comment.