/* * 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.chance.common.ImperfectField; import org.drools.chance.distribution.Distribution; import org.drools.factmodel.AnnotationDefinition; import org.drools.factmodel.BuildUtils; import org.drools.factmodel.ClassDefinition; import org.drools.factmodel.FieldDefinition; import org.drools.factmodel.traits.TraitClassBuilderImpl; import org.mvel2.asm.ClassWriter; import org.mvel2.asm.MethodVisitor; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; public class ChanceTraitBuilderImpl extends TraitClassBuilderImpl { public void init(ClassDefinition trait) { rewriteImperfectFields( trait ); super.init(trait); } protected void rewriteImperfectFields(ClassDefinition classDef) { Collection<FieldDefinition> originalFields = new ArrayList<FieldDefinition>( classDef.getFieldsDefinitions() ); for ( FieldDefinition fld : originalFields ) { if ( ! ( fld instanceof ImperfectFieldDefinition) && fld.getAnnotations() != null ) { for ( AnnotationDefinition ann : fld.getAnnotations() ) { if ( ann.getName().equals( Imperfect.class.getName() ) ) { ImperfectFieldDefinition ifld = ImperfectFieldDefinition.fromField( fld, ann ); ifld.setClassDefinition( classDef ); classDef.addField( ifld ); if ( ImperfectFieldDefinition.isLinguistic( ifld ) ) { for ( FieldDefinition xfld : originalFields ) { if ( xfld.getName().equals( ifld.getSupport() ) ) { ifld.setSupportFieldDef( xfld ); } } } break; } } } } } protected void buildSetter(ClassWriter cw, FieldDefinition field, String name, String type, String generic) { if ( field instanceof ImperfectFieldDefinition ) { super.buildSetter( cw, null, name, ImperfectField.class.getName(), type ); if ( ImperfectFieldDefinition.isLinguistic( field ) ) { ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) field; super.buildSetter( cw, null, ifld.getSupport()+"Core", ifld.getSupportFieldDef().getTypeName(), null ); } } else { super.buildSetter( cw, null, name, type, null ); } super.buildSetter( cw, null, name+"Distr", Distribution.class.getName(), type ); super.buildSetter( cw, null, name+"Value", type, null ); // super.buildSetter( cw, field, name+"Core", type, null ); buildUpdater( cw, field, name+"Distr", Distribution.class.getName(), type ); buildUpdater( cw, field, name+"Value", type, null ); } protected void buildGetter(ClassWriter cw, FieldDefinition field, String name, String type, String generic) { if ( field instanceof ImperfectFieldDefinition ) { super.buildGetter(cw, null, name, ImperfectField.class.getName(), type); if ( ImperfectFieldDefinition.isLinguistic( field ) ) { ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) field; super.buildGetter( cw, null, ifld.getSupport()+"Core", ifld.getSupportFieldDef().getTypeName(), null ); } } else { super.buildGetter(cw, null, name, type, null); } super.buildGetter( cw, null, name+"Distr", Distribution.class.getName(), type ); super.buildGetter( cw, null, name+"Value", type, null ); // super.buildGetter( cw, field, name+"Core", type, null ); } protected void buildUpdater(ClassWriter cw, FieldDefinition field, String name, String type, String generic) { MethodVisitor mv = cw.visitMethod( ACC_PUBLIC + ACC_ABSTRACT, "update" + name, "(" + BuildUtils.getTypeDescriptor( type ) + ")V", generic == null ? null : "(" + BuildUtils.getTypeDescriptor( type ).replace( ";", "<" + BuildUtils.getTypeDescriptor( generic ) + ">;") + ")V", null ); mv.visitEnd(); } protected void finalizeCreation(ClassDefinition trait) { Collection<FieldDefinition> originalFields = new HashSet<FieldDefinition>( trait.getFieldsDefinitions() ); for ( FieldDefinition field : originalFields ) { if ( field instanceof ImperfectFieldDefinition ) { ImperfectFieldDefinition ifld = (ImperfectFieldDefinition) field; FieldDefinition fieldDistr = new VirtualFieldDefinition(); fieldDistr.setName( field.getName() + "Distr" ); fieldDistr.setTypeName( Distribution.class.getName() ); fieldDistr.setInherited( field.isInherited() ); trait.addField( fieldDistr ); FieldDefinition fieldValue = new VirtualFieldDefinition(); fieldValue.setName( field.getName() + "Value" ); fieldValue.setTypeName( field.getTypeName() ); fieldValue.setInherited( field.isInherited() ); trait.addField(fieldValue); if ( ImperfectFieldDefinition.isLinguistic( ifld ) ) { FieldDefinition support = null; for ( FieldDefinition x : originalFields ) { if ( x.getName().equals( ifld.getSupport() ) ) { support = x; } } if ( support != null ) { FieldDefinition fieldCore = new DirectAccessFieldDefinition( support ); fieldCore.setName( support.getName() + "Core" ); fieldCore.setTypeName( support.getTypeName() ); fieldCore.setInherited( support.isInherited() ); trait.addField(fieldCore); } else { throw new IllegalStateException("Could not find the support field " + ifld.getSupport() + " for the Linguistic Imperfect field " + field.getName() ); } } } } } }