/* * Copyright 2011 JBoss Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.chance.factmodel; import org.drools.RuntimeDroolsException; import org.drools.chance.distribution.ImpKind; import org.drools.chance.distribution.ImpType; import org.drools.factmodel.BuildUtils; import org.drools.factmodel.ClassDefinition; import org.drools.factmodel.FieldDefinition; import org.drools.factmodel.traits.TraitTriplePropertyWrapperClassBuilderImpl; import org.mvel2.asm.Label; import org.mvel2.asm.MethodVisitor; import org.mvel2.asm.Type; import java.util.BitSet; public class ChanceTriplePropertyWrapperClassBuilderImpl extends TraitTriplePropertyWrapperClassBuilderImpl { protected boolean isVirtual( FieldDefinition field ) { return field instanceof VirtualFieldDefinition; } protected boolean isDirectAccess( FieldDefinition field ) { return field instanceof DirectAccessFieldDefinition; } protected boolean mustSkip( FieldDefinition field ) { return isVirtual( field ) || isDirectAccess( field ); } protected int initSoftFields( MethodVisitor mv, String wrapperName, ClassDefinition trait, ClassDefinition core, BitSet mask ) { int stackSize = super.initSoftFields( mv, wrapperName, trait, core, mask ); for ( FieldDefinition field : trait.getFieldsDefinitions() ) { if ( isVirtual( field ) ) continue; if ( field instanceof ImperfectFieldDefinition) { ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) field; if ( ImperfectFieldDefinition.isLinguistic(ifld) ) { FieldDefinition tfld = getSupportField( trait, ifld ); initImperfectLinguisticField( mv, wrapperName, ifld, tfld ); stackSize += 2; } else { initImperfectField( mv, wrapperName, (ImperfectFieldDefinition) field); } } else if ( field instanceof DirectAccessFieldDefinition ) { } } return stackSize + 2; } protected FieldDefinition getSupportField( ClassDefinition cdef, ImperfectFieldDefinition ifld ) { String target = ifld.getSupport(); FieldDefinition tfld = cdef.getField( target ); if ( target == null || tfld == null ) { throw new RuntimeDroolsException( " Fuzzy Linguistic Field " + ifld.getName() + " requires a support field, not found " + target ); } return tfld; } protected void initImperfectField(MethodVisitor mv, String wrapperName, ImperfectFieldDefinition impField ) { mv.visitVarInsn( ALOAD, 0 ); mv.visitFieldInsn( GETFIELD, wrapperName, "store", "Lorg/drools/core/util/TripleStore;"); mv.visitVarInsn( ALOAD, 0 ); mv.visitLdcInsn( impField.getName() +"_$$Imp" ); mv.visitMethodInsn( INVOKEVIRTUAL, wrapperName, "propertyKey", "(Ljava/lang/Object;)Lorg/drools/core/util/Triple;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/drools/core/util/TripleStore", "contains", "(Lorg/drools/core/util/Triple;)Z" ); Label l0 = new Label(); mv.visitJumpInsn( IFNE, l0 ); mv.visitTypeInsn(NEW, "org/drools/chance/common/ImperfectFieldImpl"); mv.visitInsn(DUP); createImperfectField(mv, impField.getImpKind().name(), impField.getImpType().name(), impField.getDegreeType().name(), impField.getTypeName()); mv.visitMethodInsn( INVOKESPECIAL, "org/drools/chance/common/ImperfectFieldImpl", "<init>", "(Lorg/drools/chance/distribution/DistributionStrategies;)V" ); mv.visitVarInsn(ASTORE, 1); mv.visitVarInsn( ALOAD, 0 ); mv.visitFieldInsn( GETFIELD, wrapperName, "store", "Lorg/drools/core/util/TripleStore;" ); mv.visitVarInsn( ALOAD, 0 ); mv.visitLdcInsn( impField.getName() +"_$$Imp" ); mv.visitVarInsn( ALOAD, 1 ); mv.visitMethodInsn( INVOKEVIRTUAL, wrapperName, "property", "(Ljava/lang/String;Ljava/lang/Object;)Lorg/drools/core/util/Triple;" ); mv.visitMethodInsn( INVOKEVIRTUAL, "org/drools/core/util/TripleStore", "put", "(Lorg/drools/core/util/Triple;)Z" ); mv.visitInsn( POP ); mv.visitLabel( l0 ); } protected void initImperfectLinguisticField( MethodVisitor mv, String wrapperName, ImperfectFieldDefinition impField, FieldDefinition tfld ) { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn( GETFIELD, wrapperName, "store", "Lorg/drools/core/util/TripleStore;"); mv.visitVarInsn( ALOAD, 0 ); mv.visitLdcInsn( impField.getName() +"_$$Imp" ); mv.visitMethodInsn( INVOKEVIRTUAL, wrapperName, "propertyKey", "(Ljava/lang/Object;)Lorg/drools/core/util/Triple;" ); mv.visitMethodInsn( INVOKEVIRTUAL, "org/drools/core/util/TripleStore", "contains", "(Lorg/drools/core/util/Triple;)Z"); Label l0 = new Label(); mv.visitJumpInsn( IFNE, l0 ); mv.visitVarInsn( ALOAD, 0 ); mv.visitFieldInsn( GETFIELD, wrapperName, "store", "Lorg/drools/core/util/TripleStore;" ); mv.visitVarInsn( ALOAD, 0 ); mv.visitLdcInsn( impField.getName() +"_$$Imp" ); mv.visitTypeInsn( NEW, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField" ); mv.visitInsn( DUP ); createImperfectField( mv, impField.getImpKind().name(), impField.getImpType().name(), impField.getDegreeType().name(), impField.getTypeName()); createImperfectField( mv, ImpKind.POSSIBILITY.name(), ImpType.LINGUISTIC.name(), impField.getDegreeType().name(), tfld.getTypeName() ); mv.visitInsn( ACONST_NULL ); mv.visitMethodInsn( INVOKESPECIAL, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField", "<init>", "(Lorg/drools/chance/distribution/DistributionStrategies;Lorg/drools/chance/distribution/DistributionStrategies;Ljava/lang/String;)V" ); mv.visitMethodInsn( INVOKEVIRTUAL, wrapperName, "property", "(Ljava/lang/String;Ljava/lang/Object;)Lorg/drools/core/util/Triple;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/drools/core/util/TripleStore", "put", "(Lorg/drools/core/util/Triple;)Z" ); mv.visitInsn( POP ); mv.visitLabel( l0 ); } private void createImperfectField( MethodVisitor mv, String ikind, String itype, String degree, String targetType ) { mv.visitFieldInsn(GETSTATIC, "org/drools/chance/distribution/ImpKind", ikind, "Lorg/drools/chance/distribution/ImpKind;"); mv.visitFieldInsn(GETSTATIC, "org/drools/chance/distribution/ImpType", itype, "Lorg/drools/chance/distribution/ImpType;"); mv.visitFieldInsn(GETSTATIC, "org/drools/chance/degree/DegreeType", degree, "Lorg/drools/chance/degree/DegreeType;"); mv.visitLdcInsn( Type.getType( BuildUtils.getTypeDescriptor( targetType ) ) ); mv.visitMethodInsn( INVOKESTATIC, "org/drools/chance/common/ChanceStrategyFactory", "buildStrategies", "(Lorg/drools/chance/distribution/ImpKind;" + "Lorg/drools/chance/distribution/ImpType;" + "Lorg/drools/chance/degree/DegreeType;" + "Ljava/lang/Class;)" + "Lorg/drools/chance/distribution/DistributionStrategies;"); } }