Search in sources :

Example 21 with FieldDefinition

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

the class ClassDefinitionFactory method populateDefinitionFromClass.

public static void populateDefinitionFromClass(ClassDefinition def, Resource resource, Class<?> concrete, boolean asTrait) {
    try {
        def.setClassName(concrete.getName());
        if (concrete.getSuperclass() != null) {
            def.setSuperClass(concrete.getSuperclass().getName());
        }
        ClassFieldInspector inspector = new ClassFieldInspector(concrete);
        Map<String, Method> methods = inspector.getGetterMethods();
        Map<String, Method> setters = inspector.getSetterMethods();
        int j = 0;
        Map<String, TypeFieldDescr> fields = new HashMap<String, TypeFieldDescr>();
        for (String fieldName : methods.keySet()) {
            if (asTrait && ("core".equals(fieldName) || "fields".equals(fieldName))) {
                continue;
            }
            if (!inspector.isNonGetter(fieldName) && setters.keySet().contains(fieldName)) {
                Position position = null;
                if (!concrete.isInterface()) {
                    try {
                        Field fld = concrete.getDeclaredField(fieldName);
                        position = fld.getAnnotation(Position.class);
                    } catch (NoSuchFieldException nsfe) {
                    // @Position can only annotate fields. This x means that a getter/setter pair was found with no field
                    }
                }
                Class ret = methods.get(fieldName).getReturnType();
                TypeFieldDescr field = new TypeFieldDescr();
                field.setResource(resource);
                field.setFieldName(fieldName);
                field.setPattern(new PatternDescr(ret.getName()));
                field.setIndex(position != null ? position.value() : -1);
                fields.put(fieldName, field);
            }
        }
        if (!fields.isEmpty()) {
            List<FieldDefinition> fieldDefs = sortFields(fields, null, null);
            int i = 0;
            for (FieldDefinition fieldDef : fieldDefs) {
                fieldDef.setIndex(i++);
                def.addField(fieldDef);
            }
        }
        Set<String> interfaces = new HashSet<String>();
        Collections.addAll(interfaces, def.getInterfaces());
        for (Class iKlass : ClassUtils.getAllImplementedInterfaceNames(concrete)) {
            interfaces.add(iKlass.getName());
        }
        def.setInterfaces(interfaces.toArray(new String[interfaces.size()]));
        def.setDefinedClass(concrete);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Also used : PatternDescr(org.drools.compiler.lang.descr.PatternDescr) HashMap(java.util.HashMap) Position(org.kie.api.definition.type.Position) FieldDefinition(org.drools.core.factmodel.FieldDefinition) Method(java.lang.reflect.Method) IOException(java.io.IOException) Field(java.lang.reflect.Field) TypeFieldDescr(org.drools.compiler.lang.descr.TypeFieldDescr) ClassFieldInspector(org.drools.core.util.asm.ClassFieldInspector) HashSet(java.util.HashSet)

Example 22 with FieldDefinition

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

the class ClassHierarchyManager method buildInheritedFieldDescrFromDefinition.

protected TypeFieldDescr buildInheritedFieldDescrFromDefinition(org.kie.api.definition.type.FactField fld, TypeDeclarationDescr typeDescr) {
    TypeFieldDescr inheritedFldDescr = new TypeFieldDescr();
    inheritedFldDescr.setFieldName(fld.getName());
    inheritedFldDescr.setResource(typeDescr.getResource());
    PatternDescr fldType = new PatternDescr();
    fldType.setObjectType(((FieldDefinition) fld).getTypeName());
    // also sets resource for PatternDescr fldType
    inheritedFldDescr.setPattern(fldType);
    if (fld.isKey()) {
        AnnotationDescr keyAnnotation = new AnnotationDescr(Key.class.getCanonicalName());
        keyAnnotation.setFullyQualifiedName(Key.class.getCanonicalName());
        keyAnnotation.setResource(typeDescr.getResource());
        inheritedFldDescr.addAnnotation(keyAnnotation);
    }
    inheritedFldDescr.setIndex(((FieldDefinition) fld).getDeclIndex());
    inheritedFldDescr.setInherited(true);
    String initExprOverride = ((FieldDefinition) fld).getInitExpr();
    int overrideCount = 0;
    // only @aliasing local fields may override defaults.
    for (TypeFieldDescr localField : typeDescr.getFields().values()) {
        Alias alias = localField.getTypedAnnotation(Alias.class);
        if (alias != null && fld.getName().equals(alias.value().replaceAll("\"", "")) && localField.getInitExpr() != null) {
            overrideCount++;
            initExprOverride = localField.getInitExpr();
        }
    }
    if (overrideCount > 1) {
        // however, only one is allowed
        initExprOverride = null;
    }
    inheritedFldDescr.setInitExpr(initExprOverride);
    return inheritedFldDescr;
}
Also used : PatternDescr(org.drools.compiler.lang.descr.PatternDescr) TypeFieldDescr(org.drools.compiler.lang.descr.TypeFieldDescr) Alias(org.drools.core.factmodel.traits.Alias) FieldDefinition(org.drools.core.factmodel.FieldDefinition) AnnotationDescr(org.drools.compiler.lang.descr.AnnotationDescr) Key(org.kie.api.definition.type.Key)

Example 23 with FieldDefinition

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

the class TypeDeclarationBuilder method updateTraitInformation.

protected void updateTraitInformation(AbstractClassTypeDeclarationDescr typeDescr, TypeDeclaration type, ClassDefinition def, PackageRegistry pkgRegistry) {
    if (typeDescr.hasAnnotation(Traitable.class) || (!type.getKind().equals(TypeDeclaration.Kind.TRAIT) && kbuilder.getPackageRegistry().containsKey(def.getSuperClass()) && kbuilder.getPackageRegistry(def.getSuperClass()).getTraitRegistry().getTraitables().containsKey(def.getSuperClass()))) {
        // traitable
        if (type.isNovel()) {
            try {
                PackageRegistry reg = kbuilder.getPackageRegistry(typeDescr.getNamespace());
                String availableName = typeDescr.getType().getFullName();
                Class<?> resolvedType = reg.getTypeResolver().resolveType(availableName);
                updateTraitDefinition(type, resolvedType, false);
            } catch (ClassNotFoundException cnfe) {
            // we already know the class exists
            }
        }
        pkgRegistry.getTraitRegistry().addTraitable(def);
    } else if (type.getKind().equals(TypeDeclaration.Kind.TRAIT) || typeDescr.hasAnnotation(Trait.class)) {
        // trait
        if (!type.isNovel()) {
            try {
                PackageRegistry reg = kbuilder.getPackageRegistry(typeDescr.getNamespace());
                String availableName = typeDescr.getType().getFullName();
                Class<?> resolvedType = reg.getTypeResolver().resolveType(availableName);
                if (!Thing.class.isAssignableFrom(resolvedType)) {
                    if (!resolvedType.isInterface()) {
                        kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Unable to redeclare concrete class " + resolvedType.getName() + " as a trait."));
                        return;
                    }
                    updateTraitDefinition(type, resolvedType, false);
                    String target = typeDescr.getTypeName() + TraitFactory.SUFFIX;
                    TypeDeclarationDescr tempDescr = new TypeDeclarationDescr();
                    tempDescr.setNamespace(typeDescr.getNamespace());
                    tempDescr.setFields(typeDescr.getFields());
                    tempDescr.setType(target, typeDescr.getNamespace());
                    tempDescr.setTrait(true);
                    tempDescr.addSuperType(typeDescr.getType());
                    tempDescr.setResource(type.getResource());
                    TypeDeclaration tempDeclr = new TypeDeclaration(target);
                    tempDeclr.setKind(TypeDeclaration.Kind.TRAIT);
                    tempDeclr.setTypesafe(type.isTypesafe());
                    tempDeclr.setNovel(true);
                    tempDeclr.setTypeClassName(tempDescr.getType().getFullName());
                    tempDeclr.setResource(type.getResource());
                    ClassDefinition tempDef = new ClassDefinition(target);
                    tempDef.setClassName(tempDescr.getType().getFullName());
                    tempDef.setTraitable(false);
                    for (FieldDefinition fld : def.getFieldsDefinitions()) {
                        tempDef.addField(fld);
                    }
                    tempDef.setInterfaces(def.getInterfaces());
                    tempDef.setSuperClass(def.getClassName());
                    tempDef.setDefinedClass(resolvedType);
                    tempDef.setAbstrakt(true);
                    tempDeclr.setTypeClassDef(tempDef);
                    declaredClassBuilder.generateBeanFromDefinition(tempDescr, tempDeclr, pkgRegistry, tempDef);
                    try {
                        Class<?> clazz = pkgRegistry.getTypeResolver().resolveType(tempDescr.getType().getFullName());
                        tempDeclr.setTypeClass(clazz);
                        pkgRegistry.getTraitRegistry().addTrait(tempDef.getClassName().replace(TraitFactory.SUFFIX, ""), tempDef);
                    } catch (ClassNotFoundException cnfe) {
                        kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Internal Trait extension Class '" + target + "' could not be generated correctly'"));
                    } finally {
                        pkgRegistry.getPackage().addTypeDeclaration(tempDeclr);
                    }
                } else {
                    updateTraitDefinition(type, resolvedType, true);
                    pkgRegistry.getTraitRegistry().addTrait(def);
                }
            } catch (ClassNotFoundException cnfe) {
            // we already know the class exists
            }
        } else {
            if (def.getClassName().endsWith(TraitFactory.SUFFIX)) {
                pkgRegistry.getTraitRegistry().addTrait(def.getClassName().replace(TraitFactory.SUFFIX, ""), def);
            } else {
                pkgRegistry.getTraitRegistry().addTrait(def);
            }
        }
    }
}
Also used : TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) PackageRegistry(org.drools.compiler.compiler.PackageRegistry) AbstractClassTypeDeclarationDescr(org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr) TypeDeclarationDescr(org.drools.compiler.lang.descr.TypeDeclarationDescr) FieldDefinition(org.drools.core.factmodel.FieldDefinition) Traitable(org.drools.core.factmodel.traits.Traitable) ClassDefinition(org.drools.core.factmodel.ClassDefinition) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 24 with FieldDefinition

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

the class TypeDeclarationConfigurator method buildFieldAccessors.

protected void buildFieldAccessors(final TypeDeclaration type, final PackageRegistry pkgRegistry) throws SecurityException, IllegalArgumentException, InstantiationException, IllegalAccessException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    ClassDefinition cd = type.getTypeClassDef();
    ClassFieldAccessorStore store = pkgRegistry.getPackage().getClassFieldAccessorStore();
    for (FieldDefinition attrDef : cd.getFieldsDefinitions()) {
        ClassFieldAccessor accessor = store.getAccessor(cd.getDefinedClass().getName(), attrDef.getName());
        attrDef.setReadWriteAccessor(accessor);
    }
}
Also used : ClassFieldAccessor(org.drools.core.base.ClassFieldAccessor) FieldDefinition(org.drools.core.factmodel.FieldDefinition) ClassFieldAccessorStore(org.drools.core.base.ClassFieldAccessorStore) ClassDefinition(org.drools.core.factmodel.ClassDefinition)

Example 25 with FieldDefinition

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

the class ClassDefinitionFactory method sortFields.

private static List<FieldDefinition> sortFields(Map<String, TypeFieldDescr> fields, TypeResolver typeResolver, KnowledgeBuilderImpl kbuilder) {
    List<FieldDefinition> fieldDefs = new ArrayList<FieldDefinition>(fields.size());
    int maxDeclaredPos = 0;
    BitSet occupiedPositions = new BitSet(fields.size());
    for (TypeFieldDescr field : fields.values()) {
        String typeName = field.getPattern().getObjectType();
        String typeNameKey = typeName;
        String fullFieldType = kbuilder != null ? TypeDeclarationUtils.toBuildableType(typeNameKey, kbuilder.getRootClassLoader()) : typeNameKey;
        FieldDefinition fieldDef = new FieldDefinition(field.getFieldName(), fullFieldType);
        fieldDefs.add(fieldDef);
        if (field.hasOverride()) {
            fieldDef.setOverriding(field.getOverriding().getPattern().getObjectType());
        }
        fieldDef.setInherited(field.isInherited());
        fieldDef.setRecursive(field.isRecursive());
        fieldDef.setInitExpr(TypeDeclarationUtils.rewriteInitExprWithImports(field.getInitExpr(), typeResolver));
        if (field.getIndex() >= 0) {
            int pos = field.getIndex();
            occupiedPositions.set(pos);
            maxDeclaredPos = Math.max(maxDeclaredPos, pos);
            fieldDef.addMetaData("position", pos);
        } else {
            Position position = field.getTypedAnnotation(Position.class);
            if (position != null) {
                int pos = position.value();
                field.setIndex(pos);
                occupiedPositions.set(pos);
                maxDeclaredPos = Math.max(maxDeclaredPos, pos);
                fieldDef.addMetaData("position", pos);
            }
        }
        if (field.hasAnnotation(Key.class)) {
            fieldDef.setKey(true);
            fieldDef.addMetaData("key", null);
        }
        for (AnnotationDescr annotationDescr : field.getAnnotations()) {
            if (annotationDescr.getFullyQualifiedName() == null) {
                if (annotationDescr.isStrict()) {
                    kbuilder.addBuilderResult(new TypeDeclarationError(field, "Unknown annotation @" + annotationDescr.getName() + " on field " + field.getFieldName()));
                } else {
                    // Annotation is custom metadata
                    fieldDef.addMetaData(annotationDescr.getName(), annotationDescr.getSingleValue());
                    continue;
                }
            }
            Annotation annotation = AnnotationFactory.buildAnnotation(typeResolver, annotationDescr);
            if (annotation != null) {
                try {
                    AnnotationDefinition annotationDefinition = AnnotationDefinition.build(annotation.annotationType(), field.getAnnotation(annotationDescr.getFullyQualifiedName()).getValueMap(), typeResolver);
                    fieldDef.addAnnotation(annotationDefinition);
                } catch (Exception e) {
                    kbuilder.addBuilderResult(new TypeDeclarationError(field, "Annotated field " + field.getFieldName() + "  - undefined property in @annotation " + annotationDescr.getName() + ": " + e.getMessage() + ";"));
                }
            } else {
                if (annotationDescr.isStrict()) {
                    kbuilder.addBuilderResult(new TypeDeclarationError(field, "Unknown annotation @" + annotationDescr.getName() + " on field " + field.getFieldName()));
                }
            }
        }
        fieldDef.setDeclIndex(field.getIndex());
    }
    int curr = 0;
    for (FieldDefinition fieldDef : fieldDefs) {
        if (fieldDef.getDeclIndex() < 0) {
            int freePos = occupiedPositions.nextClearBit(0);
            if (freePos < maxDeclaredPos) {
                occupiedPositions.set(freePos);
            } else {
                freePos = maxDeclaredPos + 1;
            }
            fieldDef.setPriority(freePos * 256 + curr++);
        } else {
            fieldDef.setPriority(fieldDef.getDeclIndex() * 256 + curr++);
        }
    }
    Collections.sort(fieldDefs);
    return fieldDefs;
}
Also used : AnnotationDefinition(org.drools.core.factmodel.AnnotationDefinition) Position(org.kie.api.definition.type.Position) FieldDefinition(org.drools.core.factmodel.FieldDefinition) ArrayList(java.util.ArrayList) BitSet(java.util.BitSet) AnnotationDescr(org.drools.compiler.lang.descr.AnnotationDescr) Annotation(java.lang.annotation.Annotation) IOException(java.io.IOException) TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) TypeFieldDescr(org.drools.compiler.lang.descr.TypeFieldDescr)

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