Skip to content

Commit

Permalink
[BZ-1227866] fix incremental compilation for extended rule
Browse files Browse the repository at this point in the history
(cherry picked from commit 3d3042b)
  • Loading branch information
mariofusco committed Jun 4, 2015
1 parent 2f931bb commit 10ae3a7
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceConfiguration;
import org.kie.api.io.ResourceType;
import org.kie.internal.builder.ChangeType;
import org.kie.internal.builder.CompositeKnowledgeBuilder;
import org.kie.internal.builder.ResourceChange;
import org.kie.internal.builder.ResourceChangeSet;
Expand Down Expand Up @@ -410,15 +409,13 @@ public KnowledgeBuilderImpl.AssetFilter getFilter() {
private class ChangeSetAssetFilter implements KnowledgeBuilderImpl.AssetFilter {
@Override
public Action accept(String pkgName, String assetName) {
ResourceChange change = changeMap.get(assetName);
if( change == null ) {
return Action.DO_NOTHING;
} else if( change.getChangeType().equals(ChangeType.ADDED) ) {
return Action.ADD;
} else if( change.getChangeType().equals(ChangeType.REMOVED) ) {
return Action.REMOVE;
} else if( change.getChangeType().equals(ChangeType.UPDATED) ) {
return Action.UPDATE;
ResourceChange change = changeMap.get( assetName );
if ( change != null ) {
switch (change.getChangeType()) {
case ADDED: return Action.ADD;
case REMOVED: return Action.REMOVE;
case UPDATED: return Action.UPDATE;
}
}
return Action.DO_NOTHING;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ public void addPackageFromDecisionTable(Resource resource,
ResourceConfiguration configuration) throws DroolsParserException,
IOException {
this.resource = resource;
addPackage(decisionTableToPackageDescr(resource, configuration));
addPackage( decisionTableToPackageDescr( resource, configuration ) );
this.resource = null;
}

Expand Down Expand Up @@ -406,7 +406,7 @@ public void addPackageFromScoreCard(Resource resource,
ResourceConfiguration configuration) throws DroolsParserException,
IOException {
this.resource = resource;
addPackage(scoreCardToPackageDescr(resource, configuration));
addPackage( scoreCardToPackageDescr( resource, configuration ) );
this.resource = null;
}

Expand All @@ -420,7 +420,7 @@ PackageDescr scoreCardToPackageDescr(Resource resource,

DrlParser parser = new DrlParser(this.configuration.getLanguageLevel());
PackageDescr pkg = parser.parse(resource, new StringReader(string));
this.results.addAll(parser.getErrors());
this.results.addAll( parser.getErrors() );
if (pkg == null) {
addBuilderResult(new ParserError(resource, "Parser returned a null Package", 0, 0));
}
Expand Down Expand Up @@ -489,7 +489,7 @@ public void addPackageFromXml(final Resource resource) throws DroolsParserExcept
PackageDescr xmlToPackageDescr(Resource resource) throws DroolsParserException,
IOException {
final XmlPackageReader xmlReader = new XmlPackageReader(this.configuration.getSemanticModules());
xmlReader.getParser().setClassLoader(this.rootClassLoader);
xmlReader.getParser().setClassLoader( this.rootClassLoader );

Reader reader = null;
try {
Expand Down Expand Up @@ -523,7 +523,7 @@ public void addPackageFromDrl(final Reader source,

final DrlParser parser = new DrlParser(configuration.getLanguageLevel());
final PackageDescr pkg = parser.parse(source, dsl);
this.results.addAll(parser.getErrors());
this.results.addAll( parser.getErrors() );
if (!parser.hasErrors()) {
addPackage(pkg);
}
Expand Down Expand Up @@ -699,14 +699,14 @@ void addPackageForExternalType(Resource resource,
ResourceConfiguration configuration) throws Exception {
KieAssemblers assemblers = ServiceRegistryImpl.getInstance().get(KieAssemblers.class);

KieAssemblerService assembler = assemblers.getAssemblers().get(type);
KieAssemblerService assembler = assemblers.getAssemblers().get( type );


if (assembler != null) {
assembler.addResource(this,
resource,
type,
configuration);
assembler.addResource( this,
resource,
type,
configuration );
} else {
throw new RuntimeException("Unknown resource type: " + type);
}
Expand Down Expand Up @@ -893,7 +893,7 @@ public void addPackage(final PackageDescr packageDescr) {
}

void compileAllRules(PackageDescr packageDescr, PackageRegistry pkgRegistry) {
pkgRegistry.setDialect(getPackageDialect(packageDescr));
pkgRegistry.setDialect( getPackageDialect( packageDescr ) );

validateUniqueRuleNames( packageDescr );
compileRules(packageDescr, pkgRegistry);
Expand Down Expand Up @@ -922,7 +922,7 @@ void addBuilderResult(KnowledgeBuilderResult result) {
}

PackageRegistry createPackageRegistry(PackageDescr packageDescr) {
PackageRegistry pkgRegistry = initPackageRegistry(packageDescr);
PackageRegistry pkgRegistry = initPackageRegistry( packageDescr );
if (pkgRegistry == null) {
return null;
}
Expand All @@ -948,7 +948,7 @@ private PackageRegistry initPackageRegistry(PackageDescr packageDescr) {

initPackage(packageDescr);

PackageRegistry pkgRegistry = this.pkgRegistryMap.get(packageDescr.getNamespace());
PackageRegistry pkgRegistry = this.pkgRegistryMap.get( packageDescr.getNamespace() );
if (pkgRegistry == null) {
// initialise the package and namespace if it hasn't been used before
pkgRegistry = newPackage(packageDescr);
Expand Down Expand Up @@ -1095,23 +1095,25 @@ private void sortRulesByDependency(PackageDescr packageDescr) {
// Using a topological sorting algorithm
// see http://en.wikipedia.org/wiki/Topological_sorting

PackageRegistry pkgRegistry = this.pkgRegistryMap.get(packageDescr.getNamespace());
PackageRegistry pkgRegistry = this.pkgRegistryMap.get( packageDescr.getNamespace() );
InternalKnowledgePackage pkg = pkgRegistry.getPackage();

List<RuleDescr> roots = new LinkedList<RuleDescr>();
Map<String, List<RuleDescr>> children = new HashMap<String, List<RuleDescr>>();
LinkedHashMap<String, RuleDescr> sorted = new LinkedHashMap<String, RuleDescr>();
List<RuleDescr> queries = new ArrayList<RuleDescr>();
List<String> compiledRules = new ArrayList<String>();

for (RuleDescr ruleDescr : packageDescr.getRules()) {
if (ruleDescr.isQuery()) {
queries.add(ruleDescr);
} else if (!ruleDescr.hasParent()) {
roots.add(ruleDescr);
} else if (pkg.getRule(ruleDescr.getParentName()) != null) {
// The parent of this rule has been already compiled
sorted.put(ruleDescr.getName(), ruleDescr);
} else {
if (pkg.getRule(ruleDescr.getParentName()) != null) {
// The parent of this rule has been already compiled
compiledRules.add(ruleDescr.getParentName());
}
List<RuleDescr> childz = children.get(ruleDescr.getParentName());
if (childz == null) {
childz = new ArrayList<RuleDescr>();
Expand All @@ -1129,6 +1131,11 @@ private void sortRulesByDependency(PackageDescr packageDescr) {
return;
}

for (String compiledRule : compiledRules) {
List<RuleDescr> childz = children.remove( compiledRule );
roots.addAll( childz );
}

while (!roots.isEmpty()) {
RuleDescr root = roots.remove(0);
sorted.put(root.getName(), root);
Expand All @@ -1142,8 +1149,8 @@ private void sortRulesByDependency(PackageDescr packageDescr) {

packageDescr.getRules().clear();
packageDescr.getRules().addAll(queries);
for (RuleDescr descr : sorted.values()) {
packageDescr.getRules().add(descr);
for (RuleDescr descr : sorted.values() ) {
packageDescr.getRules().add( descr );
}
}

Expand All @@ -1155,11 +1162,11 @@ private void reportHierarchyErrors(Map<String, List<RuleDescr>> parents,
if (parents.get(ruleDescr.getParentName()) != null
&& (sorted.containsKey(ruleDescr.getName()) || parents.containsKey(ruleDescr.getName()))) {
circularDep = true;
results.add(new RuleBuildError(new RuleImpl(ruleDescr.getName()), ruleDescr, null,
"Circular dependency in rules hierarchy"));
results.add( new RuleBuildError( new RuleImpl( ruleDescr.getName() ), ruleDescr, null,
"Circular dependency in rules hierarchy" ) );
break;
}
manageUnresolvedExtension(ruleDescr, sorted.values());
manageUnresolvedExtension( ruleDescr, sorted.values() );
}
if (circularDep) {
break;
Expand Down Expand Up @@ -1500,7 +1507,7 @@ void mergePackage(PackageRegistry pkgRegistry, PackageDescr packageDescr) {
unsortedDescrs.add( enumDeclarationDescr );
}

typeBuilder.processTypeDeclarations( Arrays.asList( packageDescr ), unsortedDescrs, unresolvedTypes, unprocesseableDescrs );
typeBuilder.processTypeDeclarations( Collections.singletonList( packageDescr ), unsortedDescrs, unresolvedTypes, unprocesseableDescrs );
for ( AbstractClassTypeDeclarationDescr descr : unprocesseableDescrs.values() ) {
this.addBuilderResult( new TypeDeclarationError( descr, "Unable to process type " + descr.getTypeName() ) );
}
Expand Down Expand Up @@ -1829,10 +1836,6 @@ public KnowledgeBuilderResults getResults(ResultSeverity... problemTypes) {
return new PackageBuilderResults(problems.toArray(new BaseKnowledgeBuilderResultImpl[problems.size()]));
}

/**
* @param severities
* @return
*/
private List<KnowledgeBuilderResult> getResultList(ResultSeverity... severities) {
List<ResultSeverity> typesToFetch = Arrays.asList(severities);
ArrayList<KnowledgeBuilderResult> problems = new ArrayList<KnowledgeBuilderResult>();
Expand Down Expand Up @@ -2029,7 +2032,7 @@ public int[] getLines() {
});
}
} else {
buildResources.push(Arrays.asList(resource));
buildResources.push( Collections.singletonList( resource ) );
}
}

Expand Down Expand Up @@ -2132,15 +2135,15 @@ public boolean isClassInUse(String className) {
return !(rootClassLoader instanceof ProjectClassLoader) || ((ProjectClassLoader) rootClassLoader).isClassInUse(className);
}

public static interface AssetFilter {
public static enum Action {
public interface AssetFilter {
enum Action {
DO_NOTHING, ADD, REMOVE, UPDATE
}

public Action accept(String pkgName, String assetName);
Action accept(String pkgName, String assetName);
}

public AssetFilter getAssetFilter() {
AssetFilter getAssetFilter() {
return assetFilter;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import static org.drools.core.util.StringUtils.isEmpty;

Expand Down Expand Up @@ -137,6 +139,13 @@ private <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<String>();
Collections.sort( (List<RuleDescr>) cdescrs, RULE_HIERARCHY_COMPARATOR );
}

for( T crd : cdescrs ) {
String cName = descrNameConverter.getName(crd);

Expand All @@ -150,30 +159,37 @@ private <T extends BaseDescr> void diffDescrs(byte[] ob, byte[] cb,

// using byte[] comparison because using the descriptor equals() method
// is brittle and heavier than iterating an array
if( !segmentEquals(ob, ord.getStartCharacter(), ord.getEndCharacter(),
cb, crd.getStartCharacter(), crd.getEndCharacter() ) ) {
pkgcs.getChanges().add( new ResourceChange( ChangeType.UPDATED,
type,
cName ) );
if ( !segmentEquals(ob, ord.getStartCharacter(), ord.getEndCharacter(), 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 ) );
pkgcs.getChanges().add( new ResourceChange( ChangeType.ADDED, type, cName ) );
}
}

for( T ord : odescrs ) {
for ( T ord : odescrs ) {
pkgcs.getChanges().add( new ResourceChange( ChangeType.REMOVED,
type,
descrNameConverter.getName(ord) ) );
}
}

private boolean segmentEquals( byte[] a1, int s1, int e1,
private static final RuleHierarchyComparator RULE_HIERARCHY_COMPARATOR = new RuleHierarchyComparator();
private static class RuleHierarchyComparator implements Comparator<RuleDescr> {
@Override
public int compare( RuleDescr r1, RuleDescr r2 ) {
return r1.getName().equals( r2.getParentName() ) ? -1 : r1.getName().equals( r2.getParentName() ) ? 1 : 0;
}
}

private boolean segmentEquals( byte[] a1, int s1, int e1,
byte[] a2, int s2, int e2) {
int length = e1 - s1;
if( length <= 0 || length != e2-s2 || s1+length > a1.length || s2+length > a2.length ) {
Expand Down

0 comments on commit 10ae3a7

Please sign in to comment.