Search in sources :

Example 6 with TypeFieldDescr

use of org.drools.drl.ast.descr.TypeFieldDescr 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 = getTypedAnnotation(localField, 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.drl.ast.descr.PatternDescr) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) Alias(org.drools.core.factmodel.traits.Alias) FieldDefinition(org.drools.core.factmodel.FieldDefinition) AnnotationDescr(org.drools.drl.ast.descr.AnnotationDescr) Key(org.kie.api.definition.type.Key)

Example 7 with TypeFieldDescr

use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.

the class ClassDefinitionFactory method wireFields.

protected boolean wireFields(AbstractClassTypeDeclarationDescr typeDescr, ClassDefinition def, PackageRegistry pkgRegistry, List<TypeDefinition> unresolvedTypeDefinitions) {
    // Fields are SORTED in the process
    if (!typeDescr.getFields().isEmpty()) {
        if (unresolvedTypeDefinitions != null && !unresolvedTypeDefinitions.isEmpty()) {
            for (TypeFieldDescr fld : typeDescr.getFields().values()) {
                for (TypeDefinition typeDef : unresolvedTypeDefinitions) {
                    if (fld.getPattern().getObjectType().equals(typeDef.getTypeClassName())) {
                        return false;
                    }
                }
            }
        }
        List<FieldDefinition> fieldDefs = sortFields(typeDescr.getFields(), pkgRegistry.getTypeResolver(), kbuilder);
        int i = 0;
        for (FieldDefinition fieldDef : fieldDefs) {
            fieldDef.setIndex(i++);
            def.addField(fieldDef);
        }
    }
    return true;
}
Also used : TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) FieldDefinition(org.drools.core.factmodel.FieldDefinition) GenericTypeDefinition(org.kie.internal.definition.GenericTypeDefinition)

Example 8 with TypeFieldDescr

use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.

the class DescrTypeDefinition method typeFieldsSortedByPosition.

private List<TypeFieldDescr> typeFieldsSortedByPosition(List<FieldDefinition> inheritedFields) {
    Collection<TypeFieldDescr> typeFields = typeDeclarationDescr.getFields().values().stream().filter(f -> inheritedFields.stream().map(FieldDefinition::getFieldName).noneMatch(name -> name.equals(f.getFieldName()))).collect(Collectors.toList());
    TypeFieldDescr[] sortedTypes = new TypeFieldDescr[typeFields.size()];
    List<TypeFieldDescr> nonPositionalFields = new ArrayList<>();
    for (TypeFieldDescr descr : typeFields) {
        AnnotationDescr ann = descr.getAnnotation("Position");
        if (ann == null) {
            nonPositionalFields.add(descr);
        } else {
            int pos = Integer.parseInt(ann.getValue().toString());
            if (pos >= sortedTypes.length) {
                errors.add(new TypeDeclarationError(typeDeclarationDescr, "Out of range position " + pos + " for field '" + descr.getFieldName() + "' on class " + typeDeclarationDescr.getTypeName()));
            } else if (sortedTypes[pos] != null) {
                errors.add(new TypeDeclarationError(typeDeclarationDescr, "Duplicated position " + pos + " for field '" + descr.getFieldName() + "' on class " + typeDeclarationDescr.getTypeName()));
            } else {
                sortedTypes[pos] = descr;
            }
        }
    }
    if (!errors.isEmpty()) {
        return Collections.emptyList();
    }
    int counter = 0;
    for (TypeFieldDescr descr : nonPositionalFields) {
        for (; sortedTypes[counter] != null; counter++) ;
        sortedTypes[counter++] = descr;
    }
    return Arrays.asList(sortedTypes);
}
Also used : QualifiedName(org.drools.drl.ast.descr.QualifiedName) Optional.empty(java.util.Optional.empty) Arrays(java.util.Arrays) AnnotationDescr(org.drools.drl.ast.descr.AnnotationDescr) Optional.of(java.util.Optional.of) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) ArrayList(java.util.ArrayList) FieldDefinition(org.drools.modelcompiler.builder.generator.declaredtype.api.FieldDefinition) TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) PackageDescr(org.drools.drl.ast.descr.PackageDescr) Optional.ofNullable(java.util.Optional.ofNullable) Collection(java.util.Collection) TypeDefinition(org.drools.modelcompiler.builder.generator.declaredtype.api.TypeDefinition) StreamUtils.optionalToStream(org.drools.modelcompiler.util.StreamUtils.optionalToStream) MethodDefinition(org.drools.modelcompiler.builder.generator.declaredtype.api.MethodDefinition) AnnotationDefinition(org.drools.modelcompiler.builder.generator.declaredtype.api.AnnotationDefinition) Collectors(java.util.stream.Collectors) AnnotationDeclarationError(org.drools.compiler.compiler.AnnotationDeclarationError) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Stream(java.util.stream.Stream) TypeDeclarationDescr(org.drools.drl.ast.descr.TypeDeclarationDescr) DroolsError(org.drools.drl.parser.DroolsError) Optional(java.util.Optional) Collections(java.util.Collections) POJOGenerator.quote(org.drools.modelcompiler.builder.generator.declaredtype.POJOGenerator.quote) TypeResolver(org.drools.modelcompiler.builder.generator.declaredtype.api.TypeResolver) TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) ArrayList(java.util.ArrayList) AnnotationDescr(org.drools.drl.ast.descr.AnnotationDescr)

Example 9 with TypeFieldDescr

use of org.drools.drl.ast.descr.TypeFieldDescr 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<>(fields.size());
    int maxDeclaredPos = 0;
    BitSet occupiedPositions = new BitSet(fields.size());
    for (TypeFieldDescr field : fields.values()) {
        GenericTypeDefinition genericType = field.getPattern().getGenericType().map(type -> TypeDeclarationUtils.toBuildableType(type, kbuilder != null ? kbuilder.getRootClassLoader() : null));
        FieldDefinition fieldDef = new FieldDefinition(field.getFieldName(), genericType);
        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 = getTypedAnnotation(field, 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.drl.ast.descr.AnnotationDescr) AnnotationFactory.getTypedAnnotation(org.drools.compiler.rule.builder.util.AnnotationFactory.getTypedAnnotation) Annotation(java.lang.annotation.Annotation) IOException(java.io.IOException) TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) GenericTypeDefinition(org.kie.internal.definition.GenericTypeDefinition)

Example 10 with TypeFieldDescr

use of org.drools.drl.ast.descr.TypeFieldDescr in project drools by kiegroup.

the class ClassHierarchyManager method sortByHierarchy.

/**
 * Utility method to sort declared beans. Linearizes the hierarchy,
 * i.e.generates a sequence of declaration such that, if Sub is subclass of
 * Sup, then the index of Sub will be > than the index of Sup in the
 * resulting collection. This ensures that superclasses are processed before
 * their subclasses
 */
protected List<AbstractClassTypeDeclarationDescr> sortByHierarchy(Collection<AbstractClassTypeDeclarationDescr> unsortedDescrs, KnowledgeBuilderImpl kbuilder) {
    taxonomy = new HashMap<>();
    Map<QualifiedName, AbstractClassTypeDeclarationDescr> cache = new HashMap<>();
    for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
        cache.put(tdescr.getType(), tdescr);
    }
    for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
        QualifiedName name = tdescr.getType();
        Collection<QualifiedName> supers = taxonomy.get(name);
        if (supers == null) {
            supers = new ArrayList<>();
            taxonomy.put(name, supers);
        } else {
            kbuilder.addBuilderResult(new TypeDeclarationError(tdescr, "Found duplicate declaration for type " + tdescr.getType()));
        }
        boolean circular = false;
        for (QualifiedName sup : tdescr.getSuperTypes()) {
            if (!Object.class.getName().equals(name.getFullName())) {
                if (!hasCircularDependency(tdescr.getType(), sup, taxonomy)) {
                    if (cache.containsKey(sup)) {
                        supers.add(sup);
                    }
                } else {
                    circular = true;
                    kbuilder.addBuilderResult(new TypeDeclarationError(tdescr, "Found circular dependency for type " + tdescr.getTypeName()));
                    break;
                }
            }
        }
        if (circular) {
            tdescr.getSuperTypes().clear();
        }
    }
    for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
        for (TypeFieldDescr field : tdescr.getFields().values()) {
            QualifiedName name = tdescr.getType();
            QualifiedName typeName = new QualifiedName(field.getPattern().getGenericType().getRawType());
            if (!hasCircularDependency(name, typeName, taxonomy)) {
                if (cache.containsKey(typeName)) {
                    taxonomy.get(name).add(typeName);
                }
            } else {
                field.setRecursive(true);
            }
        }
    }
    List<QualifiedName> sorted = new HierarchySorter<QualifiedName>().sort(taxonomy);
    ArrayList list = new ArrayList(sorted.size());
    for (QualifiedName name : sorted) {
        list.add(cache.get(name));
    }
    return list;
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) QualifiedName(org.drools.drl.ast.descr.QualifiedName) ArrayList(java.util.ArrayList) TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) AbstractClassTypeDeclarationDescr(org.drools.drl.ast.descr.AbstractClassTypeDeclarationDescr)

Aggregations

TypeFieldDescr (org.drools.drl.ast.descr.TypeFieldDescr)15 TypeDeclarationError (org.drools.compiler.compiler.TypeDeclarationError)6 TypeDeclarationDescr (org.drools.drl.ast.descr.TypeDeclarationDescr)6 ArrayList (java.util.ArrayList)5 PackageDescr (org.drools.drl.ast.descr.PackageDescr)5 PatternDescr (org.drools.drl.ast.descr.PatternDescr)5 IOException (java.io.IOException)4 InternalKnowledgePackage (org.drools.core.definitions.InternalKnowledgePackage)4 FieldDefinition (org.drools.core.factmodel.FieldDefinition)4 AnnotationDescr (org.drools.drl.ast.descr.AnnotationDescr)4 HashMap (java.util.HashMap)3 ClassFieldInspector (org.drools.core.base.ClassFieldInspector)3 TypeDeclaration (org.drools.core.rule.TypeDeclaration)3 QualifiedName (org.drools.drl.ast.descr.QualifiedName)3 Arrays (java.util.Arrays)2 Collection (java.util.Collection)2 Collections (java.util.Collections)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 Optional (java.util.Optional)2