Search in sources :

Example 1 with KieWeavers

use of org.kie.api.internal.weaver.KieWeavers in project drools by kiegroup.

the class KnowledgeBaseImpl 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());
    // Merge static imports
    for (String staticImport : newPkg.getStaticImports()) {
        pkg.addStaticImport(staticImport);
    }
    String lastIdent = null;
    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();
                lastIdent = identifier;
                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 convienience
                    addGlobal(identifier, this.rootClassLoader.loadClass(type));
                }
            }
        }
    } catch (ClassNotFoundException e) {
        throw new RuntimeException("Unable to resolve class '" + lastType + "' for global '" + lastIdent + "'");
    }
    // merge entry point declarations
    if (newPkg.getEntryPointIds() != null) {
        for (String ep : newPkg.getEntryPointIds()) {
            pkg.addEntryPointId(ep);
        }
    }
    // 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);
            }
        }
    }
    // merge window declarations
    if (newPkg.getWindowDeclarations() != null) {
        // add window declarations
        for (WindowDeclaration window : newPkg.getWindowDeclarations().values()) {
            if (!pkg.getWindowDeclarations().containsKey(window.getName()) || pkg.getWindowDeclarations().get(window.getName()).equals(window)) {
                pkg.addWindowDeclaration(window);
            } else {
                throw new RuntimeException("Unable to merge two conflicting window declarations for window named: " + window.getName());
            }
        }
    }
    // Merge rules into the RuleBase package
    // as this is needed for individual rule removal later on
    List<RuleImpl> rulesToBeRemoved = new ArrayList<RuleImpl>();
    for (Rule newRule : newPkg.getRules()) {
        // remove the rule if it already exists
        RuleImpl oldRule = pkg.getRule(newRule.getName());
        if (oldRule != null) {
            rulesToBeRemoved.add(oldRule);
        }
    }
    if (!rulesToBeRemoved.isEmpty()) {
        removeRules(rulesToBeRemoved);
    }
    for (Rule newRule : newPkg.getRules()) {
        pkg.addRule((RuleImpl) newRule);
    }
    // Merge The Rule Flows
    if (newPkg.getRuleFlows() != null) {
        for (Process flow : newPkg.getRuleFlows().values()) {
            pkg.addProcess(flow);
        }
    }
    if (!newPkg.getResourceTypePackages().isEmpty()) {
        for (ResourceTypePackage rtkKpg : newPkg.getResourceTypePackages().values()) {
            ResourceType rt = rtkKpg.getResourceType();
            KieWeavers weavers = ServiceRegistry.getInstance().get(KieWeavers.class);
            KieWeaverService weaver = weavers.getWeavers().get(rt);
            weaver.merge(this, pkg, rtkKpg);
        }
    }
}
Also used : KieWeaverService(org.kie.api.internal.weaver.KieWeaverService) ArrayList(java.util.ArrayList) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) Process(org.kie.api.definition.process.Process) ResourceType(org.kie.api.io.ResourceType) KieWeavers(org.kie.api.internal.weaver.KieWeavers) WindowDeclaration(org.drools.core.rule.WindowDeclaration) ImportDeclaration(org.drools.core.rule.ImportDeclaration) Rule(org.kie.api.definition.rule.Rule) ResourceTypePackage(org.kie.api.internal.io.ResourceTypePackage) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 2 with KieWeavers

use of org.kie.api.internal.weaver.KieWeavers in project drools by kiegroup.

the class KnowledgeBaseImpl method internalAddPackages.

private void internalAddPackages(List<InternalKnowledgePackage> clonedPkgs) {
    for (InternalWorkingMemory wm : getWorkingMemories()) {
        wm.flushPropagations();
    }
    // we need to merge all byte[] first, so that the root classloader can resolve classes
    for (InternalKnowledgePackage newPkg : clonedPkgs) {
        newPkg.checkValidity();
        this.eventSupport.fireBeforePackageAdded(newPkg);
        if (newPkg.hasTraitRegistry()) {
            getTraitRegistry().merge(newPkg.getTraitRegistry());
        }
        InternalKnowledgePackage pkg = this.pkgs.get(newPkg.getName());
        if (pkg == null) {
            pkg = new KnowledgePackageImpl(newPkg.getName());
            // @TODO we really should have a single root cache
            pkg.setClassFieldAccessorCache(this.classFieldAccessorCache);
            pkgs.put(pkg.getName(), pkg);
        }
        // first merge anything related to classloader re-wiring
        pkg.getDialectRuntimeRegistry().merge(newPkg.getDialectRuntimeRegistry(), this.rootClassLoader, true);
    }
    processAllTypesDeclaration(clonedPkgs);
    for (InternalKnowledgePackage newPkg : clonedPkgs) {
        // Add functions
        JavaDialectRuntimeData runtime = ((JavaDialectRuntimeData) newPkg.getDialectRuntimeRegistry().getDialectData("java"));
        for (Function function : newPkg.getFunctions().values()) {
            String functionClassName = function.getClassName();
            try {
                registerFunctionClassAndInnerClasses(functionClassName, runtime, this::registerAndLoadTypeDefinition);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException("Unable to compile function '" + function.getName() + "'", e);
            }
        }
    }
    // now iterate again, this time onBeforeExecute will handle any wiring or cloader re-creating that needs to be done as part of the merge
    for (InternalKnowledgePackage newPkg : clonedPkgs) {
        InternalKnowledgePackage pkg = this.pkgs.get(newPkg.getName());
        // this needs to go here, as functions will set a java dialect to dirty
        if (newPkg.getFunctions() != null) {
            for (Map.Entry<String, Function> entry : newPkg.getFunctions().entrySet()) {
                pkg.addFunction(entry.getValue());
            }
        }
        pkg.getDialectRuntimeRegistry().onBeforeExecute();
        // with the classloader recreated for all byte[] classes, we should now merge and wire any new accessors
        pkg.getClassFieldAccessorStore().merge(newPkg.getClassFieldAccessorStore());
    }
    for (InternalKnowledgePackage newPkg : clonedPkgs) {
        InternalKnowledgePackage pkg = this.pkgs.get(newPkg.getName());
        // now merge the new package into the existing one
        mergePackage(pkg, newPkg);
        // add the window declarations to the kbase
        for (WindowDeclaration window : newPkg.getWindowDeclarations().values()) {
            this.reteooBuilder.addNamedWindow(window);
        }
        // add entry points to the kbase
        for (String id : newPkg.getEntryPointIds()) {
            this.reteooBuilder.addEntryPoint(id);
        }
        // add the rules to the RuleBase
        for (Rule r : newPkg.getRules()) {
            RuleImpl rule = (RuleImpl) r;
            checkMultithreadedEvaluation(rule);
            internalAddRule(rule);
        }
        // add the flows to the RuleBase
        if (newPkg.getRuleFlows() != null) {
            final Map<String, Process> flows = newPkg.getRuleFlows();
            for (Process process : flows.values()) {
                internalAddProcess(process);
            }
        }
        if (!newPkg.getResourceTypePackages().isEmpty()) {
            KieWeavers weavers = ServiceRegistry.getInstance().get(KieWeavers.class);
            for (ResourceTypePackage rtkKpg : newPkg.getResourceTypePackages().values()) {
                ResourceType rt = rtkKpg.getResourceType();
                KieWeaverService factory = weavers.getWeavers().get(rt);
                factory.weave(this, newPkg, rtkKpg);
            }
        }
        ruleUnitRegistry.add(newPkg.getRuleUnitRegistry());
        this.eventSupport.fireAfterPackageAdded(newPkg);
    }
    if (config.isMultithreadEvaluation() && !hasMultiplePartitions()) {
        disableMultithreadEvaluation("The rete network cannot be partitioned: disabling multithread evaluation");
    }
}
Also used : KieWeaverService(org.kie.api.internal.weaver.KieWeaverService) RuleImpl(org.drools.core.definitions.rule.impl.RuleImpl) Process(org.kie.api.definition.process.Process) ResourceType(org.kie.api.io.ResourceType) JavaDialectRuntimeData(org.drools.core.rule.JavaDialectRuntimeData) KieWeavers(org.kie.api.internal.weaver.KieWeavers) InternalWorkingMemory(org.drools.core.common.InternalWorkingMemory) Function(org.drools.core.rule.Function) WindowDeclaration(org.drools.core.rule.WindowDeclaration) Rule(org.kie.api.definition.rule.Rule) KnowledgePackageImpl(org.drools.core.definitions.impl.KnowledgePackageImpl) ResourceTypePackage(org.kie.api.internal.io.ResourceTypePackage) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) InternalKnowledgePackage(org.drools.core.definitions.InternalKnowledgePackage)

Aggregations

HashMap (java.util.HashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)2 WindowDeclaration (org.drools.core.rule.WindowDeclaration)2 Process (org.kie.api.definition.process.Process)2 Rule (org.kie.api.definition.rule.Rule)2 ResourceTypePackage (org.kie.api.internal.io.ResourceTypePackage)2 KieWeaverService (org.kie.api.internal.weaver.KieWeaverService)2 KieWeavers (org.kie.api.internal.weaver.KieWeavers)2 ResourceType (org.kie.api.io.ResourceType)2 ArrayList (java.util.ArrayList)1 InternalWorkingMemory (org.drools.core.common.InternalWorkingMemory)1 InternalKnowledgePackage (org.drools.core.definitions.InternalKnowledgePackage)1 KnowledgePackageImpl (org.drools.core.definitions.impl.KnowledgePackageImpl)1 Function (org.drools.core.rule.Function)1 ImportDeclaration (org.drools.core.rule.ImportDeclaration)1 JavaDialectRuntimeData (org.drools.core.rule.JavaDialectRuntimeData)1 TypeDeclaration (org.drools.core.rule.TypeDeclaration)1