Search in sources :

Example 46 with TypeDeclaration

use of org.drools.core.rule.TypeDeclaration in project drools by kiegroup.

the class ClassHierarchyManager method mergeFields.

protected void mergeFields(String simpleSuperTypeName, String superTypePackageName, String fullSuper, TypeDeclarationDescr typeDescr, List<TypeDefinition> unresolvedTypes, Map<String, AbstractClassTypeDeclarationDescr> unprocessableDescrs, TypeResolver resolver) {
    Map<String, TypeFieldDescr> fieldMap = new LinkedHashMap<String, TypeFieldDescr>();
    boolean isNovel = TypeDeclarationUtils.isNovelClass(typeDescr, kbuilder.getPackageRegistry(typeDescr.getNamespace()));
    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, registry, 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.kie.soup.project.datamodel.commons.types.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.compiler.lang.descr.TypeFieldDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage)

Example 47 with TypeDeclaration

use of org.drools.core.rule.TypeDeclaration in project drools by kiegroup.

the class KnowledgeBuilderImpl method mergePackage.

/**
 * Merge a new package with an existing package. Most of the work is done by
 * the concrete implementations, but this class does some work (including
 * combining imports, compilation data, globals, and the actual Rule objects
 * into the package).
 */
private void mergePackage(InternalKnowledgePackage pkg, InternalKnowledgePackage newPkg) {
    // Merge imports
    final Map<String, ImportDeclaration> imports = pkg.getImports();
    imports.putAll(newPkg.getImports());
    String lastType = null;
    try {
        // merge globals
        if (newPkg.getGlobals() != null && newPkg.getGlobals() != Collections.EMPTY_MAP) {
            Map<String, String> globals = pkg.getGlobals();
            // Add globals
            for (final Map.Entry<String, String> entry : newPkg.getGlobals().entrySet()) {
                final String identifier = entry.getKey();
                final String type = entry.getValue();
                lastType = type;
                if (globals.containsKey(identifier) && !globals.get(identifier).equals(type)) {
                    throw new RuntimeException(pkg.getName() + " cannot be integrated");
                } else {
                    pkg.addGlobal(identifier, this.rootClassLoader.loadClass(type));
                    // this isn't a package merge, it's adding to the rulebase, but I've put it here for convenience
                    this.globals.put(identifier, this.rootClassLoader.loadClass(type));
                }
            }
        }
    } catch (ClassNotFoundException e) {
        throw new RuntimeException("Unable to resolve class '" + lastType + "'");
    }
    // merge the type declarations
    if (newPkg.getTypeDeclarations() != null) {
        // add type declarations
        for (TypeDeclaration type : newPkg.getTypeDeclarations().values()) {
            // @TODO should we allow overrides? only if the class is not in use.
            if (!pkg.getTypeDeclarations().containsKey(type.getTypeName())) {
                // add to package list of type declarations
                pkg.addTypeDeclaration(type);
            }
        }
    }
    for (final org.kie.api.definition.rule.Rule newRule : newPkg.getRules()) {
        pkg.addRule(((RuleImpl) newRule));
    }
    // Merge The Rule Flows
    if (newPkg.getRuleFlows() != null) {
        final Map flows = newPkg.getRuleFlows();
        for (Object o : flows.values()) {
            final Process flow = (Process) o;
            pkg.addProcess(flow);
        }
    }
}
Also used : RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) Process(org.kie.api.definition.process.Process) ImportDeclaration(org.drools.core.rule.ImportDeclaration) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 48 with TypeDeclaration

use of org.drools.core.rule.TypeDeclaration in project drools by kiegroup.

the class TypeDeclarationCache method getExistingTypeDeclaration.

private TypeDeclaration getExistingTypeDeclaration(Class<?> cls) {
    TypeDeclaration typeDeclaration = null;
    PackageRegistry pkgReg = kbuilder.getPackageRegistry(ClassUtils.getPackage(cls));
    if (pkgReg != null) {
        String className = cls.getName();
        String typeName = className.substring(className.lastIndexOf(".") + 1);
        typeDeclaration = pkgReg.getPackage().getTypeDeclaration(typeName);
    }
    return typeDeclaration;
}
Also used : PackageRegistry(org.drools.compiler.compiler.PackageRegistry) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 49 with TypeDeclaration

use of org.drools.core.rule.TypeDeclaration in project drools by kiegroup.

the class TypeDeclarationCache method createTypeDeclarationForBean.

private TypeDeclaration createTypeDeclarationForBean(Class<?> cls) {
    Annotated annotated = new Annotated.ClassAdapter(cls);
    TypeDeclaration typeDeclaration = TypeDeclaration.createTypeDeclarationForBean(cls, annotated, kbuilder.getBuilderConfiguration().getPropertySpecificOption());
    String namespace = ClassUtils.getPackage(cls);
    PackageRegistry pkgRegistry = kbuilder.getOrCreatePackageRegistry(new PackageDescr(namespace));
    processMvelBasedAccessors(kbuilder, pkgRegistry, annotated, typeDeclaration);
    return typeDeclaration;
}
Also used : Annotated(org.drools.core.rule.Annotated) PackageRegistry(org.drools.compiler.compiler.PackageRegistry) PackageDescr(org.drools.compiler.lang.descr.PackageDescr) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 50 with TypeDeclaration

use of org.drools.core.rule.TypeDeclaration in project drools by kiegroup.

the class DialectUtil method rewriteUpdateDescr.

private static void rewriteUpdateDescr(RuleBuildContext context, JavaBlockDescr d, StringBuilder consequence, Declaration declr, String obj) {
    BitMask modificationMask = AllSetBitMask.get();
    Class<?> typeClass = findModifiedClass(context, d, declr);
    TypeDeclaration typeDeclaration = typeClass == null ? null : context.getKnowledgeBuilder().getTypeDeclaration(typeClass);
    if (typeDeclaration != null) {
        boolean isPropertyReactive = typeDeclaration.isPropertyReactive();
        List<String> settableProperties = null;
        if (isPropertyReactive) {
            typeDeclaration.setTypeClass(typeClass);
            settableProperties = typeDeclaration.getAccessibleProperties();
            modificationMask = getEmptyPropertyReactiveMask(settableProperties.size());
        }
        ConsequenceMetaData.Statement statement = new ConsequenceMetaData.Statement(ConsequenceMetaData.Statement.Type.MODIFY, typeClass);
        context.getRule().getConsequenceMetaData().addStatement(statement);
        if (isPropertyReactive) {
            boolean parsedExprOnce = false;
            // a late optimization to include this for-loop within this if
            for (String expr : splitStatements(consequence)) {
                String updateExpr = expr.replaceFirst("^\\Q" + obj + "\\E\\s*\\.", "");
                if (!updateExpr.equals(expr)) {
                    parsedExprOnce = true;
                    modificationMask = parseModifiedProperties(statement, settableProperties, typeDeclaration, isPropertyReactive, modificationMask, updateExpr);
                    if (modificationMask == allSetButTraitBitMask()) {
                        // opt: if we were unable to detect the property in the mask is all set, so avoid the rest of the cycle
                        break;
                    }
                }
            }
            if (!parsedExprOnce) {
                // never called parseModifiedProperties(), hence never had the opportunity to "miss" the property and set mask to All-set; doing so here:
                modificationMask = allSetButTraitBitMask();
            }
        }
    }
    appendUpdateStatement(consequence, declr, obj, modificationMask, typeClass);
}
Also used : ConsequenceMetaData(org.drools.core.rule.ConsequenceMetaData) PropertySpecificUtil.allSetButTraitBitMask(org.drools.core.reteoo.PropertySpecificUtil.allSetButTraitBitMask) BitMask(org.drools.core.util.bitmask.BitMask) AllSetBitMask(org.drools.core.util.bitmask.AllSetBitMask) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Aggregations

TypeDeclaration (org.drools.core.rule.TypeDeclaration)72 Test (org.junit.Test)15 InternalKnowledgePackage (org.drools.core.definitions.InternalKnowledgePackage)12 KnowledgeBuilderImpl (org.drools.compiler.builder.impl.KnowledgeBuilderImpl)11 PackageRegistry (org.drools.compiler.compiler.PackageRegistry)10 ClassDefinition (org.drools.core.factmodel.ClassDefinition)9 ClassObjectType (org.drools.core.base.ClassObjectType)7 TypeDeclarationDescr (org.drools.compiler.lang.descr.TypeDeclarationDescr)5 HashMap (java.util.HashMap)4 Map (java.util.Map)4 TypeDeclarationError (org.drools.compiler.compiler.TypeDeclarationError)4 AbstractClassTypeDeclarationDescr (org.drools.compiler.lang.descr.AbstractClassTypeDeclarationDescr)4 PackageDescr (org.drools.compiler.lang.descr.PackageDescr)4 ObjectType (org.drools.core.spi.ObjectType)4 ArrayList (java.util.ArrayList)3 LinkedHashMap (java.util.LinkedHashMap)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 BindingDescr (org.drools.compiler.lang.descr.BindingDescr)3 TypeFieldDescr (org.drools.compiler.lang.descr.TypeFieldDescr)3 KnowledgePackageImpl (org.drools.core.definitions.impl.KnowledgePackageImpl)3