use of org.kie.internal.builder.ResourceChange in project drools by kiegroup.
the class KieBaseUpdater method updateResourcesIncrementally.
private int updateResourcesIncrementally(KnowledgeBuilderImpl kbuilder, CompositeKnowledgeBuilder ckbuilder) {
int fileCount = ctx.modifiedClasses.size();
for (ResourceChangeSet rcs : ctx.cs.getChanges().values()) {
if (rcs.getChangeType() != ChangeType.REMOVED) {
String resourceName = rcs.getResourceName();
if (!resourceName.endsWith(".properties") && isFileInKBase(ctx.newKM, ctx.newKieBaseModel, resourceName)) {
List<ResourceChange> changes = rcs.getChanges();
if (!changes.isEmpty()) {
// we need to deal with individual parts of the resource
fileCount += AbstractKieModule.updateResource(ckbuilder, ctx.newKM, resourceName, rcs) ? 1 : 0;
} else {
// the whole resource has to handled
if (rcs.getChangeType() == ChangeType.UPDATED) {
Resource resource = ctx.currentKM.getResource(resourceName);
kbuilder.removeObjectsGeneratedFromResource(resource);
}
fileCount += ctx.newKM.addResourceToCompiler(ckbuilder, ctx.newKieBaseModel, resourceName, rcs) ? 1 : 0;
}
}
}
for (ResourceChangeSet.RuleLoadOrder loadOrder : rcs.getLoadOrder()) {
KnowledgePackageImpl pkg = (KnowledgePackageImpl) ctx.kBase.getKiePackage(loadOrder.getPkgName());
if (pkg != null) {
RuleImpl rule = pkg.getRule(loadOrder.getRuleName());
if (rule != null) {
// rule can be null, if it didn't exist before
rule.setLoadOrder(loadOrder.getLoadOrder());
}
}
}
}
return fileCount;
}
use of org.kie.internal.builder.ResourceChange in project drools by kiegroup.
the class ChangeSetBuilderTest method testModified.
@Test
public void testModified() {
String drl1 = "package org.drools\n" + "rule R1 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n";
String drl2 = "package org.drools\n" + "rule R2 when\n" + " $m : Message( message == \"Hello World\" )\n" + "then\n" + "end\n";
String drl3 = "package org.drools\n" + "rule R3 when\n" + " $m : Message( message == \"Good bye World\" )\n" + "then\n" + "end\n";
InternalKieModule kieJar1 = createKieJar(drl1, drl2);
InternalKieModule kieJar2 = createKieJar(drl1, drl3);
KieJarChangeSet changes = ChangeSetBuilder.build(kieJar1, kieJar2);
String modifiedFile = (String) kieJar2.getFileNames().toArray()[1];
assertThat(changes.getChanges().size(), is(1));
ResourceChangeSet cs = changes.getChanges().get(modifiedFile);
assertThat(cs, not(nullValue()));
assertThat(cs.getChangeType(), is(ChangeType.UPDATED));
assertThat(cs.getChanges().size(), is(2));
assertThat(cs.getChanges().get(1), is(new ResourceChange(ChangeType.ADDED, Type.RULE, "R3")));
assertThat(cs.getChanges().get(0), is(new ResourceChange(ChangeType.REMOVED, Type.RULE, "R2")));
// ChangeSetBuilder builder = new ChangeSetBuilder();
// System.out.println( builder.toProperties( changes ) );
}
use of org.kie.internal.builder.ResourceChange in project drools by kiegroup.
the class CanonicalKieBaseUpdater method run.
@Override
public void run() {
CanonicalKieModule oldKM = (CanonicalKieModule) ctx.currentKM;
CanonicalKieModule newKM = (CanonicalKieModule) ctx.newKM;
Map<String, AtomicInteger> globalsCounter = new HashMap<>();
// To keep compatible the classes generated from declared types the new kmodule has to be loaded with the classloader of the old one
newKM.setIncrementalUpdate(true);
CanonicalKiePackages newPkgs = newKM.getKiePackages(ctx.newKieBaseModel);
InternalKnowledgeBuilder pkgbuilder = ctx.kbuilder;
CompositeKnowledgeBuilder ckbuilder = pkgbuilder.batch();
newKM.setIncrementalUpdate(false);
removeResources(pkgbuilder);
List<RuleImpl> rulesToBeRemoved;
List<RuleImpl> rulesToBeAdded;
if (ctx.modifyingUsedClass) {
// remove all ObjectTypeNodes for the modified classes
for (Class<?> cls : ctx.modifiedClasses) {
clearInstancesOfModifiedClass(cls);
}
for (InternalKnowledgePackage kpkg : ctx.kBase.getPackagesMap().values()) {
List<TypeDeclaration> types = new ArrayList<>(kpkg.getTypeDeclarations().values());
for (TypeDeclaration type : types) {
kpkg.removeTypeDeclaration(type.getTypeName());
kpkg.addTypeDeclaration(((InternalKnowledgePackage) newPkgs.getKiePackage(kpkg.getName())).getTypeDeclaration(type.getTypeName()));
}
}
rulesToBeRemoved = getAllRulesInKieBase(oldKM, ctx.currentKieBaseModel);
rulesToBeAdded = getAllRulesInKieBase(newKM, ctx.newKieBaseModel);
} else {
ctx.kBase.processAllTypesDeclaration(newPkgs.getKiePackages());
rulesToBeRemoved = new ArrayList<>();
rulesToBeAdded = new ArrayList<>();
for (ResourceChangeSet changeSet : ctx.cs.getChanges().values()) {
if (!isPackageInKieBase(ctx.newKieBaseModel, changeSet.getResourceName())) {
continue;
}
InternalKnowledgePackage kpkg = (InternalKnowledgePackage) newPkgs.getKiePackage(changeSet.getResourceName());
InternalKnowledgePackage oldKpkg = ctx.kBase.getPackage(changeSet.getResourceName());
if (oldKpkg == null) {
try {
oldKpkg = (InternalKnowledgePackage) ctx.kBase.addPackage(CoreComponentFactory.get().createKnowledgePackage(changeSet.getResourceName())).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
if (kpkg != null) {
for (Rule newRule : kpkg.getRules()) {
RuleImpl rule = oldKpkg.getRule(newRule.getName());
if (rule != null) {
rule.setLoadOrder(((RuleImpl) newRule).getLoadOrder());
}
}
}
this.updateResource(pkgbuilder, ckbuilder, changeSet);
for (ResourceChange change : changeSet.getChanges()) {
String changedItemName = change.getName();
if (change.getChangeType() == ChangeType.UPDATED || change.getChangeType() == ChangeType.REMOVED) {
switch(change.getType()) {
case GLOBAL:
oldKpkg.removeGlobal(changedItemName);
AtomicInteger globalCounter = globalsCounter.get(changedItemName);
if (globalCounter == null || globalCounter.decrementAndGet() <= 0) {
ctx.kBase.removeGlobal(changedItemName);
}
break;
case RULE:
RuleImpl removedRule = oldKpkg.getRule(changedItemName);
if (removedRule != null) {
rulesToBeRemoved.add(removedRule);
oldKpkg.removeRule(removedRule);
}
break;
case DECLARATION:
oldKpkg.removeTypeDeclaration(changedItemName);
break;
case FUNCTION:
oldKpkg.removeFunction(changedItemName);
break;
default:
throw new IllegalArgumentException("Unsupported change type: " + change.getType() + "!");
}
}
if (kpkg != null && (change.getChangeType() == ChangeType.UPDATED || change.getChangeType() == ChangeType.ADDED)) {
switch(change.getType()) {
case GLOBAL:
globalsCounter.computeIfAbsent(changedItemName, name -> ctx.kBase.getGlobals().get(name) == null ? new AtomicInteger(1) : new AtomicInteger(0)).incrementAndGet();
Class<?> globalClass = kpkg.getGlobals().get(changedItemName);
oldKpkg.addGlobal(changedItemName, globalClass);
ctx.kBase.addGlobal(changedItemName, globalClass);
break;
case RULE:
RuleImpl addedRule = kpkg.getRule(changedItemName);
rulesToBeAdded.add(addedRule);
oldKpkg.addRule(addedRule);
break;
case DECLARATION:
TypeDeclaration addedType = kpkg.getTypeDeclaration(changedItemName);
oldKpkg.addTypeDeclaration(addedType);
break;
case FUNCTION:
Function addedFunction = kpkg.getFunctions().get(changedItemName);
oldKpkg.addFunction(addedFunction);
break;
default:
throw new IllegalArgumentException("Unsupported change type: " + change.getType() + "!");
}
}
}
}
}
if (ctx.modifyingUsedClass) {
invalidateAccessorForOldClass();
updateAllResources(pkgbuilder, ckbuilder);
}
((CompositeKnowledgeBuilderImpl) ckbuilder).build(false);
KieBaseUpdate kieBaseUpdate = new KieBaseUpdate(rulesToBeRemoved, rulesToBeAdded);
ctx.kBase.beforeIncrementalUpdate(kieBaseUpdate);
ctx.kBase.removeRules(rulesToBeRemoved);
ctx.kBase.addRules(rulesToBeAdded);
ctx.kBase.afterIncrementalUpdate(kieBaseUpdate);
for (InternalWorkingMemory wm : ctx.kBase.getWorkingMemories()) {
wm.notifyWaitOnRest();
}
}
use of org.kie.internal.builder.ResourceChange in project drools by kiegroup.
the class KieBaseUpdaterImpl method updateResource.
protected int updateResource(InternalKnowledgeBuilder kbuilder, CompositeKnowledgeBuilder ckbuilder, ResourceChangeSet rcs) {
int fileCount = 0;
if (rcs.getChangeType() != ChangeType.REMOVED) {
String resourceName = rcs.getResourceName();
if (!resourceName.endsWith(".properties") && isFileInKBase(ctx.newKM, ctx.newKieBaseModel, resourceName)) {
List<ResourceChange> changes = rcs.getChanges();
if (!changes.isEmpty()) {
// we need to deal with individual parts of the resource
fileCount += AbstractKieModule.updateResource(ckbuilder, ctx.newKM, resourceName, rcs) ? 1 : 0;
} else {
// the whole resource has to handled
if (rcs.getChangeType() == ChangeType.UPDATED) {
Resource resource = ctx.currentKM.getResource(resourceName);
kbuilder.removeObjectsGeneratedFromResource(resource);
}
fileCount += ctx.newKM.addResourceToCompiler(ckbuilder, ctx.newKieBaseModel, resourceName, rcs) ? 1 : 0;
}
}
}
for (ResourceChangeSet.RuleLoadOrder loadOrder : rcs.getLoadOrder()) {
KnowledgePackageImpl pkg = (KnowledgePackageImpl) ctx.kBase.getKiePackage(loadOrder.getPkgName());
if (pkg != null) {
RuleImpl rule = pkg.getRule(loadOrder.getRuleName());
if (rule != null) {
// rule can be null, if it didn't exist before
rule.setLoadOrder(loadOrder.getLoadOrder());
}
}
}
return fileCount;
}
use of org.kie.internal.builder.ResourceChange in project drools by kiegroup.
the class ChangeSetBuilder method diffDescrs.
private static <T extends BaseDescr> void diffDescrs(byte[] ob, byte[] cb, ResourceChangeSet pkgcs, List<T> odescrs, List<T> cdescrs, ResourceChange.Type type, DescrNameConverter<T> descrNameConverter) {
Set<String> updatedRules = null;
if (type == ResourceChange.Type.RULE) {
updatedRules = new HashSet<>();
((List<RuleDescr>) cdescrs).sort(RULE_HIERARCHY_COMPARATOR);
}
for (T crd : cdescrs) {
String cName = descrNameConverter.getName(crd);
// unfortunately have to iterate search for a rule with the same name
boolean found = false;
for (Iterator<T> it = odescrs.iterator(); it.hasNext(); ) {
T ord = it.next();
if (descrNameConverter.getName(ord).equals(cName)) {
found = true;
it.remove();
// is brittle and heavier than iterating an array
if (!StringUtils.codeAwareEqualsIgnoreSpaces(new String(Arrays.copyOfRange(ob, ord.getStartCharacter(), ord.getEndCharacter())), new String(Arrays.copyOfRange(cb, crd.getStartCharacter(), crd.getEndCharacter()))) || (type == ResourceChange.Type.RULE && updatedRules.contains(((RuleDescr) crd).getParentName()))) {
pkgcs.getChanges().add(new ResourceChange(ChangeType.UPDATED, type, cName));
if (type == ResourceChange.Type.RULE) {
updatedRules.add(cName);
}
}
break;
}
}
if (!found) {
pkgcs.getChanges().add(new ResourceChange(ChangeType.ADDED, type, cName));
}
}
for (T ord : odescrs) {
pkgcs.getChanges().add(new ResourceChange(ChangeType.REMOVED, type, descrNameConverter.getName(ord)));
}
}
Aggregations