Search in sources :

Example 41 with FieldDefinition

use of org.drools.core.factmodel.FieldDefinition in project drools by kiegroup.

the class AbstractProxyClassBuilderImpl method shedField.

protected void shedField(MethodVisitor mv, FieldDefinition fld, String proxyName, ClassDefinition core, boolean hardField, int j) {
    FieldDefinition coreField = core.getFieldByAlias(fld.resolveAlias());
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, BuildUtils.getInternalType(proxyName), "object", Type.getDescriptor(core.getDefinedClass()));
    mv.visitTypeInsn(CHECKCAST, Type.getInternalName(TraitableBean.class));
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(TraitableBean.class), "_getFieldTMS", Type.getMethodDescriptor(Type.getType(TraitFieldTMS.class)), true);
    mv.visitVarInsn(ASTORE, 1);
    mv.visitVarInsn(ALOAD, 1);
    // fld Name
    mv.visitLdcInsn(fld.resolveAlias());
    // this
    mv.visitVarInsn(ALOAD, 0);
    // fld type
    if (BuildUtils.isPrimitive(fld.getTypeName())) {
        mv.visitLdcInsn(Type.getType(BuildUtils.getTypeDescriptor(BuildUtils.box(fld.getTypeName()))));
    } else {
        mv.visitLdcInsn(Type.getType(Type.getDescriptor(fld.getType())));
    }
    if (hardField) {
        if (BuildUtils.isPrimitive(coreField.getTypeName())) {
            mv.visitLdcInsn(Type.getType(BuildUtils.getTypeDescriptor(BuildUtils.box(coreField.getTypeName()))));
        } else {
            mv.visitLdcInsn(Type.getType(Type.getDescriptor(coreField.getType())));
        }
    } else {
        mv.visitLdcInsn(Type.getType(Type.getDescriptor(Object.class)));
    }
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(TraitFieldTMS.class), "shedField", Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(String.class), Type.getType(TraitType.class), Type.getType(Class.class), Type.getType(Class.class)), true);
    mv.visitVarInsn(ASTORE, j);
    if (hardField) {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, BuildUtils.getInternalType(proxyName), "object", Type.getDescriptor(core.getDefinedClass()));
        mv.visitVarInsn(ALOAD, j);
        fixPrimitive(mv, coreField, j);
        mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(core.getDefinedClass()), BuildUtils.setterName(coreField.getName(), coreField.getTypeName()), "(" + BuildUtils.getTypeDescriptor(coreField.getTypeName()) + ")" + Type.getDescriptor(void.class), false);
    } else {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, BuildUtils.getInternalType(proxyName), "map", Type.getDescriptor(Map.class));
        mv.visitLdcInsn(fld.resolveAlias());
        mv.visitVarInsn(ALOAD, j);
        mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Map.class), "put", Type.getMethodDescriptor(Type.getType(Object.class), Type.getType(Object.class), Type.getType(Object.class)), true);
    }
}
Also used : FieldDefinition(org.drools.core.factmodel.FieldDefinition) Map(java.util.Map)

Example 42 with FieldDefinition

use of org.drools.core.factmodel.FieldDefinition in project drools by kiegroup.

the class AbstractProxyClassBuilderImpl method helpSet.

public void helpSet(ClassDefinition core, FieldDefinition field, MethodVisitor mv, String masterName) {
    // The trait field update will be done by the core setter. However, types may mismatch here
    FieldDefinition hardField = core.getFieldByAlias(field.resolveAlias());
    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;
        Label l0 = new Label();
        mv.visitVarInsn(ALOAD, 1);
        mv.visitJumpInsn(IFNULL, l0);
        if (isCoreTrait && !isTraitTrait) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(TraitableBean.class));
            mv.visitLdcInsn(hardField.getTypeName());
            mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(TraitableBean.class), "getTrait", Type.getMethodDescriptor(Type.getType(Thing.class), Type.getType(String.class)), true);
            mv.visitVarInsn(ASTORE, 1);
        } else if (!isCoreTrait && isTraitTrait) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(TraitProxy.class));
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(TraitProxy.class), "getObject", Type.getMethodDescriptor(Type.getType(TraitableBean.class)), false);
            mv.visitVarInsn(ASTORE, 1);
        } else if (isCoreTrait) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(TraitProxy.class));
            mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(TraitProxy.class), "getObject", Type.getMethodDescriptor(Type.getType(TraitableBean.class)), false);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(TraitableBean.class));
            mv.visitLdcInsn(hardField.getTypeName());
            mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(TraitableBean.class), "getTrait", Type.getMethodDescriptor(Type.getType(Thing.class), Type.getType(String.class)), true);
            mv.visitVarInsn(ASTORE, 1);
        } else {
            // handled by normal inheritance, exceptions should have been thrown
            if (!hardField.getType().isAssignableFrom(field.getType())) {
                mv.visitInsn(RETURN);
            }
        }
        Label l1 = new Label();
        mv.visitJumpInsn(GOTO, l1);
        mv.visitLabel(l0);
        mv.visitInsn(ACONST_NULL);
        mv.visitVarInsn(ASTORE, 1);
        mv.visitLabel(l1);
    } else if (field.getType().isPrimitive()) {
        if (!hardField.getType().equals(field.getType())) {
            mv.visitInsn(RETURN);
        }
    }
    if (isHardField && CoreWrapper.class.isAssignableFrom(core.getDefinedClass())) {
        logicalSetter(mv, field, masterName, core);
    }
}
Also used : FieldDefinition(org.drools.core.factmodel.FieldDefinition) Label(org.mvel2.asm.Label)

Example 43 with FieldDefinition

use of org.drools.core.factmodel.FieldDefinition in project drools by kiegroup.

the class TypeDeclarationFactory method compareTypeDeclarations.

protected int compareTypeDeclarations(TypeDeclaration oldDeclaration, TypeDeclaration newDeclaration) throws IncompatibleClassChangeError {
    // different formats -> incompatible
    if (!oldDeclaration.getFormat().equals(newDeclaration.getFormat())) {
        throw new IncompatibleClassChangeError("Type Declaration " + newDeclaration.getTypeName() + " has a different" + " format that its previous definition: " + newDeclaration.getFormat() + "!=" + oldDeclaration.getFormat());
    }
    // different superclasses -> Incompatible (TODO: check for hierarchy)
    if (!oldDeclaration.getTypeClassDef().getSuperClass().equals(newDeclaration.getTypeClassDef().getSuperClass())) {
        if (oldDeclaration.getNature() == TypeDeclaration.Nature.DEFINITION && newDeclaration.getNature() == TypeDeclaration.Nature.DECLARATION && Object.class.getName().equals(newDeclaration.getTypeClassDef().getSuperClass())) {
        // actually do nothing. The new declaration just recalls the previous definition, probably to extend it.
        } else {
            throw new IncompatibleClassChangeError("Type Declaration " + newDeclaration.getTypeName() + " has a different" + " superclass that its previous definition: " + newDeclaration.getTypeClassDef().getSuperClass() + " != " + oldDeclaration.getTypeClassDef().getSuperClass());
        }
    }
    // different duration -> Incompatible
    if (!nullSafeEqualityComparison(oldDeclaration.getDurationAttribute(), newDeclaration.getDurationAttribute())) {
        throw new IncompatibleClassChangeError("Type Declaration " + newDeclaration.getTypeName() + " has a different" + " duration: " + newDeclaration.getDurationAttribute() + " != " + oldDeclaration.getDurationAttribute());
    }
    // //different masks -> incompatible
    if (newDeclaration.getNature().equals(TypeDeclaration.Nature.DEFINITION)) {
        if (oldDeclaration.getSetMask() != newDeclaration.getSetMask()) {
            throw new IncompatibleClassChangeError("Type Declaration " + newDeclaration.getTypeName() + " is incompatible with" + " the previous definition: " + newDeclaration + " != " + oldDeclaration);
        }
    }
    // TODO: further comparison?
    // Field comparison
    List<FactField> oldFields = oldDeclaration.getTypeClassDef().getFields();
    Map<String, FactField> newFieldsMap = new HashMap<String, FactField>();
    for (FactField factField : newDeclaration.getTypeClassDef().getFields()) {
        newFieldsMap.put(factField.getName(), factField);
    }
    // each of the fields in the old definition that are also present in the
    // new definition must have the same type. If not -> Incompatible
    boolean allFieldsInOldDeclarationAreStillPresent = true;
    for (FactField oldFactField : oldFields) {
        FactField newFactField = newFieldsMap.get(oldFactField.getName());
        if (newFactField != null) {
            // we can't use newFactField.getType() since it throws a NPE at this point.
            String newFactType = ((FieldDefinition) newFactField).getTypeName();
            if (!newFactType.equals(((FieldDefinition) oldFactField).getTypeName())) {
                throw new IncompatibleClassChangeError("Type Declaration " + newDeclaration.getTypeName() + "." + newFactField.getName() + " has a different" + " type that its previous definition: " + newFactType + " != " + oldFactField.getType().getCanonicalName());
            }
        } else {
            allFieldsInOldDeclarationAreStillPresent = false;
        }
    }
    // If the old declaration has less fields than the new declaration, oldDefinition < newDefinition
    if (oldFields.size() < newFieldsMap.size()) {
        return -1;
    }
    // If the old declaration has more fields than the new declaration, oldDefinition > newDefinition
    if (oldFields.size() > newFieldsMap.size()) {
        return 1;
    }
    // they are incompatible
    if (allFieldsInOldDeclarationAreStillPresent) {
        return 0;
    }
    // fields in the old declaration are present in the new declaration.
    throw new IncompatibleClassChangeError(newDeclaration.getTypeName() + " introduces" + " fields that are not present in its previous version.");
}
Also used : FactField(org.kie.api.definition.type.FactField) HashMap(java.util.HashMap) FieldDefinition(org.drools.core.factmodel.FieldDefinition)

Example 44 with FieldDefinition

use of org.drools.core.factmodel.FieldDefinition in project drools by kiegroup.

the class KieModuleMavenTest method testKieModulePojoDependencies.

@Test
public void testKieModulePojoDependencies() throws Exception {
    KieServices ks = KieServices.Factory.get();
    // Create and deploy a standard mavenized pojo jar
    String pojoNS = "org.kie.pojos";
    ReleaseId pojoID = KieServices.Factory.get().newReleaseId(pojoNS, "pojojar", "2.0.0");
    String className = "Message";
    ClassDefinition def = new ClassDefinition(pojoNS + "." + className);
    def.addField(new FieldDefinition("text", String.class.getName()));
    byte[] messageClazz = ClassBuilderFactory.getDefaultBeanClassBuilder().buildClass(def, null);
    MemoryFileSystem mfs = new MemoryFileSystem();
    mfs.write(pojoNS.replace('.', '/') + "/" + className + ".class", messageClazz);
    byte[] pomContent = generatePomXml(pojoID).getBytes();
    mfs.write("META-INF/maven/" + pojoID.getGroupId() + "/" + pojoID.getArtifactId() + "/pom.xml", pomContent);
    mfs.write("META-INF/maven/" + pojoID.getGroupId() + "/" + pojoID.getArtifactId() + "/pom.properties", generatePomProperties(pojoID).getBytes());
    byte[] pojojar = mfs.writeAsBytes();
    MavenRepository.getMavenRepository().installArtifact(pojoID, pojojar, pomContent);
    // Create and deploy a kjar that depends on the previous pojo jar
    String kjarNS = "org.kie.test1";
    ReleaseId kjarID = KieServices.Factory.get().newReleaseId(kjarNS, "rkjar", "1.0.0");
    String rule = getRule(kjarNS, pojoNS, "R1");
    String pom = generatePomXml(kjarID, pojoID);
    byte[] rkjar = createKJar(ks, kjarID, pom, rule);
    KieModule kmodule = deployJar(ks, rkjar);
    assertNotNull(kmodule);
    KieContainer kContainer = ks.newKieContainer(kjarID);
    KieSession kSession = kContainer.newKieSession();
    List<?> list = new ArrayList<Object>();
    kSession.setGlobal("list", list);
    kSession.fireAllRules();
    assertEquals(1, list.size());
}
Also used : MemoryFileSystem(org.drools.compiler.compiler.io.memory.MemoryFileSystem) FieldDefinition(org.drools.core.factmodel.FieldDefinition) ArrayList(java.util.ArrayList) KieServices(org.kie.api.KieServices) KieSession(org.kie.api.runtime.KieSession) ReleaseId(org.kie.api.builder.ReleaseId) ClassDefinition(org.drools.core.factmodel.ClassDefinition) InternalKieModule(org.drools.compiler.kie.builder.impl.InternalKieModule) KieModule(org.kie.api.builder.KieModule) KieContainer(org.kie.api.runtime.KieContainer) Test(org.junit.Test)

Aggregations

FieldDefinition (org.drools.core.factmodel.FieldDefinition)44 MethodVisitor (org.mvel2.asm.MethodVisitor)23 Map (java.util.Map)11 Label (org.mvel2.asm.Label)10 BitSet (java.util.BitSet)6 Collection (java.util.Collection)6 ClassDefinition (org.drools.core.factmodel.ClassDefinition)6 HashSet (java.util.HashSet)5 ArrayList (java.util.ArrayList)4 Set (java.util.Set)4 TypeFieldDescr (org.drools.compiler.lang.descr.TypeFieldDescr)4 Field (java.lang.reflect.Field)3 TypeDeclarationError (org.drools.compiler.compiler.TypeDeclarationError)3 FactField (org.kie.api.definition.type.FactField)3 Position (org.kie.api.definition.type.Position)3 IOException (java.io.IOException)2 Method (java.lang.reflect.Method)2 HashMap (java.util.HashMap)2 AnnotationDescr (org.drools.compiler.lang.descr.AnnotationDescr)2 PatternDescr (org.drools.compiler.lang.descr.PatternDescr)2