Skip to content

Commit fc9bcc7

Browse files
committed
[DROOLS-879] add support for Drools Rule Template in KIE API
1 parent 803190c commit fc9bcc7

File tree

16 files changed

+303
-203
lines changed

16 files changed

+303
-203
lines changed

drools-compiler/src/main/java/org/drools/compiler/builder/impl/CompositeKnowledgeBuilderImpl.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ private Collection<CompositePackageDescr> buildPackageDescr() {
304304
buildResource(packages, ResourceType.SCARD, SCARD_TO_PKG_DESCR);
305305
buildResource(packages, ResourceType.TDRL, DRL_TO_PKG_DESCR);
306306
buildResource(packages, ResourceType.TEMPLATE, TEMPLATE_TO_PKG_DESCR);
307+
this.resourcesByType.remove(ResourceType.DRT); // drt is a template for dtables but doesn't have to be built on its own
307308
return packages.values();
308309
}
309310

@@ -330,7 +331,9 @@ private void registerPackageDescr(ResourceDescr resourceDescr, Map<String, Compo
330331
if (packageDescr != null) {
331332
CompositePackageDescr compositePackageDescr = packages.get(packageDescr.getNamespace());
332333
if (compositePackageDescr == null) {
333-
compositePackageDescr = new CompositePackageDescr(resource, packageDescr);
334+
compositePackageDescr = packageDescr instanceof CompositePackageDescr ?
335+
( (CompositePackageDescr) packageDescr ) :
336+
new CompositePackageDescr(resource, packageDescr);
334337
packages.put(packageDescr.getNamespace(), compositePackageDescr);
335338
} else {
336339
compositePackageDescr.addPackageDescr(resource, packageDescr);

drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderImpl.java

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.drools.compiler.lang.descr.AnnotationDescr;
5656
import org.drools.compiler.lang.descr.AttributeDescr;
5757
import org.drools.compiler.lang.descr.BaseDescr;
58+
import org.drools.compiler.lang.descr.CompositePackageDescr;
5859
import org.drools.compiler.lang.descr.ConditionalElementDescr;
5960
import org.drools.compiler.lang.descr.EntryPointDeclarationDescr;
6061
import org.drools.compiler.lang.descr.EnumDeclarationDescr;
@@ -394,17 +395,43 @@ PackageDescr decisionTableToPackageDescr(Resource resource,
394395
DecisionTableConfiguration dtableConfiguration = configuration instanceof DecisionTableConfiguration ?
395396
(DecisionTableConfiguration) configuration :
396397
null;
398+
399+
if ( dtableConfiguration != null && !dtableConfiguration.getRuleTemplateConfigurations().isEmpty() ) {
400+
List<String> generatedDrls = DecisionTableFactory.loadFromInputStreamWithTemplates( resource, dtableConfiguration );
401+
if ( generatedDrls.size() == 1 ) {
402+
return generatedDrlToPackageDescr( resource, generatedDrls.get(0) );
403+
}
404+
CompositePackageDescr compositePackageDescr = null;
405+
for ( String generatedDrl : generatedDrls ) {
406+
PackageDescr packageDescr = generatedDrlToPackageDescr( resource, generatedDrl );
407+
if ( packageDescr != null ) {
408+
if ( compositePackageDescr == null ) {
409+
compositePackageDescr = new CompositePackageDescr( resource, packageDescr );
410+
} else {
411+
compositePackageDescr.addPackageDescr( resource, packageDescr );
412+
}
413+
}
414+
}
415+
return compositePackageDescr;
416+
}
417+
397418
String generatedDrl = DecisionTableFactory.loadFromInputStream(resource.getInputStream(), dtableConfiguration);
419+
return generatedDrlToPackageDescr( resource, generatedDrl );
420+
}
421+
422+
private PackageDescr generatedDrlToPackageDescr( Resource resource, String generatedDrl ) throws DroolsParserException {
398423
// dump the generated DRL if the dump dir was configured
399424
if (this.configuration.getDumpDir() != null) {
400425
dumpDrlGeneratedFromDTable(this.configuration.getDumpDir(), generatedDrl, resource.getSourcePath());
401426
}
402427

403-
DrlParser parser = new DrlParser(this.configuration.getLanguageLevel());
428+
DrlParser parser = new DrlParser(configuration.getLanguageLevel());
404429
PackageDescr pkg = parser.parse(resource, new StringReader(generatedDrl));
405430
this.results.addAll(parser.getErrors());
406431
if (pkg == null) {
407432
addBuilderResult(new ParserError(resource, "Parser returned a null Package", 0, 0));
433+
} else {
434+
pkg.setResource(resource);
408435
}
409436
return parser.hasErrors() ? null : pkg;
410437
}
@@ -444,14 +471,7 @@ PackageDescr scoreCardToPackageDescr(Resource resource,
444471
(ScoreCardConfiguration) configuration :
445472
null;
446473
String string = ScoreCardFactory.loadFromInputStream(resource.getInputStream(), scardConfiguration);
447-
448-
DrlParser parser = new DrlParser(this.configuration.getLanguageLevel());
449-
PackageDescr pkg = parser.parse(resource, new StringReader(string));
450-
this.results.addAll( parser.getErrors() );
451-
if (pkg == null) {
452-
addBuilderResult(new ParserError(resource, "Parser returned a null Package", 0, 0));
453-
}
454-
return parser.hasErrors() ? null : pkg;
474+
return generatedDrlToPackageDescr( resource, string );
455475
}
456476

457477
public void addPackageFromTemplate(Resource resource) throws DroolsParserException,
@@ -800,15 +820,7 @@ PackageDescr pmmlModelToPackageDescr(PMMLCompiler compiler,
800820
return null;
801821
}
802822

803-
DrlParser parser = new DrlParser(configuration.getLanguageLevel());
804-
PackageDescr pkg = parser.parse(resource, new StringReader(theory));
805-
this.results.addAll(parser.getErrors());
806-
if (pkg == null) {
807-
addBuilderResult(new ParserError(resource, "Parser returned a null Package", 0, 0));
808-
return pkg;
809-
} else {
810-
return parser.hasErrors() ? null : pkg;
811-
}
823+
return generatedDrlToPackageDescr( resource, theory );
812824
}
813825

814826
void addPackageFromXSD(Resource resource,

drools-compiler/src/main/java/org/drools/compiler/compiler/DecisionTableFactory.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515

1616
package org.drools.compiler.compiler;
1717

18-
import java.io.InputStream;
19-
18+
import org.kie.api.io.Resource;
2019
import org.kie.internal.builder.DecisionTableConfiguration;
2120
import org.kie.internal.utils.ServiceRegistryImpl;
2221

22+
import java.io.InputStream;
23+
import java.util.List;
24+
2325
public class DecisionTableFactory {
2426

2527
private static final String PROVIDER_CLASS = "org.drools.decisiontable.DecisionTableProviderImpl";
@@ -29,7 +31,11 @@ public class DecisionTableFactory {
2931
public static String loadFromInputStream(InputStream is, DecisionTableConfiguration configuration) {
3032
return getDecisionTableProvider().loadFromInputStream( is, configuration );
3133
}
32-
34+
35+
public static List<String> loadFromInputStreamWithTemplates(Resource resource, DecisionTableConfiguration configuration) {
36+
return getDecisionTableProvider().loadFromInputStreamWithTemplates( resource, configuration );
37+
}
38+
3339
public static synchronized void setDecisionTableProvider(DecisionTableProvider provider) {
3440
DecisionTableFactory.provider = provider;
3541
}

drools-compiler/src/main/java/org/drools/compiler/compiler/DecisionTableProvider.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,20 @@
1515

1616
package org.drools.compiler.compiler;
1717

18-
import java.io.InputStream;
19-
2018
import org.kie.api.Service;
19+
import org.kie.api.io.Resource;
2120
import org.kie.internal.builder.DecisionTableConfiguration;
2221

22+
import java.io.InputStream;
23+
import java.util.List;
24+
2325
public interface DecisionTableProvider extends Service {
2426

2527
String loadFromInputStream(InputStream is,
2628
DecisionTableConfiguration configuration);
2729

30+
List<String> loadFromInputStreamWithTemplates(Resource resource,
31+
DecisionTableConfiguration configuration);
32+
2833

2934
}

drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieModule.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,12 @@
3838
import org.kie.api.builder.Results;
3939
import org.kie.api.builder.model.KieBaseModel;
4040
import org.kie.api.builder.model.KieModuleModel;
41+
import org.kie.api.builder.model.RuleTemplateModel;
4142
import org.kie.api.io.Resource;
4243
import org.kie.api.io.ResourceConfiguration;
4344
import org.kie.api.io.ResourceType;
4445
import org.kie.internal.builder.CompositeKnowledgeBuilder;
46+
import org.kie.internal.builder.DecisionTableConfiguration;
4547
import org.kie.internal.builder.DecisionTableInputType;
4648
import org.kie.internal.builder.KnowledgeBuilder;
4749
import org.kie.internal.builder.KnowledgeBuilderError;
@@ -231,7 +233,7 @@ static KnowledgeBuilder buildKnowledgePackages( KieBaseModelImpl kBaseModel,
231233
}
232234
} else {
233235
for (Map.Entry<String, InternalKieModule> entry : assets.entrySet()) {
234-
entry.getValue().addResourceToCompiler(ckbuilder, entry.getKey());
236+
entry.getValue().addResourceToCompiler(ckbuilder, kBaseModel, entry.getKey());
235237
}
236238
}
237239

@@ -279,20 +281,29 @@ private static void addFiles(Map<String, InternalKieModule> assets,
279281
}
280282
}
281283

282-
public boolean addResourceToCompiler(CompositeKnowledgeBuilder ckbuilder, String fileName) {
284+
public final boolean addResourceToCompiler(CompositeKnowledgeBuilder ckbuilder, KieBaseModel kieBaseModel, String fileName) {
283285
ResourceConfiguration conf = getResourceConfiguration(fileName);
284286
Resource resource = getResource(fileName);
285287
if (resource != null) {
288+
ResourceType resourceType = conf instanceof ResourceConfigurationImpl && ((ResourceConfigurationImpl)conf).getResourceType() != null ?
289+
((ResourceConfigurationImpl)conf).getResourceType() :
290+
ResourceType.determineResourceType(fileName);
291+
292+
if (resourceType == ResourceType.DTABLE && conf instanceof DecisionTableConfiguration) {
293+
for (RuleTemplateModel template : kieBaseModel.getRuleTemplates()) {
294+
if (template.getDtable().equals( fileName )) {
295+
Resource templateResource = getResource( template.getTemplate() );
296+
if ( templateResource != null ) {
297+
( (DecisionTableConfiguration) conf ).addRuleTemplateConfiguration( templateResource, template.getRow(), template.getCol() );
298+
}
299+
}
300+
}
301+
}
302+
286303
if (conf == null) {
287-
ckbuilder.add(resource,
288-
ResourceType.determineResourceType(fileName));
304+
ckbuilder.add(resource, resourceType);
289305
} else {
290-
ResourceType confType = conf instanceof ResourceConfigurationImpl ?
291-
((ResourceConfigurationImpl)conf).getResourceType() :
292-
null;
293-
ckbuilder.add(resource,
294-
confType != null ? confType : ResourceType.determineResourceType(fileName),
295-
conf);
306+
ckbuilder.add(resource, resourceType, conf);
296307
}
297308
return true;
298309
}

drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/InternalKieModule.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.kie.api.builder.KieModule;
2121
import org.kie.api.builder.ReleaseId;
2222
import org.kie.api.builder.Results;
23+
import org.kie.api.builder.model.KieBaseModel;
2324
import org.kie.api.builder.model.KieModuleModel;
2425
import org.kie.api.io.Resource;
2526
import org.kie.api.io.ResourceConfiguration;
@@ -74,7 +75,7 @@ public interface InternalKieModule extends KieModule {
7475

7576
Map<String, byte[]> getClassesMap(boolean includeTypeDeclarations);
7677

77-
boolean addResourceToCompiler(CompositeKnowledgeBuilder ckbuilder, String fileName);
78+
boolean addResourceToCompiler(CompositeKnowledgeBuilder ckbuilder, KieBaseModel kieBaseModel, String fileName);
7879

7980
long getCreationTimestamp();
8081

drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieBuilderSetImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ private boolean addResource( CompositeKnowledgeBuilder ckbuilder,
173173
String resourceName ) {
174174
return !resourceName.endsWith(".properties") &&
175175
filterFileInKBase(kieModule, kieBaseModel, resourceName) &&
176-
kieModule.addResourceToCompiler(ckbuilder, resourceName);
176+
kieModule.addResourceToCompiler(ckbuilder, kieBaseModel, resourceName);
177177
}
178178

179179
public static class DummyResource extends BaseResource {

drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/KieContainerImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ private Results update(InternalKieModule currentKM, ReleaseId newReleaseId) {
201201
// readd unchanged dsl files to the kbuilder
202202
for (String dslFile : dslFiles) {
203203
if (isFileInKBase(newKM, kieBaseModel, dslFile)) {
204-
newKM.addResourceToCompiler(ckbuilder, dslFile);
204+
newKM.addResourceToCompiler(ckbuilder, kieBaseModel, dslFile);
205205
}
206206
}
207207
rebuildAll(newReleaseId, results, newKM, modifiedClasses, kieBaseModel, pkgbuilder, ckbuilder);
@@ -292,7 +292,7 @@ private void updateAllResources(InternalKieModule currentKM, InternalKieModule n
292292
}
293293
for (String resourceName : newKM.getFileNames()) {
294294
if ( !resourceName.endsWith( ".properties" ) && isFileInKBase(newKM, kieBaseModel, resourceName) ) {
295-
newKM.addResourceToCompiler(ckbuilder, resourceName);
295+
newKM.addResourceToCompiler(ckbuilder, kieBaseModel, resourceName);
296296
}
297297
}
298298
}
@@ -323,7 +323,7 @@ private int updateResourcesIncrementally(InternalKieModule currentKM,
323323
Resource resource = currentKM.getResource(resourceName);
324324
kbuilder.removeObjectsGeneratedFromResource(resource);
325325
}
326-
fileCount += newKM.addResourceToCompiler(ckbuilder, resourceName) ? 1 : 0;
326+
fileCount += newKM.addResourceToCompiler(ckbuilder, kieBaseModel, resourceName) ? 1 : 0;
327327
}
328328
}
329329
}

drools-compiler/src/main/java/org/drools/compiler/kproject/models/KieBaseModelImpl.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424
import org.kie.api.builder.model.KieBaseModel;
2525
import org.kie.api.builder.model.KieModuleModel;
2626
import org.kie.api.builder.model.KieSessionModel;
27+
import org.kie.api.builder.model.RuleTemplateModel;
28+
import org.kie.api.conf.DeclarativeAgendaOption;
2729
import org.kie.api.conf.EqualityBehaviorOption;
2830
import org.kie.api.conf.EventProcessingOption;
2931
import org.kie.api.io.ResourceType;
30-
import org.kie.api.conf.DeclarativeAgendaOption;
3132

3233
import java.util.ArrayList;
3334
import java.util.Collections;
@@ -64,6 +65,8 @@ public class KieBaseModelImpl
6465

6566
private String scope = "javax.enterprise.context.ApplicationScoped";
6667

68+
private List<RuleTemplateModel> ruleTemplates = new ArrayList<RuleTemplateModel>();
69+
6770
private boolean isDefault = false;
6871

6972
public KieBaseModelImpl() {
@@ -164,6 +167,19 @@ public void moveKSession(String oldQName,
164167
setKSessions( newMap );
165168
}
166169

170+
public List<RuleTemplateModel> getRuleTemplates() {
171+
return Collections.unmodifiableList( ruleTemplates );
172+
}
173+
174+
public List<RuleTemplateModel> getRawRuleTemplates() {
175+
return ruleTemplates;
176+
}
177+
178+
public KieBaseModel addRuleTemplate(String dtable, String template, int row, int col) {
179+
ruleTemplates.add( new RuleTemplateModelImpl( this, dtable, template, row, col ) );
180+
return this;
181+
}
182+
167183
/* (non-Javadoc)
168184
* @see org.kie.kproject.KieBaseModel#getName()
169185
*/
@@ -338,9 +354,13 @@ public void marshal(Object value,
338354
writer.addAttribute( "includes", sb.toString() );
339355
}
340356

341-
for ( KieSessionModel kSessionModel : kBase.getKieSessionModels().values()) {
342-
writeObject( writer, context, "ksession", kSessionModel);
357+
for ( RuleTemplateModel ruleTemplateModel : kBase.getRuleTemplates()) {
358+
writeObject( writer, context, "ruleTemplate", ruleTemplateModel);
343359
}
360+
361+
for ( KieSessionModel kSessionModel : kBase.getKieSessionModels().values()) {
362+
writeObject( writer, context, "ksession", kSessionModel);
363+
}
344364
}
345365

346366
public Object unmarshal(HierarchicalStreamReader reader,
@@ -391,6 +411,10 @@ public void onNode(HierarchicalStreamReader reader,
391411
KieSessionModelImpl kSession = readObject( reader, context, KieSessionModelImpl.class );
392412
kBase.getRawKieSessionModels().put( kSession.getName(), kSession );
393413
kSession.setKBase(kBase);
414+
} else if ( "ruleTemplate".equals( name ) ) {
415+
RuleTemplateModelImpl ruleTemplate = readObject( reader, context, RuleTemplateModelImpl.class );
416+
kBase.getRawRuleTemplates().add( ruleTemplate );
417+
ruleTemplate.setKBase( kBase );
394418
}
395419

396420
// @TODO we don't use support nested includes

drools-compiler/src/main/java/org/drools/compiler/kproject/models/KieModuleModelImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,13 +170,15 @@ private kModuleMarshaller() {
170170
xStream.registerConverter(new ListenerModelImpl.ListenerConverter());
171171
xStream.registerConverter(new QualifierModelImpl.QualifierConverter());
172172
xStream.registerConverter(new WorkItemHandlerModelImpl.WorkItemHandelerConverter());
173+
xStream.registerConverter(new RuleTemplateModelImpl.RuleTemplateConverter());
173174
xStream.alias("kmodule", KieModuleModelImpl.class);
174175
xStream.alias("kbase", KieBaseModelImpl.class);
175176
xStream.alias("ksession", KieSessionModelImpl.class);
176177
xStream.alias("listener", ListenerModelImpl.class);
177178
xStream.alias("qualifier", QualifierModelImpl.class);
178179
xStream.alias("workItemHandler", WorkItemHandlerModelImpl.class);
179180
xStream.alias("fileLogger", FileLoggerModelImpl.class);
181+
xStream.alias("ruleTemplate", RuleTemplateModelImpl.class);
180182
xStream.setClassLoader(KieModuleModelImpl.class.getClassLoader());
181183
}
182184

0 commit comments

Comments
 (0)