/*
* 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.common.ImperfectField;
import org.drools.chance.distribution.Distribution;
import org.drools.chance.distribution.ImpKind;
import org.drools.chance.distribution.ImpType;
import org.drools.factmodel.*;
import org.mvel2.asm.*;
import java.beans.IntrospectionException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
public class ChanceBeanBuilderImpl extends DefaultBeanClassBuilder {
public byte[] buildClass( ClassDefinition classDef ) throws IntrospectionException,
InvocationTargetException,
ClassNotFoundException,
IOException,
NoSuchMethodException,
NoSuchFieldException,
InstantiationException,
IllegalAccessException {
try {
if ( classDef.getFieldsDefinitions().size() > 0 ) {
rewriteImperfectFields( classDef );
}
byte[] code = super.buildClass(classDef);
finalizeCreation( classDef );
return code;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void rewriteImperfectFields(ClassDefinition classDef) {
Collection<FieldDefinition> originalFields = new ArrayList<FieldDefinition>( classDef.getFieldsDefinitions() );
for ( FieldDefinition fld : originalFields ) {
if ( fld.getAnnotations() != null ) {
for ( AnnotationDefinition ann : fld.getAnnotations() ) {
if ( ann.getName().equals( Imperfect.class.getName() ) ) {
ImperfectFieldDefinition ifld = ImperfectFieldDefinition.fromField( fld, ann );
if ( ImperfectFieldDefinition.isLinguistic( ifld ) ) {
for ( FieldDefinition xfld : originalFields ) {
if ( xfld.getName().equals( ifld.getSupport() ) ) {
ifld.setSupportFieldDef( xfld );
}
}
}
classDef.addField( ifld );
break;
}
}
}
}
}
protected void finalizeCreation( ClassDefinition klass ) {
Collection<FieldDefinition> originalFields = new HashSet<FieldDefinition>( klass.getFieldsDefinitions() );
for ( FieldDefinition field : originalFields ) {
if ( field instanceof ImperfectFieldDefinition ) {
FieldDefinition fieldDistr = new VirtualFieldDefinition();
fieldDistr.setName( field.getName() + "Distr" );
fieldDistr.setTypeName( Distribution.class.getName() );
fieldDistr.setInherited( field.isInherited() );
klass.addField(fieldDistr);
FieldDefinition fieldValue = new VirtualFieldDefinition();
fieldValue.setName( field.getName() + "Value" );
fieldValue.setTypeName( field.getTypeName() );
fieldValue.setInherited( field.isInherited() );
klass.addField(fieldValue);
}
}
}
/*******************************************************************************************************************
*
* Constructors
*
*******************************************************************************************************************/
@Override
protected void buildConstructorWithFields( ClassVisitor cw, ClassDefinition classDef, Collection<FieldDefinition> fieldDefs ) {
Type[] params = new Type[fieldDefs.size()];
int index = 0;
for ( FieldDefinition field : fieldDefs ) {
if ( field instanceof VirtualFieldDefinition ) continue;
params[index++] = Type.getType( BuildUtils.getTypeDescriptor(field.getTypeName()) );
}
MethodVisitor mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
"<init>",
Type.getMethodDescriptor( Type.VOID_TYPE,
params ),
null,
null );
mv.visitCode();
Label l0 = null;
if ( this.debug ) {
l0 = new Label();
mv.visitLabel( l0 );
}
fieldConstructorStart( mv, classDef, fieldDefs );
initImperfectFields( classDef, mv );
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, BuildUtils.getInternalType( classDef.getName() ), "synchFields", "()V");
mv.visitInsn( Opcodes.RETURN );
Label l1 = null;
if ( this.debug ) {
l1 = new Label();
mv.visitLabel( l1 );
mv.visitLocalVariable( "this",
BuildUtils.getTypeDescriptor( classDef.getClassName() ),
null,
l0,
l1,
0 );
for ( FieldDefinition field : classDef.getFieldsDefinitions() ) {
if ( field instanceof VirtualFieldDefinition ) continue;
Label l11 = new Label();
mv.visitLabel( l11 );
mv.visitLocalVariable( field.getName(),
BuildUtils.getTypeDescriptor( field.getTypeName() ),
null,
l0,
l1,
0 );
}
}
mv.visitMaxs( 0,
0 );
mv.visitEnd();
}
@Override
protected void buildDefaultConstructor( ClassVisitor cw, ClassDefinition classDef ) {
MethodVisitor mv = cw.visitMethod( Opcodes.ACC_PUBLIC,
"<init>",
Type.getMethodDescriptor( Type.VOID_TYPE,
new Type[]{} ),
null,
null );
mv.visitCode();
Label l0 = null;
if ( this.debug ) {
l0 = new Label();
mv.visitLabel( l0 );
}
boolean hasObjects = defaultConstructorStart( mv, classDef );
initImperfectFields( classDef, mv );
defaultConstructorInitValues( mv, classDef );
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, BuildUtils.getInternalType( classDef.getName() ), "synchFields", "()V");
mv.visitInsn(Opcodes.RETURN);
Label l1 = null;
if ( this.debug ) {
l1 = new Label();
mv.visitLabel( l1 );
mv.visitLocalVariable( "this",
BuildUtils.getTypeDescriptor( classDef.getClassName() ),
null,
l0,
l1,
0 );
}
mv.visitMaxs( hasObjects ? 3 : 0,
hasObjects ? 1 : 0 );
mv.visitEnd();
}
protected boolean defaultConstructorStart( MethodVisitor mv, ClassDefinition classDef ) {
// Building default constructor
mv.visitVarInsn( Opcodes.ALOAD,
0 );
String sup;
try {
sup = Type.getInternalName(Class.forName(classDef.getSuperClass()));
} catch (ClassNotFoundException e) {
sup = BuildUtils.getInternalType( classDef.getSuperClass() );
}
mv.visitMethodInsn( Opcodes.INVOKESPECIAL,
sup,
"<init>",
Type.getMethodDescriptor( Type.VOID_TYPE,
new Type[]{} ) );
boolean hasObjects = false;
if ( classDef.isTraitable() ) {
initializeDynamicTypeStructures( mv, classDef );
}
return hasObjects;
}
protected boolean defaultConstructorInitValues( MethodVisitor mv, ClassDefinition classDef ) {
boolean hasObjects = false;
for (FieldDefinition field : classDef.getFieldsDefinitions()) {
if ( field.isInherited() ) { continue; }
if ( field instanceof VirtualFieldDefinition ) { continue; }
Object val;
if ( field instanceof ImperfectFieldDefinition ) {
val = field.getInitExpr();
} else {
val = BuildUtils.getDefaultValue(field);
}
if (val != null) {
if ( field instanceof ImperfectFieldDefinition ) {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD,
BuildUtils.getInternalType( classDef.getClassName() ),
field.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() )
);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD,
BuildUtils.getInternalType( classDef.getClassName() ),
field.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getStrategies",
"()Lorg/drools/chance/distribution/DistributionStrategies;");
mv.visitLdcInsn( field.getInitExpr() );
mv.visitMethodInsn( INVOKEINTERFACE,
"org/drools/chance/distribution/DistributionStrategies",
"parse",
"(Ljava/lang/String;)Lorg/drools/chance/distribution/Distribution;" );
} else {
mv.visitVarInsn(Opcodes.ALOAD, 0);
if ( BuildUtils.isPrimitive( field.getTypeName() )
|| BuildUtils.isBoxed( field.getTypeName() )
|| String.class.getName().equals( field.getTypeName() ) ) {
mv.visitLdcInsn(val);
if ( BuildUtils.isBoxed(field.getTypeName()) ) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
BuildUtils.getInternalType(field.getTypeName()),
"valueOf",
"("+BuildUtils.unBox(field.getTypeName())+")"+BuildUtils.getTypeDescriptor(field.getTypeName()));
}
} else {
hasObjects = true;
String type = BuildUtils.getInternalType( val.getClass().getName() );
mv.visitTypeInsn( NEW, type );
mv.visitInsn(DUP);
mv.visitMethodInsn( INVOKESPECIAL,
type,
"<init>",
"()V");
}
if (! field.isInherited()) {
mv.visitFieldInsn( Opcodes.PUTFIELD,
BuildUtils.getInternalType( classDef.getClassName() ),
field.getName(),
BuildUtils.getTypeDescriptor( field.getTypeName() ) );
} else {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
BuildUtils.getInternalType(classDef.getClassName()),
field.getWriteMethod(),
Type.getMethodDescriptor(Type.VOID_TYPE,
new Type[]{Type.getType(BuildUtils.getTypeDescriptor(field.getTypeName()))}
));
}
}
}
}
return hasObjects;
}
/*******************************************************************************************************************
*
* Fields
*
*******************************************************************************************************************/
@Override
protected void buildFields(ClassWriter cw, ClassDefinition classDef) {
super.buildFields( cw, classDef );
buildImperfectFields( cw, classDef );
buildSynchFieldsMethod(cw, classDef.getName(), classDef.getName(), classDef);
}
protected void initImperfectFields( ClassDefinition cdef, MethodVisitor mv ) {
for ( FieldDefinition fld : cdef.getFieldsDefinitions() ) {
if ( fld instanceof VirtualFieldDefinition ) continue;
if ( fld instanceof ImperfectFieldDefinition ) {
ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) fld;
if ( ImperfectFieldDefinition.isLinguistic( ifld ) ) {
FieldDefinition tfld = getSupportField( cdef, ifld );
initImperfectLinguisticField(mv, cdef.getName(), ifld, tfld);
} else {
initImperfectField(mv, cdef.getName(), ifld);
}
}
}
}
protected void buildImperfectFields( ClassWriter cw, ClassDefinition classDef ) {
for ( FieldDefinition fld : classDef.getFieldsDefinitions() ) {
if ( fld instanceof VirtualFieldDefinition ) continue;
if ( fld instanceof ImperfectFieldDefinition ) {
FieldVisitor fv = cw.visitField( ACC_PRIVATE,
fld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ),
"L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( fld.getTypeName() ) + ">;",
null );
fv.visitEnd();
}
}
}
protected void initImperfectField( MethodVisitor mv, String beanName, ImperfectFieldDefinition ifld ) {
mv.visitVarInsn(ALOAD, 0);
mv.visitTypeInsn( NEW, ifld.getHistory() == 0 ?
"org/drools/chance/common/ImperfectFieldImpl" :
"org/drools/chance/common/ImperfectHistoryField" );
mv.visitInsn(DUP);
createImperfectField( mv, ifld.getImpKind().name(), ifld.getImpType().name(), ifld.getDegreeType().name(), ifld.getTypeName() );
if ( ifld.getHistory() > 0 ) {
mv.visitLdcInsn( ""+ifld.getHistory() );
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
}
if ( ifld.getInitExpr() != null ) {
mv.visitLdcInsn( ifld.getInitExpr() );
}
// if ( ifld.getHistory() > 0 ) {
// if ( ifld.getInitExpr() != null ) {
// mv.visitMethodInsn( INVOKESPECIAL,
// "org/drools/chance/common/ImperfectHistoryField",
// "<init>",
// "(Lorg/drools/chance/distribution/DistributionStrategies;ILjava/lang/String;)V" );
// } else {
// throw new UnsupportedOperationException( " ImpHistoricalField must have an init expr " );
// }
// } else {
if ( ifld.getInitExpr() != null ) {
mv.visitMethodInsn( INVOKESPECIAL,
"org/drools/chance/common/ImperfectFieldImpl",
"<init>",
"(Lorg/drools/chance/distribution/DistributionStrategies;Ljava/lang/String;)V");
} else {
mv.visitMethodInsn( INVOKESPECIAL,
"org/drools/chance/common/ImperfectFieldImpl",
"<init>",
"(Lorg/drools/chance/distribution/DistributionStrategies;)V");
}
// }
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( beanName ),
ifld.getName()+ "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
}
protected void initImperfectLinguisticField( MethodVisitor mv, String beanName, ImperfectFieldDefinition ifld, FieldDefinition tfld ) {
mv.visitVarInsn(ALOAD, 0);
mv.visitTypeInsn(NEW, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
mv.visitInsn(DUP);
createImperfectField(mv, ifld.getImpKind().name(), ifld.getImpType().name(), ifld.getDegreeType().name(), ifld.getTypeName());
createImperfectField( mv, ImpKind.POSSIBILITY.name(), ImpType.LINGUISTIC.name(), ifld.getDegreeType().name(), tfld.getTypeName() );
if ( ifld.getInitExpr() == null ) {
mv.visitInsn( ACONST_NULL );
} else {
mv.visitLdcInsn( ifld.getInitExpr() );
}
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.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( beanName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
}
protected void buildSynchFieldsMethod( ClassWriter cw, String proxyName, String coreName, ClassDefinition def ) {
{
MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "synchFields", "()V", null, null);
mv.visitCode();
for ( FieldDefinition fld : def.getFieldsDefinitions() ) {
if ( fld instanceof VirtualFieldDefinition ) continue;
if ( fld instanceof ImperfectFieldDefinition ) {
ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) fld;
if ( ImperfectFieldDefinition.isLinguistic( ifld ) ) {
FieldDefinition tfld = getSupportField(def, ifld);
synchLinguisticField( mv, fld, tfld, coreName );
} else {
synchField( mv, ifld, proxyName, coreName );
}
}
}
mv.visitInsn(RETURN);
mv.visitMaxs( 3, 3 );
mv.visitEnd();
}
}
protected void synchLinguisticField( MethodVisitor mv, FieldDefinition fld, FieldDefinition tfld, String coreName ) {
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
tfld.getName(),
BuildUtils.getTypeDescriptor( tfld.getTypeName() ) );
Label l0 = new Label();
mv.visitJumpInsn( IFNULL, l0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitTypeInsn( CHECKCAST,
"org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField" );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
tfld.getName(),
BuildUtils.getTypeDescriptor( tfld.getTypeName() ) );
mv.visitMethodInsn( INVOKEVIRTUAL,
"org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField",
"fuzzify",
"(Ljava/lang/Number;)Lorg/drools/chance/distribution/Distribution;" );
mv.visitVarInsn( ASTORE, 1 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitVarInsn( ALOAD, 1 );
mv.visitInsn( ICONST_0 );
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Lorg/drools/chance/distribution/Distribution;Z)V" );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;" );
mv.visitTypeInsn( CHECKCAST,
BuildUtils.getInternalType( fld.getTypeName() ) );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName(),
BuildUtils.getTypeDescriptor( fld.getTypeName() ) );
Label l1 = new Label();
mv.visitJumpInsn( GOTO, l1 );
mv.visitLabel( l0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName(),
BuildUtils.getTypeDescriptor( fld.getTypeName() ) );
Label l2 = new Label();
mv.visitJumpInsn( IFNULL, l2 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName(),
BuildUtils.getTypeDescriptor( fld.getTypeName() ) );
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;)V" );
mv.visitLabel( l2 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitJumpInsn( IFNULL, l1 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;" );
mv.visitTypeInsn( CHECKCAST,
BuildUtils.getInternalType( fld.getTypeName() ) );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName(),
BuildUtils.getTypeDescriptor( fld.getTypeName() ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
fld.getName() +"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitTypeInsn( CHECKCAST,
"org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField" );
defuzzify( mv, tfld.getTypeName() );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( coreName ),
tfld.getName(),
BuildUtils.getTypeDescriptor( tfld.getTypeName() ) );
mv.visitLabel( l1 );
}
protected void synchField( MethodVisitor mv, FieldDefinition ifld, String proxyName, String coreName ) {
getTargetValue( mv, ifld, proxyName, coreName );
Label l0 = new Label();
mv.visitJumpInsn( IFNULL, l0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
getTargetValue( mv, ifld, proxyName, coreName );
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;)V");
mv.visitLabel( l0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
Label l1 = new Label();
mv.visitJumpInsn( IFNULL, l1 );
mv.visitVarInsn( ALOAD, 0 );
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn( CHECKCAST,
BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, coreName, ifld );
mv.visitLabel( l1 );
}
/*******************************************************************************************************************
*
* Accessors
*
*******************************************************************************************************************/
@Override
protected void buildGettersAndSetters(ClassWriter cw, ClassDefinition classDef) {
for ( FieldDefinition fld : classDef.getFieldsDefinitions() ) {
if ( fld instanceof VirtualFieldDefinition ) continue;
if ( ! fld.isInherited() ) {
if ( fld instanceof ImperfectFieldDefinition ) {
ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) fld;
if ( ImperfectFieldDefinition.isLinguistic( ifld ) ) {
FieldDefinition tfld = getSupportField( classDef, ifld );
buildImperfectLinguisticFieldGettersAndSetters(cw, classDef.getName(), classDef.getName(), ifld, tfld);
} else {
buildImperfectFieldGettersAndSetters( cw, classDef.getName(), classDef.getName(), ifld );
}
} else {
if ( ! isSupport( classDef, fld ) ) {
this.buildGetMethod( cw,
classDef,
fld );
this.buildSetMethod( cw,
classDef,
fld );
}
}
}
}
}
protected void buildImperfectFieldGettersAndSetters( ClassWriter cw, String proxyName, String core, ImperfectFieldDefinition ifld) {
MethodVisitor mv;
String getter = BuildUtils.getterName( ifld.getName(), ifld.getTypeName() );
String setter = BuildUtils.setterName( ifld.getName(), ifld.getTypeName() );
{
mv = cw.visitMethod( ACC_PUBLIC,
getter,
"()Lorg/drools/chance/common/ImperfectField;",
"()L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() )+ ">;", null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
getter+"Distr",
"()Lorg/drools/chance/distribution/Distribution;",
"()Lorg/drools/chance/distribution/Distribution<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() )+ ">;",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCurrent",
"()Lorg/drools/chance/distribution/Distribution;");
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
getter+"Value",
"()"+BuildUtils.getTypeDescriptor(ifld.getTypeName()),
null, null);
mv.visitCode();
getTargetValue( mv, ifld, proxyName, core );
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
setter,
"(" + BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) + ")V",
"(L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() )+ ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, core );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD,
BuildUtils.getInternalType(proxyName),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn(INVOKEINTERFACE, BuildUtils.getInternalType( ImperfectField.class.getName() ), "getCrisp", "()Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(ifld.getTypeName()));
setTargetValue( mv, core, ifld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
setter.replace( "set", "update" ),
"(" + BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) + ")V",
"(L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() )+ ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCurrent",
"()Lorg/drools/chance/distribution/Distribution;");
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"update",
"(Lorg/drools/chance/distribution/Distribution;)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, core );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD,
BuildUtils.getInternalType(proxyName),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn(INVOKEINTERFACE, BuildUtils.getInternalType( ImperfectField.class.getName() ), "getCrisp", "()Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType(ifld.getTypeName()));
setTargetValue( mv, core, ifld );
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
setter + "Value",
"("+BuildUtils.getTypeDescriptor( ifld.getTypeName() ) +")V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, core );
mv.visitVarInsn(ALOAD, 1);
setTargetValue( mv, core, ifld );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;Z)V");
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
setter.replace("set","update") + "Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ")V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ICONST_1);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;Z)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, core );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, core, ifld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
setter+"Distr",
"(Lorg/drools/chance/distribution/Distribution;)V",
"(Lorg/drools/chance/distribution/Distribution<" +BuildUtils.getTypeDescriptor( ifld.getTypeName() ) +">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Lorg/drools/chance/distribution/Distribution;Z)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, core );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, core, ifld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC,
setter.replace("set","update")+"Distr",
"(Lorg/drools/chance/distribution/Distribution;)V",
"(Lorg/drools/chance/distribution/Distribution<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"update",
"(Lorg/drools/chance/distribution/Distribution;)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, core );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName()+"_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn(CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, core, ifld );
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC + ACC_VARARGS,
setter.replace("set","update")+"Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + "Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V",
null,
null );
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"update",
"(Ljava/lang/Object;Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V" );
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn(INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;" );
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName(),
BuildUtils.getTypeDescriptor( ifld.getTypeName() ) );
mv.visitInsn(RETURN);
mv.visitMaxs(4, 4);
mv.visitEnd();
}
{
mv = cw.visitMethod( ACC_PUBLIC + ACC_VARARGS,
setter+"Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + "Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V",
null,
null );
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V" );
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn(INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;" );
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName(),
BuildUtils.getTypeDescriptor( ifld.getTypeName() ) );
mv.visitInsn(RETURN);
mv.visitMaxs(4, 4);
mv.visitEnd();
}
}
protected void buildImperfectLinguisticFieldGettersAndSetters(ClassWriter cw, String proxyName, String coreName, ImperfectFieldDefinition ifld, FieldDefinition tfld) {
String getter = BuildUtils.getterName( ifld.getName(), ifld.getTypeName() );
String setter = BuildUtils.setterName( ifld.getName(), ifld.getTypeName() );
String targetGetter = BuildUtils.getterName( tfld.getName(), tfld.getTypeName() );
String targetSetter = BuildUtils.setterName( tfld.getName(), tfld.getTypeName() );
String targetType = tfld.getTypeName();
// first build the fuzzy field
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
getter,
"()Lorg/drools/chance/common/ImperfectField;",
"()L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;",
null);
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ) ,
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitInsn( ARETURN );
mv.visitMaxs( 1, 1 );
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
getter+"Distr",
"()Lorg/drools/chance/distribution/Distribution;",
"()Lorg/drools/chance/distribution/Distribution<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;",
null);
mv.visitCode();
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ) ,
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCurrent",
"()Lorg/drools/chance/distribution/Distribution;");
mv.visitInsn( ARETURN );
mv.visitMaxs( 1, 1 );
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
getter + "Value",
"()" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ),
null, null);
mv.visitCode();
getTargetValue( mv, ifld, proxyName, coreName );
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter,
"(" + BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) + ")V",
"(L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ) ,
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn( ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn(CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
defuzzify( mv, targetType );
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter+"Distr",
"(Lorg/drools/chance/distribution/Distribution;)V",
"(Lorg/drools/chance/distribution/Distribution<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ) ,
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Lorg/drools/chance/distribution/Distribution;Z)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn( ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn(CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
defuzzify( mv, targetType );
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter + "Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ")V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 1);
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;Z)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ) ,
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn(CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
defuzzify( mv, targetType );
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter + "Core",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ")V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 1);
setTargetValue( mv, coreName, ifld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter.replace("set","update"),
"(" + BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) + ")V",
"(L" + BuildUtils.getInternalType( ImperfectField.class.getName() ) + "<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCurrent",
"()Lorg/drools/chance/distribution/Distribution;");
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"update",
"(Lorg/drools/chance/distribution/Distribution;)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn( ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn(CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
defuzzify( mv, targetType );
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter.replace("set","update") + "Distr",
"(Lorg/drools/chance/distribution/Distribution;)V",
"(Lorg/drools/chance/distribution/Distribution<" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ">;)V",
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"update",
"(Lorg/drools/chance/distribution/Distribution;)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn( ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn(CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
defuzzify( mv, targetType );
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
setter.replace( "set", "update" ) + "Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + ")V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 1);
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(ICONST_1);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;Z)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn( CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField" );
defuzzify( mv, targetType );
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC + ACC_VARARGS,
setter+"Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + "Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V",
null,
null );
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Ljava/lang/Object;Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V" );
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn(INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;" );
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName(),
BuildUtils.getTypeDescriptor( ifld.getTypeName() ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitTypeInsn( CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField" );
mv.visitMethodInsn( INVOKEVIRTUAL, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField", "defuzzify", "()Ljava/lang/Number;");
mv.visitMethodInsn( INVOKEVIRTUAL,
"java/lang/Number",
BuildUtils.numericMorph( tfld.getTypeName() ),
"()" + BuildUtils.unBox( tfld.getTypeName() ) );
mv.visitMethodInsn( INVOKESTATIC,
BuildUtils.getInternalType( tfld.getTypeName() ),
"valueOf",
"(" + BuildUtils.getInternalType( BuildUtils.unBox( tfld.getTypeName() ) ) + ")" + BuildUtils.getTypeDescriptor( tfld.getTypeName() ) ) ;
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
tfld.getName(),
BuildUtils.getTypeDescriptor( tfld.getTypeName() ) );
mv.visitInsn(RETURN);
mv.visitMaxs(4, 4);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC + ACC_VARARGS,
setter.replace("set","update")+"Value",
"(" + BuildUtils.getTypeDescriptor( ifld.getTypeName() ) + "Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V",
null,
null );
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"update",
"(Ljava/lang/Object;Lorg/drools/chance/degree/Degree;[Ljava/lang/String;)V" );
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitMethodInsn(INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;" );
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ) );
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName(),
BuildUtils.getTypeDescriptor( ifld.getTypeName() ) );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ) );
mv.visitTypeInsn( CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField" );
mv.visitMethodInsn( INVOKEVIRTUAL, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField", "defuzzify", "()Ljava/lang/Number;");
mv.visitMethodInsn( INVOKEVIRTUAL,
"java/lang/Number",
BuildUtils.numericMorph( tfld.getTypeName() ),
"()" + BuildUtils.unBox( tfld.getTypeName() ) );
mv.visitMethodInsn( INVOKESTATIC,
BuildUtils.getInternalType( tfld.getTypeName() ),
"valueOf",
"(" + BuildUtils.getInternalType( BuildUtils.unBox( tfld.getTypeName() ) ) + ")" + BuildUtils.getTypeDescriptor( tfld.getTypeName() ) ) ;
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( proxyName ),
tfld.getName(),
BuildUtils.getTypeDescriptor( tfld.getTypeName() ) );
mv.visitInsn(RETURN);
mv.visitMaxs(4, 4);
mv.visitEnd();
}
// Now build for the target support field
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
targetGetter,
"()" + BuildUtils.getTypeDescriptor( targetType ) + "", null, null);
mv.visitCode();
getTargetValue( mv, tfld, proxyName, coreName );
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
targetSetter,
"(" + BuildUtils.getTypeDescriptor( targetType ) + ")V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitTypeInsn( CHECKCAST, "org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField");
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn( INVOKEVIRTUAL,
"org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField",
"fuzzify",
"(Ljava/lang/Number;)Lorg/drools/chance/distribution/Distribution;");
mv.visitVarInsn(ASTORE, 2);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitVarInsn(ALOAD, 2);
mv.visitInsn(ICONST_0);
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"setValue",
"(Lorg/drools/chance/distribution/Distribution;Z)V");
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( proxyName ),
ifld.getName() + "_$$Imp",
BuildUtils.getTypeDescriptor( ImperfectField.class.getName() ));
mv.visitMethodInsn( INVOKEINTERFACE,
BuildUtils.getInternalType( ImperfectField.class.getName() ),
"getCrisp",
"()Ljava/lang/Object;");
mv.visitTypeInsn( CHECKCAST, BuildUtils.getInternalType( ifld.getTypeName() ));
setTargetValue( mv, coreName, ifld );
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 1);
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 3);
mv.visitEnd();
}
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC,
targetSetter + "Core",
"(" + BuildUtils.getTypeDescriptor( targetType ) + ")V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
prepareSetTargetValue( mv, proxyName, coreName );
mv.visitVarInsn(ALOAD, 1);
setTargetValue( mv, coreName, tfld );
mv.visitInsn(RETURN);
mv.visitMaxs(3, 2);
mv.visitEnd();
}
}
protected boolean buildFieldsToString( ClassDefinition classDef, MethodVisitor mv, boolean previous ) {
for ( FieldDefinition field : classDef.getFieldsDefinitions() ) {
if ( field.getName().endsWith( "Distr" ) && classDef.getField( field.getName().replace( "Distr", "" ) ) != null ) {
continue;
}
buildFieldToString( field, classDef, mv, previous );
}
return previous;
}
/*******************************************************************************************************************
*
* Utilities
*
*******************************************************************************************************************/
private void defuzzify( MethodVisitor mv, String targetType ) {
mv.visitMethodInsn( INVOKEVIRTUAL,
"org/drools/chance/distribution/fuzzy/linguistic/LinguisticImperfectField",
"defuzzify",
"()Ljava/lang/Number;");
mv.visitTypeInsn(CHECKCAST, "java/lang/Number" );
mv.visitMethodInsn( INVOKEVIRTUAL,
"java/lang/Number",
BuildUtils.numericMorph( targetType ),
"()" + BuildUtils.unBox( targetType ) );
if ( ! BuildUtils.isPrimitive( targetType ) ) {
mv.visitMethodInsn(INVOKESTATIC,
BuildUtils.getInternalType( targetType ),
"valueOf",
"(" + BuildUtils.unBox( targetType )+ ")" + BuildUtils.getTypeDescriptor( targetType ) );
}
}
private boolean isSupport(ClassDefinition classDef, FieldDefinition field) {
for ( FieldDefinition fld : classDef.getFieldsDefinitions() ) {
if ( fld instanceof ImperfectFieldDefinition &&
ImperfectFieldDefinition.isLinguistic( fld ) &&
((ImperfectFieldDefinition) fld).getSupportFieldDef().equals( field ) ) {
return true;
}
}
return false;
}
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 setTargetValue(MethodVisitor mv, String coreName, FieldDefinition field ) {
mv.visitFieldInsn( PUTFIELD,
BuildUtils.getInternalType( coreName ),
field.getName(),
BuildUtils.getTypeDescriptor( field.getTypeName() ) );
}
protected void prepareSetTargetValue(MethodVisitor mv, String proxyName, String coreName ) {
}
protected void getTargetValue( MethodVisitor mv, FieldDefinition field, String proxyName, String coreName ) {
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn( GETFIELD,
BuildUtils.getInternalType( coreName ),
field.getName(),
BuildUtils.getTypeDescriptor( field.getTypeName() ) );
}
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;");
}
}