use of org.drools.core.rule.JavaDialectRuntimeData in project drools by kiegroup.
the class JavaDialect method addRule.
/**
* This will add the rule for compiling later on.
* It will not actually call the compiler
*/
public void addRule(final RuleBuildContext context) {
final RuleImpl rule = context.getRule();
final RuleDescr ruleDescr = context.getRuleDescr();
RuleClassBuilder classBuilder = context.getDialect().getRuleClassBuilder();
String ruleClass = classBuilder.buildRule(context);
// return if there is no ruleclass name;
if (ruleClass == null) {
return;
}
// The compilation result is for the entire rule, so difficult to associate with any descr
addClassCompileTask(this.pkg.getName() + "." + ruleDescr.getClassName(), ruleDescr, ruleClass, this.src, new RuleErrorHandler(ruleDescr, rule, "Rule Compilation error"));
JavaDialectRuntimeData data = (JavaDialectRuntimeData) this.pkg.getDialectRuntimeRegistry().getDialectData(ID);
for (Map.Entry<String, String> invokers : context.getInvokers().entrySet()) {
final String className = invokers.getKey();
// Check if an invoker - returnvalue, predicate, eval or consequence has been associated
// If so we add it to the PackageCompilationData as it will get wired up on compilation
final Object invoker = context.getInvokerLookup(className);
if (invoker instanceof Wireable) {
data.putInvoker(className, (Wireable) invoker);
}
final String text = invokers.getValue();
final BaseDescr descr = context.getDescrLookup(className);
addClassCompileTask(className, descr, text, this.src, new RuleInvokerErrorHandler(descr, rule, "Unable to generate rule invoker."));
}
// setup the line mappins for this rule
final String name = this.pkg.getName() + "." + StringUtils.ucFirst(ruleDescr.getClassName());
final LineMappings mapping = new LineMappings(name);
mapping.setStartLine(ruleDescr.getConsequenceLine());
mapping.setOffset(ruleDescr.getConsequenceOffset());
this.pkg.getDialectRuntimeRegistry().getLineMappings().put(name, mapping);
}
use of org.drools.core.rule.JavaDialectRuntimeData in project drools by kiegroup.
the class DisposeCommandPublicAPITest method testDisposeCommand.
@Test
public void testDisposeCommand() {
InternalKnowledgeBase kBase;
RuleImpl rule;
InternalKnowledgePackage pkg;
kBase = KnowledgeBaseFactory.newKnowledgeBase();
pkg = new KnowledgePackageImpl("org.droos.test");
pkg.setClassFieldAccessorCache(new ClassFieldAccessorCache(Thread.currentThread().getContextClassLoader()));
JavaDialectRuntimeData data = new JavaDialectRuntimeData();
data.onAdd(pkg.getDialectRuntimeRegistry(), kBase.getRootClassLoader());
pkg.getDialectRuntimeRegistry().setDialectData("java", data);
rule = new RuleImpl("Test");
rule.setDialect("java");
rule.setConsequence(new Consequence() {
public void evaluate(KnowledgeHelper knowledgeHelper, WorkingMemory workingMemory) throws Exception {
}
public String getName() {
return "default";
}
});
pkg.addRule(rule);
kBase.addPackage(pkg);
KieSession session = kBase.newKieSession();
Command dispose = KieServices.Factory.get().getCommands().newDispose();
session.insert("whatever");
session.fireAllRules();
session.execute(dispose);
try {
session.insert("whatever");
} catch (Exception e) {
Assert.assertEquals(e.getMessage(), "Illegal method call. This session was previously disposed.");
}
}
use of org.drools.core.rule.JavaDialectRuntimeData in project drools by kiegroup.
the class KnowledgeBuilderTest method testReload.
@Test
public void testReload() throws Exception {
final KnowledgeBuilderImpl builder = new KnowledgeBuilderImpl();
final PackageDescr packageDescr = new PackageDescr("p1");
final RuleDescr ruleDescr = new RuleDescr("rule-1");
packageDescr.addRule(ruleDescr);
final AndDescr lhs = new AndDescr();
ruleDescr.setLhs(lhs);
packageDescr.addGlobal(new GlobalDescr("map", "java.util.Map"));
ruleDescr.setConsequence("map.put(\"value\", new Integer(1) );");
builder.addPackage(packageDescr);
InternalKnowledgePackage pkg = builder.getPackage(packageDescr.getName());
RuleImpl rule = pkg.getRule("rule-1");
assertLength(0, builder.getErrors().getErrors());
InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
kBase.addGlobal("map", Map.class);
final KieSession workingMemory = kBase.newKieSession();
final HashMap map = new HashMap();
workingMemory.setGlobal("map", map);
final LeftTupleImpl tuple = new MockTuple(new HashMap());
tuple.setLeftTupleSink(new RuleTerminalNode(1, new CompositeObjectSinkAdapterTest.MockBetaNode(), rule, rule.getLhs(), 0, new BuildContext(kBase)));
final Activation activation = new MockActivation(rule, 0, rule.getLhs(), tuple);
DefaultKnowledgeHelper knowledgeHelper = new org.drools.core.base.DefaultKnowledgeHelper(((StatefulKnowledgeSessionImpl) workingMemory));
knowledgeHelper.setActivation(activation);
rule.getConsequence().evaluate(knowledgeHelper, ((StatefulKnowledgeSessionImpl) workingMemory));
assertEquals(new Integer(1), map.get("value"));
ruleDescr.setConsequence("map.put(\"value\", new Integer(2) );");
pkg.removeRule(rule);
// Make sure the compiled classes are also removed
assertEquals(0, ((JavaDialectRuntimeData) pkg.getDialectRuntimeRegistry().getDialectData("java")).getStore().size());
builder.addPackage(packageDescr);
pkg = builder.getPackage(packageDescr.getName());
rule = pkg.getRule("rule-1");
knowledgeHelper = new org.drools.core.base.DefaultKnowledgeHelper(((StatefulKnowledgeSessionImpl) workingMemory));
knowledgeHelper.setActivation(activation);
rule.getConsequence().evaluate(knowledgeHelper, ((StatefulKnowledgeSessionImpl) workingMemory));
assertEquals(new Integer(2), map.get("value"));
}
use of org.drools.core.rule.JavaDialectRuntimeData 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");
}
}
use of org.drools.core.rule.JavaDialectRuntimeData in project drools by kiegroup.
the class KnowledgePackageImpl method deepCloneIfAlreadyInUse.
public KnowledgePackageImpl deepCloneIfAlreadyInUse(ClassLoader classLoader) {
if (inUse.compareAndSet(false, true)) {
return this;
}
if (classLoader instanceof ProjectClassLoader) {
JavaDialectRuntimeData javaDialectRuntimeData = (JavaDialectRuntimeData) dialectRuntimeRegistry.getDialectData("java");
if (javaDialectRuntimeData == null) {
// using the canonical model there's no runtime registry and no need for any clone
return this;
}
ClassLoader originalClassLoader = javaDialectRuntimeData.getRootClassLoader();
if (classLoader == originalClassLoader) {
// if the classloader isn't changed there's no need for a clone
return this;
}
if (originalClassLoader instanceof ProjectClassLoader) {
((ProjectClassLoader) classLoader).initFrom((ProjectClassLoader) originalClassLoader);
}
}
return ClassUtils.deepClone(this, classLoader, cloningResources);
}
Aggregations