Search in sources :

Example 1 with TypeFieldDescr

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

the class KnowledgeBuilderTest method testTypeDeclarationWithFieldMetadata.

@Test
public void testTypeDeclarationWithFieldMetadata() throws Exception {
    PackageDescr pkgDescr = new PackageDescr("org.drools.mvel.compiler.test");
    TypeDeclarationDescr typeDescr = new TypeDeclarationDescr("TypeWithFieldMeta");
    TypeFieldDescr f1 = new TypeFieldDescr("field", new PatternDescr("String"));
    f1.addAnnotation("custom", null);
    typeDescr.addField(f1);
    pkgDescr.addTypeDeclaration(typeDescr);
    KnowledgeBuilderImpl builder = new KnowledgeBuilderImpl();
    builder.addPackage(pkgDescr);
    assertFalse(builder.hasErrors());
    InternalKnowledgePackage bp = builder.getPackage(pkgDescr.getName());
    final FactType factType = bp.getFactType("org.drools.mvel.compiler.test.TypeWithFieldMeta");
    assertNotNull(factType);
    final FactField field = factType.getField("field");
    assertNotNull(field);
    final Map<String, Object> fieldMetaData = field.getMetaData();
    assertNotNull("No field-level custom metadata got compiled", fieldMetaData);
    assertTrue("Field metadata does not include expected value", fieldMetaData.containsKey("custom"));
}
Also used : FactField(org.kie.api.definition.type.FactField) TypeDeclarationDescr(org.drools.drl.ast.descr.TypeDeclarationDescr) PatternDescr(org.drools.drl.ast.descr.PatternDescr) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) KnowledgeBuilderImpl(org.drools.compiler.builder.impl.KnowledgeBuilderImpl) PackageDescr(org.drools.drl.ast.descr.PackageDescr) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage) FactType(org.kie.api.definition.type.FactType) Test(org.junit.Test)

Example 2 with TypeFieldDescr

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

the class KnowledgeBuilderTest method testTypeDeclarationNewBean.

@Test
public void testTypeDeclarationNewBean() throws Exception {
    PackageDescr pkgDescr = new PackageDescr("org.drools.mvel.compiler.test");
    TypeDeclarationDescr typeDescr = new TypeDeclarationDescr("NewBean");
    TypeFieldDescr f1 = new TypeFieldDescr("name", new PatternDescr("String"));
    TypeFieldDescr f2 = new TypeFieldDescr("age", new PatternDescr("int"));
    typeDescr.addField(f1);
    typeDescr.addField(f2);
    pkgDescr.addTypeDeclaration(typeDescr);
    KnowledgeBuilderImpl builder = new KnowledgeBuilderImpl();
    builder.addPackage(pkgDescr);
    InternalKnowledgePackage pkg = builder.getPackage(pkgDescr.getName());
    assertEquals(1, pkg.getTypeDeclarations().size());
    TypeDeclaration type = pkg.getTypeDeclaration("NewBean");
    assertEquals("NewBean", type.getTypeName());
    assertEquals(Role.Type.FACT, type.getRole());
    assertEquals("org.drools.mvel.compiler.test.NewBean", type.getTypeClass().getName());
    assertFalse(builder.hasErrors());
    InternalKnowledgePackage bp = builder.getPackage(pkgDescr.getName());
    Class newBean = bp.getPackageClassLoader().loadClass("org.drools.mvel.compiler.test.NewBean");
    assertNotNull(newBean);
}
Also used : TypeDeclarationDescr(org.drools.drl.ast.descr.TypeDeclarationDescr) PatternDescr(org.drools.drl.ast.descr.PatternDescr) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) KnowledgeBuilderImpl(org.drools.compiler.builder.impl.KnowledgeBuilderImpl) PackageDescr(org.drools.drl.ast.descr.PackageDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage) Test(org.junit.Test)

Example 3 with TypeFieldDescr

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

the class ChangeSetBuilder method build.

public static KieJarChangeSet build(InternalKieModule original, InternalKieModule currentJar) {
    KieJarChangeSet result = new KieJarChangeSet();
    Collection<String> originalFiles = original.getFileNames();
    Collection<String> currentFiles = currentJar.getFileNames();
    ArrayList<String> removedFiles = new ArrayList<>(originalFiles);
    removedFiles.removeAll(currentFiles);
    if (!removedFiles.isEmpty()) {
        for (String file : removedFiles) {
            // there should be a way to get the JAR name/url to produce a proper URL for the file in it
            result.removeFile(file);
        }
    }
    List<TypeDeclarationDescr> typeDeclarations = new ArrayList<>();
    Map<String, String> changedClasses = new HashMap<>();
    for (String file : currentFiles) {
        if (originalFiles.contains(file)) {
            // check for modification
            byte[] ob = original.getBytes(file);
            byte[] cb = currentJar.getBytes(file);
            if (!Arrays.equals(ob, cb)) {
                if (file.endsWith(".class")) {
                    changedClasses.put(convertResourceToClassName(file), file);
                } else if (!ResourceType.DRL.matchesExtension(file) || !StringUtils.codeAwareEqualsIgnoreSpaces(new String(ob), new String(cb))) {
                    // check that: (NOT drl file) OR (NOT equalsIgnoringSpaces)
                    // parse the file to figure out the difference
                    result.registerChanges(file, diffResource(file, ob, cb, typeDeclarations));
                }
            }
        } else {
            // file was added
            result.addFile(file);
        }
    }
    for (TypeDeclarationDescr typeDeclaration : typeDeclarations) {
        String fqn = typeDeclaration.getFullTypeName();
        if (changedClasses.containsKey(fqn)) {
            continue;
        }
        InternalKnowledgePackage pkg = original.getPackage(typeDeclaration.getNamespace());
        if (pkg == null) {
            continue;
        }
        TypeResolver resolver = pkg.getTypeResolver();
        for (TypeFieldDescr field : typeDeclaration.getFields().values()) {
            String fieldType;
            try {
                fieldType = resolver.resolveType(field.getPattern().getObjectType()).getCanonicalName();
            } catch (ClassNotFoundException e) {
                continue;
            }
            if (changedClasses.containsKey(fieldType)) {
                changedClasses.put(fqn, convertClassToResourcePath(fqn));
                break;
            }
        }
    }
    for (String changedClass : changedClasses.values()) {
        result.registerChanges(changedClass, new ResourceChangeSet(changedClass, ChangeType.UPDATED));
    }
    if (original.getKieModuleModel() != null) {
        for (String kieBaseName : original.getKieModuleModel().getKieBaseModels().keySet()) {
            KnowledgeBuilder originalKbuilder = original.getKnowledgeBuilderForKieBase(kieBaseName);
            if (originalKbuilder != null && currentJar.getKnowledgeBuilderForKieBase(kieBaseName) == null) {
                currentJar.cacheKnowledgeBuilderForKieBase(kieBaseName, originalKbuilder);
            }
        }
    }
    return result;
}
Also used : TypeDeclarationDescr(org.drools.drl.ast.descr.TypeDeclarationDescr) HashMap(java.util.HashMap) TypeResolver(org.drools.core.addon.TypeResolver) ArrayList(java.util.ArrayList) ResourceChangeSet(org.kie.internal.builder.ResourceChangeSet) KnowledgeBuilder(org.kie.internal.builder.KnowledgeBuilder) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage)

Example 4 with TypeFieldDescr

use of org.drools.drl.ast.descr.TypeFieldDescr 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 = CoreComponentsBuilder.get().createClassFieldInspector(concrete);
        Map<String, Method> methods = inspector.getGetterMethods();
        Map<String, Method> setters = inspector.getSetterMethods();
        Map<String, TypeFieldDescr> fields = new HashMap<>();
        for (String fieldName : methods.keySet()) {
            if (asTrait && ("core".equals(fieldName) || "fields".equals(fieldName))) {
                continue;
            }
            if (!inspector.isNonGetter(fieldName) && setters.containsKey(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<>();
        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.drl.ast.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.drl.ast.descr.TypeFieldDescr) ClassFieldInspector(org.drools.core.base.ClassFieldInspector) HashSet(java.util.HashSet)

Example 5 with TypeFieldDescr

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

the class ClassHierarchyManager method mergeFields.

protected void mergeFields(String simpleSuperTypeName, String superTypePackageName, String fullSuper, TypeDeclarationDescr typeDescr, Map<String, AbstractClassTypeDeclarationDescr> unprocessableDescrs, TypeResolver resolver) {
    Map<String, TypeFieldDescr> fieldMap = new LinkedHashMap<>();
    PackageRegistry registry = kbuilder.getPackageRegistry(superTypePackageName);
    InternalKnowledgePackage pack = null;
    if (registry != null) {
        pack = registry.getPackage();
    }
    if (unprocessableDescrs.containsKey(fullSuper)) {
        unprocessableDescrs.put(typeDescr.getType().getFullName(), typeDescr);
        return;
    }
    // if a class is declared in DRL, its package can't be null? The default package is replaced by "defaultpkg"
    boolean isSuperClassTagged = false;
    // in the same package, or in a previous one
    boolean isSuperClassDeclared = true;
    if (pack != null) {
        // look for the supertype declaration in available packages
        TypeDeclaration superTypeDeclaration = pack.getTypeDeclaration(simpleSuperTypeName);
        if (superTypeDeclaration != null && superTypeDeclaration.getTypeClassDef() != null) {
            ClassDefinition classDef = superTypeDeclaration.getTypeClassDef();
            // inherit fields
            for (org.kie.api.definition.type.FactField fld : classDef.getFields()) {
                TypeFieldDescr inheritedFlDescr = buildInheritedFieldDescrFromDefinition(fld, typeDescr);
                fieldMap.put(inheritedFlDescr.getFieldName(), inheritedFlDescr);
            }
            // new classes are already distinguished from tagged external classes
            isSuperClassTagged = !superTypeDeclaration.isNovel();
        }
    } else {
        isSuperClassDeclared = false;
    }
    // look for the class externally
    if (!isSuperClassDeclared || isSuperClassTagged) {
        try {
            Class superKlass;
            if (registry != null) {
                superKlass = registry.getTypeResolver().resolveType(fullSuper);
            } else {
                // if the supertype has not been declared, and we have got so far, it means that this class is not novel
                superKlass = resolver.resolveType(fullSuper);
            }
            buildDescrsFromFields(superKlass, typeDescr, fieldMap);
        } catch (ClassNotFoundException cnfe) {
            unprocessableDescrs.put(typeDescr.getType().getFullName(), typeDescr);
            return;
        }
    }
    // notice that it is not possible to override a field changing its type
    for (String fieldName : typeDescr.getFields().keySet()) {
        if (fieldMap.containsKey(fieldName)) {
            String type1 = fieldMap.get(fieldName).getPattern().getObjectType();
            String type2 = typeDescr.getFields().get(fieldName).getPattern().getObjectType();
            if (type2.lastIndexOf(".") < 0) {
                try {
                    TypeResolver typeResolver = kbuilder.getPackageRegistry(typeDescr.getNamespace()).getTypeResolver();
                    type1 = typeResolver.resolveType(type1).getName();
                    type2 = typeResolver.resolveType(type2).getName();
                    // now that we are at it... this will be needed later anyway
                    fieldMap.get(fieldName).getPattern().setObjectType(type1);
                    typeDescr.getFields().get(fieldName).getPattern().setObjectType(type2);
                } catch (ClassNotFoundException cnfe) {
                // will fail later
                }
            }
            boolean clash = !type1.equals(type2);
            TypeFieldDescr overriding = null;
            if (clash) {
                // this may still be an override using a subclass of the original type
                try {
                    Class<?> sup = resolver.resolveType(type1);
                    Class<?> loc = resolver.resolveType(type2);
                    if (sup.isAssignableFrom(loc)) {
                        clash = false;
                        // mark as non inherited so that a new field is actually built
                        overriding = fieldMap.get(fieldName);
                    }
                } catch (ClassNotFoundException cnfe) {
                // not much to do
                }
            }
            if (clash) {
                kbuilder.addBuilderResult(new TypeDeclarationError(typeDescr, "Cannot redeclare field '" + fieldName + " from " + type1 + " to " + type2));
                typeDescr.setType(null, null);
                return;
            } else {
                String initVal = fieldMap.get(fieldName).getInitExpr();
                TypeFieldDescr fd = typeDescr.getFields().get(fieldName);
                if (fd.getInitExpr() == null) {
                    fd.setInitExpr(initVal);
                }
                fd.setInherited(fieldMap.get(fieldName).isInherited());
                fd.setOverriding(overriding);
                for (String key : fieldMap.get(fieldName).getAnnotationNames()) {
                    if (fd.getAnnotation(key) == null) {
                        fd.addAnnotation(fieldMap.get(fieldName).getAnnotation(key));
                    }
                }
                if (fd.getIndex() < 0) {
                    fd.setIndex(fieldMap.get(fieldName).getIndex());
                }
            }
        }
        fieldMap.put(fieldName, typeDescr.getFields().get(fieldName));
    }
    typeDescr.setFields(fieldMap);
}
Also used : TypeResolver(org.drools.core.addon.TypeResolver) ClassDefinition(org.drools.core.factmodel.ClassDefinition) LinkedHashMap(java.util.LinkedHashMap) TypeDeclarationError(org.drools.compiler.compiler.TypeDeclarationError) PackageRegistry(org.drools.compiler.compiler.PackageRegistry) TypeFieldDescr(org.drools.drl.ast.descr.TypeFieldDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage)

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