Search in sources :

Example 1 with TypeResolver

use of org.drools.core.addon.TypeResolver in project drools by kiegroup.

the class RuleBuildContext method initRuleUnitClassName.

private void initRuleUnitClassName() {
    String ruleUnitClassName = rule.getRuleUnitClassName();
    boolean nameInferredFromResource = false;
    if (ruleUnitClassName == null && rule.getResource() != null && rule.getResource().getSourcePath() != null) {
        // We cannot depend on splitting based on File.separator, because e.g. MemoryFileSystem is "/" based
        // also on Windows => We need to parse the classname based on Java classname allowed characters.
        ruleUnitClassName = extractClassNameFromSourcePath();
        nameInferredFromResource = true;
    }
    if (RuleUnitComponentFactory.get() != null && ruleUnitClassName != null) {
        TypeResolver typeResolver = getPkg().getTypeResolver();
        boolean unitFound = false;
        Class<?> ruleUnitClass = ClassUtils.safeLoadClass(typeResolver.getClassLoader(), ruleUnitClassName);
        if (ruleUnitClass != null) {
            unitFound = RuleUnitComponentFactory.get().isRuleUnitClass(ruleUnitClass);
            if (unitFound && nameInferredFromResource) {
                rule.setRuleUnitClassName(ruleUnitClassName);
            }
        }
        if (!unitFound && !nameInferredFromResource) {
            addError(new RuleBuildError(rule, getParentDescr(), null, ruleUnitClassName + " is not a valid RuleUnit class name"));
        }
    }
}
Also used : TypeResolver(org.drools.core.addon.TypeResolver) RuleBuildError(org.drools.compiler.compiler.RuleBuildError)

Example 2 with TypeResolver

use of org.drools.core.addon.TypeResolver in project drools by kiegroup.

the class CompilerTest method test.

default void test(Consumer<MvelCompilerContext> testFunction, String inputExpression, String expectedResult, Consumer<CompiledBlockResult> resultAssert) {
    Set<String> imports = new HashSet<>();
    imports.add("java.util.List");
    imports.add("java.util.ArrayList");
    imports.add("java.util.HashMap");
    imports.add("java.util.Map");
    imports.add("java.math.BigDecimal");
    imports.add("org.drools.Address");
    imports.add(Person.class.getCanonicalName());
    imports.add(Gender.class.getCanonicalName());
    TypeResolver typeResolver = new ClassTypeResolver(imports, this.getClass().getClassLoader());
    MvelCompilerContext mvelCompilerContext = new MvelCompilerContext(typeResolver);
    testFunction.accept(mvelCompilerContext);
    CompiledBlockResult compiled = new MvelCompiler(mvelCompilerContext).compileStatement(inputExpression);
    verifyBodyWithBetterDiff(expectedResult, compiled.resultAsString());
    resultAssert.accept(compiled);
}
Also used : MvelCompilerContext(org.drools.mvelcompiler.context.MvelCompilerContext) TypeResolver(org.drools.core.addon.TypeResolver) ClassTypeResolver(org.drools.core.addon.ClassTypeResolver) Gender(org.drools.Gender) Person(org.drools.Person) ClassTypeResolver(org.drools.core.addon.ClassTypeResolver) HashSet(java.util.HashSet)

Example 3 with TypeResolver

use of org.drools.core.addon.TypeResolver in project drools by kiegroup.

the class ConstraintCompilerTest method testExpression.

public void testExpression(Consumer<MvelCompilerContext> testFunction, String inputExpression, String expectedResult, Consumer<CompiledExpressionResult> resultAssert) {
    Set<String> imports = new HashSet<>();
    imports.add("java.util.List");
    imports.add("java.util.ArrayList");
    imports.add("java.util.HashMap");
    imports.add("java.util.Map");
    imports.add("java.math.BigDecimal");
    imports.add("org.drools.Address");
    imports.add(Person.class.getCanonicalName());
    imports.add(Gender.class.getCanonicalName());
    TypeResolver typeResolver = new ClassTypeResolver(imports, this.getClass().getClassLoader());
    MvelCompilerContext mvelCompilerContext = new MvelCompilerContext(typeResolver);
    testFunction.accept(mvelCompilerContext);
    CompiledExpressionResult compiled = new ConstraintCompiler(mvelCompilerContext).compileExpression(inputExpression);
    verifyBodyWithBetterDiff(expectedResult, compiled.resultAsString());
    resultAssert.accept(compiled);
}
Also used : MvelCompilerContext(org.drools.mvelcompiler.context.MvelCompilerContext) ClassTypeResolver(org.drools.core.addon.ClassTypeResolver) TypeResolver(org.drools.core.addon.TypeResolver) Gender(org.drools.Gender) Person(org.drools.Person) ClassTypeResolver(org.drools.core.addon.ClassTypeResolver) HashSet(java.util.HashSet)

Example 4 with TypeResolver

use of org.drools.core.addon.TypeResolver 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 5 with TypeResolver

use of org.drools.core.addon.TypeResolver 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

TypeResolver (org.drools.core.addon.TypeResolver)12 HashSet (java.util.HashSet)7 ClassTypeResolver (org.drools.core.addon.ClassTypeResolver)6 InternalKnowledgePackage (org.drools.core.definitions.InternalKnowledgePackage)3 MvelCompilerContext (org.drools.mvelcompiler.context.MvelCompilerContext)3 ArrayList (java.util.ArrayList)2 Gender (org.drools.Gender)2 Person (org.drools.Person)2 TypeDeclarationDescr (org.drools.drl.ast.descr.TypeDeclarationDescr)2 TypeFieldDescr (org.drools.drl.ast.descr.TypeFieldDescr)2 TypeDeclaration (com.github.javaparser.ast.body.TypeDeclaration)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1 PackageRegistry (org.drools.compiler.compiler.PackageRegistry)1 RuleBuildError (org.drools.compiler.compiler.RuleBuildError)1 TypeDeclarationError (org.drools.compiler.compiler.TypeDeclarationError)1 ClassDefinition (org.drools.core.factmodel.ClassDefinition)1 TypeDeclaration (org.drools.core.rule.TypeDeclaration)1 EnumDeclarationDescr (org.drools.drl.ast.descr.EnumDeclarationDescr)1