You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by ma...@apache.org on 2024/01/17 13:29:17 UTC
(incubator-kie-drools) branch main updated: [KIE-792] introducing prototypes (#5639)
This is an automated email from the ASF dual-hosted git repository.
mariofusco pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git
The following commit(s) were added to refs/heads/main by this push:
new 999a28e71d [KIE-792] introducing prototypes (#5639)
999a28e71d is described below
commit 999a28e71d2ce80410fdf99efc3caea732b93d76
Author: Mario Fusco <ma...@gmail.com>
AuthorDate: Wed Jan 17 14:29:12 2024 +0100
[KIE-792] introducing prototypes (#5639)
* [KIE-792] introducing prototype dialect
* implement prototype field setting in consequence
* minor refactor
* rewrite prototype field access in consequence
* add dialect attribute to yaml rule format + test it in quarkus extension
* isolate prototypes in their own module
* introduce new public API for prototypes
* get rid of fact templates
* turn prototype dialect into a KieBase option
* implement access of map values via field notation in the mvel compiler
---
bom/drools-bom/pom.xml | 18 +
.../java/org/drools/base/base/ClassObjectType.java | 2 +-
.../main/java/org/drools/base/base/ObjectType.java | 2 +-
.../main/java/org/drools/base/base/ValueType.java | 8 +-
.../base/definitions/InternalKnowledgePackage.java | 6 +-
.../definitions/impl/KnowledgePackageImpl.java | 25 +-
.../org/drools/base/facttemplates/FactImpl.java | 89 ----
.../drools/base/facttemplates/FactTemplate.java | 63 ---
.../base/facttemplates/FactTemplateImpl.java | 150 ------
.../drools/base/facttemplates/FieldTemplate.java | 29 --
.../base/facttemplates/FieldTemplateImpl.java | 87 ----
.../PrototypeFieldExtractor.java} | 85 ++--
.../PrototypeObjectType.java} | 70 ++-
.../drools/base/reteoo/PropertySpecificUtil.java | 10 +-
.../src/main/java/org/drools/base/rule/From.java | 4 +-
.../java/org/drools/base/rule/TypeDeclaration.java | 32 +-
.../drools/base/rule/accessor/GlobalExtractor.java | 6 +-
.../base/rule/accessor/PatternExtractor.java | 6 +-
.../builder/impl/DroolsAssemblerContextImpl.java | 2 +-
.../KnowledgeBuilderRulesConfigurationImpl.java | 18 +-
.../builder/impl/TypeDeclarationManagerImpl.java | 2 +-
.../drools/compiler/compiler/BoundIdentifiers.java | 4 +-
.../compiler/compiler/FactTemplateError.java | 73 ---
.../compiler/compiler/FieldTemplateError.java | 72 ---
.../kie/builder/impl/AbstractKieModule.java | 13 +-
.../compiler/kproject/models/KieBaseModelImpl.java | 20 +-
.../compiler/rule/builder/PatternBuilder.java | 33 +-
.../org/drools/core/RuleBaseConfiguration.java | 40 +-
.../common/ObjectTypeConfigurationRegistry.java | 15 +-
.../org/drools/core/phreak/PropagationEntry.java | 6 +-
...emplateTypeConf.java => PrototypeTypeConf.java} | 44 +-
.../FactTemplateFieldExtractorTest.java | 108 ----
.../core/facttemplates/FactTemplateTest.java | 120 -----
.../src/test/resources/expected/test1.yml | 1 +
.../src/test/resources/expected/test2.drl.txt | 1 +
.../integration/tests/ProgrammaticProjectTest.java | 52 +-
.../org/drools/drlonyaml/model/DrlPackage.java | 13 +-
.../src/main/resources/drlonyaml-schema.json | 3 +
.../src/main/resources/drl.ftl | 1 +
.../impact/analysis/parser/impl/PackageParser.java | 4 +-
.../impact/analysis/parser/impl/RhsParser.java | 6 +-
.../kiesession/entrypoints/NamedEntryPoint.java | 31 +-
.../org/drools/model/PrototypeFactFactory.java | 51 --
.../src/main/java/org/drools/model/Variable.java | 4 +
drools-model/drools-model-codegen/pom.xml | 4 +
.../model/codegen/execmodel/PackageModel.java | 48 +-
.../codegen/execmodel/generator/AggregateKey.java | 30 +-
.../execmodel/generator/BoxedParameters.java | 48 +-
.../codegen/execmodel/generator/Consequence.java | 23 +-
.../execmodel/generator/DeclarationSpec.java | 153 +-----
.../codegen/execmodel/generator/DrlxParseUtil.java | 6 +-
.../execmodel/generator/DslMethodNames.java | 12 +
.../execmodel/generator/ModelGenerator.java | 59 +--
.../execmodel/generator/OOPathExprGenerator.java | 2 +-
.../generator/PrototypeDeclarationSpec.java | 82 ++++
.../execmodel/generator/QueryGenerator.java | 9 +-
.../codegen/execmodel/generator/RuleContext.java | 103 ++--
...larationSpec.java => TypedDeclarationSpec.java} | 92 +++-
.../generator/drlxparse/ConstraintExpression.java | 2 +-
.../generator/drlxparse/ConstraintParser.java | 10 +-
.../expression/AbstractExpressionBuilder.java | 2 +-
.../generator/expressiontyper/ExpressionTyper.java | 20 +-
.../execmodel/generator/visitor/FromVisitor.java | 6 +-
.../visitor/accumulate/AccumulateInline.java | 10 +-
.../visitor/accumulate/AccumulateVisitor.java | 42 +-
.../visitor/accumulate/GroupByVisitor.java | 4 +-
.../visitor/accumulate/LegacyAccumulate.java | 2 +-
.../{PatternDSL.java => ClassPatternDSL.java} | 214 +++++---
.../visitor/pattern/ConstraintOOPath.java | 6 +-
.../pattern/PatternAccumulateConstraint.java | 2 +-
.../pattern/PatternConstraintParseResult.java | 24 +-
.../generator/visitor/pattern/PatternDSL.java | 312 +-----------
.../visitor/pattern/PatternDSLPattern.java | 136 ------
.../generator/visitor/pattern/PatternVisitor.java | 5 +-
.../visitor/pattern/PrototypePatternDSL.java | 132 +++++
.../processors/ModelMainCompilationPhase.java | 12 +-
.../KogitoKnowledgeBuilderConfigurationImpl.java | 53 --
.../{FactTemplateTest.java => PrototypeTest.java} | 544 ++++++++++-----------
.../codegen/execmodel/PrototypesAllowedTest.java | 215 ++++++++
.../execmodel/SegmentPrototypeExpressionTest.java | 23 +-
.../execmodel/generator/ExpressionTyperTest.java | 18 +-
.../drools/modelcompiler/KiePackagesBuilder.java | 17 +-
.../org/drools/modelcompiler/PrototypeService.java | 50 ++
.../modelcompiler/facttemplate/FactFactory.java | 82 ----
.../facttemplate/PrototypeFactFactoryImpl.java | 38 --
.../services/org.drools.model.PrototypeFactFactory | 1 -
drools-model/drools-model-prototype/pom.xml | 50 ++
.../org/drools/model/prototype}/PrototypeDSL.java | 117 ++---
.../model/prototype}/PrototypeExpression.java | 42 +-
.../drools/model/prototype}/PrototypeVariable.java | 13 +-
.../model/prototype/impl}/HashMapEventImpl.java | 22 +-
.../model/prototype/impl}/HashMapFactImpl.java | 31 +-
.../model/prototype/impl/PrototypeBuilderImpl.java | 82 ++++
.../model/prototype/impl/PrototypeEventImpl.java | 21 +-
.../model/prototype/impl/PrototypeFactImpl.java | 23 +-
.../model/prototype}/impl/PrototypeImpl.java | 69 +--
.../model/prototype/impl/PrototypeServiceImpl.java | 44 ++
.../prototype}/impl/PrototypeVariableImpl.java | 15 +-
.../org.drools.modelcompiler.PrototypeService | 1 +
.../org.kie.api.prototype.PrototypeBuilder$Creator | 1 +
.../prototype/PrototypeFieldExtractorTest.java | 86 ++++
.../java/org/drools/mvelcompiler/LHSPhase.java | 10 +-
.../drools/mvelcompiler/PreprocessCompiler.java | 44 +-
.../java/org/drools/mvelcompiler/RHSPhase.java | 15 +-
.../ast/{MapPutExprT.java => MapGetExprT.java} | 25 +-
.../org/drools/mvelcompiler/ast/MapPutExprT.java | 16 +-
.../org/drools/mvelcompiler/util/TypeUtils.java | 19 +
.../org/drools/mvelcompiler/MvelCompilerTest.java | 21 +
.../mvelcompiler/PreprocessCompilerTest.java | 3 +-
drools-model/pom.xml | 3 +-
.../org/drools/mvel/MVELKnowledgePackageImpl.java | 4 +-
.../org/drools/quarkus/test/TestableResource.java | 20 +-
.../src/main/resources/META-INF/kmodule.xml | 7 +-
.../src/main/resources/application.properties | 20 +
.../org/drools/prototype/CanDrink.drl.yaml | 22 +
.../java/org/drools/quarkus/test/RuntimeTest.java | 32 +-
.../deployment/DroolsQuarkusResourceUtils.java | 21 +-
.../test/ReliabilityCepOnceAfterTest.java | 49 +-
.../test/ReliabilityCepOnceWithinTest.java | 35 +-
.../test/ReliabilityCepTimeWindowTest.java | 14 +-
.../test/ReliabilityCepTimedOutTest.java | 63 ++-
.../reliability/test/ReliabilityTestBasics.java | 36 +-
.../test/proto/HashMapEventImplAdaptor.java | 12 +-
.../reliability/test/util/PrototypeUtils.java | 32 +-
.../conf/KnowledgeBaseConfigurationTest.java | 20 +
.../drools/mvel/integrationtests/Misc2Test.java | 29 --
.../java/org/drools/mvel/rule/PatternTest.java | 46 +-
.../impl/TraitKnowledgePackageImpl.java | 4 +-
.../xml/support/converters/KBaseConverter.java | 9 +
.../org/kie/api/builder/model/KieBaseModel.java | 12 +
.../java/org/kie/api/conf/PrototypesOption.java | 56 +++
.../java/org/kie/api/prototype}/Prototype.java | 21 +-
.../org/kie/api/prototype/PrototypeBuilder.java | 50 ++
.../java/org/kie/api/prototype/PrototypeEvent.java | 9 +-
.../kie/api/prototype/PrototypeEventInstance.java | 6 +-
.../java/org/kie/api/prototype/PrototypeFact.java | 8 +-
.../kie/api/prototype/PrototypeFactInstance.java | 11 +-
kie-api/src/main/resources/org/kie/api/kmodule.xsd | 8 +
.../java/org/kie/internal/utils/KieHelper.java | 26 +-
139 files changed, 2596 insertions(+), 2941 deletions(-)
diff --git a/bom/drools-bom/pom.xml b/bom/drools-bom/pom.xml
index 746b669770..f718a910cf 100644
--- a/bom/drools-bom/pom.xml
+++ b/bom/drools-bom/pom.xml
@@ -630,6 +630,24 @@
<type>test-jar</type>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-model-prototype</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-model-prototype</artifactId>
+ <version>${project.version}</version>
+ <classifier>sources</classifier>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-model-prototype</artifactId>
+ <version>${project.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
<!-- Quarkus Extension -->
<dependency>
diff --git a/drools-base/src/main/java/org/drools/base/base/ClassObjectType.java b/drools-base/src/main/java/org/drools/base/base/ClassObjectType.java
index 150fad3d6e..5b674f2398 100644
--- a/drools-base/src/main/java/org/drools/base/base/ClassObjectType.java
+++ b/drools-base/src/main/java/org/drools/base/base/ClassObjectType.java
@@ -185,7 +185,7 @@ public class ClassObjectType
}
@Override
- public boolean isTemplate() {
+ public boolean isPrototype() {
return false;
}
diff --git a/drools-base/src/main/java/org/drools/base/base/ObjectType.java b/drools-base/src/main/java/org/drools/base/base/ObjectType.java
index 03cdd4f648..49f13d78c8 100644
--- a/drools-base/src/main/java/org/drools/base/base/ObjectType.java
+++ b/drools-base/src/main/java/org/drools/base/base/ObjectType.java
@@ -48,5 +48,5 @@ public interface ObjectType
boolean hasField(String name);
- boolean isTemplate();
+ boolean isPrototype();
}
diff --git a/drools-base/src/main/java/org/drools/base/base/ValueType.java b/drools-base/src/main/java/org/drools/base/base/ValueType.java
index e3edc67f65..63bb006991 100644
--- a/drools-base/src/main/java/org/drools/base/base/ValueType.java
+++ b/drools-base/src/main/java/org/drools/base/base/ValueType.java
@@ -27,8 +27,8 @@ import java.util.function.Function;
import org.drools.base.factmodel.traits.Thing;
import org.drools.base.factmodel.traits.Trait;
-import org.drools.base.facttemplates.FactTemplate;
import org.drools.util.CoercionUtil;
+import org.kie.api.prototype.Prototype;
import org.kie.api.runtime.rule.EventHandle;
public enum ValueType {
@@ -65,7 +65,7 @@ public enum ValueType {
ARRAY_TYPE( "Array", Object[].class, SimpleValueType.LIST ),
STRING_TYPE( "String", String.class, SimpleValueType.STRING, CoercionUtil::coerceToString ),
OBJECT_TYPE( "Object", Object.class, SimpleValueType.OBJECT ),
- FACTTEMPLATE_TYPE( "FactTemplate", FactTemplate.class, SimpleValueType.UNKNOWN ),
+ PROTOTYPE_TYPE("Prototype", Prototype.class, SimpleValueType.UNKNOWN ),
EVENT_TYPE("Event", EventHandle.class, SimpleValueType.OBJECT ),
QUERY_TYPE("Query", DroolsQuery.class, SimpleValueType.OBJECT ),
@@ -141,8 +141,8 @@ public enum ValueType {
}
// primitives
- if ( clazz == FactTemplate.class ) {
- return ValueType.FACTTEMPLATE_TYPE;
+ if ( clazz == Prototype.class ) {
+ return ValueType.PROTOTYPE_TYPE;
} else if ( clazz == DroolsQuery.class ) {
return ValueType.QUERY_TYPE;
} else if ( clazz == Character.TYPE ) {
diff --git a/drools-base/src/main/java/org/drools/base/definitions/InternalKnowledgePackage.java b/drools-base/src/main/java/org/drools/base/definitions/InternalKnowledgePackage.java
index 19cd8c5ce5..f2953066e1 100644
--- a/drools-base/src/main/java/org/drools/base/definitions/InternalKnowledgePackage.java
+++ b/drools-base/src/main/java/org/drools/base/definitions/InternalKnowledgePackage.java
@@ -30,7 +30,6 @@ import org.drools.base.RuleBase;
import org.drools.base.base.AcceptsClassObjectType;
import org.drools.base.base.ObjectType;
import org.drools.base.definitions.rule.impl.RuleImpl;
-import org.drools.base.facttemplates.FactTemplate;
import org.drools.base.rule.DialectRuntimeRegistry;
import org.drools.base.rule.Function;
import org.drools.base.rule.ImportDeclaration;
@@ -44,6 +43,7 @@ import org.kie.api.definition.KiePackage;
import org.kie.api.definition.process.Process;
import org.kie.api.definition.type.FactType;
import org.kie.api.io.Resource;
+import org.kie.api.prototype.Prototype;
import org.kie.api.runtime.rule.AccumulateFunction;
import org.kie.internal.builder.KnowledgeBuilderResult;
@@ -98,7 +98,7 @@ public interface InternalKnowledgePackage extends KiePackage,
void addTypeDeclaration(TypeDeclaration typeDecl);
- void addFactTemplate(FactTemplate factTemplate);
+ void addPrototype(Prototype prototype);
void addImport(ImportDeclaration importDecl);
@@ -141,7 +141,7 @@ public interface InternalKnowledgePackage extends KiePackage,
TypeDeclaration getTypeDeclaration(String type);
- FactTemplate getFactTemplate(String name);
+ Prototype getPrototype(String name);
ClassLoader getPackageClassLoader();
diff --git a/drools-base/src/main/java/org/drools/base/definitions/impl/KnowledgePackageImpl.java b/drools-base/src/main/java/org/drools/base/definitions/impl/KnowledgePackageImpl.java
index f2dc9e3b3f..b96b3cbb05 100644
--- a/drools-base/src/main/java/org/drools/base/definitions/impl/KnowledgePackageImpl.java
+++ b/drools-base/src/main/java/org/drools/base/definitions/impl/KnowledgePackageImpl.java
@@ -45,7 +45,6 @@ import org.drools.base.definitions.ProcessPackage;
import org.drools.base.definitions.ResourceTypePackageRegistry;
import org.drools.base.definitions.rule.impl.GlobalImpl;
import org.drools.base.definitions.rule.impl.RuleImpl;
-import org.drools.base.facttemplates.FactTemplate;
import org.drools.base.rule.DialectRuntimeData;
import org.drools.base.rule.DialectRuntimeRegistry;
import org.drools.base.rule.DuplicateRuleNameException;
@@ -68,6 +67,7 @@ import org.kie.api.definition.rule.Rule;
import org.kie.api.definition.type.FactType;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceType;
+import org.kie.api.prototype.Prototype;
import org.kie.api.runtime.rule.AccumulateFunction;
public class KnowledgePackageImpl
@@ -103,7 +103,7 @@ public class KnowledgePackageImpl
protected Map<String, Type> globals;
- protected Map<String, FactTemplate> factTemplates;
+ protected Map<String, Prototype> prototypes;
protected DialectRuntimeRegistry dialectRuntimeRegistry;
@@ -151,7 +151,7 @@ public class KnowledgePackageImpl
this.accumulateFunctions = Collections.emptyMap();
this.staticImports = Collections.emptySet();
this.globals = Collections.emptyMap();
- this.factTemplates = Collections.emptyMap();
+ this.prototypes = Collections.emptyMap();
this.functions = Collections.emptyMap();
this.dialectRuntimeRegistry = new DialectRuntimeRegistry();
this.entryPointsIds = Collections.emptySet();
@@ -243,7 +243,7 @@ public class KnowledgePackageImpl
out.writeObject(this.staticImports);
out.writeObject(this.functions);
out.writeObject(this.accumulateFunctions);
- out.writeObject(this.factTemplates);
+ out.writeObject(this.prototypes);
out.writeObject(this.globals);
out.writeBoolean(this.valid);
out.writeBoolean(this.needStreamMode);
@@ -289,7 +289,7 @@ public class KnowledgePackageImpl
this.staticImports = (Set) in.readObject();
this.functions = (Map<String, Function>) in.readObject();
this.accumulateFunctions = (Map<String, AccumulateFunction>) in.readObject();
- this.factTemplates = (Map) in.readObject();
+ this.prototypes = (Map) in.readObject();
this.globals = (Map<String, Type>) in.readObject();
this.valid = in.readBoolean();
this.needStreamMode = in.readBoolean();
@@ -445,17 +445,16 @@ public class KnowledgePackageImpl
}
@Override
- public FactTemplate getFactTemplate(final String name) {
- return this.factTemplates.get(name);
+ public Prototype getPrototype(final String name) {
+ return this.prototypes.get(name);
}
@Override
- public void addFactTemplate(final FactTemplate factTemplate) {
- if (this.factTemplates == Collections.EMPTY_MAP) {
- this.factTemplates = new HashMap<>(1);
+ public void addPrototype(final Prototype prototype) {
+ if (this.prototypes == Collections.EMPTY_MAP) {
+ this.prototypes = new HashMap<>(1);
}
- this.factTemplates.put(factTemplate.getName(),
- factTemplate);
+ this.prototypes.put(prototype.getName(), prototype);
}
/**
@@ -586,7 +585,7 @@ public class KnowledgePackageImpl
this.accumulateFunctions.clear();
this.staticImports.clear();
this.globals.clear();
- this.factTemplates.clear();
+ this.prototypes.clear();
this.typeDeclarations.clear();
this.windowDeclarations.clear();
}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FactImpl.java b/drools-base/src/main/java/org/drools/base/facttemplates/FactImpl.java
deleted file mode 100644
index b081e5817a..0000000000
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FactImpl.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.base.facttemplates;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-//import woolfel.engine.rule.Rule;
-
-public class FactImpl implements Fact, Externalizable {
-
- private FactTemplate factTemplate = null;
- private Map<String, Object> values = new HashMap<>();
-
- public FactImpl() {
- }
-
- public FactImpl(final FactTemplate template) {
- this.factTemplate = template;
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- factTemplate = (FactTemplate)in.readObject();
- values = (Map<String, Object>)in.readObject();
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(factTemplate);
- out.writeObject(values);
- }
-
- public Object get(final String name) {
- return this.values.get( name );
- }
-
- public void set(final String name, final Object value) {
- this.values.put( name, value );
- }
-
- /**
- * Return the deftemplate for the fact
- */
- public FactTemplate getFactTemplate() {
- return this.factTemplate;
- }
-
- @Override
- public Map<String, Object> asMap() {
- return values;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- FactImpl fact = (FactImpl) o;
- return factTemplate.equals(fact.factTemplate) && values.equals(fact.values);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(factTemplate, values);
- }
-}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplate.java b/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplate.java
deleted file mode 100644
index 4b0ffaed98..0000000000
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplate.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.base.facttemplates;
-
-import java.io.Externalizable;
-import java.util.Collection;
-
-import org.drools.base.definitions.InternalKnowledgePackage;
-
-
-public interface FactTemplate
- extends
- Externalizable {
-
- InternalKnowledgePackage getPackage();
-
- /**
- * The name of the template may be the fully qualified
- * class name, or an alias.
- * @return
- */
- String getName();
-
- /**
- * templates may have 1 or more slots. A slot is a named
- * pattern with a specific type of value.
- * @return
- */
- int getNumberOfFields();
-
- Collection<String> getFieldNames();
-
- /**
- * Return the slot with the String name
- * @return
- */
- FieldTemplate getFieldTemplate(String name);
-
- /**
- * Get the pattern index with the given name
- * @param name
- * @return
- */
- int getFieldTemplateIndex(String name);
-
- Fact createFact();
-}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateImpl.java b/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateImpl.java
deleted file mode 100644
index 07622df7cf..0000000000
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateImpl.java
+++ /dev/null
@@ -1,150 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.base.facttemplates;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.drools.base.definitions.InternalKnowledgePackage;
-
-
-public class FactTemplateImpl implements FactTemplate {
-
- private InternalKnowledgePackage pkg;
- private String name;
- private SortedMap<String, FieldTemplate> fields = new TreeMap<>();
-
- public FactTemplateImpl() {
-
- }
-
- public FactTemplateImpl(final InternalKnowledgePackage pkg,
- final String name,
- final FieldTemplate... fields) {
- this.pkg = pkg;
- this.name = name;
- this.pkg.addFactTemplate( this );
-
- if (fields != null && fields.length > 0) {
- this.fields = new TreeMap<>();
- for (FieldTemplate field : fields) {
- this.fields.put(field.getName(), field);
- }
- } else {
- this.fields = Collections.emptySortedMap();
- }
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- pkg = (InternalKnowledgePackage)in.readObject();
- name = (String)in.readObject();
- fields = (SortedMap<String, FieldTemplate>)in.readObject();
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(pkg);
- out.writeObject(name);
- out.writeObject(fields);
- }
-
- public InternalKnowledgePackage getPackage() {
- return this.pkg;
- }
-
- /**
- * the template name is an alias for an object
- */
- public String getName() {
- return this.name;
- }
-
- /**
- * Return the number of slots in the deftemplate
- * @return
- */
- public int getNumberOfFields() {
- return this.fields.size();
- }
-
- /**
- * Return all the slots
- * @return
- */
- public Collection<String> getFieldNames() {
- return this.fields.keySet();
- }
-
- /**
- * A convienance method for finding the slot matching
- * the String name.
- * @param name
- * @return
- */
- public FieldTemplate getFieldTemplate(final String name) {
- return this.fields.get(name);
- }
-
- /**
- * Look up the pattern index of the slot
- */
- public int getFieldTemplateIndex(final String name) {
- int i = 0;
- for ( String field : fields.keySet() ) {
- if ( field.equals( name ) ) {
- return i;
- }
- i++;
- }
- return -1;
- }
-
- /**
- * Method takes a list of Slots and creates a deffact from it.
- */
- public Fact createFact() {
- return new FactImpl( this );
- }
-
- public String toString() {
- return "FactTemplate of: " + this.name;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- FactTemplateImpl that = (FactTemplateImpl) o;
- return pkg.getName().equals(that.pkg.getName()) && name.equals(that.name) && fields.equals(that.fields);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(pkg.getName(), name, fields);
- }
-}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FieldTemplate.java b/drools-base/src/main/java/org/drools/base/facttemplates/FieldTemplate.java
deleted file mode 100644
index fd77a04de1..0000000000
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FieldTemplate.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.base.facttemplates;
-
-import org.drools.base.base.ValueType;
-
-public interface FieldTemplate {
-
- String getName();
-
- ValueType getValueType();
-
-}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FieldTemplateImpl.java b/drools-base/src/main/java/org/drools/base/facttemplates/FieldTemplateImpl.java
deleted file mode 100644
index e0de97e9bf..0000000000
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FieldTemplateImpl.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.base.facttemplates;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-import org.drools.base.base.ValueType;
-
-public class FieldTemplateImpl implements FieldTemplate, Externalizable {
-
- private static final long serialVersionUID = 510l;
-
- private String name;
- private ValueType valueType;
-
- public FieldTemplateImpl() {
-
- }
-
- public FieldTemplateImpl(String name, Class clazz) {
- this.name = name;
- this.valueType = clazz != null ? ValueType.OBJECT_TYPE : ValueType.determineValueType( clazz );
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- name = (String)in.readObject();
- valueType = (ValueType)in.readObject();
- if (valueType != null) {
- valueType = ValueType.determineValueType(valueType.getClassType());
- }
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(name);
- out.writeObject(valueType);
- }
-
- public String getName() {
- return this.name;
- }
-
- public ValueType getValueType() {
- return this.valueType;
- }
-
- public int hashCode() {
- final int PRIME = 31;
- int result = 1;
- result = PRIME * result + this.name.hashCode();
- result = PRIME * result + this.valueType.hashCode();
- return result;
- }
-
- public boolean equals(final Object object) {
- if ( this == object ) {
- return true;
- }
-
- if ( object == null || getClass() != object.getClass() ) {
- return false;
- }
-
- final FieldTemplateImpl other = (FieldTemplateImpl) object;
-
- return this.name.equals( other.name ) && this.valueType.equals( other.valueType );
- }
-
-}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateFieldExtractor.java b/drools-base/src/main/java/org/drools/base/prototype/PrototypeFieldExtractor.java
similarity index 58%
rename from drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateFieldExtractor.java
rename to drools-base/src/main/java/org/drools/base/prototype/PrototypeFieldExtractor.java
index bbf498076d..4a6732fd58 100644
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateFieldExtractor.java
+++ b/drools-base/src/main/java/org/drools/base/prototype/PrototypeFieldExtractor.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.base.facttemplates;
+package org.drools.base.prototype;
import java.io.Externalizable;
import java.io.IOException;
@@ -28,47 +28,45 @@ import org.drools.base.base.ValueResolver;
import org.drools.base.base.ValueType;
import org.drools.base.rule.accessor.ReadAccessor;
import org.drools.util.ClassUtils;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
-public class FactTemplateFieldExtractor
- implements
- Externalizable,
- ReadAccessor {
+public class PrototypeFieldExtractor implements Externalizable, ReadAccessor {
private static final long serialVersionUID = 510l;
- private FactTemplate factTemplate;
+ private Prototype prototype;
private String fieldName;
private int fieldIndex;
- public FactTemplateFieldExtractor() {
+ public PrototypeFieldExtractor() {
}
- public FactTemplateFieldExtractor(FactTemplate factTemplate, String fieldName) {
- this.factTemplate = factTemplate;
+ public PrototypeFieldExtractor(Prototype prototype, String fieldName) {
+ this.prototype = prototype;
this.fieldName = fieldName;
- this.fieldIndex = factTemplate.getFieldTemplateIndex(fieldName);
+ this.fieldIndex = prototype.getFieldIndex(fieldName);
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
- factTemplate = (FactTemplate) in.readObject();
+ prototype = (Prototype) in.readObject();
fieldName = in.readUTF();
fieldIndex = in.readInt();
}
public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject( factTemplate );
+ out.writeObject( prototype );
out.writeUTF( fieldName );
out.writeInt( fieldIndex );
}
public ValueType getValueType() {
- return this.factTemplate.getFieldTemplate( this.fieldName ).getValueType();
+ return ValueType.determineValueType(getExtractToClass());
}
- public Object getValue(ValueResolver valueResolver,
- final Object object) {
- return ((Fact) object).get( this.fieldName );
+ public Object getValue(ValueResolver valueResolver, final Object object) {
+ return ((PrototypeFactInstance) object).get(this.fieldName );
}
public int getIndex() {
@@ -76,51 +74,44 @@ public class FactTemplateFieldExtractor
}
public Class getExtractToClass() {
- return this.factTemplate.getFieldTemplate( fieldName ).getValueType().getClassType();
+ Prototype.Field field = this.prototype.getField( fieldName );
+ return field != null ? field.getClass() : Object.class;
}
public String getExtractToClassName() {
return ClassUtils.canonicalName( getExtractToClass() );
}
- public boolean getBooleanValue(ValueResolver valueResolver,
- final Object object) {
- return ((Boolean) ((Fact) object).get( fieldName )).booleanValue();
+ public boolean getBooleanValue(ValueResolver valueResolver, Object object) {
+ return (Boolean) ((PrototypeFactInstance) object).get(fieldName);
}
- public byte getByteValue(ValueResolver valueResolver,
- final Object object) {
- return ((Number) ((Fact) object).get( fieldName )).byteValue();
+ public byte getByteValue(ValueResolver valueResolver, Object object) {
+ return ((Number) ((PrototypeFactInstance) object).get( fieldName )).byteValue();
}
- public char getCharValue(ValueResolver valueResolver,
- final Object object) {
- return ((Character) ((Fact) object).get( fieldName )).charValue();
+ public char getCharValue(ValueResolver valueResolver, Object object) {
+ return (Character) ((PrototypeFactInstance) object).get(fieldName);
}
- public double getDoubleValue(ValueResolver valueResolver,
- final Object object) {
- return ((Number) ((Fact) object).get( fieldName )).doubleValue();
+ public double getDoubleValue(ValueResolver valueResolver, Object object) {
+ return ((Number) ((PrototypeFactInstance) object).get( fieldName )).doubleValue();
}
- public float getFloatValue(ValueResolver valueResolver,
- final Object object) {
- return ((Number) ((Fact) object).get( fieldName )).floatValue();
+ public float getFloatValue(ValueResolver valueResolver, Object object) {
+ return ((Number) ((PrototypeFactInstance) object).get( fieldName )).floatValue();
}
- public int getIntValue(ValueResolver valueResolver,
- final Object object) {
- return ((Number) ((Fact) object).get( fieldName )).intValue();
+ public int getIntValue(ValueResolver valueResolver, Object object) {
+ return ((Number) ((PrototypeFactInstance) object).get( fieldName )).intValue();
}
- public long getLongValue(ValueResolver valueResolver,
- final Object object) {
- return ((Number) ((Fact) object).get( fieldName )).longValue();
+ public long getLongValue(ValueResolver valueResolver, Object object) {
+ return ((Number) ((PrototypeFactInstance) object).get( fieldName )).longValue();
}
- public short getShortValue(ValueResolver valueResolver,
- final Object object) {
- return ((Number) ((Fact) object).get( fieldName )).shortValue();
+ public short getShortValue(ValueResolver valueResolver, Object object) {
+ return ((Number) ((PrototypeFactInstance) object).get( fieldName )).shortValue();
}
public Method getNativeReadMethod() {
@@ -150,7 +141,7 @@ public class FactTemplateFieldExtractor
}
public boolean isNullValue(ValueResolver valueResolver, Object object) {
- return ((Fact) object).get( this.fieldName ) == null;
+ return ((PrototypeFactInstance) object).get( this.fieldName ) == null;
}
public int getHashCode(Object object) {
@@ -169,7 +160,7 @@ public class FactTemplateFieldExtractor
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + ((factTemplate == null) ? 0 : factTemplate.hashCode());
+ result = prime * result + ((prototype == null) ? 0 : prototype.hashCode());
result = prime * result + fieldIndex;
return result;
}
@@ -185,13 +176,13 @@ public class FactTemplateFieldExtractor
if ( getClass() != obj.getClass() ) {
return false;
}
- FactTemplateFieldExtractor other = (FactTemplateFieldExtractor) obj;
+ PrototypeFieldExtractor other = (PrototypeFieldExtractor) obj;
- if ( factTemplate == null ) {
- if ( other.factTemplate != null ) {
+ if ( prototype == null ) {
+ if ( other.prototype != null ) {
return false;
}
- } else if ( !factTemplate.equals( other.factTemplate ) ) {
+ } else if ( !prototype.equals( other.prototype ) ) {
return false;
}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateObjectType.java b/drools-base/src/main/java/org/drools/base/prototype/PrototypeObjectType.java
similarity index 63%
rename from drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateObjectType.java
rename to drools-base/src/main/java/org/drools/base/prototype/PrototypeObjectType.java
index cd782deed0..d62088f18e 100644
--- a/drools-base/src/main/java/org/drools/base/facttemplates/FactTemplateObjectType.java
+++ b/drools-base/src/main/java/org/drools/base/prototype/PrototypeObjectType.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.base.facttemplates;
+package org.drools.base.prototype;
import java.io.IOException;
import java.io.ObjectInput;
@@ -25,51 +25,39 @@ import java.util.Collection;
import org.drools.base.base.ObjectType;
import org.drools.base.base.ValueType;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
-public class FactTemplateObjectType
- implements
- ObjectType {
+public class PrototypeObjectType implements ObjectType {
+ protected Prototype prototype;
- private static final long serialVersionUID = 510l;
-
- /** FieldTemplate. */
- protected FactTemplate factTemplate;
-
- private boolean isEvent;
+ private boolean isEvent;
// ------------------------------------------------------------
// Constructors
// ------------------------------------------------------------
- public FactTemplateObjectType() {
+ public PrototypeObjectType() {
}
- public FactTemplateObjectType(final FactTemplate factTemplate) {
- this.factTemplate = factTemplate;
+ public PrototypeObjectType(Prototype prototype) {
+ this.prototype = prototype;
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- factTemplate = (FactTemplate)in.readObject();
- isEvent = in.readBoolean();
+ prototype = (Prototype)in.readObject();
+ isEvent = in.readBoolean();
}
public void writeExternal(ObjectOutput out) throws IOException {
- out.writeObject(factTemplate);
+ out.writeObject(prototype);
out.writeBoolean(isEvent);
}
- // ------------------------------------------------------------
- // Instance methods
- // ------------------------------------------------------------
- /**
- * Return the Fact Template.
- *
- * @return The Fact Template
- */
- public FactTemplate getFactTemplate() {
- return this.factTemplate;
+ public Prototype getPrototype() {
+ return prototype;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -87,8 +75,8 @@ public class FactTemplateObjectType
* object type, else <code>false</code>.
*/
public boolean matches(final Object object) {
- if ( object instanceof Fact f ) {
- return this.factTemplate.equals( f.getFactTemplate() );
+ if ( object instanceof PrototypeFactInstance f ) {
+ return this.prototype.equals( f.getPrototype() );
} else {
return false;
}
@@ -106,16 +94,16 @@ public class FactTemplateObjectType
@Override
public boolean isAssignableFrom(ObjectType objectType) {
- if ( !(objectType instanceof FactTemplateObjectType) ) {
+ if ( !(objectType instanceof PrototypeObjectType) ) {
return false;
} else {
- return this.factTemplate.equals( ((FactTemplateObjectType) objectType).getFactTemplate() );
+ return this.prototype.equals( ((PrototypeObjectType) objectType).getPrototype() );
}
}
@Override
public ValueType getValueType() {
- return ValueType.FACTTEMPLATE_TYPE;
+ return ValueType.PROTOTYPE_TYPE;
}
@Override
@@ -129,31 +117,31 @@ public class FactTemplateObjectType
@Override
public Object getTypeKey() {
- return factTemplate.getName();
+ return prototype.getName();
}
@Override
- public boolean isTemplate() {
+ public boolean isPrototype() {
return true;
}
@Override
public String getClassName() {
- return factTemplate.getPackage() + "." + factTemplate.getName();
+ return prototype.getFullName();
}
@Override
public boolean hasField(String name) {
- return factTemplate.getFieldTemplate(name) != null;
+ return prototype.getField(name) != null;
}
public Collection<String> getFieldNames() {
- return factTemplate.getFieldNames();
+ return prototype.getFieldNames();
}
@Override
public String toString() {
- return "[FactTemplateObjectType "+( this.isEvent ? "event=" : "template=") + this.factTemplate.getName() + "]";
+ return "[PrototypeObjectType "+( this.isEvent ? "event=" : "template=") + this.prototype.getName() + "]";
}
@Override
@@ -162,17 +150,17 @@ public class FactTemplateObjectType
return true;
}
- if (!(object instanceof FactTemplateObjectType)) {
+ if (!(object instanceof PrototypeObjectType)) {
return false;
}
- final FactTemplateObjectType other = (FactTemplateObjectType) object;
+ final PrototypeObjectType other = (PrototypeObjectType) object;
- return this.factTemplate.equals( other.factTemplate );
+ return this.prototype.equals( other.prototype );
}
@Override
public int hashCode() {
- return this.factTemplate.hashCode();
+ return this.prototype.hashCode();
}
}
diff --git a/drools-base/src/main/java/org/drools/base/reteoo/PropertySpecificUtil.java b/drools-base/src/main/java/org/drools/base/reteoo/PropertySpecificUtil.java
index aa634c35c8..dcb45106c1 100644
--- a/drools-base/src/main/java/org/drools/base/reteoo/PropertySpecificUtil.java
+++ b/drools-base/src/main/java/org/drools/base/reteoo/PropertySpecificUtil.java
@@ -26,7 +26,7 @@ import org.drools.base.RuleBase;
import org.drools.base.base.ClassObjectType;
import org.drools.base.base.ObjectType;
import org.drools.base.factmodel.traits.TraitConstants;
-import org.drools.base.facttemplates.FactTemplateObjectType;
+import org.drools.base.prototype.PrototypeObjectType;
import org.drools.base.rule.TypeDeclaration;
import org.drools.util.bitmask.AllSetBitMask;
import org.drools.util.bitmask.AllSetButLastBitMask;
@@ -40,8 +40,8 @@ public class PropertySpecificUtil {
public static final int CUSTOM_BITS_OFFSET = 1;
public static boolean isPropertyReactive(RuleBase ruleBase, ObjectType objectType) {
- if (objectType.isTemplate()) {
- return !((FactTemplateObjectType) objectType).getFieldNames().isEmpty();
+ if (objectType.isPrototype()) {
+ return !((PrototypeObjectType) objectType).getFieldNames().isEmpty();
}
TypeDeclaration typeDeclaration = ruleBase.getTypeDeclaration(((ClassObjectType) objectType).getClassType() );
return typeDeclaration != null && typeDeclaration.isPropertyReactive();
@@ -128,8 +128,8 @@ public class PropertySpecificUtil {
}
public static List<String> getAccessibleProperties(RuleBase ruleBase, ObjectType objectType) {
- return objectType.isTemplate() ?
- new ArrayList<>(((FactTemplateObjectType) objectType).getFieldNames()) :
+ return objectType.isPrototype() ?
+ new ArrayList<>(((PrototypeObjectType) objectType).getFieldNames()) :
getAccessibleProperties(ruleBase, ((ClassObjectType) objectType).getClassType());
}
diff --git a/drools-base/src/main/java/org/drools/base/rule/From.java b/drools-base/src/main/java/org/drools/base/rule/From.java
index 37e6371d5c..3a6f8947d6 100644
--- a/drools-base/src/main/java/org/drools/base/rule/From.java
+++ b/drools-base/src/main/java/org/drools/base/rule/From.java
@@ -27,9 +27,9 @@ import java.util.List;
import java.util.Map;
import org.drools.base.base.ClassObjectType;
-import org.drools.base.facttemplates.Fact;
import org.drools.base.rule.accessor.DataProvider;
import org.drools.base.rule.accessor.Wireable;
+import org.kie.api.prototype.PrototypeFactInstance;
public class From extends ConditionalElement
implements
@@ -131,7 +131,7 @@ public class From extends ConditionalElement
public Class<?> getResultClass() {
return resultClass != null ?
resultClass :
- (resultPattern.getObjectType().isTemplate() ? Fact.class : ((ClassObjectType) resultPattern.getObjectType()).getClassType());
+ (resultPattern.getObjectType().isPrototype() ? PrototypeFactInstance.class : ((ClassObjectType) resultPattern.getObjectType()).getClassType());
}
public void setResultClass(Class<?> resultClass) {
diff --git a/drools-base/src/main/java/org/drools/base/rule/TypeDeclaration.java b/drools-base/src/main/java/org/drools/base/rule/TypeDeclaration.java
index 78b014161c..f6779f408d 100644
--- a/drools-base/src/main/java/org/drools/base/rule/TypeDeclaration.java
+++ b/drools-base/src/main/java/org/drools/base/rule/TypeDeclaration.java
@@ -29,8 +29,7 @@ import org.drools.base.base.ClassObjectType;
import org.drools.base.base.ObjectType;
import org.drools.base.factmodel.ClassDefinition;
import org.drools.base.factmodel.GeneratedFact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateObjectType;
+import org.drools.base.prototype.PrototypeObjectType;
import org.drools.base.rule.accessor.ReadAccessor;
import org.drools.base.util.PropertyReactivityUtil;
import org.drools.base.util.TimeIntervalParser;
@@ -41,6 +40,7 @@ import org.kie.api.definition.type.Expires.Policy;
import org.kie.api.definition.type.PropertyReactive;
import org.kie.api.definition.type.Role;
import org.kie.api.io.Resource;
+import org.kie.api.prototype.Prototype;
import org.kie.internal.builder.conf.PropertySpecificOption;
import org.kie.internal.definition.KnowledgeDefinition;
@@ -110,7 +110,7 @@ public class TypeDeclaration
private ReadAccessor timestampExtractor;
private transient Class< ? > typeClass;
private String typeClassName;
- private FactTemplate typeTemplate;
+ private Prototype prototype;
private ClassDefinition typeClassDef;
private Resource resource;
private boolean dynamic;
@@ -163,7 +163,7 @@ public class TypeDeclaration
this.durationAttribute = null;
this.timestampAttribute = null;
- this.typeTemplate = null;
+ this.prototype = null;
this.typesafe = true;
this.valid = true;
}
@@ -178,7 +178,7 @@ public class TypeDeclaration
this.durationAttribute = (String) in.readObject();
this.timestampAttribute = (String) in.readObject();
this.typeClassName = (String) in.readObject();
- this.typeTemplate = (FactTemplate) in.readObject();
+ this.prototype = (Prototype) in.readObject();
this.typeClassDef = (ClassDefinition) in.readObject();
this.durationExtractor = (ReadAccessor) in.readObject();
this.timestampExtractor = (ReadAccessor) in.readObject();
@@ -200,7 +200,7 @@ public class TypeDeclaration
out.writeObject( durationAttribute );
out.writeObject( timestampAttribute );
out.writeObject( typeClassName );
- out.writeObject( typeTemplate );
+ out.writeObject( prototype );
out.writeObject( typeClassDef );
out.writeObject( durationExtractor );
out.writeObject( timestampExtractor );
@@ -342,26 +342,16 @@ public class TypeDeclaration
return typeClass != null && GeneratedFact.class.isAssignableFrom( typeClass );
}
- /**
- * @return the typeTemplate
- */
- public FactTemplate getTypeTemplate() {
- return typeTemplate;
- }
-
- /**
- * @param typeTemplate the typeTemplate to set
- */
- public void setTypeTemplate(FactTemplate typeTemplate) {
- this.typeTemplate = typeTemplate;
+ public Prototype getPrototype() {
+ return prototype;
}
/**
* Returns true if the given parameter matches this type declaration
*/
public boolean matches(Object clazz) {
- return clazz instanceof FactTemplate ?
- this.typeTemplate.equals( clazz ) :
+ return clazz instanceof Prototype ?
+ this.prototype.equals( clazz ) :
this.typeClass.isAssignableFrom( (Class< ? >) clazz );
}
@@ -444,7 +434,7 @@ public class TypeDeclaration
if ( this.getFormat() == Format.POJO ) {
this.objectType = new ClassObjectType( this.getTypeClass() );
} else {
- this.objectType = new FactTemplateObjectType( this.getTypeTemplate() );
+ this.objectType = new PrototypeObjectType(this.getPrototype() );
}
}
return this.objectType;
diff --git a/drools-base/src/main/java/org/drools/base/rule/accessor/GlobalExtractor.java b/drools-base/src/main/java/org/drools/base/rule/accessor/GlobalExtractor.java
index fb4808e5fd..5988701cfc 100755
--- a/drools-base/src/main/java/org/drools/base/rule/accessor/GlobalExtractor.java
+++ b/drools-base/src/main/java/org/drools/base/rule/accessor/GlobalExtractor.java
@@ -29,8 +29,8 @@ import org.drools.base.base.ClassObjectType;
import org.drools.base.base.ObjectType;
import org.drools.base.base.ValueResolver;
import org.drools.base.base.extractors.BaseObjectClassFieldReader;
-import org.drools.base.facttemplates.Fact;
import org.drools.util.ClassUtils;
+import org.kie.api.prototype.PrototypeFactInstance;
/**
* This is a global variable extractor used to get a global variable value
@@ -91,7 +91,7 @@ public class GlobalExtractor extends BaseObjectClassFieldReader
if ( this.objectType instanceof ClassObjectType cot ) {
return cot.getClassType();
} else {
- return Fact.class;
+ return PrototypeFactInstance.class;
}
}
@@ -101,7 +101,7 @@ public class GlobalExtractor extends BaseObjectClassFieldReader
if ( this.objectType instanceof ClassObjectType cot ) {
clazz = cot.getClassType();
} else {
- clazz = Fact.class;
+ clazz = PrototypeFactInstance.class;
}
return ClassUtils.canonicalName( clazz );
}
diff --git a/drools-base/src/main/java/org/drools/base/rule/accessor/PatternExtractor.java b/drools-base/src/main/java/org/drools/base/rule/accessor/PatternExtractor.java
index 5981010738..d5e274eb90 100644
--- a/drools-base/src/main/java/org/drools/base/rule/accessor/PatternExtractor.java
+++ b/drools-base/src/main/java/org/drools/base/rule/accessor/PatternExtractor.java
@@ -29,8 +29,8 @@ import org.drools.base.base.ClassObjectType;
import org.drools.base.base.ObjectType;
import org.drools.base.base.ValueResolver;
import org.drools.base.base.extractors.BaseObjectClassFieldReader;
-import org.drools.base.facttemplates.Fact;
import org.drools.util.ClassUtils;
+import org.kie.api.prototype.PrototypeFactInstance;
public class PatternExtractor extends BaseObjectClassFieldReader
implements
@@ -85,14 +85,14 @@ public class PatternExtractor extends BaseObjectClassFieldReader
if ( this.objectType instanceof ClassObjectType ) {
return ((ClassObjectType) this.objectType).getClassType();
} else {
- return Fact.class;
+ return PrototypeFactInstance.class;
}
}
public String getExtractToClassName() {
Class<?> clazz = this.objectType instanceof ClassObjectType ?
((ClassObjectType) this.objectType).getClassType() :
- Fact.class;
+ PrototypeFactInstance.class;
return ClassUtils.canonicalName( clazz );
}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/DroolsAssemblerContextImpl.java b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/DroolsAssemblerContextImpl.java
index 74e0c96e6d..8478e263a0 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/DroolsAssemblerContextImpl.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/DroolsAssemblerContextImpl.java
@@ -92,7 +92,7 @@ public class DroolsAssemblerContextImpl implements DroolsAssemblerContext, Build
@Override
public TypeDeclaration getTypeDeclaration(ObjectType objectType) {
- return objectType.isTemplate() ?
+ return objectType.isPrototype() ?
typeBuilder.getExistingTypeDeclaration(objectType.getClassName()) :
typeBuilder.getTypeDeclaration(((ClassObjectType) objectType).getClassType());
}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderRulesConfigurationImpl.java b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderRulesConfigurationImpl.java
index e34574cd3b..09ee9e930f 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderRulesConfigurationImpl.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/KnowledgeBuilderRulesConfigurationImpl.java
@@ -31,6 +31,7 @@ import org.drools.core.BaseConfiguration;
import org.drools.drl.parser.DrlParser;
import org.kie.api.conf.ConfigurationKey;
import org.kie.api.conf.OptionKey;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.runtime.rule.AccumulateFunction;
import org.kie.internal.builder.KnowledgeBuilderConfiguration;
import org.kie.internal.builder.conf.AccumulateFunctionOption;
@@ -106,6 +107,8 @@ public class KnowledgeBuilderRulesConfigurationImpl extends BaseConfiguration<Kn
private static final PropertySpecificOption DEFAULT_PROP_SPEC_OPT = PropertySpecificOption.ALWAYS;
private PropertySpecificOption propertySpecificOption = DEFAULT_PROP_SPEC_OPT;
+ private PrototypesOption prototypesOption = PrototypesOption.DISABLED;
+
private LanguageLevelOption languageLevel = DrlParser.DEFAULT_LANGUAGE_LEVEL;
private CompilationCache compilationCache = null;
@@ -165,9 +168,12 @@ public class KnowledgeBuilderRulesConfigurationImpl extends BaseConfiguration<Kn
return getClassLoader();
}
- public boolean setInternalProperty(String name,
- String value) {
+ public boolean setInternalProperty(String name, String value) {
switch (name) {
+ case PrototypesOption.PROPERTY_NAME: {
+ setPrototypesOption(PrototypesOption.determinePrototypesOption(value));
+ break;
+ }
case ProcessStringEscapesOption.PROPERTY_NAME: {
setProcessStringEscapes(Boolean.parseBoolean(value));
break;
@@ -382,6 +388,14 @@ public class KnowledgeBuilderRulesConfigurationImpl extends BaseConfiguration<Kn
this.propertySpecificOption = propertySpecificOption;
}
+ public PrototypesOption getPrototypesOption() {
+ return prototypesOption;
+ }
+
+ public void setPrototypesOption(PrototypesOption prototypesOption) {
+ this.prototypesOption = prototypesOption;
+ }
+
public boolean isExternaliseCanonicalModelLambda() {
return externaliseCanonicalModelLambda;
}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/TypeDeclarationManagerImpl.java b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/TypeDeclarationManagerImpl.java
index 2c847740b8..11ddb625c3 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/builder/impl/TypeDeclarationManagerImpl.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/builder/impl/TypeDeclarationManagerImpl.java
@@ -64,7 +64,7 @@ public class TypeDeclarationManagerImpl implements TypeDeclarationManager {
@Override
public TypeDeclaration getTypeDeclaration(ObjectType objectType) {
- return objectType.isTemplate() ?
+ return objectType.isPrototype() ?
typeBuilder.getExistingTypeDeclaration(objectType.getClassName()) :
typeBuilder.getTypeDeclaration(((ClassObjectType) objectType).getClassType());
}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/compiler/BoundIdentifiers.java b/drools-compiler/src/main/java/org/drools/compiler/compiler/BoundIdentifiers.java
index a4e6207973..4ad5d5027e 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/compiler/BoundIdentifiers.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/compiler/BoundIdentifiers.java
@@ -26,13 +26,13 @@ import java.util.Map;
import org.drools.base.base.ClassObjectType;
import org.drools.base.base.ObjectType;
-import org.drools.base.facttemplates.Fact;
import org.drools.base.rule.Declaration;
import org.drools.base.rule.Pattern;
import org.drools.base.rule.XpathBackReference;
import org.drools.compiler.rule.builder.EvaluatorWrapper;
import org.drools.compiler.rule.builder.PackageBuildContext;
import org.drools.compiler.rule.builder.RuleBuildContext;
+import org.kie.api.prototype.PrototypeFactInstance;
import static org.drools.util.ClassUtils.rawType;
@@ -62,7 +62,7 @@ public class BoundIdentifiers {
PackageBuildContext context,
Map<String, EvaluatorWrapper> operators,
ObjectType objectType) {
- this(getDeclarationsMap( pattern, context ), context, operators, objectType.isTemplate() ? Fact.class : ((ClassObjectType) objectType).getClassType());
+ this(getDeclarationsMap( pattern, context ), context, operators, objectType.isPrototype() ? PrototypeFactInstance.class : ((ClassObjectType) objectType).getClassType());
}
public BoundIdentifiers(Map<String, Class< ? >> declarations,
diff --git a/drools-compiler/src/main/java/org/drools/compiler/compiler/FactTemplateError.java b/drools-compiler/src/main/java/org/drools/compiler/compiler/FactTemplateError.java
deleted file mode 100644
index 33996d979a..0000000000
--- a/drools-compiler/src/main/java/org/drools/compiler/compiler/FactTemplateError.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.compiler.compiler;
-
-import org.drools.drl.ast.descr.BaseDescr;
-import org.drools.drl.parser.DroolsError;
-
-public class FactTemplateError extends DroolsError {
- private Package pkg;
- private BaseDescr descr;
- private Object object;
- private int[] line;
- private String namespace;
-
- public FactTemplateError(final Package pkg,
- final BaseDescr descr,
- final Object object,
- final String message) {
- super(descr.getResource(), BuilderResultUtils.getProblemMessage( object, message ));
- this.namespace = pkg.getName();
- this.pkg = pkg;
- this.descr = descr;
- this.object = object;
- this.line = new int[] {this.descr.getLine()};
- }
-
- @Override
- public String getNamespace() {
- return namespace;
- }
-
- public Package getPackage() {
- return this.pkg;
- }
-
- public BaseDescr getDescr() {
- return this.descr;
- }
-
- public Object getObject() {
- return this.object;
- }
-
- public int[] getLines() {
- return this.line;
- }
-
- /**
- * This will return the line number of the error, if possible
- * Otherwise it will be -1
- */
- public int getLine() {
- return this.line[0];
- }
-
-
-}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/compiler/FieldTemplateError.java b/drools-compiler/src/main/java/org/drools/compiler/compiler/FieldTemplateError.java
deleted file mode 100644
index 30d746f126..0000000000
--- a/drools-compiler/src/main/java/org/drools/compiler/compiler/FieldTemplateError.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.compiler.compiler;
-
-import org.drools.drl.ast.descr.BaseDescr;
-import org.drools.drl.parser.DroolsError;
-
-public class FieldTemplateError extends DroolsError {
- private Package pkg;
- private BaseDescr descr;
- private Object object;
- private int[] line;
- private String namespace;
-
- public FieldTemplateError(final Package pkg,
- final BaseDescr descr,
- final Object object,
- final String message) {
- super(descr.getResource(), BuilderResultUtils.getProblemMessage( object, message ));
- this.namespace = pkg.getName();
- this.pkg = pkg;
- this.descr = descr;
- this.object = object;
- this.line = new int[] {this.descr.getLine()};
- }
-
- @Override
- public String getNamespace() {
- return namespace;
- }
-
- public Package getPackage() {
- return this.pkg;
- }
-
- public BaseDescr getDescr() {
- return this.descr;
- }
-
- public Object getObject() {
- return this.object;
- }
-
- public int[] getLines() {
- return this.line;
- }
-
- /**
- * This will return the line number of the error, if possible
- * Otherwise it will be -1
- */
- public int getLine() {
- return this.line[0];
- }
-
-}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieModule.java b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieModule.java
index 16e8186af6..de8b1839cb 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieModule.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/kie/builder/impl/AbstractKieModule.java
@@ -32,6 +32,7 @@ import java.util.Properties;
import java.util.function.Function;
import java.util.function.Predicate;
+import org.drools.base.RuleBase;
import org.drools.base.definitions.InternalKnowledgePackage;
import org.drools.base.definitions.impl.KnowledgePackageImpl;
import org.drools.compiler.builder.InternalKnowledgeBuilder;
@@ -39,8 +40,6 @@ import org.drools.compiler.builder.conf.DecisionTableConfigurationImpl;
import org.drools.compiler.builder.impl.KnowledgeBuilderConfigurationImpl;
import org.drools.compiler.kproject.models.KieBaseModelImpl;
import org.drools.core.RuleBaseConfiguration;
-import org.drools.base.definitions.InternalKnowledgePackage;
-import org.drools.base.definitions.impl.KnowledgePackageImpl;
import org.drools.core.impl.RuleBaseFactory;
import org.drools.io.ResourceConfigurationImpl;
import org.drools.kiesession.rulebase.InternalKnowledgeBase;
@@ -54,6 +53,7 @@ import org.kie.api.builder.model.KieBaseModel;
import org.kie.api.builder.model.KieModuleModel;
import org.kie.api.builder.model.RuleTemplateModel;
import org.kie.api.conf.EventProcessingOption;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.definition.KiePackage;
import org.kie.api.io.Resource;
import org.kie.api.io.ResourceConfiguration;
@@ -70,7 +70,6 @@ import org.kie.util.maven.support.PomModel;
import org.kie.util.maven.support.ReleaseIdImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.drools.base.RuleBase;
import static org.kie.internal.builder.KnowledgeBuilderFactory.newKnowledgeBuilderConfiguration;
@@ -252,11 +251,15 @@ public abstract class AbstractKieModule implements InternalKieModule, Serializab
public KnowledgeBuilderConfiguration createBuilderConfiguration( KieBaseModel kBaseModel, ClassLoader classLoader) {
KnowledgeBuilderConfigurationImpl pconf = newKnowledgeBuilderConfiguration(classLoader).as(KnowledgeBuilderConfigurationImpl.KEY);
pconf.setCompilationCache(getCompilationCache(kBaseModel.getName()));
- setModelPropsOnConf( ((KieBaseModelImpl) kBaseModel).getKModule(), pconf );
+ setModelPropsOnConf( kBaseModel, pconf );
return pconf;
}
- static void setModelPropsOnConf( KieModuleModel kModuleModel, KnowledgeBuilderConfigurationImpl pconf ) {
+ private static void setModelPropsOnConf( KieBaseModel kBaseModel, KnowledgeBuilderConfigurationImpl pconf ) {
+ if (kBaseModel.getPrototypes() != null) {
+ pconf.setProperty(PrototypesOption.PROPERTY_NAME, kBaseModel.getPrototypes().toString());
+ }
+ KieModuleModel kModuleModel = ((KieBaseModelImpl) kBaseModel).getKModule();
for (Map.Entry<String, String> entry : kModuleModel.getConfigurationProperties().entrySet()) {
pconf.setProperty(entry.getKey(), entry.getValue());
}
diff --git a/drools-compiler/src/main/java/org/drools/compiler/kproject/models/KieBaseModelImpl.java b/drools-compiler/src/main/java/org/drools/compiler/kproject/models/KieBaseModelImpl.java
index c4c1361de0..ff42cd4d16 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/kproject/models/KieBaseModelImpl.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/kproject/models/KieBaseModelImpl.java
@@ -39,6 +39,7 @@ import org.kie.api.conf.DeclarativeAgendaOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.conf.KieBaseMutabilityOption;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.conf.SequentialOption;
import org.kie.api.conf.SessionsPoolOption;
import org.kie.api.io.ResourceType;
@@ -57,6 +58,8 @@ public class KieBaseModelImpl
private EqualityBehaviorOption equalsBehavior = EqualityBehaviorOption.IDENTITY;
+ private PrototypesOption prototypes = PrototypesOption.DISABLED;
+
private KieBaseMutabilityOption mutability = KieBaseMutabilityOption.ALLOWED;
private EventProcessingOption eventProcessingMode = EventProcessingOption.CLOUD;
@@ -234,21 +237,24 @@ public class KieBaseModelImpl
return this;
}
- /* (non-Javadoc)
- * @see org.kie.kproject.KieBaseModel#getEqualsBehavior()
- */
public EqualityBehaviorOption getEqualsBehavior() {
return equalsBehavior;
}
- /* (non-Javadoc)
- * @see org.kie.kproject.KieBaseModel#setEqualsBehavior(org.kie.api.conf.EqualityBehaviorOption)
- */
public KieBaseModel setEqualsBehavior(EqualityBehaviorOption equalsBehaviour) {
this.equalsBehavior = equalsBehaviour;
return this;
}
+ public PrototypesOption getPrototypes() {
+ return prototypes;
+ }
+
+ public KieBaseModel setPrototypes(PrototypesOption prototypes) {
+ this.prototypes = prototypes;
+ return this;
+ }
+
public KieBaseMutabilityOption getMutability() {
return mutability;
}
@@ -353,7 +359,7 @@ public class KieBaseModelImpl
@Override
public String toString() {
- return "KieBaseModelImpl [name=" + name + ", includes=" + includes + ", packages=" + getPackages() + ", equalsBehavior=" + equalsBehavior + ", mutability=" + mutability + ", eventProcessingMode=" + eventProcessingMode + ", kSessions=" + kSessions + "]";
+ return "KieBaseModelImpl [name=" + name + ", includes=" + includes + ", packages=" + getPackages() + ", equalsBehavior=" + equalsBehavior + ", prototypes=" + prototypes + ", mutability=" + mutability + ", eventProcessingMode=" + eventProcessingMode + ", kSessions=" + kSessions + "]";
}
@Override
diff --git a/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java b/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
index d50ef6c1bc..fdd709abcd 100644
--- a/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
+++ b/drools-compiler/src/main/java/org/drools/compiler/rule/builder/PatternBuilder.java
@@ -42,9 +42,8 @@ import org.drools.base.definitions.rule.impl.RuleImpl;
import org.drools.base.factmodel.AnnotationDefinition;
import org.drools.base.factmodel.ClassDefinition;
import org.drools.base.factmodel.FieldDefinition;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateFieldExtractor;
-import org.drools.base.facttemplates.FactTemplateObjectType;
+import org.drools.base.prototype.PrototypeFieldExtractor;
+import org.drools.base.prototype.PrototypeObjectType;
import org.drools.base.reteoo.SortDeclarations;
import org.drools.base.rule.Declaration;
import org.drools.base.rule.Pattern;
@@ -105,6 +104,7 @@ import org.drools.util.StringUtils;
import org.drools.util.TypeResolver;
import org.kie.api.definition.rule.Watch;
import org.kie.api.definition.type.Role;
+import org.kie.api.prototype.Prototype;
import org.kie.internal.builder.KnowledgeBuilderResult;
import org.kie.internal.builder.ResultSeverity;
import org.kie.internal.builder.conf.LanguageLevelOption;
@@ -321,9 +321,9 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
}
private ObjectType getObjectType(RuleBuildContext context, PatternDescr patternDescr, String objectType) {
- final FactTemplate factTemplate = context.getPkg().getFactTemplate(objectType);
- if (factTemplate != null) {
- return new FactTemplateObjectType(factTemplate);
+ Prototype prototype = context.getPkg().getPrototype(objectType);
+ if (prototype != null) {
+ return new PrototypeObjectType(prototype);
} else {
try {
final Class<?> userProvidedClass = context.getDialect().getTypeResolver().resolveType(objectType);
@@ -558,8 +558,8 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
protected Collection<String> getSettableProperties(RuleBuildContext context, PatternDescr patternDescr, Pattern pattern) {
ObjectType patternType = pattern.getObjectType();
- if (patternType.isTemplate()) {
- return ((FactTemplateObjectType) patternType).getFieldNames();
+ if (patternType.isPrototype()) {
+ return ((PrototypeObjectType) patternType).getFieldNames();
}
Class<?> patternClass = ((ClassObjectType) patternType).getClassType();
@@ -843,7 +843,7 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
XpathConstraint xpathConstraint = new XpathConstraint();
ObjectType objectType = pattern.getObjectType();
- if (objectType.isTemplate()) {
+ if (objectType.isPrototype()) {
throw new UnsupportedOperationException("xpath is not supported with fact templates");
}
@@ -1086,8 +1086,8 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
}
ObjectType objectType = pattern.getObjectType();
- if (objectType.isTemplate()) {
- return ((FactTemplateObjectType) objectType).getFactTemplate().getFieldTemplate(leftValue).getValueType();
+ if (objectType.isPrototype()) {
+ return ValueType.determineValueType( ( (PrototypeObjectType) objectType).getPrototype().getField(leftValue).getType() );
}
Class<?> clazz = ((ClassObjectType) objectType).getClassType();
@@ -1121,7 +1121,7 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
ConstraintBuilder.get().setExprInputs( context, valueExpr,
(pattern.getObjectType() instanceof ClassObjectType) ?
((ClassObjectType) pattern.getObjectType()).getClassType() :
- FactTemplate.class,
+ Prototype.class,
value);
if (!isIdentifierLiteral(value)) {
String identifier = StringUtils.extractFirstIdentifier(value, 0);
@@ -1533,7 +1533,7 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
mvelDeclarations[i++] = context.getDeclarationResolver().getDeclaration(global);
}
- boolean isDynamic = pattern.getObjectType().isTemplate() ||
+ boolean isDynamic = pattern.getObjectType().isPrototype() ||
( !((ClassObjectType) pattern.getObjectType()).getClassType().isArray() &&
!context.getKnowledgeBuilder().getTypeDeclaration(pattern.getObjectType()).isTypesafe() );
@@ -1721,7 +1721,7 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
final ObjectType objectType,
final String fieldName,
final AcceptsReadAccessor target) {
- if (!ValueType.FACTTEMPLATE_TYPE.equals(objectType.getValueType())) {
+ if (!ValueType.PROTOTYPE_TYPE.equals(objectType.getValueType())) {
context.getPkg().getReader(objectType.getClassName(), fieldName, target);
}
}
@@ -1745,10 +1745,9 @@ public class PatternBuilder implements RuleConditionBuilder<PatternDescr> {
// reportError is needed as some times failure to build accessor is not a failure, just an indication that building is not possible so try something else.
ReadAccessor reader;
- if (ValueType.FACTTEMPLATE_TYPE.equals(objectType.getValueType())) {
+ if (ValueType.PROTOTYPE_TYPE.equals(objectType.getValueType())) {
//@todo use accessor cache
- final FactTemplate factTemplate = ((FactTemplateObjectType) objectType).getFactTemplate();
- reader = new FactTemplateFieldExtractor(factTemplate, fieldName);
+ reader = new PrototypeFieldExtractor(((PrototypeObjectType) objectType).getPrototype(), fieldName);
if (target != null) {
target.setReadAccessor(reader);
}
diff --git a/drools-core/src/main/java/org/drools/core/RuleBaseConfiguration.java b/drools-core/src/main/java/org/drools/core/RuleBaseConfiguration.java
index 214e8ea8ce..d9be2283d0 100755
--- a/drools-core/src/main/java/org/drools/core/RuleBaseConfiguration.java
+++ b/drools-core/src/main/java/org/drools/core/RuleBaseConfiguration.java
@@ -37,6 +37,7 @@ import org.kie.api.conf.EventProcessingOption;
import org.kie.api.conf.KieBaseOption;
import org.kie.api.conf.MultiValueKieBaseOption;
import org.kie.api.conf.OptionKey;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.conf.RemoveIdentitiesOption;
import org.kie.api.conf.SequentialOption;
import org.kie.api.conf.SessionsPoolOption;
@@ -141,6 +142,8 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
private EventProcessingOption eventProcessingMode;
+ private PrototypesOption prototypesOption;
+
private IndexPrecedenceOption indexPrecedenceOption;
// if parallelism is enabled, rulebase builder will try to split
@@ -202,17 +205,15 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
setSequential(Boolean.parseBoolean(getPropertyValue(SequentialOption.PROPERTY_NAME, "false")));
- setParallelExecution(ParallelExecutionOption.determineParallelExecution(getPropertyValue(ParallelExecutionOption.PROPERTY_NAME,
- "sequential")));
+ setParallelExecution(ParallelExecutionOption.determineParallelExecution(getPropertyValue(ParallelExecutionOption.PROPERTY_NAME, "sequential")));
+
+ setMaxThreads( Integer.parseInt( getPropertyValue( MaxThreadsOption.PROPERTY_NAME, "3" ) ) );
- setMaxThreads( Integer.parseInt( getPropertyValue( MaxThreadsOption.PROPERTY_NAME,
- "3" ) ) );
+ setEventProcessingMode( EventProcessingOption.determineEventProcessingMode( getPropertyValue( EventProcessingOption.PROPERTY_NAME, "cloud" ) ) );
- setEventProcessingMode( EventProcessingOption.determineEventProcessingMode( getPropertyValue( EventProcessingOption.PROPERTY_NAME,
- "cloud" ) ) );
+ setPrototypesOption( PrototypesOption.determinePrototypesOption( getPropertyValue( PrototypesOption.PROPERTY_NAME, "disabled" ) ) );
- setDeclarativeAgendaEnabled( Boolean.parseBoolean(getPropertyValue(DeclarativeAgendaOption.PROPERTY_NAME,
- "false")) );
+ setDeclarativeAgendaEnabled( Boolean.parseBoolean(getPropertyValue(DeclarativeAgendaOption.PROPERTY_NAME, "false")) );
}
public void writeExternal(ObjectOutput out) throws IOException {
@@ -333,6 +334,9 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
case EventProcessingOption.PROPERTY_NAME: {
return (T) getEventProcessingMode();
}
+ case PrototypesOption.PROPERTY_NAME: {
+ return (T) getPrototypesOption();
+ }
case MaxThreadsOption.PROPERTY_NAME: {
return (T) MaxThreadsOption.get(getMaxThreads());
}
@@ -417,6 +421,10 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
setEventProcessingMode( (EventProcessingOption) option);
break;
}
+ case PrototypesOption.PROPERTY_NAME: {
+ setPrototypesOption( (PrototypesOption) option);
+ break;
+ }
case MaxThreadsOption.PROPERTY_NAME: {
setMaxThreads( ( (MaxThreadsOption) option ).getMaxThreads());
break;
@@ -516,6 +524,10 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
setEventProcessingMode(EventProcessingOption.determineEventProcessingMode(StringUtils.isEmpty(value) ? "cloud" : value));
break;
}
+ case PrototypesOption.PROPERTY_NAME: {
+ setPrototypesOption(PrototypesOption.determinePrototypesOption(StringUtils.isEmpty(value) ? "disabled" : value));
+ break;
+ }
default : {
return false;
}
@@ -586,6 +598,9 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
case EventProcessingOption.PROPERTY_NAME: {
return getEventProcessingMode().getMode();
}
+ case PrototypesOption.PROPERTY_NAME: {
+ return getPrototypesOption().toString().toLowerCase();
+ }
}
return null;
@@ -698,6 +713,15 @@ public class RuleBaseConfiguration extends BaseConfiguration<KieBaseOption, Sin
this.eventProcessingMode = mode;
}
+ public PrototypesOption getPrototypesOption() {
+ return this.prototypesOption;
+ }
+
+ public void setPrototypesOption(final PrototypesOption prototypesOption) {
+ checkCanChange(); // throws an exception if a change isn't possible;
+ this.prototypesOption = prototypesOption;
+ }
+
public int getCompositeKeyDepth() {
return this.compositeKeyDepth;
}
diff --git a/drools-core/src/main/java/org/drools/core/common/ObjectTypeConfigurationRegistry.java b/drools-core/src/main/java/org/drools/core/common/ObjectTypeConfigurationRegistry.java
index 8821488803..aab549640e 100644
--- a/drools-core/src/main/java/org/drools/core/common/ObjectTypeConfigurationRegistry.java
+++ b/drools-core/src/main/java/org/drools/core/common/ObjectTypeConfigurationRegistry.java
@@ -25,15 +25,14 @@ import java.util.concurrent.ConcurrentHashMap;
import org.drools.base.base.ClassObjectType;
import org.drools.base.base.ObjectType;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactImpl;
import org.drools.base.rule.EntryPointId;
import org.drools.core.impl.InternalRuleBase;
import org.drools.core.reteoo.ClassObjectTypeConf;
-import org.drools.core.reteoo.FactTemplateTypeConf;
import org.drools.core.reteoo.ObjectTypeConf;
+import org.drools.core.reteoo.PrototypeTypeConf;
import org.drools.core.reteoo.RuleTerminalNodeLeftTuple;
import org.drools.core.rule.consequence.InternalMatch;
+import org.kie.api.prototype.PrototypeFactInstance;
public class ObjectTypeConfigurationRegistry implements Serializable {
private static final long serialVersionUID = 510l;
@@ -73,10 +72,8 @@ public class ObjectTypeConfigurationRegistry implements Serializable {
private Object getKey( Object object ) {
if (object instanceof RuleTerminalNodeLeftTuple) {
return ClassObjectType.Match_ObjectType.getClassType();
- } else if (object instanceof FactImpl) {
- return ((FactImpl) object).getFactTemplate().getName();
- } else if (object instanceof Fact) {
- return ((Fact) object).getFactTemplate().getName();
+ } else if (object instanceof PrototypeFactInstance p) {
+ return p.getPrototype().getFullName();
} else if (object instanceof InternalMatch) {
return ClassObjectType.Match_ObjectType.getClassType();
}
@@ -84,8 +81,8 @@ public class ObjectTypeConfigurationRegistry implements Serializable {
}
private ObjectTypeConf createObjectTypeConf(EntryPointId entrypoint, Object key, Object object) {
- return object instanceof Fact ?
- new FactTemplateTypeConf( entrypoint, ((Fact) object).getFactTemplate(), this.ruleBase ) :
+ return object instanceof PrototypeFactInstance p ?
+ new PrototypeTypeConf(entrypoint, p.getPrototype(), this.ruleBase ) :
new ClassObjectTypeConf( entrypoint, (Class<?>) key, this.ruleBase );
}
diff --git a/drools-core/src/main/java/org/drools/core/phreak/PropagationEntry.java b/drools-core/src/main/java/org/drools/core/phreak/PropagationEntry.java
index d2163e62fd..a3c02ff349 100644
--- a/drools-core/src/main/java/org/drools/core/phreak/PropagationEntry.java
+++ b/drools-core/src/main/java/org/drools/core/phreak/PropagationEntry.java
@@ -24,7 +24,6 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.concurrent.CountDownLatch;
-import org.drools.base.facttemplates.Event;
import org.drools.base.reteoo.NodeTypeEnums;
import org.drools.core.base.DroolsQueryImpl;
import org.drools.core.common.DefaultEventHandle;
@@ -46,6 +45,7 @@ import org.drools.core.reteoo.TerminalNode;
import org.drools.core.time.JobContext;
import org.drools.core.time.impl.DefaultJobHandle;
import org.drools.core.time.impl.PointInTimeTrigger;
+import org.kie.api.prototype.PrototypeEventInstance;
import static org.drools.base.rule.TypeDeclaration.NEVER_EXPIRES;
import static org.drools.core.reteoo.EntryPointNode.removeRightTuplesMatchingOTN;
@@ -252,11 +252,11 @@ public interface PropagationEntry {
private static void scheduleExpiration(ReteEvaluator reteEvaluator, InternalFactHandle handle, PropagationContext context, ObjectTypeConf objectTypeConf, long insertionTime) {
for ( ObjectTypeNode otn : objectTypeConf.getObjectTypeNodes() ) {
- long expirationOffset = objectTypeConf.isPrototype() ? ((Event) handle.getObject()).getExpiration() : otn.getExpirationOffset();
+ long expirationOffset = objectTypeConf.isPrototype() ? ((PrototypeEventInstance) handle.getObject()).getExpiration() : otn.getExpirationOffset();
scheduleExpiration( reteEvaluator, handle, context, otn, insertionTime, expirationOffset );
}
if ( objectTypeConf.getConcreteObjectTypeNode() == null ) {
- long expirationOffset = objectTypeConf.isPrototype() ? ((Event) handle.getObject()).getExpiration() : ((ClassObjectTypeConf) objectTypeConf).getExpirationOffset();
+ long expirationOffset = objectTypeConf.isPrototype() ? ((PrototypeEventInstance) handle.getObject()).getExpiration() : ((ClassObjectTypeConf) objectTypeConf).getExpirationOffset();
scheduleExpiration( reteEvaluator, handle, context, null, insertionTime, expirationOffset);
}
}
diff --git a/drools-core/src/main/java/org/drools/core/reteoo/FactTemplateTypeConf.java b/drools-core/src/main/java/org/drools/core/reteoo/PrototypeTypeConf.java
similarity index 80%
rename from drools-core/src/main/java/org/drools/core/reteoo/FactTemplateTypeConf.java
rename to drools-core/src/main/java/org/drools/core/reteoo/PrototypeTypeConf.java
index 7ac53a3b21..d8d3f96584 100644
--- a/drools-core/src/main/java/org/drools/core/reteoo/FactTemplateTypeConf.java
+++ b/drools-core/src/main/java/org/drools/core/reteoo/PrototypeTypeConf.java
@@ -24,10 +24,7 @@ import java.io.ObjectInput;
import java.io.ObjectOutput;
import org.drools.base.base.ObjectType;
-import org.drools.base.facttemplates.Event;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateObjectType;
+import org.drools.base.prototype.PrototypeObjectType;
import org.drools.base.rule.EntryPointId;
import org.drools.base.rule.TypeDeclaration;
import org.drools.core.WorkingMemoryEntryPoint;
@@ -35,8 +32,11 @@ import org.drools.core.common.InternalFactHandle;
import org.drools.core.common.ReteEvaluator;
import org.drools.core.impl.InternalRuleBase;
import org.drools.core.rule.accessor.FactHandleFactory;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeEventInstance;
+import org.kie.api.prototype.PrototypeFactInstance;
-public class FactTemplateTypeConf
+public class PrototypeTypeConf
implements
ObjectTypeConf,
Externalizable {
@@ -45,33 +45,33 @@ public class FactTemplateTypeConf
private transient InternalRuleBase ruleBase;
- private ObjectType objectType;
- private FactTemplate factTemplate;
- private ObjectTypeNode concreteObjectTypeNode;
- private ObjectTypeNode[] cache;
+ private ObjectType objectType;
+ private Prototype prototype;
+ private ObjectTypeNode concreteObjectTypeNode;
+ private ObjectTypeNode[] cache;
- private boolean tmsEnabled;
+ private boolean tmsEnabled;
EntryPointId entryPoint;
- public FactTemplateTypeConf() {
+ public PrototypeTypeConf() {
}
- public FactTemplateTypeConf(final EntryPointId entryPoint,
- final FactTemplate factTemplate,
- final InternalRuleBase ruleBase) {
+ public PrototypeTypeConf(final EntryPointId entryPoint,
+ final Prototype prototype,
+ final InternalRuleBase ruleBase) {
this.ruleBase = ruleBase;
- this.factTemplate = factTemplate;
+ this.prototype = prototype;
this.entryPoint = entryPoint;
- this.objectType = new FactTemplateObjectType( factTemplate );
+ this.objectType = new PrototypeObjectType(prototype);
this.concreteObjectTypeNode = ruleBase.getRete().getObjectTypeNodes( entryPoint ).get( objectType );
}
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
ruleBase = (InternalRuleBase) in.readObject();
- factTemplate = (FactTemplate) in.readObject();
+ prototype = (Prototype) in.readObject();
concreteObjectTypeNode = (ObjectTypeNode) in.readObject();
cache = (ObjectTypeNode[]) in.readObject();
objectType = (ObjectType) in.readObject();
@@ -79,7 +79,7 @@ public class FactTemplateTypeConf
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject( ruleBase );
- out.writeObject( factTemplate );
+ out.writeObject( prototype );
out.writeObject( concreteObjectTypeNode );
out.writeObject( cache );
out.writeObject( objectType );
@@ -100,7 +100,7 @@ public class FactTemplateTypeConf
}
public boolean isAssignableFrom(Object object) {
- return this.factTemplate.equals( object );
+ return this.prototype.equals( object );
}
public void resetCache() {
@@ -145,15 +145,15 @@ public class FactTemplateTypeConf
@Override
public String getTypeName() {
- return factTemplate.getName();
+ return prototype.getFullName();
}
@Override
public InternalFactHandle createFactHandle(FactHandleFactory factHandleFactory, long id, Object object, long recency,
ReteEvaluator reteEvaluator, WorkingMemoryEntryPoint entryPoint) {
- Fact fact = (Fact) object;
+ PrototypeFactInstance fact = (PrototypeFactInstance) object;
if (fact.isEvent()) {
- Event event = (Event) fact;
+ PrototypeEventInstance event = (PrototypeEventInstance) fact;
long timestamp = event.getTimestamp() >= 0 ? event.getTimestamp() : reteEvaluator.getTimerService().getCurrentTime();
return factHandleFactory.createEventFactHandle(id, object, recency, entryPoint, timestamp, 0);
}
diff --git a/drools-core/src/test/java/org/drools/core/facttemplates/FactTemplateFieldExtractorTest.java b/drools-core/src/test/java/org/drools/core/facttemplates/FactTemplateFieldExtractorTest.java
deleted file mode 100644
index ec769f2427..0000000000
--- a/drools-core/src/test/java/org/drools/core/facttemplates/FactTemplateFieldExtractorTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.core.facttemplates;
-
-import org.drools.base.definitions.InternalKnowledgePackage;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateFieldExtractor;
-import org.drools.base.facttemplates.FactTemplateImpl;
-import org.drools.base.facttemplates.FactTemplateObjectType;
-import org.drools.base.facttemplates.FieldTemplate;
-import org.drools.base.facttemplates.FieldTemplateImpl;
-import org.drools.base.rule.Declaration;
-import org.drools.base.rule.Pattern;
-import org.drools.base.rule.accessor.ReadAccessor;
-import org.drools.core.reteoo.CoreComponentFactory;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class FactTemplateFieldExtractorTest {
- @Test
- public void testExtractor() {
- InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage( "org.store" );
-
- final FieldTemplate cheeseName = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields = new FieldTemplate[]{cheeseName, cheesePrice};
- final FactTemplate cheese = new FactTemplateImpl( pkg, "Cheese", fields );
-
- final ReadAccessor extractName = new FactTemplateFieldExtractor( cheese, "name" );
- final ReadAccessor extractPrice = new FactTemplateFieldExtractor( cheese, "price" );
-
- final Fact stilton = cheese.createFact();
- stilton.set( "name", "stilton" );
- stilton.set( "price", 200 );
-
- assertThat(extractName.getValue(null, stilton)).isEqualTo("stilton");
-
- assertThat(extractPrice.getValue(null, stilton)).isEqualTo(200);
-
- assertThat(extractName.isNullValue(null, stilton)).isFalse();
-
- stilton.set( "name", null );
-
- assertThat(extractName.isNullValue(null, stilton)).isTrue();
- assertThat(extractPrice.isNullValue(null, stilton)).isFalse();
-
- final Fact brie = cheese.createFact();
- brie.set( "name", "brie" );
- brie.set( "price", 55 );
-
- assertThat(extractName.getValue(null, brie)).isEqualTo("brie");
-
- assertThat(extractPrice.getValue(null, brie)).isEqualTo(55);
-
- assertThat(extractName.isNullValue(null, brie)).isFalse();
-
- brie.set( "name", null );
-
- assertThat(extractName.isNullValue(null, brie)).isTrue();
- assertThat(extractPrice.isNullValue(null, stilton)).isFalse();
- }
-
- @Test
- public void testDeclaration() {
- InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage( "org.store" );
-
- final FieldTemplate cheeseName = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields = new FieldTemplate[]{cheeseName, cheesePrice};
- final FactTemplate cheese = new FactTemplateImpl( pkg,
- "Cheese",
- fields );
-
- final ReadAccessor extractName = new FactTemplateFieldExtractor( cheese, "name" );
-
- final Pattern pattern = new Pattern( 0,
- new FactTemplateObjectType( cheese ) );
-
- final Declaration declaration = new Declaration( "typeOfCheese",
- extractName,
- pattern );
-
- final Fact brie = cheese.createFact();
- brie.set( "name", "brie" );
- brie.set( "price", 55 );
-
- // Check we can extract Declarations correctly
- assertThat(declaration.getValue(null, brie)).isEqualTo("brie");
- }
-}
diff --git a/drools-core/src/test/java/org/drools/core/facttemplates/FactTemplateTest.java b/drools-core/src/test/java/org/drools/core/facttemplates/FactTemplateTest.java
deleted file mode 100644
index a2335299f7..0000000000
--- a/drools-core/src/test/java/org/drools/core/facttemplates/FactTemplateTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.core.facttemplates;
-
-import org.drools.base.definitions.InternalKnowledgePackage;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateImpl;
-import org.drools.base.facttemplates.FieldTemplate;
-import org.drools.base.facttemplates.FieldTemplateImpl;
-import org.drools.core.reteoo.CoreComponentFactory;
-import org.junit.Test;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class FactTemplateTest {
- @Test
- public void testFieldsAndGetters() {
- InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage( "org.store" );
- final FieldTemplate cheeseName = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields = new FieldTemplate[]{cheeseName, cheesePrice};
- final FactTemplate cheese = new FactTemplateImpl( pkg,
- "Cheese",
- fields );
-
- assertThat(cheese.getPackage().getName()).isEqualTo("org.store");
- assertThat(cheese.getName()).isEqualTo("Cheese");
-
- assertThat(cheese.getNumberOfFields()).isEqualTo(2);
-
- assertThat(cheese.getFieldTemplate("name")).isSameAs(cheeseName);
- assertThat(cheese.getFieldTemplate("price")).isSameAs(cheesePrice);
-
- assertThat(cheese.getFieldTemplateIndex("name")).isEqualTo(0);
- assertThat(cheese.getFieldTemplateIndex("price")).isEqualTo(1);
- }
-
- @Test
- public void testEqualsAndHashCode() {
- InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage( "org.store" );
-
- // Create cheese1 with name and price fields
- final FieldTemplate cheeseName = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields1 = new FieldTemplate[]{cheeseName, cheesePrice};
- final FactTemplate cheese1 = new FactTemplateImpl( pkg,
- "Cheese",
- fields1 );
-
- // Create cheese2 with type and price fields
- final FieldTemplate cheeseType = new FieldTemplateImpl( "type", String.class );
- final FieldTemplate[] fields2 = new FieldTemplate[]{cheeseType, cheesePrice};
- final FactTemplate cheese2 = new FactTemplateImpl( pkg,
- "Cheese",
- fields2 );
-
- assertThat(cheese1).isNotSameAs(cheese2);
- assertThat(cheese1).isNotEqualTo(cheese2);
- assertThat(cheese1).doesNotHaveSameHashCodeAs(cheese2);
-
- // create cheese3 with name and price fields, using new instances
- final FieldTemplate cheeseName2 = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice2 = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields3 = new FieldTemplate[]{cheeseName2, cheesePrice2};
- final FactTemplate cheese3 = new FactTemplateImpl( pkg,
- "Cheese",
- fields3 );
-
- assertThat(cheese1).isNotSameAs(cheese3);
- assertThat(cheese3).isEqualTo(cheese1);
- assertThat(cheese3).hasSameHashCodeAs(cheese1);
- }
-
- @Test
- public void testFacts() {
- InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage( "org.store" );
- final FieldTemplate cheeseName = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields1 = new FieldTemplate[]{cheeseName, cheesePrice};
- final FactTemplate cheese1 = new FactTemplateImpl( pkg,
- "Cheese",
- fields1 );
-
- final Fact stilton1 = cheese1.createFact();
- stilton1.set( "name", "stilton" );
- stilton1.set( "price", 200 );
-
- final Fact stilton2 = cheese1.createFact();
- stilton2.set( "name", "stilton" );
- stilton2.set( "price", 200 );
-
- assertThat(stilton2).isEqualTo(stilton1);
- assertThat(stilton2.hashCode()).isEqualTo(stilton1.hashCode());
-
- final Fact brie = cheese1.createFact();
- brie.set( "name", "brie" );
- brie.set( "price", 55 );
-
- assertThat(stilton1).isNotEqualTo(brie);
- assertThat(stilton1).doesNotHaveSameHashCodeAs(brie);
-
- }
-}
diff --git a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test1.yml b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test1.yml
index 6fbdcaf860..0e652f88ff 100644
--- a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test1.yml
+++ b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test1.yml
@@ -1,5 +1,6 @@
---
name: mypkg
+dialect: java
imports:
- java.lang.Number
- java.lang.Long
diff --git a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test2.drl.txt b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test2.drl.txt
index 24d576d4ba..0694efdf5f 100644
--- a/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test2.drl.txt
+++ b/drools-drlonyaml-parent/drools-drlonyaml-cli-tests/src/test/resources/expected/test2.drl.txt
@@ -1,5 +1,6 @@
// This file was automatically generated from a YAML representation.
package mypkg;
+dialect "java";
import java.lang.Number;
import java.lang.Long;
rule "R1"
diff --git a/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java b/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java
index b9259d09f1..9496a73943 100644
--- a/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java
+++ b/drools-drlonyaml-parent/drools-drlonyaml-integration-tests/src/test/java/org/drools/drlonyaml/integration/tests/ProgrammaticProjectTest.java
@@ -83,33 +83,35 @@ public class ProgrammaticProjectTest {
}
private String getDrlRule() {
- return "package org.drools.drlonyaml.integration.tests\n" +
- "\n" +
- "global java.util.List result;\n" +
- "\n" +
- "rule R when\n" +
- " $i : Integer()\n" +
- " $m : Message( size == $i )\n" +
- "then\n" +
- " result.add( $m.getText() );\n" +
- "end";
+ return """
+ package org.drools.drlonyaml.integration.tests
+
+ global java.util.List result;
+
+ rule R when
+ $i : Integer()
+ $m : Message( size == $i )
+ then
+ result.add( $m.getText() );
+ end""";
}
private String getYamlRule() {
- return "name: org.drools.drlonyaml.integration.tests\n" +
- "globals:\n" +
- "- type: java.util.List\n" +
- " id: result\n" +
- "rules:\n" +
- "- name: R\n" +
- " when:\n" +
- " - given: Integer\n" +
- " as: $i\n" +
- " - given: Message\n" +
- " as: $m\n" +
- " having:\n" +
- " - size == $i\n" +
- " then: |\n" +
- " result.add( $m.getText() );";
+ return """
+ name: org.drools.drlonyaml.integration.tests
+ globals:
+ - type: java.util.List
+ id: result
+ rules:
+ - name: R
+ when:
+ - given: Integer
+ as: $i
+ - given: Message
+ as: $m
+ having:
+ - size == $i
+ then: |
+ result.add( $m.getText() );""";
}
}
diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/java/org/drools/drlonyaml/model/DrlPackage.java b/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/java/org/drools/drlonyaml/model/DrlPackage.java
index dd578aa22f..097dc884f2 100644
--- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/java/org/drools/drlonyaml/model/DrlPackage.java
+++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/java/org/drools/drlonyaml/model/DrlPackage.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
+import org.drools.drl.ast.descr.AttributeDescr;
import org.drools.drl.ast.descr.FunctionDescr;
import org.drools.drl.ast.descr.GlobalDescr;
import org.drools.drl.ast.descr.ImportDescr;
@@ -32,11 +33,13 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
-@JsonPropertyOrder({"name", "imports", "globals", "rules", "functions"})
+@JsonPropertyOrder({"name", "dialect", "imports", "globals", "rules", "functions"})
public class DrlPackage {
@JsonInclude(Include.NON_EMPTY)
private String name = ""; // default empty, consistent with DRL parser.
@JsonInclude(Include.NON_EMPTY)
+ private String dialect = "java";
+ @JsonInclude(Include.NON_EMPTY)
private List<Import> imports = new ArrayList<>();
@JsonInclude(Include.NON_EMPTY)
private List<Global> globals = new ArrayList<>();
@@ -48,6 +51,10 @@ public class DrlPackage {
Objects.requireNonNull(o);
DrlPackage result = new DrlPackage();
result.name = o.getName();
+ AttributeDescr dialectAttr = o.getAttribute("dialect");
+ if (dialectAttr != null) {
+ result.dialect = dialectAttr.getValue();
+ }
for (ImportDescr i : o.getImports()) {
result.imports.add(Import.from(i));
}
@@ -67,6 +74,10 @@ public class DrlPackage {
return name;
}
+ public String getDialect() {
+ return dialect;
+ }
+
public List<Import> getImports() {
return imports;
}
diff --git a/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/resources/drlonyaml-schema.json b/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/resources/drlonyaml-schema.json
index 82d153571e..0e44db5a4d 100644
--- a/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/resources/drlonyaml-schema.json
+++ b/drools-drlonyaml-parent/drools-drlonyaml-model/src/main/resources/drlonyaml-schema.json
@@ -163,6 +163,9 @@
"name" : {
"type" : "string"
},
+ "dialect" : {
+ "type" : "string"
+ },
"imports" : {
"type" : "array",
"items" : {
diff --git a/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/main/resources/drl.ftl b/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/main/resources/drl.ftl
index bf32316784..44b68a9592 100644
--- a/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/main/resources/drl.ftl
+++ b/drools-drlonyaml-parent/drools-drlonyaml-todrl/src/main/resources/drl.ftl
@@ -1,5 +1,6 @@
// This file was automatically generated from a YAML representation.
<#if name?has_content>package ${name};</#if>
+<#if dialect?has_content>dialect "${dialect}";</#if>
<#--
## DRL imports
diff --git a/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/PackageParser.java b/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/PackageParser.java
index c0615b2732..c60e69393c 100644
--- a/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/PackageParser.java
+++ b/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/PackageParser.java
@@ -32,6 +32,8 @@ import org.drools.model.codegen.execmodel.generator.RuleContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static org.drools.model.codegen.execmodel.generator.RuleContext.DIALECT_ATTRIBUTE;
+
public class PackageParser {
Logger logger = LoggerFactory.getLogger(PackageParser.class);
@@ -59,7 +61,7 @@ public class PackageParser {
private Rule parseRule( RuleDescr ruleDescr ) {
RuleContext context = new ImpactAnalysisRuleContext(kbuilder, packageModel, pkgRegistry.getTypeResolver(), ruleDescr);
context.addGlobalDeclarations();
- context.setDialectFromAttributes( packageDescr.getAttributes() );
+ context.setDialectFromAttribute( packageDescr.getAttribute( DIALECT_ATTRIBUTE ) );
Rule rule = new Rule( packageDescr.getName(), ruleDescr.getName(), ruleDescr.getResource().getSourcePath() );
logger.debug("Parsing : " + rule.getName());
diff --git a/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/RhsParser.java b/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/RhsParser.java
index 5847149018..d11ef174a0 100644
--- a/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/RhsParser.java
+++ b/drools-impact-analysis/drools-impact-analysis-parser/src/main/java/org/drools/impact/analysis/parser/impl/RhsParser.java
@@ -43,7 +43,7 @@ import org.drools.impact.analysis.model.right.ModifiedMapProperty;
import org.drools.impact.analysis.model.right.ModifiedProperty;
import org.drools.impact.analysis.model.right.ModifyAction;
import org.drools.model.codegen.execmodel.generator.Consequence;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.RuleContext;
import static org.drools.util.StringUtils.ucFirst;
@@ -97,7 +97,7 @@ public class RhsParser {
Expression actionArg = statement.getArgument(0);
Class<?> actionClass = null;
if (actionArg.isNameExpr()) {
- actionClass = context.getDeclarationById(actionArg.toString()).map(DeclarationSpec::getDeclarationClass)
+ actionClass = context.getTypedDeclarationById(actionArg.toString()).map(TypedDeclarationSpec::getDeclarationClass)
.orElseGet(() -> getClassFromAssignment(consequenceExpr, actionArg));
} else if (actionArg.isLiteralExpr()) {
actionClass = literalType(actionArg.asLiteralExpr());
@@ -175,7 +175,7 @@ public class RhsParser {
private ModifyAction processModify( RuleContext context, MethodCallExpr consequenceExpr, MethodCallExpr statement, BlockStmt ruleVariablesBlock ) {
String modifiedId = statement.getArgument( 0 ).toString();
- Class<?> modifiedClass = context.getDeclarationById( modifiedId ).orElseThrow( () -> new RuntimeException("Unknown declaration: " + modifiedId) ).getDeclarationClass();
+ Class<?> modifiedClass = context.getTypedDeclarationById(modifiedId ).orElseThrow(() -> new RuntimeException("Unknown declaration: " + modifiedId) ).getDeclarationClass();
ModifyAction action = new ModifyAction(modifiedClass);
diff --git a/drools-kiesession/src/main/java/org/drools/kiesession/entrypoints/NamedEntryPoint.java b/drools-kiesession/src/main/java/org/drools/kiesession/entrypoints/NamedEntryPoint.java
index 0cf93817c8..e83bdc4b28 100644
--- a/drools-kiesession/src/main/java/org/drools/kiesession/entrypoints/NamedEntryPoint.java
+++ b/drools-kiesession/src/main/java/org/drools/kiesession/entrypoints/NamedEntryPoint.java
@@ -18,9 +18,19 @@
*/
package org.drools.kiesession.entrypoints;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.locks.ReentrantLock;
import org.drools.base.definitions.rule.impl.RuleImpl;
-import org.drools.base.facttemplates.Fact;
import org.drools.base.rule.EntryPointId;
import org.drools.base.rule.TypeDeclaration;
import org.drools.core.RuleBaseConfiguration;
@@ -52,22 +62,11 @@ import org.drools.core.rule.consequence.InternalMatch;
import org.drools.util.bitmask.AllSetBitMask;
import org.drools.util.bitmask.BitMask;
import org.kie.api.conf.KieBaseMutabilityOption;
+import org.kie.api.prototype.PrototypeFactInstance;
import org.kie.api.runtime.rule.FactHandle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.locks.ReentrantLock;
-
import static java.util.Arrays.asList;
import static org.drools.base.reteoo.PropertySpecificUtil.allSetBitMask;
import static org.drools.base.reteoo.PropertySpecificUtil.calculatePositiveMask;
@@ -303,9 +302,9 @@ public class NamedEntryPoint implements InternalWorkingMemoryEntryPoint, Propert
List<String> accessibleProperties;
boolean isPropertyReactive;
- if (object instanceof Fact) {
- accessibleProperties = new ArrayList<>(((Fact) object).getFactTemplate().getFieldNames());
- modifiedTypeName = ((Fact) object).getFactTemplate().getName();
+ if (object instanceof PrototypeFactInstance p) {
+ accessibleProperties = new ArrayList<>(p.getPrototype().getFieldNames());
+ modifiedTypeName = p.getPrototype().getFullName();
isPropertyReactive = !accessibleProperties.isEmpty();
} else {
Class<?> modifiedClass = object.getClass();
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeFactFactory.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeFactFactory.java
deleted file mode 100644
index 0843ccb4b1..0000000000
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeFactFactory.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.model;
-
-import java.util.Map;
-import java.util.ServiceLoader;
-
-public interface PrototypeFactFactory {
-
- PrototypeFact createMapBasedFact(Prototype prototype);
-
- PrototypeFact createMapBasedFact(Prototype prototype, Map<String, Object> valuesMap);
-
- static PrototypeFactFactory get() {
- return Factory.get();
- }
-
- /**
- * A Factory for this KieServices
- */
- class Factory {
-
- private static class LazyHolder {
- private static PrototypeFactFactory INSTANCE = ServiceLoader.load(PrototypeFactFactory.class)
- .findFirst().orElseThrow(() -> new RuntimeException("Unable to fine PrototypeFactFactory service, is drools-model-compiler on the classpath?"));
- }
-
- /**
- * Returns a reference to the KieServices singleton
- */
- public static PrototypeFactFactory get() {
- return LazyHolder.INSTANCE;
- }
- }
-}
\ No newline at end of file
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/Variable.java b/drools-model/drools-canonical-model/src/main/java/org/drools/model/Variable.java
index efb0b28af5..1afc5efff1 100644
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/Variable.java
+++ b/drools-model/drools-canonical-model/src/main/java/org/drools/model/Variable.java
@@ -25,4 +25,8 @@ public interface Variable<T> extends Argument<T> {
default boolean isFact() {
return true;
}
+
+ default boolean isPrototype() {
+ return false;
+ }
}
diff --git a/drools-model/drools-model-codegen/pom.xml b/drools-model/drools-model-codegen/pom.xml
index ae5732e79b..b8df4eda91 100644
--- a/drools-model/drools-model-codegen/pom.xml
+++ b/drools-model/drools-model-codegen/pom.xml
@@ -77,6 +77,10 @@
<groupId>org.drools</groupId>
<artifactId>drools-model-compiler</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-model-prototype</artifactId>
+ </dependency>
<dependency>
<groupId>com.github.javaparser</groupId>
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
index 530da853b3..530b3e9b9c 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/PackageModel.java
@@ -18,6 +18,21 @@
*/
package org.drools.model.codegen.execmodel;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
+
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration;
@@ -50,6 +65,7 @@ import org.drools.codegen.common.DroolsModelBuildContext;
import org.drools.compiler.builder.impl.BuildResultCollector;
import org.drools.compiler.builder.impl.KnowledgeBuilderConfigurationImpl;
import org.drools.compiler.builder.impl.KnowledgeBuilderImpl;
+import org.drools.compiler.builder.impl.KnowledgeBuilderRulesConfigurationImpl;
import org.drools.compiler.builder.impl.TypeDeclarationContext;
import org.drools.compiler.builder.impl.TypeDeclarationUtils;
import org.drools.compiler.compiler.DialectCompiletimeRegistry;
@@ -77,25 +93,11 @@ import org.drools.modelcompiler.util.StringUtil;
import org.drools.util.StringUtils;
import org.drools.util.TypeResolver;
import org.kie.api.builder.ReleaseId;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.runtime.rule.AccumulateFunction;
import org.kie.internal.ruleunit.RuleUnitDescription;
import org.kie.internal.ruleunit.RuleUnitVariable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
import static com.github.javaparser.StaticJavaParser.parseBodyDeclaration;
import static com.github.javaparser.ast.Modifier.finalModifier;
import static com.github.javaparser.ast.Modifier.publicModifier;
@@ -182,6 +184,8 @@ public class PackageModel {
private final String executableRulesClass;
private final Collection<String> executableRulesClasses = new HashSet<>();
+ private final boolean prototypesAllowed;
+
private PackageModel( ReleaseId releaseId, String name, KnowledgeBuilderConfigurationImpl configuration, DialectCompiletimeRegistry dialectCompiletimeRegistry, DRLIdGenerator exprIdGenerator) {
this(name, configuration, dialectCompiletimeRegistry, exprIdGenerator, getPkgUUID(releaseId, name));
}
@@ -197,8 +201,9 @@ public class PackageModel {
this.configuration = configuration;
this.exprIdGenerator = exprIdGenerator;
this.dialectCompiletimeRegistry = dialectCompiletimeRegistry;
- executableRulesClass = name + "." + rulesFileName;
- executableRulesClasses.add(executableRulesClass);
+ this.executableRulesClass = name + "." + rulesFileName;
+ this.executableRulesClasses.add(executableRulesClass);
+ this.prototypesAllowed = configuration != null && configuration.as(KnowledgeBuilderRulesConfigurationImpl.KEY).getPrototypesOption() == PrototypesOption.ALLOWED;
}
public static PackageModel createPackageModel(KnowledgeBuilderConfigurationImpl configuration, PackageDescr packageDescr, PackageRegistry pkgRegistry, String pkgName, ReleaseId releaseId, DRLIdGenerator exprIdGenerator) {
@@ -942,6 +947,10 @@ public class PackageModel {
return otnsClasses;
}
+ public boolean arePrototypesAllowed() {
+ return prototypesAllowed;
+ }
+
public String getDomainClassesMetadataSource() {
StringBuilder sb = new StringBuilder(
"package " + name + ";\n" +
@@ -1048,4 +1057,9 @@ public class PackageModel {
final Map<String, java.lang.reflect.Type> globals = new HashMap<>();
final Set<String> entryPoints = new HashSet<>();
}
+
+ @Override
+ public String toString() {
+ return pkg.toString();
+ }
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/AggregateKey.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/AggregateKey.java
index 0ee30f6f90..2b03cf5cc6 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/AggregateKey.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/AggregateKey.java
@@ -18,33 +18,5 @@
*/
package org.drools.model.codegen.execmodel.generator;
-import java.util.Objects;
-
-public final class AggregateKey {
- String key;
- Class<?> clazz;
-
- public AggregateKey(String key, Class<?> clazz) {
- this.key = key;
- this.clazz = clazz;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- AggregateKey that = (AggregateKey) o;
- return key.equals(that.key) &&
- clazz.equals(that.clazz);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(key, clazz);
- }
-}
+public record AggregateKey(String key, String type) { }
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/BoxedParameters.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/BoxedParameters.java
index d76cc757a2..a681ee3d75 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/BoxedParameters.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/BoxedParameters.java
@@ -23,15 +23,17 @@ import java.util.Collection;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.body.VariableDeclarator;
-import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.type.Type;
+import org.kie.api.prototype.PrototypeFactInstance;
+
+import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toClassOrInterfaceType;
public class BoxedParameters {
- RuleContext context;
+ private final RuleContext context;
public BoxedParameters(RuleContext context) {
this.context = context;
@@ -40,27 +42,35 @@ public class BoxedParameters {
// Types in the executable model are promoted to boxed to type check the Java DSL.
// We add such promoted types as _<PARAMETER_NAME> (with the underscore prefix)
// and then we downcast to the original unboxed type in the body of the function (methodBody)
- public NodeList<Parameter> getBoxedParametersWithUnboxedAssignment(Collection<String> declarationUsedInRHS,
- BlockStmt methodBody) {
-
+ public NodeList<Parameter> getBoxedParametersWithUnboxedAssignment(Collection<String> declarationUsedInRHS, BlockStmt methodBody) {
NodeList<Parameter> parameters = NodeList.nodeList();
-
for (String parameterName : declarationUsedInRHS) {
- DeclarationSpec declaration = context.getDeclarationByIdWithException(parameterName);
+ TypedDeclarationSpec declaration = context.getTypedDeclarationByIdWithException(parameterName);
+ Parameter boxedParameter = getTypedParameter(methodBody, parameterName, declaration);
+ parameters.add(boxedParameter);
+ }
+ return parameters;
+ }
+
+ private static Parameter getTypedParameter(BlockStmt methodBody, String parameterName, TypedDeclarationSpec declaration) {
+ Type boxedType = declaration.getBoxedType();
+ if (!declaration.isBoxed()) {
+ return new Parameter(boxedType, parameterName);
+ }
- Parameter boxedParameter;
- Type boxedType = declaration.getBoxedType();
+ String boxedParameterName = "_" + parameterName;
+ VariableDeclarator varDec = new VariableDeclarator(declaration.getRawType(), parameterName, new NameExpr(boxedParameterName));
+ methodBody.addStatement(0, new VariableDeclarationExpr(varDec));
+ return new Parameter(boxedType, boxedParameterName);
+ }
- if (declaration.isBoxed()) {
- String boxedParameterName = "_" + parameterName;
- boxedParameter = new Parameter(boxedType, boxedParameterName);
- Expression unboxedTypeDowncast = new VariableDeclarationExpr(new VariableDeclarator(declaration.getRawType(),
- parameterName,
- new NameExpr(boxedParameterName)));
- methodBody.addStatement(0, unboxedTypeDowncast);
- } else {
- boxedParameter = new Parameter(boxedType, parameterName);
- }
+ public NodeList<Parameter> getParametersForPrototype(Collection<String> declarationUsedInRHS, BlockStmt methodBody) {
+ NodeList<Parameter> parameters = NodeList.nodeList();
+ for (String parameterName : declarationUsedInRHS) {
+ DeclarationSpec declaration = context.getDeclarationByIdWithException(parameterName);
+ Parameter boxedParameter = declaration instanceof TypedDeclarationSpec tSpec ?
+ getTypedParameter(methodBody, parameterName, tSpec) :
+ new Parameter(toClassOrInterfaceType(PrototypeFactInstance.class), parameterName);
parameters.add(boxedParameter);
}
return parameters;
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/Consequence.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/Consequence.java
index bdd8282553..9ce2ebd940 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/Consequence.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/Consequence.java
@@ -48,9 +48,9 @@ import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.type.Type;
+import org.drools.base.factmodel.ClassDefinition;
import org.drools.compiler.compiler.MissingDependencyError;
import org.drools.core.common.TruthMaintenanceSystemFactory;
-import org.drools.base.factmodel.ClassDefinition;
import org.drools.model.BitMask;
import org.drools.model.bitmask.AllSetButLastBitMask;
import org.drools.model.codegen.execmodel.PackageModel;
@@ -60,8 +60,8 @@ import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
import org.drools.model.codegen.execmodel.errors.MvelCompilationError;
import org.drools.modelcompiler.consequence.DroolsImpl;
import org.drools.mvelcompiler.CompiledBlockResult;
-import org.drools.mvelcompiler.PreprocessCompiler;
import org.drools.mvelcompiler.MvelCompilerException;
+import org.drools.mvelcompiler.PreprocessCompiler;
import org.drools.util.StringUtils;
import static com.github.javaparser.StaticJavaParser.parseExpression;
@@ -260,7 +260,7 @@ public class Consequence {
if (context.getRuleDialect() == RuleContext.RuleDialect.MVEL) {
return existingDecls.stream().filter(d -> containsWord(d, consequenceString)).collect(toSet());
- } else if (context.getRuleDialect() == RuleContext.RuleDialect.JAVA) {
+ } else if (ruleConsequence != null) {
Set<String> declUsedInRHS = ruleConsequence.findAll(NameExpr.class).stream().map(NameExpr::getNameAsString).collect(toSet());
return existingDecls.stream().filter(declUsedInRHS::contains).collect(toSet());
}
@@ -288,7 +288,9 @@ public class Consequence {
executeLambda.addParameter(new Parameter(toClassOrInterfaceType(org.drools.model.Drools.class), "drools"));
}
- NodeList<Parameter> parameters = new BoxedParameters(context).getBoxedParametersWithUnboxedAssignment(verifiedDeclUsedInRHS, ruleConsequence);
+ NodeList<Parameter> parameters = context.arePrototypesAllowed() ?
+ new BoxedParameters(context).getParametersForPrototype(verifiedDeclUsedInRHS, ruleConsequence) :
+ new BoxedParameters(context).getBoxedParametersWithUnboxedAssignment(verifiedDeclUsedInRHS, ruleConsequence);
parameters.forEach(executeLambda::addParameter);
executeLambda.setBody(ruleConsequence);
@@ -308,13 +310,14 @@ public class Consequence {
private String preprocessConsequence(String consequence) {
int modifyPos = StringUtils.indexOfOutOfQuotes(consequence, "modify");
int textBlockPos = StringUtils.indexOfOutOfQuotes(consequence, "\"\"\"");
+ Set<String> prototypes = context.getPrototypeDeclarations();
- if (modifyPos < 0 && textBlockPos < 0) {
+ if (modifyPos < 0 && textBlockPos < 0 && prototypes.isEmpty()) {
return consequence;
}
PreprocessCompiler preprocessCompiler = new PreprocessCompiler();
- CompiledBlockResult compile = preprocessCompiler.compile(addCurlyBracesToBlock(consequence));
+ CompiledBlockResult compile = preprocessCompiler.compile(addCurlyBracesToBlock(consequence), prototypes);
return printNode(compile.statementResults());
}
@@ -421,8 +424,8 @@ public class Consequence {
throw new ConsequenceRewriteException();
}
} else {
- return context.getDeclarationById(updatedVar)
- .map(DeclarationSpec::getDeclarationClass)
+ return context.getTypedDeclarationById(updatedVar)
+ .map(TypedDeclarationSpec::getDeclarationClass)
.orElseThrow(ConsequenceRewriteException::new);
}
}
@@ -527,8 +530,8 @@ public class Consequence {
}
private boolean isDataStoreScope(Expression scope) {
- return scope.isNameExpr() && context.getDeclarationById(scope.asNameExpr().getNameAsString())
- .map(DeclarationSpec::getDeclarationClass)
+ return scope.isNameExpr() && context.getTypedDeclarationById(scope.asNameExpr().getNameAsString())
+ .map(TypedDeclarationSpec::getDeclarationClass)
.map(dataStoreClass::isAssignableFrom).orElse(false);
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java
index f8d01f49b1..29e650c187 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java
@@ -18,156 +18,27 @@
*/
package org.drools.model.codegen.execmodel.generator;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Collections;
-import java.util.List;
import java.util.Optional;
-import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
-import org.drools.base.base.ClassObjectType;
-import org.drools.base.rule.Declaration;
-import org.drools.base.rule.accessor.PatternExtractor;
-import org.drools.drl.ast.descr.BehaviorDescr;
-import org.drools.drl.ast.descr.EntryPointDescr;
-import org.drools.drl.ast.descr.PatternDescr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import org.drools.model.codegen.execmodel.PackageModel;
-import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toClassOrInterfaceType;
-import static org.drools.util.ClassUtils.rawType;
+public interface DeclarationSpec {
+ String getBindingId();
-public class DeclarationSpec {
- private final String bindingId;
- private final Type declarationType;
- private final Optional<PatternDescr> optPattern;
- private final Optional<Expression> declarationSource;
- private final Optional<String> variableName;
- private final boolean isGlobal;
+ Optional<String> getVariableName();
- private String boundVariable;
- private MethodCallExpr bindingExpr;
- private boolean boxed = false;
- private Optional<PatternDescr> belongingPatternDescr = Optional.empty();
+ Class<?> getDeclarationClass();
- public DeclarationSpec(String bindingId, Type declarationType) {
- this(bindingId, declarationType, Optional.empty(), Optional.empty(), Optional.empty(), false);
- }
-
- public DeclarationSpec(String bindingId, Type declarationType, boolean isGlobal) {
- this(bindingId, declarationType, Optional.empty(), Optional.empty(), Optional.empty(), isGlobal);
- }
-
- DeclarationSpec(String bindingId, Type declarationType, String variableName) {
- this(bindingId, declarationType, Optional.empty(), Optional.empty(), Optional.of(variableName), false);
- }
-
- DeclarationSpec(String bindingId, Type declarationType, Expression declarationSource) {
- this(bindingId, declarationType, Optional.empty(), Optional.of(declarationSource), Optional.empty(), false);
- }
-
- DeclarationSpec(String bindingId, Type declarationType, Optional<PatternDescr> pattern, Optional<Expression> declarationSource, Optional<String> variableName, boolean isGlobal) {
- this.bindingId = bindingId;
- this.declarationType = declarationType;
- this.optPattern = pattern;
- this.declarationSource = declarationSource;
- this.variableName = variableName;
- this.isGlobal = isGlobal;
- }
-
- Optional<String> getEntryPoint() {
- return optPattern.flatMap(pattern -> pattern.getSource() instanceof EntryPointDescr ?
- Optional.of(((EntryPointDescr) pattern.getSource()).getEntryId()) :
- Optional.empty()
- );
- }
-
- public List<BehaviorDescr> getBehaviors() {
- return optPattern.map(PatternDescr::getBehaviors).orElse(Collections.emptyList());
- }
-
- public String getBindingId() {
- return bindingId;
- }
-
- public Class<?> getDeclarationClass() {
- return rawType( declarationType );
- }
-
- public Type getDeclarationType() {
- return declarationType;
- }
-
- public boolean isParametrizedType() {
- return declarationType instanceof ParameterizedType;
- }
-
- public Optional<Expression> getDeclarationSource() {
- return declarationSource;
- }
-
- public Optional<String> getVariableName() {
- return variableName;
- }
-
- public com.github.javaparser.ast.type.Type getBoxedType() {
- return DrlxParseUtil.classToReferenceType(this);
- }
-
- public com.github.javaparser.ast.type.Type getRawType() {
- return toClassOrInterfaceType(getDeclarationClass());
- }
-
- public boolean isGlobal() {
- return isGlobal;
- }
-
- public Optional<String> getBoundVariable() {
- return Optional.ofNullable( boundVariable );
- }
-
- public void setBoundVariable( String boundVariable ) {
- this.boundVariable = boundVariable;
- }
-
- public MethodCallExpr getBindingExpr() {
- return bindingExpr;
- }
-
- public void setBindingExpr( MethodCallExpr bindingExpr ) {
- this.bindingExpr = bindingExpr;
- }
-
- @Override
- public String toString() {
- return "DeclarationSpec{" +
- "bindingId='" + bindingId + '\'' +
- ", declarationClass=" + declarationType +
- ", isGlobal=" + isGlobal +
- ", boxed=" + boxed +
- '}';
- }
-
- public Declaration asDeclaration() {
- Class<?> declarationClass = getDeclarationClass();
- Declaration decl = new Declaration( bindingId, new PatternExtractor( new ClassObjectType(declarationClass) ), null );
- decl.setDeclarationClass(declarationClass);
- return decl;
- }
-
- public void setBoxed(boolean boxed) {
- this.boxed = boxed;
- }
+ boolean isGlobal();
- public boolean isBoxed() {
- return boxed;
- }
+ MethodCallExpr getBindingExpr();
+ void setBindingExpr( MethodCallExpr bindingExpr );
- public Optional<PatternDescr> getBelongingPatternDescr() {
- return belongingPatternDescr;
- }
+ void registerOnPackage(PackageModel packageModel, RuleContext context, BlockStmt ruleBlock);
- public void setBelongingPatternDescr(Optional<PatternDescr> belongingPatternDescr) {
- this.belongingPatternDescr = belongingPatternDescr;
+ default boolean isPrototypeDeclaration() {
+ return false;
}
-
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
index 86c96ac505..b39396d8ce 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DrlxParseUtil.java
@@ -295,7 +295,7 @@ public class DrlxParseUtil {
if (usedDeclarations != null) {
usedDeclarations.add(name);
}
- Optional<java.lang.reflect.Type> type = context.getDeclarationById( name ).map(DeclarationSpec::getDeclarationClass);
+ Optional<java.lang.reflect.Type> type = context.getTypedDeclarationById(name ).map(TypedDeclarationSpec::getDeclarationClass);
return type.orElseThrow(() -> new NoSuchElementException("Cannot get expression type by name " + name + "!"));
}
@@ -587,7 +587,7 @@ public class DrlxParseUtil {
return classNameToReferenceTypeWithBoxing(declarationClass).parsedType;
}
- public static Type classToReferenceType(DeclarationSpec declaration) {
+ public static Type classToReferenceType(TypedDeclarationSpec declaration) {
if (declaration.isParametrizedType()) {
return StaticJavaParser.parseClassOrInterfaceType(declaration.getDeclarationType().getTypeName());
}
@@ -947,7 +947,7 @@ public class DrlxParseUtil {
List<DeclarationSpec> allDeclarations = new ArrayList<>(context.getAllDeclarations());
originalPatternType.ifPresent(pt -> {
- allDeclarations.add(new DeclarationSpec(THIS_PLACEHOLDER, pt));
+ allDeclarations.add(new TypedDeclarationSpec(THIS_PLACEHOLDER, pt));
mvelCompilerContext.setRootPatternPrefix(pt, THIS_PLACEHOLDER);
});
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DslMethodNames.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DslMethodNames.java
index f457cec38e..f863319ce0 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DslMethodNames.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DslMethodNames.java
@@ -22,6 +22,7 @@ import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
+import org.drools.model.prototype.PrototypeDSL;
public class DslMethodNames {
@@ -70,6 +71,13 @@ public class DslMethodNames {
public static final String EVAL_CALL = "eval";
public static final String NO_OP_EXPR = "NO_OP_EXPR";
+ // prototypes
+ public static final NameExpr PROTO_DSL_NAMESPACE = new NameExpr(PrototypeDSL.class.getCanonicalName());
+ public static final String PROTO_PATTERN_CALL = "protoPattern";
+ public static final String PROTO_EXPR_CALL = "expr";
+ public static final String PROTOTYPE_FACT_CALL = "prototypeFact";
+ public static final String PROTOTYPE_VARIABLE_CALL = "variable";
+
// expressions
public static final String EVAL_EXPR_CALL = "expr";
public static final String EXPR_CALL = "expr";
@@ -109,4 +117,8 @@ public class DslMethodNames {
public static boolean isDslTopLevelNamespace(Expression expr) {
return DSL_NAMESPACE.equals(expr);
}
+
+ public static MethodCallExpr createProtoDslTopLevelMethod(String name) {
+ return new MethodCallExpr(PROTO_DSL_NAMESPACE.clone(), name);
+ }
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/ModelGenerator.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/ModelGenerator.java
index b932598ca2..517c1c403f 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/ModelGenerator.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/ModelGenerator.java
@@ -91,6 +91,7 @@ import static org.drools.model.codegen.execmodel.generator.DslMethodNames.SUPPLY
import static org.drools.model.codegen.execmodel.generator.DslMethodNames.UNIT_CALL;
import static org.drools.model.codegen.execmodel.generator.DslMethodNames.WINDOW_CALL;
import static org.drools.model.codegen.execmodel.generator.DslMethodNames.createDslTopLevelMethod;
+import static org.drools.model.codegen.execmodel.generator.RuleContext.DIALECT_ATTRIBUTE;
import static org.drools.modelcompiler.util.ClassUtil.asJavaSourceName;
import static org.drools.modelcompiler.util.StringUtil.toId;
import static org.drools.modelcompiler.util.TimerUtil.validateTimer;
@@ -178,7 +179,7 @@ public class ModelGenerator {
if (context.getRuleUnitDescr() != null) {
ruleUnitDescrs.add(context.getRuleUnitDescr());
}
- context.setDialectFromAttributes(packageDescr.getAttributes());
+ context.setDialectFromAttribute(packageDescr.getAttribute( DIALECT_ATTRIBUTE ));
if (descr instanceof QueryDescr) {
QueryGenerator.processQueryDef(packageModel, context);
}
@@ -213,7 +214,7 @@ public class ModelGenerator {
QueryGenerator.processQuery(context.getPackageModel(), (QueryDescr) context.getRuleDescr());
return;
}
- context.setDialectFromAttributes(packageDescr.getAttributes());
+ context.setDialectFromAttribute(packageDescr.getAttribute( DIALECT_ATTRIBUTE ));
processRule(packageDescr, context);
}
@@ -221,7 +222,7 @@ public class ModelGenerator {
PackageModel packageModel = context.getPackageModel();
RuleDescr ruleDescr = context.getRuleDescr();
context.addGlobalDeclarations();
- context.setDialectFromAttributes(ruleDescr.getAttributes().values());
+ context.setDialectFromAttribute(ruleDescr.getAttributes().get( DIALECT_ATTRIBUTE ));
for(Entry<String, Object> kv : ruleDescr.getNamedConsequences().entrySet()) {
context.addNamedConsequence(kv.getKey(), kv.getValue().toString());
@@ -492,58 +493,8 @@ public class ModelGenerator {
public static void createVariables(BlockStmt block, PackageModel packageModel, RuleContext context) {
for (DeclarationSpec decl : context.getAllDeclarations()) {
- boolean domainClass = packageModel.registerDomainClass( decl.getDeclarationClass() );
- if (!context.getGlobals().containsKey(decl.getBindingId()) && context.getQueryParameterByName(decl.getBindingId()).isEmpty()) {
- addVariable(block, decl, context, domainClass);
- }
+ decl.registerOnPackage(packageModel, context, block);
}
}
- private static void addVariable(BlockStmt ruleBlock, DeclarationSpec declaration, RuleContext context, boolean domainClass) {
- if (declaration.getDeclarationClass() == null) {
- context.addCompilationError( new UnknownDeclarationError( declaration.getBindingId() ) );
- return;
- }
- Type declType = classToReferenceType( declaration );
-
- ClassOrInterfaceType varType = toClassOrInterfaceType(Variable.class);
- varType.setTypeArguments(declType);
- VariableDeclarationExpr var_ = new VariableDeclarationExpr(varType, context.getVar(declaration.getBindingId()), Modifier.finalModifier());
-
- MethodCallExpr declarationOfCall = createDslTopLevelMethod(DECLARATION_OF_CALL);
-
- declarationOfCall.addArgument(new ClassExpr( declaration.getBoxedType() ));
-
- if (domainClass) {
- String domainClassSourceName = asJavaSourceName( declaration.getDeclarationClass() );
- declarationOfCall.addArgument( DOMAIN_CLASSESS_METADATA_FILE_NAME + context.getPackageModel().getPackageUUID() + "." + domainClassSourceName + DOMAIN_CLASS_METADATA_INSTANCE );
- }
-
- declarationOfCall.addArgument(toStringLiteral(declaration.getVariableName().orElse(declaration.getBindingId())));
-
- declaration.getDeclarationSource().ifPresent(declarationOfCall::addArgument);
-
- declaration.getEntryPoint().ifPresent( ep -> {
- MethodCallExpr entryPointCall = createDslTopLevelMethod(ENTRY_POINT_CALL);
- entryPointCall.addArgument( toStringLiteral(ep ) );
- declarationOfCall.addArgument( entryPointCall );
- } );
- for ( BehaviorDescr behaviorDescr : declaration.getBehaviors() ) {
- MethodCallExpr windowCall = createDslTopLevelMethod(WINDOW_CALL);
- if ( BehaviorRuntime.BehaviorType.TIME_WINDOW.matches(behaviorDescr.getSubType()) ) {
- windowCall.addArgument( "org.drools.model.Window.Type.TIME" );
- windowCall.addArgument( "" + TimeUtils.parseTimeString(behaviorDescr.getParameters().get(0 ) ) );
- }
- if ( BehaviorRuntime.BehaviorType.LENGTH_WINDOW.matches(behaviorDescr.getSubType()) ) {
- windowCall.addArgument( "org.drools.model.Window.Type.LENGTH" );
- windowCall.addArgument( "" + Integer.valueOf( behaviorDescr.getParameters().get( 0 ) ) );
- }
- declarationOfCall.addArgument( windowCall );
- }
-
- AssignExpr var_assign = new AssignExpr(var_, declarationOfCall, AssignExpr.Operator.ASSIGN);
- if (!DrlxParseUtil.hasDuplicateExpr(ruleBlock, var_assign)) {
- ruleBlock.addStatement(var_assign);
- }
- }
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java
index 4c845e06fe..e16ba61bcf 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/OOPathExprGenerator.java
@@ -137,7 +137,7 @@ public class OOPathExprGenerator {
bindingId = context.getOOPathId(fieldType, originalBind + fieldName + pos);
}
- DeclarationSpec newDeclaration = context.addDeclaration(bindingId, fieldType, reactiveFrom);
+ TypedDeclarationSpec newDeclaration = context.addDeclaration(bindingId, fieldType, reactiveFrom);
context.addOOPathDeclaration(newDeclaration);
final List<DrlxExpression> conditions = chunk.getConditions();
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/PrototypeDeclarationSpec.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/PrototypeDeclarationSpec.java
new file mode 100644
index 0000000000..ce7d7e171a
--- /dev/null
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/PrototypeDeclarationSpec.java
@@ -0,0 +1,82 @@
+package org.drools.model.codegen.execmodel.generator;
+
+import java.util.Optional;
+
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import org.drools.model.codegen.execmodel.PackageModel;
+import org.drools.model.prototype.PrototypeVariable;
+
+import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toClassOrInterfaceType;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PROTOTYPE_FACT_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PROTOTYPE_VARIABLE_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.createProtoDslTopLevelMethod;
+
+public class PrototypeDeclarationSpec implements DeclarationSpec {
+
+ private final String bindingId;
+ private final String prototypeType;
+ private final boolean isGlobal;
+
+ private MethodCallExpr bindingExpr;
+
+ PrototypeDeclarationSpec(String bindingId, String prototypeType, boolean isGlobal) {
+ this.bindingId = bindingId;
+ this.prototypeType = prototypeType;
+ this.isGlobal = isGlobal;
+ }
+
+ @Override
+ public String getBindingId() {
+ return bindingId;
+ }
+
+ @Override
+ public Optional<String> getVariableName() {
+ return Optional.empty();
+ }
+
+ @Override
+ public Class<?> getDeclarationClass() {
+ return null;
+ }
+
+ @Override
+ public boolean isGlobal() {
+ return isGlobal;
+ }
+
+ @Override
+ public boolean isPrototypeDeclaration() {
+ return true;
+ }
+
+ @Override
+ public MethodCallExpr getBindingExpr() {
+ return bindingExpr;
+ }
+
+ @Override
+ public void setBindingExpr( MethodCallExpr bindingExpr ) {
+ this.bindingExpr = bindingExpr;
+ }
+
+ @Override
+ public void registerOnPackage(PackageModel packageModel, RuleContext context, BlockStmt ruleBlock) {
+ ClassOrInterfaceType varType = toClassOrInterfaceType(PrototypeVariable.class);
+ VariableDeclarationExpr varExpr = new VariableDeclarationExpr(varType, context.getVar(getBindingId()), Modifier.finalModifier());
+
+ MethodCallExpr prototypeCall = createProtoDslTopLevelMethod(PROTOTYPE_FACT_CALL);
+ prototypeCall.addArgument(new StringLiteralExpr(prototypeType));
+ MethodCallExpr variableCall = createProtoDslTopLevelMethod(PROTOTYPE_VARIABLE_CALL);
+ variableCall.addArgument(prototypeCall);
+
+ AssignExpr varAssign = new AssignExpr(varExpr, variableCall, AssignExpr.Operator.ASSIGN);
+ ruleBlock.addStatement(varAssign);
+ }
+}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/QueryGenerator.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/QueryGenerator.java
index 458e1c9e92..4e54336b6d 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/QueryGenerator.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/QueryGenerator.java
@@ -43,6 +43,7 @@ import org.drools.model.codegen.execmodel.QueryModel;
import org.drools.model.codegen.execmodel.generator.visitor.ModelGeneratorVisitor;
import org.kie.internal.ruleunit.RuleUnitDescription;
+import static org.drools.model.codegen.execmodel.generator.RuleContext.DIALECT_ATTRIBUTE;
import static org.drools.model.impl.VariableImpl.GENERATED_VARIABLE_PREFIX;
import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.getClassFromContext;
import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toClassOrInterfaceType;
@@ -79,9 +80,9 @@ public class QueryGenerator {
}
public static class QueryDefWithType {
- private ClassOrInterfaceType queryType;
- private MethodCallExpr methodCallExpr;
- private RuleContext context;
+ private final ClassOrInterfaceType queryType;
+ private final MethodCallExpr methodCallExpr;
+ private final RuleContext context;
public QueryDefWithType(ClassOrInterfaceType queryType, MethodCallExpr methodCallExpr, RuleContext contex) {
this.queryType = queryType;
@@ -107,7 +108,7 @@ public class QueryGenerator {
RuleContext context = packageModel.getQueryDefWithType().get(queryDefVariableName).getContext();
context.addGlobalDeclarations();
- context.setDialectFromAttributes(queryDescr.getAttributes().values());
+ context.setDialectFromAttribute(queryDescr.getAttributes().get( DIALECT_ATTRIBUTE ));
new ModelGeneratorVisitor(context, packageModel).visit(queryDescr.getLhs());
if (context.getRuleUnitDescr() != null) {
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/RuleContext.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/RuleContext.java
index 737d68a3e2..686a539b7c 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/RuleContext.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/RuleContext.java
@@ -23,6 +23,7 @@ import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
@@ -34,6 +35,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.expr.Expression;
@@ -77,6 +79,8 @@ import static org.drools.util.ClassUtils.rawType;
public class RuleContext {
+ public static final String DIALECT_ATTRIBUTE = "dialect";
+
private static final String SCOPE_SUFFIX = "_sCoPe";
private final TypeDeclarationContext typeDeclarationContext;
@@ -90,7 +94,7 @@ public class RuleContext {
private final Map<String, DeclarationSpec> allDeclarations = new LinkedHashMap<>();
private final Map<String, DeclarationSpec> scopedDeclarations = new LinkedHashMap<>();
- private final List<DeclarationSpec> ooPathDeclarations = new ArrayList<>();
+ private final List<TypedDeclarationSpec> ooPathDeclarations = new ArrayList<>();
private final Deque<Consumer<Expression>> exprPointer = new ArrayDeque<>();
private final List<Expression> expressions = new ArrayList<>();
private final Map<String, String> namedConsequences = new HashMap<>();
@@ -113,6 +117,8 @@ public class RuleContext {
private RuleDialect ruleDialect = RuleDialect.JAVA; // assumed is java by default as per Drools manual.
+ private boolean prototypesAllowed = false;
+
private int scopeCounter = 1;
private Scope currentScope = new Scope();
private final Deque<Scope> scopesStack = new LinkedList<>();
@@ -131,7 +137,21 @@ public class RuleContext {
private boolean hasCompilationError;
public enum RuleDialect {
- JAVA, MVEL
+ JAVA, MVEL;
+
+ public static RuleDialect resolveDialect(String dialect) {
+ if (dialect == null) {
+ return JAVA;
+ }
+ switch (dialect) {
+ case "java":
+ return JAVA;
+ case "mvel":
+ return MVEL;
+ default:
+ throw new IllegalArgumentException("Unknown dialect: " + dialect);
+ }
+ }
}
private AndDescr parentDescr;
@@ -145,7 +165,7 @@ public class RuleContext {
this.resultCollector = resultCollector;
this.packageModel = packageModel;
this.idGenerator = packageModel.getExprIdGenerator();
- exprPointer.push( this.expressions::add );
+ this.exprPointer.push( this.expressions::add );
this.typeResolver = typeResolver;
this.ruleDescr = ruleDescr;
this.ruleUnitDescr = findUnitDescr();
@@ -224,20 +244,38 @@ public class RuleContext {
return ofNullable(explicitCastType.get(field));
}
+ public Optional<TypedDeclarationSpec> getTypedDeclarationById(String id) {
+ return getDeclarationById(id).map(TypedDeclarationSpec.class::cast);
+ }
+
+ public TypedDeclarationSpec getTypedDeclarationByIdWithException(String id) {
+ return getTypedDeclarationById(id).orElseThrow(() -> new UnknownDeclarationException("Unknown declaration: " + id));
+ }
+
public Optional<DeclarationSpec> getDeclarationById(String id) {
- DeclarationSpec spec = scopedDeclarations.get( getDeclarationKey( id ));
+ DeclarationSpec spec = scopedDeclarations.get(getDeclarationKey(id ));
if (spec == null) {
Class<?> unitVarType = ruleUnitVarsOriginalType.get( id );
if(unitVarType == null) {
unitVarType = ruleUnitVars.get(id);
}
if (unitVarType != null) {
- spec = new DeclarationSpec(id, unitVarType);
+ spec = new TypedDeclarationSpec(id, unitVarType);
}
}
return ofNullable( spec );
}
+ public boolean isPrototypeDeclaration(String id) {
+ return getDeclarationById(id).map(DeclarationSpec::isPrototypeDeclaration).orElse(false);
+ }
+
+ public Set<String> getPrototypeDeclarations() {
+ return arePrototypesAllowed() ?
+ scopedDeclarations.values().stream().filter(DeclarationSpec::isPrototypeDeclaration).map(DeclarationSpec::getBindingId).collect(Collectors.toSet()) :
+ Collections.emptySet();
+ }
+
public DeclarationSpec getDeclarationByIdWithException(String id) {
return getDeclarationById(id).orElseThrow(() -> new UnknownDeclarationException("Unknown declaration: " + id));
}
@@ -289,7 +327,7 @@ public class RuleContext {
for (Map.Entry<String, java.lang.reflect.Type> ks : globals.entrySet()) {
definedVars.put(ks.getKey(), ks.getKey());
- addDeclaration(new DeclarationSpec(ks.getKey(), ks.getValue(), true));
+ addDeclaration(new TypedDeclarationSpec(ks.getKey(), ks.getValue(), true));
}
}
@@ -312,7 +350,7 @@ public class RuleContext {
return packageModel.hasEntryPoint(name) || (ruleUnitDescr != null && packageModel.hasEntryPointForUnit(name, ruleUnitDescr.getSimpleName()));
}
- public Optional<DeclarationSpec> getOOPathDeclarationById(String id) {
+ public Optional<TypedDeclarationSpec> getOOPathDeclarationById(String id) {
return ooPathDeclarations.stream().filter(d -> d.getBindingId().equals(id)).findFirst();
}
@@ -329,24 +367,28 @@ public class RuleContext {
if (varType != null) {
return varType;
}
- DeclarationSpec decl = scopedDeclarations.get( "$p" );
- return decl != null ? decl.getDeclarationClass() : null;
+ DeclarationSpec decl = scopedDeclarations.get("$p" );
+ return decl instanceof TypedDeclarationSpec tDecl ? tDecl.getDeclarationClass() : null;
}
- public DeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass) {
- return addDeclaration(new DeclarationSpec(defineVar(bindingId), declarationClass));
+ public TypedDeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass) {
+ return addDeclaration(new TypedDeclarationSpec(defineVar(bindingId), declarationClass));
}
- public DeclarationSpec addDeclaration( String bindingId, Class<?> declarationClass, Optional<PatternDescr> pattern, Optional<Expression> declarationSource) {
- return addDeclaration(new DeclarationSpec(defineVar(bindingId), declarationClass, pattern, declarationSource, Optional.empty(), false));
+ public TypedDeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass, Optional<PatternDescr> pattern, Optional<Expression> declarationSource) {
+ return addDeclaration(new TypedDeclarationSpec(defineVar(bindingId), declarationClass, pattern, declarationSource, Optional.empty(), false));
}
- public DeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass, String variableName) {
- return addDeclaration(new DeclarationSpec(defineVar(bindingId), declarationClass, variableName));
+ public TypedDeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass, String variableName) {
+ return addDeclaration(new TypedDeclarationSpec(defineVar(bindingId), declarationClass, variableName));
}
- public DeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass, Expression declarationSource) {
- return addDeclaration(new DeclarationSpec(defineVar(bindingId), declarationClass, declarationSource));
+ public TypedDeclarationSpec addDeclaration(String bindingId, Class<?> declarationClass, Expression declarationSource) {
+ return addDeclaration(new TypedDeclarationSpec(defineVar(bindingId), declarationClass, declarationSource));
+ }
+
+ public PrototypeDeclarationSpec addPrototypeDeclaration(String bindingId, String prototypeType) {
+ return addDeclaration(new PrototypeDeclarationSpec(defineVar(bindingId), prototypeType, false));
}
private String defineVar(String var) {
@@ -360,15 +402,15 @@ public class RuleContext {
return currentScope.id;
}
- public DeclarationSpec addDeclaration(DeclarationSpec d) {
+ public <T extends DeclarationSpec> T addDeclaration(T d) {
this.scopedDeclarations.putIfAbsent( d.getBindingId(), d );
this.allDeclarations.putIfAbsent( d.getBindingId(), d );
return d;
}
- public void addDeclarationReplacing(DeclarationSpec d) {
+ public void addDeclarationReplacing(TypedDeclarationSpec d) {
final String bindingId = d.getBindingId();
- final Optional<DeclarationSpec> declarationById = getDeclarationById(bindingId);
+ final Optional<TypedDeclarationSpec> declarationById = getTypedDeclarationById(bindingId);
if (declarationById.isPresent()) {
removeDeclarationById(bindingId);
}
@@ -387,7 +429,7 @@ public class RuleContext {
}
}
- public void addOOPathDeclaration(DeclarationSpec d) {
+ public void addOOPathDeclaration(TypedDeclarationSpec d) {
if(getOOPathDeclarationById(d.getBindingId()).isEmpty()) {
this.ooPathDeclarations.add(d);
}
@@ -401,7 +443,7 @@ public class RuleContext {
return scopedDeclarations.keySet();
}
- public List<DeclarationSpec> getOOPathDeclarations() {
+ public List<TypedDeclarationSpec> getOOPathDeclarations() {
return ooPathDeclarations;
}
@@ -480,6 +522,10 @@ public class RuleContext {
return ruleDialect;
}
+ public boolean arePrototypesAllowed() {
+ return packageModel.arePrototypesAllowed();
+ }
+
public void setRuleDialect(RuleDialect ruleDialect) {
this.ruleDialect = ruleDialect;
}
@@ -689,14 +735,9 @@ public class RuleContext {
}
}
- public void setDialectFromAttributes(Collection<AttributeDescr> attributes) {
- for (AttributeDescr a : attributes) {
- if (a.getName().equals("dialect")) {
- if (a.getValue().equals("mvel")) {
- setRuleDialect(RuleDialect.MVEL);
- }
- return;
- }
+ public void setDialectFromAttribute(AttributeDescr attribute) {
+ if (attribute != null) {
+ setRuleDialect(RuleDialect.resolveDialect(attribute.getValue()));
}
}
@@ -709,7 +750,7 @@ public class RuleContext {
}
public Type getDelarationType(String variableName) {
- return getDeclarationById(variableName).map(DeclarationSpec::getBoxedType)
+ return getTypedDeclarationById(variableName).map(TypedDeclarationSpec::getBoxedType)
.orElseGet(UnknownType::new);
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/TypedDeclarationSpec.java
similarity index 52%
copy from drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java
copy to drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/TypedDeclarationSpec.java
index f8d01f49b1..fc75419cee 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/DeclarationSpec.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/TypedDeclarationSpec.java
@@ -24,19 +24,39 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
+import com.github.javaparser.ast.Modifier;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.ClassExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.VariableDeclarationExpr;
+import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
import org.drools.base.base.ClassObjectType;
import org.drools.base.rule.Declaration;
import org.drools.base.rule.accessor.PatternExtractor;
+import org.drools.base.time.TimeUtils;
+import org.drools.core.rule.BehaviorRuntime;
import org.drools.drl.ast.descr.BehaviorDescr;
import org.drools.drl.ast.descr.EntryPointDescr;
import org.drools.drl.ast.descr.PatternDescr;
+import org.drools.model.Variable;
+import org.drools.model.codegen.execmodel.PackageModel;
+import org.drools.model.codegen.execmodel.errors.UnknownDeclarationError;
+import static org.drools.model.codegen.execmodel.PackageModel.DOMAIN_CLASSESS_METADATA_FILE_NAME;
+import static org.drools.model.codegen.execmodel.PackageModel.DOMAIN_CLASS_METADATA_INSTANCE;
+import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.classToReferenceType;
import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toClassOrInterfaceType;
+import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.toStringLiteral;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.DECLARATION_OF_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.ENTRY_POINT_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.WINDOW_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.createDslTopLevelMethod;
+import static org.drools.modelcompiler.util.ClassUtil.asJavaSourceName;
import static org.drools.util.ClassUtils.rawType;
-public class DeclarationSpec {
+public class TypedDeclarationSpec implements DeclarationSpec {
private final String bindingId;
private final Type declarationType;
private final Optional<PatternDescr> optPattern;
@@ -49,23 +69,23 @@ public class DeclarationSpec {
private boolean boxed = false;
private Optional<PatternDescr> belongingPatternDescr = Optional.empty();
- public DeclarationSpec(String bindingId, Type declarationType) {
+ public TypedDeclarationSpec(String bindingId, Type declarationType) {
this(bindingId, declarationType, Optional.empty(), Optional.empty(), Optional.empty(), false);
}
- public DeclarationSpec(String bindingId, Type declarationType, boolean isGlobal) {
+ public TypedDeclarationSpec(String bindingId, Type declarationType, boolean isGlobal) {
this(bindingId, declarationType, Optional.empty(), Optional.empty(), Optional.empty(), isGlobal);
}
- DeclarationSpec(String bindingId, Type declarationType, String variableName) {
+ TypedDeclarationSpec(String bindingId, Type declarationType, String variableName) {
this(bindingId, declarationType, Optional.empty(), Optional.empty(), Optional.of(variableName), false);
}
- DeclarationSpec(String bindingId, Type declarationType, Expression declarationSource) {
+ TypedDeclarationSpec(String bindingId, Type declarationType, Expression declarationSource) {
this(bindingId, declarationType, Optional.empty(), Optional.of(declarationSource), Optional.empty(), false);
}
- DeclarationSpec(String bindingId, Type declarationType, Optional<PatternDescr> pattern, Optional<Expression> declarationSource, Optional<String> variableName, boolean isGlobal) {
+ TypedDeclarationSpec(String bindingId, Type declarationType, Optional<PatternDescr> pattern, Optional<Expression> declarationSource, Optional<String> variableName, boolean isGlobal) {
this.bindingId = bindingId;
this.declarationType = declarationType;
this.optPattern = pattern;
@@ -85,10 +105,12 @@ public class DeclarationSpec {
return optPattern.map(PatternDescr::getBehaviors).orElse(Collections.emptyList());
}
+ @Override
public String getBindingId() {
return bindingId;
}
+ @Override
public Class<?> getDeclarationClass() {
return rawType( declarationType );
}
@@ -105,6 +127,7 @@ public class DeclarationSpec {
return declarationSource;
}
+ @Override
public Optional<String> getVariableName() {
return variableName;
}
@@ -117,6 +140,7 @@ public class DeclarationSpec {
return toClassOrInterfaceType(getDeclarationClass());
}
+ @Override
public boolean isGlobal() {
return isGlobal;
}
@@ -129,10 +153,12 @@ public class DeclarationSpec {
this.boundVariable = boundVariable;
}
+ @Override
public MethodCallExpr getBindingExpr() {
return bindingExpr;
}
+ @Override
public void setBindingExpr( MethodCallExpr bindingExpr ) {
this.bindingExpr = bindingExpr;
}
@@ -170,4 +196,58 @@ public class DeclarationSpec {
this.belongingPatternDescr = belongingPatternDescr;
}
+ @Override
+ public void registerOnPackage(PackageModel packageModel, RuleContext context, BlockStmt ruleBlock) {
+ boolean domainClass = packageModel.registerDomainClass( getDeclarationClass() );
+ if (!context.getGlobals().containsKey(getBindingId()) && context.getQueryParameterByName(getBindingId()).isEmpty()) {
+ addVariable(ruleBlock, context, domainClass);
+ }
+ }
+
+ private void addVariable(BlockStmt ruleBlock, RuleContext context, boolean domainClass) {
+ if (getDeclarationClass() == null) {
+ context.addCompilationError( new UnknownDeclarationError( getBindingId() ) );
+ return;
+ }
+
+ MethodCallExpr declarationOfCall = createDslTopLevelMethod(DECLARATION_OF_CALL);
+ declarationOfCall.addArgument(new ClassExpr(getBoxedType() ));
+
+ if (domainClass) {
+ String domainClassSourceName = asJavaSourceName( getDeclarationClass() );
+ declarationOfCall.addArgument( DOMAIN_CLASSESS_METADATA_FILE_NAME + context.getPackageModel().getPackageUUID() + "." + domainClassSourceName + DOMAIN_CLASS_METADATA_INSTANCE );
+ }
+
+ declarationOfCall.addArgument(toStringLiteral(getVariableName().orElse(getBindingId())));
+
+ getDeclarationSource().ifPresent(declarationOfCall::addArgument);
+
+ getEntryPoint().ifPresent( ep -> {
+ MethodCallExpr entryPointCall = createDslTopLevelMethod(ENTRY_POINT_CALL);
+ entryPointCall.addArgument( toStringLiteral(ep ) );
+ declarationOfCall.addArgument( entryPointCall );
+ } );
+
+ for ( BehaviorDescr behaviorDescr : getBehaviors() ) {
+ MethodCallExpr windowCall = createDslTopLevelMethod(WINDOW_CALL);
+ if ( BehaviorRuntime.BehaviorType.TIME_WINDOW.matches(behaviorDescr.getSubType()) ) {
+ windowCall.addArgument( "org.drools.model.Window.Type.TIME" );
+ windowCall.addArgument( "" + TimeUtils.parseTimeString(behaviorDescr.getParameters().get(0 ) ) );
+ }
+ if ( BehaviorRuntime.BehaviorType.LENGTH_WINDOW.matches(behaviorDescr.getSubType()) ) {
+ windowCall.addArgument( "org.drools.model.Window.Type.LENGTH" );
+ windowCall.addArgument( "" + Integer.valueOf( behaviorDescr.getParameters().get( 0 ) ) );
+ }
+ declarationOfCall.addArgument( windowCall );
+ }
+
+ ClassOrInterfaceType varType = toClassOrInterfaceType(Variable.class);
+ varType.setTypeArguments( classToReferenceType(this) );
+ VariableDeclarationExpr varExpr = new VariableDeclarationExpr(varType, context.getVar(getBindingId()), Modifier.finalModifier());
+
+ AssignExpr varAssign = new AssignExpr(varExpr, declarationOfCall, AssignExpr.Operator.ASSIGN);
+ if (!DrlxParseUtil.hasDuplicateExpr(ruleBlock, varAssign)) {
+ ruleBlock.addStatement(varAssign);
+ }
+ }
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintExpression.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintExpression.java
index 0563c0340c..08c4786c82 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintExpression.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintExpression.java
@@ -67,7 +67,7 @@ public class ConstraintExpression {
private static String parseConstraintExpression( RuleContext context, Class<?> patternType, BaseDescr constraint, boolean isPositional ) {
if (isPositional) {
String expr = constraint.toString();
- boolean isConstraint = !isIdentifier(expr) || context.getDeclarationById( expr ).isPresent();
+ boolean isConstraint = !isIdentifier(expr) || context.getTypedDeclarationById(expr ).isPresent();
int position = ((ExprConstraintDescr ) constraint).getPosition();
Optional<String> field = getFieldAtPosition(context, patternType, position);
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java
index 36b8f67a29..8702e687c9 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/drlxparse/ConstraintParser.java
@@ -53,7 +53,7 @@ import org.drools.model.Index;
import org.drools.model.codegen.execmodel.PackageModel;
import org.drools.model.codegen.execmodel.errors.ParseExpressionErrorResult;
import org.drools.model.codegen.execmodel.errors.VariableUsedInBindingError;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.ModelGenerator;
import org.drools.model.codegen.execmodel.generator.RuleContext;
@@ -200,7 +200,7 @@ public class ConstraintParser {
}
private void addDeclaration(DrlxExpression drlx, SingleDrlxParseSuccess singleResult, String bindId) {
- DeclarationSpec decl = context.addDeclaration(bindId, getDeclarationType(drlx, singleResult));
+ TypedDeclarationSpec decl = context.addDeclaration(bindId, getDeclarationType(drlx, singleResult));
if (drlx.getExpr() instanceof NameExpr) {
decl.setBoundVariable( PrintUtil.printNode(drlx.getExpr()) );
} else if (drlx.getExpr() instanceof BinaryExpr) {
@@ -505,7 +505,7 @@ public class ConstraintParser {
.setLeft( new TypedExpression( withThis, converted.getType() ) )
.addReactOnProperty( lcFirstForBean(nameExpr.getNameAsString()) );
} else if (context.hasDeclaration( expression )) {
- Optional<DeclarationSpec> declarationSpec = context.getDeclarationById(expression);
+ Optional<TypedDeclarationSpec> declarationSpec = context.getTypedDeclarationById(expression);
if (declarationSpec.isPresent()) {
return new SingleDrlxParseSuccess(patternType, bindingId, context.getVarExpr(printNode(drlxExpr)), declarationSpec.get().getDeclarationClass() ).setIsPredicate(true);
} else {
@@ -800,10 +800,10 @@ public class ConstraintParser {
private boolean hasDeclarationFromOtherPattern(ExpressionTyperContext expressionTyperContext) {
return expressionTyperContext.getUsedDeclarations()
.stream()
- .map(context::getDeclarationById)
+ .map(context::getTypedDeclarationById)
.anyMatch(optDecl -> {
if (optDecl.isPresent()) {
- DeclarationSpec decl = optDecl.get();
+ TypedDeclarationSpec decl = optDecl.get();
if (!decl.isGlobal() && decl.getBelongingPatternDescr() != context.getCurrentPatternDescr()) {
return true;
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expression/AbstractExpressionBuilder.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expression/AbstractExpressionBuilder.java
index 0bd0ebcb8a..8c071c0d43 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expression/AbstractExpressionBuilder.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expression/AbstractExpressionBuilder.java
@@ -184,7 +184,7 @@ public abstract class AbstractExpressionBuilder {
return false;
}
return usedDeclarations.stream()
- .map( context::getDeclarationById )
+ .map( context::getTypedDeclarationById)
.noneMatch(optDecl -> optDecl.isPresent() && optDecl.get().isGlobal() );
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
index 8fdfb696c4..2aad35aba3 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/expressiontyper/ExpressionTyper.java
@@ -65,7 +65,7 @@ import com.github.javaparser.ast.type.ReferenceType;
import com.github.javaparser.ast.type.Type;
import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
import org.drools.model.codegen.execmodel.errors.ParseExpressionErrorResult;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.ModelGenerator;
import org.drools.model.codegen.execmodel.generator.RuleContext;
@@ -450,7 +450,7 @@ public class ExpressionTyper {
return of(new TypedExpression(plusThis, expression.getType(), name));
}
- Optional<DeclarationSpec> decl = ruleContext.getDeclarationById(name);
+ Optional<TypedDeclarationSpec> decl = ruleContext.getTypedDeclarationById(name);
if (decl.isPresent()) {
// then drlxExpr is a single NameExpr referring to a binding, e.g.: "$p1".
context.addUsedDeclarations(name);
@@ -535,7 +535,7 @@ public class ExpressionTyper {
if (originalTypeCursor != null && originalTypeCursor.equals(Object.class)) {
// try infer type from the declarations
- final Optional<DeclarationSpec> declarationById = ruleContext.getDeclarationById(printNode(firstChild));
+ final Optional<TypedDeclarationSpec> declarationById = ruleContext.getTypedDeclarationById(printNode(firstChild));
originalTypeCursor = declarationById.map(d -> (java.lang.reflect.Type)d.getDeclarationClass()).orElse(originalTypeCursor);
}
@@ -641,7 +641,7 @@ public class ExpressionTyper {
}
} else if (arg instanceof NameExpr) {
String name = ((NameExpr) arg).getNameAsString();
- ruleContext.getDeclarationById(name)
+ ruleContext.getTypedDeclarationById(name)
.filter(decl -> decl.getBelongingPatternDescr().isPresent())
.filter(decl -> {
if (decl.getBelongingPatternDescr().equals(ruleContext.getCurrentPatternDescr())) {
@@ -713,7 +713,7 @@ public class ExpressionTyper {
} else if (firstNode instanceof MethodCallExpr) {
Optional<Expression> scopeExpr = ((MethodCallExpr) firstNode).getScope();
- Optional<DeclarationSpec> scopeDecl = scopeExpr.flatMap( scope -> ruleContext.getDeclarationById(PrintUtil.printNode(scope) ) );
+ Optional<TypedDeclarationSpec> scopeDecl = scopeExpr.flatMap(scope -> ruleContext.getTypedDeclarationById(PrintUtil.printNode(scope) ) );
Expression scope;
java.lang.reflect.Type type;
@@ -751,7 +751,7 @@ public class ExpressionTyper {
result = of( binaryExpr( ( BinaryExpr ) firstNode ));
} else if (firstNode instanceof ArrayAccessExpr) {
- Optional<DeclarationSpec> scopeDecl = ruleContext.getDeclarationById( ((ArrayAccessExpr) firstNode).getName().toString() );
+ Optional<TypedDeclarationSpec> scopeDecl = ruleContext.getTypedDeclarationById(((ArrayAccessExpr) firstNode).getName().toString() );
Expression scope;
java.lang.reflect.Type type;
@@ -1127,10 +1127,10 @@ public class ExpressionTyper {
// In OOPath a declaration is based on a position rather than a name.
// Only an OOPath chunk can have a backreference expression
- Optional<DeclarationSpec> backReference = empty();
+ Optional<TypedDeclarationSpec> backReference = empty();
if ( firstNode.getBackReferencesCount() > 0) {
- List<DeclarationSpec> ooPathDeclarations = ruleContext.getOOPathDeclarations();
- DeclarationSpec backReferenceDeclaration = ooPathDeclarations.get(ooPathDeclarations.size() - 1 - firstNode.getBackReferencesCount());
+ List<TypedDeclarationSpec> ooPathDeclarations = ruleContext.getOOPathDeclarations();
+ TypedDeclarationSpec backReferenceDeclaration = ooPathDeclarations.get(ooPathDeclarations.size() - 1 - firstNode.getBackReferencesCount());
typeCursor = backReferenceDeclaration.getDeclarationClass();
backReference = of(backReferenceDeclaration);
context.addUsedDeclarations(backReferenceDeclaration.getBindingId());
@@ -1181,7 +1181,7 @@ public class ExpressionTyper {
}
}
- Optional<DeclarationSpec> declarationById = ruleContext.getDeclarationById(firstName);
+ Optional<TypedDeclarationSpec> declarationById = ruleContext.getTypedDeclarationById(firstName);
if (declarationById.isPresent()) {
// do NOT append any reactOnProperties.
// because reactOnProperties is referring only to the properties of the type of the pattern, not other declarations properites.
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/FromVisitor.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/FromVisitor.java
index 0e04eacedd..56ac90e42f 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/FromVisitor.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/FromVisitor.java
@@ -37,7 +37,7 @@ import com.github.javaparser.ast.stmt.ExpressionStmt;
import org.drools.drl.ast.descr.FromDescr;
import org.drools.drl.ast.descr.PatternSourceDescr;
import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.RuleContext;
import org.drools.model.codegen.execmodel.generator.TypedExpression;
@@ -121,7 +121,7 @@ public class FromVisitor {
if (isEnumeratedList( expr )) {
asListCall.addArgument( createListForLiteralFrom( expr.substring( 1, expr.length()-1 ), fromCall, usedDeclarations ) );
} else {
- Optional<DeclarationSpec> optContainsBinding = context.getDeclarationById( expr );
+ Optional<TypedDeclarationSpec> optContainsBinding = context.getTypedDeclarationById(expr );
if ( optContainsBinding.isPresent() ) {
String bindingId = optContainsBinding.get().getBindingId();
fromCall.addArgument( context.getVarExpr( bindingId ) );
@@ -269,7 +269,7 @@ public class FromVisitor {
private Expression createArg(String expression, String bindingId, MethodCallExpr fromCall) {
if (bindingId != null) {
- DeclarationSpec declarationSpec = context.getDeclarationById( bindingId ).orElseThrow( RuntimeException::new );
+ TypedDeclarationSpec declarationSpec = context.getTypedDeclarationById(bindingId ).orElseThrow(RuntimeException::new );
Class<?> clazz = declarationSpec.getDeclarationClass();
DrlxParseResult drlxParseResult = ConstraintParser.withoutVariableValidationConstraintParser(context, context.getPackageModel())
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateInline.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateInline.java
index 2034e4220c..d6a111d1ca 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateInline.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateInline.java
@@ -55,7 +55,7 @@ import org.drools.drl.ast.descr.FromDescr;
import org.drools.drl.ast.descr.PatternDescr;
import org.drools.drl.ast.descr.PatternSourceDescr;
import org.drools.model.codegen.execmodel.PackageModel;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.RuleContext;
import org.drools.modelcompiler.util.StringUtil;
@@ -86,7 +86,7 @@ public class AccumulateInline {
private ClassOrInterfaceDeclaration contextData;
private String accumulateInlineClassName;
- private final List<DeclarationSpec> accumulateDeclarations = new ArrayList<>();
+ private final List<TypedDeclarationSpec> accumulateDeclarations = new ArrayList<>();
private final List<String> contextFieldNames = new ArrayList<>();
private Set<String> usedExternalDeclarations = new HashSet<>();
private Type singleAccumulateType;
@@ -130,7 +130,7 @@ public class AccumulateInline {
throw new UnsupportedInlineAccumulate();
}
- for (DeclarationSpec d : accumulateDeclarations) {
+ for (TypedDeclarationSpec d : accumulateDeclarations) {
context.addDeclaration(d);
}
@@ -202,7 +202,7 @@ public class AccumulateInline {
initMethodBody.addStatement(initStmt);
initStmt.findAll(NameExpr.class).stream().map(Node::toString).filter(context::hasDeclaration).forEach(usedExternalDeclarations::add);
});
- accumulateDeclarations.add(new DeclarationSpec(variableName, DrlxParseUtil.getClassFromContext(context.getTypeResolver(), vd.getType().asString())));
+ accumulateDeclarations.add(new TypedDeclarationSpec(variableName, DrlxParseUtil.getClassFromContext(context.getTypeResolver(), vd.getType().asString())));
}
}
}
@@ -237,7 +237,7 @@ public class AccumulateInline {
String nameExpr = allNamesInActionBlock.iterator().next();
accumulateMethod.getParameter(1).setName(nameExpr);
singleAccumulateType =
- context.getDeclarationById(nameExpr)
+ context.getTypedDeclarationById(nameExpr)
.orElseThrow(() -> new IllegalStateException("Cannot find declaration by name " + nameExpr + "!"))
.getBoxedType();
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateVisitor.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateVisitor.java
index 7b202abedb..773bcc19a3 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateVisitor.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/AccumulateVisitor.java
@@ -18,6 +18,15 @@
*/
package org.drools.model.codegen.execmodel.generator.visitor.accumulate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.Parameter;
@@ -29,7 +38,6 @@ import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.MethodReferenceExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
-import com.github.javaparser.ast.expr.StringLiteralExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
@@ -47,6 +55,7 @@ import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.RuleContext;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.TypedExpression;
import org.drools.model.codegen.execmodel.generator.drlxparse.ConstraintParser;
import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseFail;
@@ -65,15 +74,6 @@ import org.drools.mvel.parser.ast.expr.DrlNameExpr;
import org.kie.api.runtime.rule.AccumulateFunction;
import org.kie.internal.builder.conf.AccumulateFunctionOption;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;
import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.getLiteralExpressionType;
@@ -237,7 +237,7 @@ public class AccumulateVisitor {
private void nameExprParameter(PatternDescr basePattern, AccumulateDescr.AccumulateFunctionCallDescr function, MethodCallExpr functionDSL, String bindingId, Expression accumulateFunctionParameter) {
String nameExpr = ((DrlNameExpr) accumulateFunctionParameter).getName().asString();
- Optional<DeclarationSpec> declaration = context.getDeclarationById(nameExpr);
+ Optional<DeclarationSpec> declaration = context.getTypedDeclarationById(nameExpr).map(DeclarationSpec.class::cast);
if (declaration.isEmpty()) {
String name = nameExpr;
declaration = context.getAllDeclarations().stream().filter( d -> d.getVariableName().map( n -> n.equals( name ) ).orElse( false ) ).findFirst();
@@ -271,9 +271,9 @@ public class AccumulateVisitor {
final DrlxParseUtil.RemoveRootNodeResult methodCallWithoutRootNode = DrlxParseUtil.removeRootNode(parameterConverted);
String rootNodeName = getRootNodeName(methodCallWithoutRootNode);
- Optional<DeclarationSpec> decl = context.getDeclarationById(rootNodeName);
+ Optional<TypedDeclarationSpec> decl = context.getTypedDeclarationById(rootNodeName);
- Class<?> clazz = decl.map(DeclarationSpec::getDeclarationClass)
+ Class<?> clazz = decl.map(TypedDeclarationSpec::getDeclarationClass)
.orElseGet( () -> {
try {
return context.getTypeResolver().resolveType(rootNodeName);
@@ -307,7 +307,7 @@ public class AccumulateVisitor {
PatternDescr inputPattern = decl.isPresent() ? null : findInputPattern(input);
if (inputPattern != null) {
String inputId = inputPattern.getIdentifier();
- Optional<DeclarationSpec> accumulateClassDeclOpt = context.getDeclarationById(inputId);
+ Optional<TypedDeclarationSpec> accumulateClassDeclOpt = context.getTypedDeclarationById(inputId);
if (accumulateClassDeclOpt.isPresent()) {
// when static method is used in accumulate function, "_this" is a pattern input
// Note that DrlxParseUtil.generateLambdaWithoutParameters() takes the patternType as a class of "_this"
@@ -364,10 +364,10 @@ public class AccumulateVisitor {
SingleDrlxParseSuccess singleResult = drlxParseResult;
singleResult.setExprBinding(bindExpressionVariable);
final MethodCallExpr binding = expressionBuilder.buildBinding(singleResult);
- context.addDeclarationReplacing(new DeclarationSpec(bindExpressionVariable, methodCallExprType));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(bindExpressionVariable, methodCallExprType));
functionDSL.addArgument(context.getVarExpr(bindExpressionVariable));
- context.addDeclarationReplacing(new DeclarationSpec(bindingId, accumulateFunctionResultType));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(bindingId, accumulateFunctionResultType));
context.getExpressions().forEach(expression -> replaceTypeInExprLambdaAndIndex(bindingId, accumulateFunctionResultType, expression));
@@ -421,12 +421,12 @@ public class AccumulateVisitor {
singleResult.setExprBinding(bindExpressionVariable);
- context.addDeclarationReplacing(new DeclarationSpec(singleResult.getPatternBinding(), exprRawClass));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(singleResult.getPatternBinding(), exprRawClass));
context.getExpressions().forEach(expression -> replaceTypeInExprLambdaAndIndex(bindingId, exprRawClass, expression));
functionDSL.addArgument(createAccSupplierExpr(accumulateFunction));
final MethodCallExpr newBindingFromBinary = AccumulateVisitor.this.buildBinding(bindExpressionVariable, singleResult.getUsedDeclarations(), singleResult.getExpr());
- context.addDeclarationReplacing(new DeclarationSpec(bindExpressionVariable, exprRawClass));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(bindExpressionVariable, exprRawClass));
functionDSL.addArgument(context.getVarExpr(bindExpressionVariable));
return Optional.of(new NewBinding(Collections.emptyList(), newBindingFromBinary));
}
@@ -443,7 +443,7 @@ public class AccumulateVisitor {
validateAccFunctionTypeAgainstPatternType(context, basePattern, accumulateFunction);
functionDSL.addArgument(createAccSupplierExpr(accumulateFunction));
Class accumulateFunctionResultType = accumulateFunction.getResultType();
- context.addDeclarationReplacing(new DeclarationSpec(bindingId, accumulateFunctionResultType));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(bindingId, accumulateFunctionResultType));
context.getExpressions().forEach(expression -> replaceTypeInExprLambdaAndIndex(bindingId, accumulateFunctionResultType, expression));
}
@@ -485,7 +485,7 @@ public class AccumulateVisitor {
private void addBindingAsDeclaration(RuleContext context, String bindingId, Class accumulateFunctionResultType) {
if (bindingId != null) {
- context.addDeclarationReplacing(new DeclarationSpec(bindingId, accumulateFunctionResultType));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(bindingId, accumulateFunctionResultType));
if (context.getExpressions().size() > 1) {
// replace the type of the lambda with the one resulting from the accumulate operation only in the pattern immediately before it
replaceTypeInExprLambdaAndIndex(bindingId, accumulateFunctionResultType, context.getExpressions().get(context.getExpressions().size()-2));
@@ -530,7 +530,7 @@ public class AccumulateVisitor {
static List<String> collectNamesInBlock(BlockStmt block, RuleContext context) {
return block.findAll(NameExpr.class, n -> {
- Optional<DeclarationSpec> optD = context.getDeclarationById(n.getNameAsString());
+ Optional<TypedDeclarationSpec> optD = context.getTypedDeclarationById(n.getNameAsString());
return optD.filter(d -> !d.isGlobal()).isPresent(); // Global aren't supported
})
.stream()
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/GroupByVisitor.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/GroupByVisitor.java
index c093a232fa..67e0392e89 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/GroupByVisitor.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/GroupByVisitor.java
@@ -26,7 +26,7 @@ import org.drools.drl.ast.descr.GroupByDescr;
import org.drools.drl.ast.descr.PatternDescr;
import org.drools.model.codegen.execmodel.PackageModel;
import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.RuleContext;
import org.drools.model.codegen.execmodel.generator.TypedExpression;
import org.drools.model.codegen.execmodel.generator.expressiontyper.ExpressionTyper;
@@ -65,7 +65,7 @@ public class GroupByVisitor extends AccumulateVisitor {
TypedExpression typedExpression = optResult.get();
String groupingKey = groupByDescr.getGroupingKey() != null ? groupByDescr.getGroupingKey() : generateUUID();
- context.addDeclarationReplacing(new DeclarationSpec(groupingKey, typedExpression.getRawClass()));
+ context.addDeclarationReplacing(new TypedDeclarationSpec(groupingKey, typedExpression.getRawClass()));
accumulateDSL.addArgument(toVar(groupingKey));
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/LegacyAccumulate.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/LegacyAccumulate.java
index 212d1c0f70..94ebb85469 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/LegacyAccumulate.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/accumulate/LegacyAccumulate.java
@@ -230,7 +230,7 @@ public class LegacyAccumulate {
public Map<String, Declaration> getDeclarations( RuleImpl rule ) {
Map<String, Declaration> declarationMap = new HashMap<>();
for (String externalDeclr : externalDeclrs) {
- context.getDeclarationById( externalDeclr ).ifPresent( dSpec -> declarationMap.put(externalDeclr, dSpec.asDeclaration()) );
+ context.getTypedDeclarationById(externalDeclr ).ifPresent(dSpec -> declarationMap.put(externalDeclr, dSpec.asDeclaration()) );
}
declarationMap.putAll( delegate.getDeclarations( rule ) );
return declarationMap;
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
similarity index 72%
copy from drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java
copy to drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
index 6e1ec9d698..31ef46b782 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ClassPatternDSL.java
@@ -18,13 +18,21 @@
*/
package org.drools.model.codegen.execmodel.generator.visitor.pattern;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.Collectors;
+
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
import org.drools.base.util.PropertyReactivityUtil;
import org.drools.compiler.compiler.DescrBuildError;
-import org.drools.drl.ast.descr.AccumulateDescr;
import org.drools.drl.ast.descr.BaseDescr;
-import org.drools.drl.ast.descr.ExprConstraintDescr;
import org.drools.drl.ast.descr.PatternDescr;
import org.drools.drl.ast.descr.PatternSourceDescr;
import org.drools.model.codegen.execmodel.PackageModel;
@@ -34,6 +42,7 @@ import org.drools.model.codegen.execmodel.generator.ConstraintUtil;
import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.RuleContext;
+import org.drools.model.codegen.execmodel.generator.TypedDeclarationSpec;
import org.drools.model.codegen.execmodel.generator.WindowReferenceGenerator;
import org.drools.model.codegen.execmodel.generator.drlxparse.ConstraintExpression;
import org.drools.model.codegen.execmodel.generator.drlxparse.ConstraintParser;
@@ -47,51 +56,91 @@ import org.drools.model.codegen.execmodel.generator.visitor.DSLNode;
import org.drools.model.codegen.execmodel.generator.visitor.FromVisitor;
import org.kie.api.definition.rule.Watch;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
import static org.drools.compiler.rule.builder.PatternBuilder.lookAheadFieldsOfIdentifier;
+import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.findLastMethodInChain;
+import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.findRootNodeViaScope;
import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.getPatternListenedProperties;
-import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.validateDuplicateBindings;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.NO_OP_EXPR;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PASSIVE_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PATTERN_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.WATCH_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.createDslTopLevelMethod;
import static org.drools.model.impl.NamesGenerator.generateName;
import static org.drools.model.impl.VariableImpl.GENERATED_VARIABLE_PREFIX;
import static org.drools.mvel.parser.printer.PrintUtil.printNode;
import static org.drools.util.StreamUtils.optionalToStream;
-public abstract class PatternDSL implements DSLNode {
+public class ClassPatternDSL extends PatternDSL {
- protected final RuleContext context;
- protected final PackageModel packageModel;
- protected final PatternDescr pattern;
- private final List<? extends BaseDescr> constraintDescrs;
- protected Class<?> patternType;
+ private Class<?> patternType;
- PatternDSL(RuleContext context, PackageModel packageModel, PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
- this.context = context;
- this.packageModel = packageModel;
- this.pattern = pattern;
- this.constraintDescrs = constraintDescrs;
+ ClassPatternDSL(RuleContext context, PackageModel packageModel, PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
+ super(context, packageModel, pattern, constraintDescrs);
this.patternType = patternType;
}
+ @Override
+ protected String getPatternTypeName() {
+ return patternType.getSimpleName();
+ }
+
+ @Override
+ protected Class<?> getPatternType() {
+ return patternType;
+ }
+
+ @Override
public DeclarationSpec initPattern() {
generatePatternIdentifierIfMissing();
context.addPatternBinding(pattern.getIdentifier());
final Optional<Expression> declarationSource = buildFromDeclaration(pattern);
- return context.addDeclaration(pattern.getIdentifier(), patternType, Optional.of(pattern), declarationSource);
+ return context.addDeclaration(pattern.getIdentifier(), getPatternType(), Optional.of(pattern), declarationSource);
}
- private static boolean isPositional(BaseDescr constraint) {
- return constraint instanceof ExprConstraintDescr &&
- ((ExprConstraintDescr) constraint).getType() == ExprConstraintDescr.Type.POSITIONAL &&
- !constraint.getText().contains( ":=" );
+ @Override
+ protected void buildPattern(DeclarationSpec declarationSpec, List<PatternConstraintParseResult> patternConstraintParseResults) {
+ MethodCallExpr patternExpression = createPatternExpression(pattern, (TypedDeclarationSpec) declarationSpec);
+
+ List<Expression> exprs = new ArrayList<>();
+ context.pushExprPointer(exprs::add);
+ buildConstraints(pattern, patternType, patternConstraintParseResults);
+ context.popExprPointer();
+
+ List<Expression> additionalPatterns = new ArrayList<>();
+ for (Expression expr : exprs) {
+ Optional<Expression> rootScope = findRootNodeViaScope(expr );
+ if ( rootScope.isPresent() && (( MethodCallExpr ) rootScope.get()).getNameAsString().equals( PATTERN_CALL ) ) {
+ additionalPatterns.add( expr );
+ } else {
+ MethodCallExpr currentExpr = ( MethodCallExpr ) expr;
+ MethodCallExpr lastMethodInChain = findLastMethodInChain(currentExpr);
+ if (!NO_OP_EXPR.equals(lastMethodInChain.getNameAsString())) {
+ lastMethodInChain.setScope(patternExpression);
+ patternExpression = currentExpr;
+ }
+ }
+ }
+
+ if (pattern.isQuery()) {
+ patternExpression = new MethodCallExpr( patternExpression, PASSIVE_CALL );
+ }
+
+ context.addExpression( addWatchToPattern( patternExpression ) );
+ additionalPatterns.forEach( context::addExpression );
+ }
+
+ protected void generatePatternIdentifierIfMissing() {
+ // the PatternDescr can be shared by multiple rules in case of rules inheritance, so its identifier has to
+ // be set atomically when rule generation is performed in parallel
+ synchronized (pattern) {
+ if (pattern.getIdentifier() == null) {
+ final String generatedName = generateName("pattern_" + getPatternTypeName());
+ final String patternNameAggregated = findFirstInnerBinding(constraintDescrs, patternType)
+ .map(ib -> context.getAggregatePatternMap().putIfAbsent(new AggregateKey(ib, getPatternTypeName()), generatedName))
+ .orElse(generatedName);
+ pattern.setIdentifier(GENERATED_VARIABLE_PREFIX + patternNameAggregated);
+ }
+ }
}
private Optional<Expression> buildFromDeclaration(PatternDescr pattern) {
@@ -108,20 +157,6 @@ public abstract class PatternDSL implements DSLNode {
return source.flatMap(sourceDescr -> new WindowReferenceGenerator(packageModel, context.getTypeResolver()).visit(sourceDescr, context));
}
- private void generatePatternIdentifierIfMissing() {
- // the PatternDescr can be shared by multiple rules in case of rules inheritance, so its identifier has to
- // be set atomically when rule generation is performed in parallel
- synchronized (pattern) {
- if (pattern.getIdentifier() == null) {
- final String generatedName = generateName("pattern_" + patternType.getSimpleName());
- final String patternNameAggregated = findFirstInnerBinding(constraintDescrs, patternType)
- .map(ib -> context.getAggregatePatternMap().putIfAbsent(new AggregateKey(ib, patternType), generatedName))
- .orElse(generatedName);
- pattern.setIdentifier(GENERATED_VARIABLE_PREFIX + patternNameAggregated);
- }
- }
- }
-
private Optional<String> findFirstInnerBinding(List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
return constraintDescrs.stream()
.map( constraint -> ConstraintExpression.createConstraintExpression( context, patternType, constraint, isPositional(constraint) ).getExpression() )
@@ -131,7 +166,8 @@ public abstract class PatternDSL implements DSLNode {
.findFirst();
}
- private List<PatternConstraintParseResult> findAllConstraint(PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
+ @Override
+ protected List<PatternConstraintParseResult> findAllConstraint(PatternDescr pattern, List<? extends BaseDescr> constraintDescrs) {
ConstraintParser constraintParser = ConstraintParser.defaultConstraintParser(context, packageModel);
List<PatternConstraintParseResult> patternConstraintParseResults = new ArrayList<>();
@@ -181,7 +217,7 @@ public abstract class PatternDSL implements DSLNode {
private void addImplicitCastExpr(ConstraintParser constraintParser, String patternIdentifier, List<PatternConstraintParseResult> patternConstraintParseResults) {
final boolean hasInstanceOfExpr = patternConstraintParseResults.stream()
- .anyMatch(r -> r.getDrlxParseResult().acceptWithReturnValue(new ParseResultVisitor<>() {
+ .anyMatch(r -> r.drlxParseResult().acceptWithReturnValue(new ParseResultVisitor<>() {
@Override
public Boolean onSuccess(DrlxParseSuccess t) {
Expression expr = t.getExpr();
@@ -196,7 +232,7 @@ public abstract class PatternDSL implements DSLNode {
final Optional<Expression> implicitCastExpression =
patternConstraintParseResults.stream()
- .flatMap(r -> optionalToStream(r.getDrlxParseResult().acceptWithReturnValue(new ParseResultVisitor<Optional<Expression>>() {
+ .flatMap(r -> optionalToStream(r.drlxParseResult().acceptWithReturnValue(new ParseResultVisitor<Optional<Expression>>() {
@Override
public Optional<Expression> onSuccess(DrlxParseSuccess t) {
return t.getImplicitCastExpression();
@@ -221,7 +257,7 @@ public abstract class PatternDSL implements DSLNode {
private void addNullSafeExpr(ConstraintParser constraintParser, String patternIdentifier, List<PatternConstraintParseResult> patternConstraintParseResults) {
final List<Expression> nullSafeExpressions =
patternConstraintParseResults.stream()
- .flatMap(r -> r.getDrlxParseResult().acceptWithReturnValue(new ParseResultVisitor<List<Expression>>() {
+ .flatMap(r -> r.drlxParseResult().acceptWithReturnValue(new ParseResultVisitor<List<Expression>>() {
@Override
public List<Expression> onSuccess(DrlxParseSuccess t) {
@@ -252,8 +288,8 @@ public abstract class PatternDSL implements DSLNode {
return newNullSafeExpressions;
}
- void buildConstraint(PatternDescr pattern, Class<?> patternType, PatternConstraintParseResult patternConstraintParseResult) {
- DrlxParseResult drlxParseResult = patternConstraintParseResult.getDrlxParseResult();
+ private void buildConstraint(PatternDescr pattern, Class<?> patternType, PatternConstraintParseResult patternConstraintParseResult) {
+ DrlxParseResult drlxParseResult = patternConstraintParseResult.drlxParseResult();
DrlxParseResult withBindingCheck = drlxParseResult.acceptWithReturnValue(new ParseResultVisitor<>() {
@Override
@@ -300,34 +336,7 @@ public abstract class PatternDSL implements DSLNode {
}
}
- @Override
- public void buildPattern() {
- try {
- context.setCurrentPatternDescr(Optional.of(pattern));
- DeclarationSpec declarationSpec = initPattern();
-
- if (constraintDescrs.isEmpty() && !(pattern.getSource() instanceof AccumulateDescr)) {
- context.addExpression(input(declarationSpec));
- } else {
- final List<PatternConstraintParseResult> patternConstraintParseResults = findAllConstraint(pattern, constraintDescrs, patternType);
- final List<String> allBindings = patternConstraintParseResults
- .stream()
- .map(p -> p.getDrlxParseResult().acceptWithReturnValue( DrlxParseSuccess::getExprBinding ))
- .filter(Objects::nonNull)
- .collect(Collectors.toList());
-
- validateDuplicateBindings(context.getRuleName(), allBindings).ifPresent(context::addCompilationError);
-
- if (!context.hasErrors()) {
- buildPattern(declarationSpec, patternConstraintParseResults);
- }
- }
- } finally {
- context.resetCurrentPatternDescr();
- }
- }
-
- Set<String> getSettableWatchedProps() {
+ private Set<String> getSettableWatchedProps() {
Set<String> settableWatchedProps = new HashSet<>();
Collection<String> settableProps = PropertyReactivityUtil.getAccessibleProperties(patternType);
@@ -360,9 +369,54 @@ public abstract class PatternDSL implements DSLNode {
}
}
- protected abstract void buildPattern(DeclarationSpec declarationSpec, List<PatternConstraintParseResult> patternConstraintParseResults);
+ @Override
+ protected MethodCallExpr input(DeclarationSpec declarationSpec) {
+ return addWatchToPattern( createPatternExpression(pattern, (TypedDeclarationSpec) declarationSpec) );
+ }
- protected abstract MethodCallExpr input(DeclarationSpec declarationSpec);
+ private MethodCallExpr addWatchToPattern( MethodCallExpr patternExpression ) {
+ Set<String> settableWatchedProps = getSettableWatchedProps();
+ if ( !settableWatchedProps.isEmpty() ) {
+ if (context.isPropertyReactive(patternType)) {
+ patternExpression = new MethodCallExpr(patternExpression, WATCH_CALL);
+ settableWatchedProps.stream().map(StringLiteralExpr::new).forEach(patternExpression::addArgument);
+ } else {
+ context.addCompilationError(new InvalidExpressionErrorResult("Wrong usage of @" + Watch.class.getSimpleName() + " annotation on class " + patternType.getName() + " that is not annotated as @PropertyReactive"));
+ }
+ }
+ return patternExpression;
+ }
- protected abstract DSLNode createSimpleConstraint( DrlxParseSuccess drlxParseResult, PatternDescr pattern );
+ private MethodCallExpr createPatternExpression(PatternDescr pattern, TypedDeclarationSpec declarationSpec) {
+ MethodCallExpr dslExpr = createDslTopLevelMethod(PATTERN_CALL);
+ dslExpr.addArgument( context.getVarExpr( pattern.getIdentifier()) );
+ if (context.isQuery()) {
+ Optional<Expression> declarationSource = declarationSpec.getDeclarationSource();
+ declarationSource.ifPresent(dslExpr::addArgument);
+ }
+ return dslExpr;
+ }
+
+ private void buildConstraints(PatternDescr pattern, Class<?> patternType, List<PatternConstraintParseResult> patternConstraintParseResults) {
+ boolean hasOOPath = false;
+ for (PatternConstraintParseResult patternConstraintParseResult : patternConstraintParseResults) {
+ // only one oopath per pattern is allowed
+ if (patternConstraintParseResult.drlxParseResult().isOOPath()) {
+ if (hasOOPath) {
+ context.addCompilationError(new InvalidExpressionErrorResult("Only one oopath per pattern is allowed"));
+ break;
+ } else {
+ hasOOPath = true;
+ }
+ }
+ buildConstraint(pattern, patternType, patternConstraintParseResult);
+ }
+ if (hasOOPath) {
+ context.clearOOPathPatternExpr();
+ }
+ }
+
+ private DSLNode createSimpleConstraint( DrlxParseSuccess drlxParseResult, PatternDescr pattern ) {
+ return new PatternDSLSimpleConstraint( context, pattern, drlxParseResult );
+ }
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ConstraintOOPath.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ConstraintOOPath.java
index 984fe1a948..61cbbf7c97 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ConstraintOOPath.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/ConstraintOOPath.java
@@ -43,7 +43,7 @@ class ConstraintOOPath implements DSLNode {
this.pattern = pattern;
this.patternType = patternType;
this.patternConstraintParseResult = patternConstraintParseResult;
- this.expression = patternConstraintParseResult.getExpression();
+ this.expression = patternConstraintParseResult.expression();
this.drlxParseResult = drlxParseResult;
}
@@ -51,8 +51,8 @@ class ConstraintOOPath implements DSLNode {
public void buildPattern() {
final String patternIdentifierGenerated;
// If the outer pattern does not have a binding we generate it
- if (patternConstraintParseResult.getPatternIdentifier() != null) {
- patternIdentifierGenerated = patternConstraintParseResult.getPatternIdentifier();
+ if (patternConstraintParseResult.patternIdentifier() != null) {
+ patternIdentifierGenerated = patternConstraintParseResult.patternIdentifier();
} else {
patternIdentifierGenerated = context.getExprId(patternType, expression);
context.addDeclaration(patternIdentifierGenerated, patternType, Optional.of(pattern), Optional.empty());
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
index 31739dbcb1..448c96dfe4 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternAccumulateConstraint.java
@@ -68,7 +68,7 @@ class PatternAccumulateConstraint implements DSLNode {
constraintsByVar.forEach( (id, constraints) -> {
pattern.setIdentifier(id);
- new PatternDSLPattern(context, packageModel, pattern, constraints, null).buildPattern();
+ new ClassPatternDSL(context, packageModel, pattern, constraints, null).buildPattern();
});
pattern.setIdentifier(null);
}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternConstraintParseResult.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternConstraintParseResult.java
index 1af3b3396c..82aee014a0 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternConstraintParseResult.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternConstraintParseResult.java
@@ -20,26 +20,4 @@ package org.drools.model.codegen.execmodel.generator.visitor.pattern;
import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseResult;
-public class PatternConstraintParseResult {
- private String expression;
- private String patternIdentifier;
- private DrlxParseResult drlxParseResult;
-
- public PatternConstraintParseResult(String expression, String patternIdentifier, DrlxParseResult drlxParseResult) {
- this.expression = expression;
- this.patternIdentifier = patternIdentifier;
- this.drlxParseResult = drlxParseResult;
- }
-
- public String getExpression() {
- return expression;
- }
-
- public String getPatternIdentifier() {
- return patternIdentifier;
- }
-
- public DrlxParseResult getDrlxParseResult() {
- return drlxParseResult;
- }
-}
+public record PatternConstraintParseResult(String expression, String patternIdentifier, DrlxParseResult drlxParseResult) { }
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java
index 6e1ec9d698..de1f4f6646 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSL.java
@@ -18,286 +18,36 @@
*/
package org.drools.model.codegen.execmodel.generator.visitor.pattern;
-import com.github.javaparser.ast.expr.Expression;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
import com.github.javaparser.ast.expr.MethodCallExpr;
-import org.drools.base.util.PropertyReactivityUtil;
-import org.drools.compiler.compiler.DescrBuildError;
import org.drools.drl.ast.descr.AccumulateDescr;
import org.drools.drl.ast.descr.BaseDescr;
import org.drools.drl.ast.descr.ExprConstraintDescr;
import org.drools.drl.ast.descr.PatternDescr;
-import org.drools.drl.ast.descr.PatternSourceDescr;
import org.drools.model.codegen.execmodel.PackageModel;
-import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
-import org.drools.model.codegen.execmodel.generator.AggregateKey;
-import org.drools.model.codegen.execmodel.generator.ConstraintUtil;
import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
-import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
import org.drools.model.codegen.execmodel.generator.RuleContext;
-import org.drools.model.codegen.execmodel.generator.WindowReferenceGenerator;
-import org.drools.model.codegen.execmodel.generator.drlxparse.ConstraintExpression;
-import org.drools.model.codegen.execmodel.generator.drlxparse.ConstraintParser;
-import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseFail;
-import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseResult;
import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseSuccess;
-import org.drools.model.codegen.execmodel.generator.drlxparse.ParseResultVisitor;
-import org.drools.model.codegen.execmodel.generator.drlxparse.ParseResultVoidVisitor;
-import org.drools.model.codegen.execmodel.generator.drlxparse.SingleDrlxParseSuccess;
import org.drools.model.codegen.execmodel.generator.visitor.DSLNode;
-import org.drools.model.codegen.execmodel.generator.visitor.FromVisitor;
-import org.kie.api.definition.rule.Watch;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static org.drools.compiler.rule.builder.PatternBuilder.lookAheadFieldsOfIdentifier;
-import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.getPatternListenedProperties;
import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.validateDuplicateBindings;
-import static org.drools.model.impl.NamesGenerator.generateName;
-import static org.drools.model.impl.VariableImpl.GENERATED_VARIABLE_PREFIX;
-import static org.drools.mvel.parser.printer.PrintUtil.printNode;
-import static org.drools.util.StreamUtils.optionalToStream;
public abstract class PatternDSL implements DSLNode {
protected final RuleContext context;
protected final PackageModel packageModel;
protected final PatternDescr pattern;
- private final List<? extends BaseDescr> constraintDescrs;
- protected Class<?> patternType;
+ protected final List<? extends BaseDescr> constraintDescrs;
- PatternDSL(RuleContext context, PackageModel packageModel, PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
+ PatternDSL(RuleContext context, PackageModel packageModel, PatternDescr pattern, List<? extends BaseDescr> constraintDescrs) {
this.context = context;
this.packageModel = packageModel;
this.pattern = pattern;
this.constraintDescrs = constraintDescrs;
- this.patternType = patternType;
- }
-
- public DeclarationSpec initPattern() {
- generatePatternIdentifierIfMissing();
- context.addPatternBinding(pattern.getIdentifier());
- final Optional<Expression> declarationSource = buildFromDeclaration(pattern);
- return context.addDeclaration(pattern.getIdentifier(), patternType, Optional.of(pattern), declarationSource);
- }
-
- private static boolean isPositional(BaseDescr constraint) {
- return constraint instanceof ExprConstraintDescr &&
- ((ExprConstraintDescr) constraint).getType() == ExprConstraintDescr.Type.POSITIONAL &&
- !constraint.getText().contains( ":=" );
- }
-
- private Optional<Expression> buildFromDeclaration(PatternDescr pattern) {
- Optional<PatternSourceDescr> source = Optional.ofNullable(pattern.getSource());
- try {
- patternType = context.getTypeResolver().resolveType( pattern.getObjectType() );
- } catch (ClassNotFoundException e) {
- throw new RuntimeException( e );
- }
- Optional<Expression> declarationSourceFrom = source.flatMap(new FromVisitor(context, patternType)::visit);
- if (declarationSourceFrom.isPresent()) {
- return declarationSourceFrom;
- }
- return source.flatMap(sourceDescr -> new WindowReferenceGenerator(packageModel, context.getTypeResolver()).visit(sourceDescr, context));
- }
-
- private void generatePatternIdentifierIfMissing() {
- // the PatternDescr can be shared by multiple rules in case of rules inheritance, so its identifier has to
- // be set atomically when rule generation is performed in parallel
- synchronized (pattern) {
- if (pattern.getIdentifier() == null) {
- final String generatedName = generateName("pattern_" + patternType.getSimpleName());
- final String patternNameAggregated = findFirstInnerBinding(constraintDescrs, patternType)
- .map(ib -> context.getAggregatePatternMap().putIfAbsent(new AggregateKey(ib, patternType), generatedName))
- .orElse(generatedName);
- pattern.setIdentifier(GENERATED_VARIABLE_PREFIX + patternNameAggregated);
- }
- }
- }
-
- private Optional<String> findFirstInnerBinding(List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
- return constraintDescrs.stream()
- .map( constraint -> ConstraintExpression.createConstraintExpression( context, patternType, constraint, isPositional(constraint) ).getExpression() )
- .map( DrlxParseUtil::parseExpression )
- .filter( drlx -> drlx.getBind() != null )
- .map( drlx -> drlx.getBind().asString() )
- .findFirst();
- }
-
- private List<PatternConstraintParseResult> findAllConstraint(PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
- ConstraintParser constraintParser = ConstraintParser.defaultConstraintParser(context, packageModel);
- List<PatternConstraintParseResult> patternConstraintParseResults = new ArrayList<>();
-
- for (BaseDescr constraint : constraintDescrs) {
- List<PatternConstraintParseResult> patternConstraintParseResultsPerConstraintDescr = new ArrayList<>();
- String patternIdentifier = pattern.getIdentifier();
-
- boolean isPositional = isPositional(constraint);
-
- ConstraintExpression constraintExpression = ConstraintExpression.createConstraintExpression(context, patternType, constraint, isPositional);
- if (constraintExpression == null) {
- continue;
- }
-
- DrlxParseResult drlxParseResult;
- try {
- context.setCurrentConstraintDescr(Optional.of(constraint));
- drlxParseResult = constraintParser.drlxParse(patternType, patternIdentifier, constraintExpression, isPositional);
- } finally {
- context.resetCurrentConstraintDescr();
- }
-
- String expression = constraintExpression.getExpression();
- if (drlxParseResult.isSuccess() && (( DrlxParseSuccess ) drlxParseResult).isRequiresSplit() && (( DrlxParseSuccess ) drlxParseResult).getExpr().isBinaryExpr()) {
- String leftExpression = printNode(((SingleDrlxParseSuccess) drlxParseResult).getLeft().getExpression());
- DrlxParseResult leftExpressionReparsed = constraintParser.drlxParse(patternType, patternIdentifier, leftExpression, isPositional);
- patternConstraintParseResultsPerConstraintDescr.add(new PatternConstraintParseResult(leftExpression, patternIdentifier, leftExpressionReparsed));
-
- String rightExpression = printNode(((SingleDrlxParseSuccess) drlxParseResult).getRight().getExpression());
- DrlxParseResult rightExpressionReparsed = constraintParser.drlxParse(patternType, patternIdentifier, rightExpression, isPositional);
- DrlxParseResult normalizedParseResult = ConstraintUtil.normalizeConstraint(rightExpressionReparsed);
- patternConstraintParseResultsPerConstraintDescr.add(new PatternConstraintParseResult(rightExpression, patternIdentifier, normalizedParseResult));
- } else {
- DrlxParseResult normalizedParseResult = ConstraintUtil.normalizeConstraint(drlxParseResult);
- patternConstraintParseResultsPerConstraintDescr.add(new PatternConstraintParseResult(expression, patternIdentifier, normalizedParseResult));
- }
-
- // Cast-check should be placed earlier than Null-check (calling the add method later means pushing the constraint earlier)
- addNullSafeExpr(constraintParser, pattern.getIdentifier(), patternConstraintParseResultsPerConstraintDescr);
- addImplicitCastExpr(constraintParser, pattern.getIdentifier(), patternConstraintParseResultsPerConstraintDescr);
-
- patternConstraintParseResults.addAll(patternConstraintParseResultsPerConstraintDescr);
- }
-
- return patternConstraintParseResults;
- }
-
- private void addImplicitCastExpr(ConstraintParser constraintParser, String patternIdentifier, List<PatternConstraintParseResult> patternConstraintParseResults) {
- final boolean hasInstanceOfExpr = patternConstraintParseResults.stream()
- .anyMatch(r -> r.getDrlxParseResult().acceptWithReturnValue(new ParseResultVisitor<>() {
- @Override
- public Boolean onSuccess(DrlxParseSuccess t) {
- Expression expr = t.getExpr();
- return expr != null && expr.isInstanceOfExpr();
- }
-
- @Override
- public Boolean onFail(DrlxParseFail failure) {
- return false;
- }
- }));
-
- final Optional<Expression> implicitCastExpression =
- patternConstraintParseResults.stream()
- .flatMap(r -> optionalToStream(r.getDrlxParseResult().acceptWithReturnValue(new ParseResultVisitor<Optional<Expression>>() {
- @Override
- public Optional<Expression> onSuccess(DrlxParseSuccess t) {
- return t.getImplicitCastExpression();
- }
-
- @Override
- public Optional<Expression> onFail(DrlxParseFail failure) {
- return Optional.empty();
- }
- })))
- .findFirst();
-
- implicitCastExpression.ifPresent(ce -> {
- if(!hasInstanceOfExpr) {
- String instanceOfExpression = printNode(ce);
- DrlxParseResult instanceOfExpressionParsed = constraintParser.drlxParse(patternType, patternIdentifier, instanceOfExpression, false);
- patternConstraintParseResults.add(0, new PatternConstraintParseResult(instanceOfExpression, patternIdentifier, instanceOfExpressionParsed));
- }
- });
- }
-
- private void addNullSafeExpr(ConstraintParser constraintParser, String patternIdentifier, List<PatternConstraintParseResult> patternConstraintParseResults) {
- final List<Expression> nullSafeExpressions =
- patternConstraintParseResults.stream()
- .flatMap(r -> r.getDrlxParseResult().acceptWithReturnValue(new ParseResultVisitor<List<Expression>>() {
-
- @Override
- public List<Expression> onSuccess(DrlxParseSuccess t) {
- return t.getNullSafeExpressions();
- }
-
- @Override
- public List<Expression> onFail(DrlxParseFail failure) {
- return Collections.emptyList();
- }
- }).stream())
- .collect(Collectors.toList());
-
- List<Expression> newNullSafeExpressions = reverseDistinct(nullSafeExpressions);
-
- newNullSafeExpressions.forEach(expr -> {
- String nullSafeExpression = printNode(expr);
- DrlxParseResult nullSafeExpressionParsed = constraintParser.drlxParse(patternType, patternIdentifier, nullSafeExpression, false);
- patternConstraintParseResults.add(0, new PatternConstraintParseResult(nullSafeExpression, patternIdentifier, nullSafeExpressionParsed));
- });
- }
-
- private List<Expression> reverseDistinct(List<Expression> nullSafeExpressions) {
- // distinct from the end of the list
- Collections.reverse(nullSafeExpressions);
- List<Expression> newNullSafeExpressions = nullSafeExpressions.stream().distinct().collect(Collectors.toList());
- Collections.reverse(newNullSafeExpressions);
- return newNullSafeExpressions;
- }
-
- void buildConstraint(PatternDescr pattern, Class<?> patternType, PatternConstraintParseResult patternConstraintParseResult) {
- DrlxParseResult drlxParseResult = patternConstraintParseResult.getDrlxParseResult();
-
- DrlxParseResult withBindingCheck = drlxParseResult.acceptWithReturnValue(new ParseResultVisitor<>() {
- @Override
- public DrlxParseResult onSuccess(DrlxParseSuccess drlxParseResult) {
-
- String exprBinding = drlxParseResult.getExprBinding();
- if (exprBinding == null && !drlxParseResult.isPredicate() && drlxParseResult.getImplicitCastExpression().isEmpty()) {
- return new DrlxParseFail(new DescrBuildError(context.getRuleDescr(), context.getRuleDescr(), "",
- String.format("Predicate '%s' must be a Boolean expression", drlxParseResult.getOriginalDrlConstraint())));
- } else {
- return drlxParseResult;
- }
- }
-
- @Override
- public DrlxParseResult onFail(DrlxParseFail failure) {
- return failure;
- }
- });
-
- withBindingCheck.accept(
- new ParseResultVoidVisitor() {
- @Override
- public void onSuccess( DrlxParseSuccess drlxParseResult ) {
- DSLNode constraint = drlxParseResult.isOOPath() ?
- new ConstraintOOPath( context, packageModel, pattern, patternType, patternConstraintParseResult, drlxParseResult ) :
- createSimpleConstraint( drlxParseResult, pattern );
- constraint.buildPattern();
- registerUsedBindingInOr(drlxParseResult.getExprBinding());
- }
-
- @Override
- public void onFail( DrlxParseFail failure ) {
- if (failure.getError() != null) {
- context.addCompilationError( failure.getError() );
- }
- }
- } );
- }
-
- private void registerUsedBindingInOr(String exprBinding) {
- if(context.isNestedInsideOr()) {
- context.getBindingOr().add(exprBinding);
- }
}
@Override
@@ -309,10 +59,10 @@ public abstract class PatternDSL implements DSLNode {
if (constraintDescrs.isEmpty() && !(pattern.getSource() instanceof AccumulateDescr)) {
context.addExpression(input(declarationSpec));
} else {
- final List<PatternConstraintParseResult> patternConstraintParseResults = findAllConstraint(pattern, constraintDescrs, patternType);
+ final List<PatternConstraintParseResult> patternConstraintParseResults = findAllConstraint(pattern, constraintDescrs);
final List<String> allBindings = patternConstraintParseResults
.stream()
- .map(p -> p.getDrlxParseResult().acceptWithReturnValue( DrlxParseSuccess::getExprBinding ))
+ .map(p -> p.drlxParseResult().acceptWithReturnValue(DrlxParseSuccess::getExprBinding))
.filter(Objects::nonNull)
.collect(Collectors.toList());
@@ -327,42 +77,22 @@ public abstract class PatternDSL implements DSLNode {
}
}
- Set<String> getSettableWatchedProps() {
- Set<String> settableWatchedProps = new HashSet<>();
- Collection<String> settableProps = PropertyReactivityUtil.getAccessibleProperties(patternType);
- List<String> propertiesInWatch = getPatternListenedProperties(pattern);
- propertiesInWatch.forEach(prop -> populateSettableWatchedProps(prop, settableProps, settableWatchedProps, true));
-
- if (context.isPropertyReactive(patternType)) {
- Collection<String> lookAheadProps = lookAheadFieldsOfIdentifier(context.getRuleDescr(), pattern);
- lookAheadProps.forEach(prop -> populateSettableWatchedProps(prop, settableProps, settableWatchedProps, false)); // okay to have non-settable prop in lookAhead
- }
-
- return settableWatchedProps;
+ protected static boolean isPositional(BaseDescr constraint) {
+ return constraint instanceof ExprConstraintDescr &&
+ ((ExprConstraintDescr) constraint).getType() == ExprConstraintDescr.Type.POSITIONAL &&
+ !constraint.getText().contains(":=");
}
- private void populateSettableWatchedProps(String property, Collection<String> settableProps, Set<String> settableWatchedProps, boolean raiseErrorForNonSettableOrDuplicatedProp) {
- String trimmedProperty = property.trim();
- String actualProperty = trimmedProperty;
- if (trimmedProperty.startsWith("!")) {
- actualProperty = property.substring(1).trim();
- trimmedProperty = "!" + actualProperty;
- }
- if (actualProperty.equals("*") || settableProps.contains(actualProperty)) {
- if (raiseErrorForNonSettableOrDuplicatedProp && (settableWatchedProps.contains(actualProperty) || settableWatchedProps.contains("!" + actualProperty))) {
- context.addCompilationError(new InvalidExpressionErrorResult("Duplicate property " + actualProperty + " in @" + Watch.class.getSimpleName() + " annotation"));
- return;
- }
- settableWatchedProps.add(trimmedProperty);
- } else if (raiseErrorForNonSettableOrDuplicatedProp) {
- context.addCompilationError(new InvalidExpressionErrorResult("Unknown property " + actualProperty + " in @watch annotation"));
- }
- }
+ public abstract DeclarationSpec initPattern();
+
+ protected abstract List<PatternConstraintParseResult> findAllConstraint(PatternDescr pattern, List<? extends BaseDescr> constraintDescrs);
protected abstract void buildPattern(DeclarationSpec declarationSpec, List<PatternConstraintParseResult> patternConstraintParseResults);
- protected abstract MethodCallExpr input(DeclarationSpec declarationSpec);
+ protected abstract String getPatternTypeName();
- protected abstract DSLNode createSimpleConstraint( DrlxParseSuccess drlxParseResult, PatternDescr pattern );
-}
+ protected abstract Class<?> getPatternType();
+
+ protected abstract MethodCallExpr input(DeclarationSpec declarationSpec);
+}
\ No newline at end of file
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSLPattern.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSLPattern.java
deleted file mode 100644
index 556b870e2b..0000000000
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternDSLPattern.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.model.codegen.execmodel.generator.visitor.pattern;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-
-import com.github.javaparser.ast.expr.Expression;
-import com.github.javaparser.ast.expr.MethodCallExpr;
-import com.github.javaparser.ast.expr.StringLiteralExpr;
-import org.drools.drl.ast.descr.BaseDescr;
-import org.drools.drl.ast.descr.PatternDescr;
-import org.drools.model.codegen.execmodel.PackageModel;
-import org.drools.model.codegen.execmodel.errors.InvalidExpressionErrorResult;
-import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
-import org.drools.model.codegen.execmodel.generator.RuleContext;
-import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseSuccess;
-import org.drools.model.codegen.execmodel.generator.visitor.DSLNode;
-import org.kie.api.definition.rule.Watch;
-
-import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.findLastMethodInChain;
-import static org.drools.model.codegen.execmodel.generator.DrlxParseUtil.findRootNodeViaScope;
-import static org.drools.model.codegen.execmodel.generator.DslMethodNames.NO_OP_EXPR;
-import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PASSIVE_CALL;
-import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PATTERN_CALL;
-import static org.drools.model.codegen.execmodel.generator.DslMethodNames.WATCH_CALL;
-import static org.drools.model.codegen.execmodel.generator.DslMethodNames.createDslTopLevelMethod;
-
-class PatternDSLPattern extends PatternDSL {
-
- protected PatternDSLPattern(RuleContext context, PackageModel packageModel, PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, Class<?> patternType) {
- super(context, packageModel, pattern, constraintDescrs, patternType);
- }
-
- @Override
- protected void buildPattern(DeclarationSpec declarationSpec, List<PatternConstraintParseResult> patternConstraintParseResults) {
- MethodCallExpr patternExpression = createPatternExpression(pattern, declarationSpec);
-
- List<Expression> exprs = new ArrayList<>();
- context.pushExprPointer(exprs::add);
- buildConstraints(pattern, patternType, patternConstraintParseResults);
- context.popExprPointer();
-
- List<Expression> additionalPatterns = new ArrayList<>();
- for (Expression expr : exprs) {
- Optional<Expression> rootScope = findRootNodeViaScope(expr );
- if ( rootScope.isPresent() && (( MethodCallExpr ) rootScope.get()).getNameAsString().equals( PATTERN_CALL ) ) {
- additionalPatterns.add( expr );
- } else {
- MethodCallExpr currentExpr = ( MethodCallExpr ) expr;
- MethodCallExpr lastMethodInChain = findLastMethodInChain(currentExpr);
- if (!NO_OP_EXPR.equals(lastMethodInChain.getNameAsString())) {
- lastMethodInChain.setScope(patternExpression);
- patternExpression = currentExpr;
- }
- }
- }
-
- if (pattern.isQuery()) {
- patternExpression = new MethodCallExpr( patternExpression, PASSIVE_CALL );
- }
-
- context.addExpression( addWatchToPattern( patternExpression ) );
- additionalPatterns.forEach( context::addExpression );
- }
-
- @Override
- public MethodCallExpr input(DeclarationSpec declarationSpec) {
- return addWatchToPattern( createPatternExpression(pattern, declarationSpec) );
- }
-
- private MethodCallExpr addWatchToPattern( MethodCallExpr patternExpression ) {
- Set<String> settableWatchedProps = getSettableWatchedProps();
- if ( !settableWatchedProps.isEmpty() ) {
- if (context.isPropertyReactive(patternType)) {
- patternExpression = new MethodCallExpr(patternExpression, WATCH_CALL);
- settableWatchedProps.stream().map(StringLiteralExpr::new).forEach(patternExpression::addArgument);
- } else {
- context.addCompilationError(new InvalidExpressionErrorResult("Wrong usage of @" + Watch.class.getSimpleName() + " annotation on class " + patternType.getName() + " that is not annotated as @PropertyReactive"));
- }
- }
- return patternExpression;
- }
-
- private MethodCallExpr createPatternExpression(PatternDescr pattern, DeclarationSpec declarationSpec) {
- MethodCallExpr dslExpr = createDslTopLevelMethod(PATTERN_CALL);
- dslExpr.addArgument( context.getVarExpr( pattern.getIdentifier()) );
- if (context.isQuery()) {
- Optional<Expression> declarationSource = declarationSpec.getDeclarationSource();
- declarationSource.ifPresent(dslExpr::addArgument);
- }
- return dslExpr;
- }
-
- private void buildConstraints(PatternDescr pattern, Class<?> patternType, List<PatternConstraintParseResult> patternConstraintParseResults) {
- boolean hasOOPath = false;
- for (PatternConstraintParseResult patternConstraintParseResult : patternConstraintParseResults) {
- // only one oopath per pattern is allowed
- if (patternConstraintParseResult.getDrlxParseResult().isOOPath()) {
- if (hasOOPath) {
- context.addCompilationError(new InvalidExpressionErrorResult("Only one oopath per pattern is allowed"));
- break;
- } else {
- hasOOPath = true;
- }
- }
- buildConstraint(pattern, patternType, patternConstraintParseResult);
- }
- if (hasOOPath) {
- context.clearOOPathPatternExpr();
- }
- }
-
- @Override
- protected DSLNode createSimpleConstraint( DrlxParseSuccess drlxParseResult, PatternDescr pattern ) {
- return new PatternDSLSimpleConstraint( context, pattern, drlxParseResult );
- }
-}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternVisitor.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternVisitor.java
index 8fd6e2c59b..8c84f66cc4 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternVisitor.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PatternVisitor.java
@@ -62,11 +62,14 @@ public class PatternVisitor {
patternType = context.getTypeResolver().resolveType(className);
packageModel.addOtnsClass(patternType);
} catch (ClassNotFoundException e) {
+ if (context.arePrototypesAllowed()) {
+ return new PrototypePatternDSL(context, packageModel, pattern, constraintDescrs, className);
+ }
context.addCompilationError( new InvalidExpressionErrorResult( "Unable to find class: " + className ) );
return () -> { };
}
- return new PatternDSLPattern(context, packageModel, pattern, constraintDescrs, patternType);
+ return new ClassPatternDSL(context, packageModel, pattern, constraintDescrs, patternType);
}
private DSLNode parsePatternWithClass(PatternDescr pattern, String className) {
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PrototypePatternDSL.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PrototypePatternDSL.java
new file mode 100644
index 0000000000..cd5c810e32
--- /dev/null
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/generator/visitor/pattern/PrototypePatternDSL.java
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.codegen.execmodel.generator.visitor.pattern;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.github.javaparser.ast.expr.BinaryExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
+import org.drools.drl.ast.descr.BaseDescr;
+import org.drools.drl.ast.descr.PatternDescr;
+import org.drools.model.Index;
+import org.drools.model.codegen.execmodel.PackageModel;
+import org.drools.model.codegen.execmodel.generator.DeclarationSpec;
+import org.drools.model.codegen.execmodel.generator.DrlxParseUtil;
+import org.drools.model.codegen.execmodel.generator.RuleContext;
+import org.drools.model.codegen.execmodel.generator.drlxparse.DrlxParseSuccess;
+import org.drools.model.codegen.execmodel.generator.drlxparse.SingleDrlxParseSuccess;
+import org.drools.mvel.parser.ast.expr.DrlxExpression;
+
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PROTO_EXPR_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.PROTO_PATTERN_CALL;
+import static org.drools.model.codegen.execmodel.generator.DslMethodNames.createProtoDslTopLevelMethod;
+import static org.drools.model.impl.VariableImpl.GENERATED_VARIABLE_PREFIX;
+
+public class PrototypePatternDSL extends PatternDSL {
+
+ private final String patternName;
+
+ PrototypePatternDSL(RuleContext context, PackageModel packageModel, PatternDescr pattern, List<? extends BaseDescr> constraintDescrs, String patternName) {
+ super(context, packageModel, pattern, constraintDescrs);
+ this.patternName = patternName;
+ }
+
+ @Override
+ protected List<PatternConstraintParseResult> findAllConstraint(PatternDescr pattern, List<? extends BaseDescr> constraintDescrs) {
+ List<PatternConstraintParseResult> patternConstraintParseResults = new ArrayList<>();
+
+ for (BaseDescr constraint : constraintDescrs) {
+ String patternIdentifier = pattern.getIdentifier();
+ String expression = constraint.toString();
+
+ DrlxExpression drlx = DrlxParseUtil.parseExpression( expression );
+ var drlxParse = new SingleDrlxParseSuccess(null, patternIdentifier, drlxToExpression(drlx), null);
+ if (drlx.getBind() != null) {
+ drlxParse.setExprBinding(drlx.getBind().asString());
+ }
+ patternConstraintParseResults.add(new PatternConstraintParseResult(expression, patternIdentifier, drlxParse));
+ }
+
+ return patternConstraintParseResults;
+ }
+
+ private Expression drlxToExpression(DrlxExpression drlx) {
+ Expression expression = drlx.getExpr();
+
+ if (expression instanceof BinaryExpr bExpr) {
+ MethodCallExpr dslExpr = new MethodCallExpr(PROTO_EXPR_CALL);
+ dslExpr.addArgument( new StringLiteralExpr(bExpr.getLeft().asNameExpr().getName().asString()) );
+ dslExpr.addArgument( Index.ConstraintType.class.getCanonicalName() + "." + DrlxParseUtil.toConstraintType(bExpr.getOperator() ) );
+ dslExpr.addArgument( bExpr.getRight() );
+ return dslExpr;
+ }
+
+ throw new UnsupportedOperationException("Unknown expression type: " + expression.getClass().getSimpleName());
+ }
+
+ @Override
+ public DeclarationSpec initPattern() {
+ generatePatternIdentifierIfMissing();
+ context.addPatternBinding(pattern.getIdentifier());
+ return context.addPrototypeDeclaration(pattern.getIdentifier(), pattern.getObjectType());
+ }
+
+ private void generatePatternIdentifierIfMissing() {
+ // the PatternDescr can be shared by multiple rules in case of rules inheritance, so its identifier has to
+ // be set atomically when rule generation is performed in parallel
+ synchronized (pattern) {
+ if (pattern.getIdentifier() == null) {
+ pattern.setIdentifier(GENERATED_VARIABLE_PREFIX + patternName);
+ }
+ }
+ }
+
+ @Override
+ protected void buildPattern(DeclarationSpec declarationSpec, List<PatternConstraintParseResult> patternConstraintParseResults) {
+ MethodCallExpr patternExpression = createPatternExpression(pattern);
+ for (PatternConstraintParseResult parseResult : patternConstraintParseResults) {
+ patternExpression = ((DrlxParseSuccess) parseResult.drlxParseResult()).getExpr().asMethodCallExpr().setScope(patternExpression);
+ }
+ context.addExpression( patternExpression );
+ }
+
+ @Override
+ protected String getPatternTypeName() {
+ return patternName;
+ }
+
+ @Override
+ protected Class<?> getPatternType() {
+ return null;
+ }
+
+ @Override
+ protected MethodCallExpr input(DeclarationSpec declarationSpec) {
+ return createPatternExpression(pattern);
+ }
+
+ private MethodCallExpr createPatternExpression(PatternDescr pattern) {
+ MethodCallExpr dslExpr = createProtoDslTopLevelMethod(PROTO_PATTERN_CALL);
+ dslExpr.addArgument( context.getVarExpr( pattern.getIdentifier()) );
+ return dslExpr;
+ }
+}
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
index 5c93e29685..c66d6e2fc0 100644
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
+++ b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/execmodel/processors/ModelMainCompilationPhase.java
@@ -18,6 +18,11 @@
*/
package org.drools.model.codegen.execmodel.processors;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Function;
+
import org.drools.compiler.builder.PackageRegistryManager;
import org.drools.compiler.builder.impl.BuildResultCollector;
import org.drools.compiler.builder.impl.BuildResultCollectorImpl;
@@ -27,9 +32,9 @@ import org.drools.compiler.builder.impl.processors.AccumulateFunctionCompilation
import org.drools.compiler.builder.impl.processors.CompilationPhase;
import org.drools.compiler.builder.impl.processors.FunctionCompilationPhase;
import org.drools.compiler.builder.impl.processors.GlobalCompilationPhase;
+import org.drools.compiler.builder.impl.processors.IteratingPhase;
import org.drools.compiler.builder.impl.processors.RuleValidator;
import org.drools.compiler.builder.impl.processors.SinglePackagePhaseFactory;
-import org.drools.compiler.builder.impl.processors.IteratingPhase;
import org.drools.compiler.builder.impl.processors.WindowDeclarationCompilationPhase;
import org.drools.compiler.lang.descr.CompositePackageDescr;
import org.drools.kiesession.rulebase.InternalKnowledgeBase;
@@ -39,11 +44,6 @@ import org.drools.model.codegen.execmodel.PackageSourceManager;
import org.kie.internal.builder.KnowledgeBuilderConfiguration;
import org.kie.internal.builder.KnowledgeBuilderResult;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.function.Function;
-
public class ModelMainCompilationPhase<T> implements CompilationPhase {
private final PackageModelManager packageModels;
diff --git a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/KogitoKnowledgeBuilderConfigurationImpl.java b/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/KogitoKnowledgeBuilderConfigurationImpl.java
deleted file mode 100644
index d5e331094c..0000000000
--- a/drools-model/drools-model-codegen/src/main/java/org/drools/model/codegen/project/KogitoKnowledgeBuilderConfigurationImpl.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.model.codegen.project;
-
-import java.util.NoSuchElementException;
-
-import org.drools.compiler.builder.impl.KnowledgeBuilderConfigurationImpl;
-import org.drools.codegen.common.DroolsModelBuildContext;
-import org.kie.internal.builder.conf.KnowledgeBuilderOption;
-import org.kie.internal.builder.conf.MultiValueKieBuilderOption;
-import org.kie.internal.builder.conf.SingleValueKieBuilderOption;
-import org.kie.internal.conf.CompositeConfiguration;
-import org.kie.internal.utils.ChainedProperties;
-
-public class KogitoKnowledgeBuilderConfigurationImpl extends KnowledgeBuilderConfigurationImpl {
-
- public static KogitoKnowledgeBuilderConfigurationImpl fromContext(DroolsModelBuildContext buildContext) {
- throw new UnsupportedOperationException();
-// KogitoKnowledgeBuilderConfigurationImpl conf = new KogitoKnowledgeBuilderConfigurationImpl(buildContext.getClassLoader());
-// for (String prop : buildContext.getApplicationProperties()) {
-// if (prop.startsWith("drools")) {
-// conf.setProperty(prop, buildContext.getApplicationProperty(prop).orElseThrow(NoSuchElementException::new));
-// }
-// }
-// return conf;
- }
-
-
- public KogitoKnowledgeBuilderConfigurationImpl(CompositeConfiguration<KnowledgeBuilderOption, SingleValueKieBuilderOption, MultiValueKieBuilderOption> compConfig, ClassLoader classLoader, ChainedProperties chainedProperties) {
- super(compConfig);
- }
-
- @Override
- protected ClassLoader getFunctionFactoryClassLoader() {
- return KogitoKnowledgeBuilderConfigurationImpl.class.getClassLoader();
- }
-}
diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FactTemplateTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PrototypeTest.java
similarity index 75%
rename from drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FactTemplateTest.java
rename to drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PrototypeTest.java
index 6bdde3cf2d..7e3ccd1154 100644
--- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/FactTemplateTest.java
+++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PrototypeTest.java
@@ -18,9 +18,18 @@
*/
package org.drools.model.codegen.execmodel;
-import org.drools.base.facttemplates.Event;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplateObjectType;
+import java.math.BigDecimal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+
+import org.drools.base.prototype.PrototypeObjectType;
import org.drools.core.ClockType;
import org.drools.core.reteoo.CompositeObjectSinkAdapter;
import org.drools.core.reteoo.EntryPointNode;
@@ -30,10 +39,6 @@ import org.drools.model.ConstraintOperator;
import org.drools.model.DSL;
import org.drools.model.Index;
import org.drools.model.Model;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeExpression;
-import org.drools.model.PrototypeFact;
-import org.drools.model.PrototypeVariable;
import org.drools.model.Query;
import org.drools.model.Rule;
import org.drools.model.Variable;
@@ -41,11 +46,18 @@ import org.drools.model.codegen.execmodel.domain.Person;
import org.drools.model.codegen.execmodel.domain.Result;
import org.drools.model.functions.Function1;
import org.drools.model.impl.ModelImpl;
+import org.drools.model.prototype.PrototypeExpression;
+import org.drools.model.prototype.PrototypeVariable;
import org.drools.modelcompiler.KieBaseBuilder;
import org.junit.Test;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.conf.EventProcessingOption;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeEventInstance;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.conf.ClockTypeOption;
@@ -54,17 +66,6 @@ import org.kie.api.runtime.rule.Row;
import org.kie.api.runtime.rule.ViewChangedEventListener;
import org.kie.api.time.SessionPseudoClock;
-import java.math.BigDecimal;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiPredicate;
-import java.util.stream.Collectors;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
import static org.drools.model.DSL.accFunction;
@@ -80,18 +81,15 @@ import static org.drools.model.PatternDSL.pattern;
import static org.drools.model.PatternDSL.query;
import static org.drools.model.PatternDSL.reactOn;
import static org.drools.model.PatternDSL.rule;
-import static org.drools.model.PrototypeDSL.field;
-import static org.drools.model.PrototypeDSL.protoPattern;
-import static org.drools.model.PrototypeDSL.prototype;
-import static org.drools.model.PrototypeDSL.variable;
-import static org.drools.model.PrototypeExpression.fixedValue;
-import static org.drools.model.PrototypeExpression.prototypeField;
-import static org.drools.model.PrototypeExpression.thisPrototype;
import static org.drools.model.codegen.execmodel.BaseModelTest.getObjectsIntoList;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedEvent;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedFact;
+import static org.drools.model.prototype.PrototypeDSL.protoPattern;
+import static org.drools.model.prototype.PrototypeDSL.variable;
+import static org.drools.model.prototype.PrototypeExpression.fixedValue;
+import static org.drools.model.prototype.PrototypeExpression.prototypeField;
+import static org.drools.model.prototype.PrototypeExpression.thisPrototype;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
-public class FactTemplateTest {
+public class PrototypeTest {
private static final ConstraintOperator listContainsOp = new ConstraintOperator() {
@Override
@@ -108,7 +106,7 @@ public class FactTemplateTest {
private static final ConstraintOperator existsFieldOp = new ConstraintOperator() {
@Override
public <T, V> BiPredicate<T, V> asPredicate() {
- return (t,v) -> ((PrototypeFact) t).has((String) v);
+ return (t,v) -> ((PrototypeFactInstance) t).has((String) v);
}
@Override
@@ -119,15 +117,15 @@ public class FactTemplateTest {
@Test
public void testAlphaWithPropertyReactivity() {
- testAlpha(prototype( "org.drools.Person", field("name", String.class), field("age", Integer.class) ), true);
+ testAlpha(prototype( "org.drools.Person").withField("name", String.class).withField("age", Integer.class).asFact(), true);
}
@Test
public void testAlphaWithoutPropertyReactivity() {
- testAlpha(prototype( "org.drools.Person" ), false);
+ testAlpha(prototype( "org.drools.Person" ).asFact(), false);
}
- private void testAlpha(Prototype personFact, boolean hasFields) {
+ private void testAlpha(PrototypeFact personFact, boolean hasFields) {
PrototypeVariable markV = variable(personFact);
Rule rule = rule( "alpha" )
@@ -144,11 +142,11 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- assertThat(hasFactTemplateObjectType(ksession, "Person")).isTrue();
+ assertThat(hasPrototypeObjectType(ksession, "org.drools.Person")).isTrue();
- Fact mark = createMapBasedFact(personFact);
- mark.set( "name", "Mark" );
- mark.set( "age", 40 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 40 );
FactHandle fh = ksession.insert( mark );
assertThat(ksession.fireAllRules()).isEqualTo(1);
@@ -156,7 +154,7 @@ public class FactTemplateTest {
Collection<Result> results = getObjectsIntoList(ksession, Result.class);
assertThat(results).contains(new Result("Found a 40 years old Mark"));
- mark.set( "age", 41 );
+ mark.put("age", 41 );
ksession.update(fh, mark, "age");
// property reactivity should prevent this firing
assertThat(ksession.fireAllRules()).isEqualTo(hasFields ? 0 : 1);
@@ -169,7 +167,7 @@ public class FactTemplateTest {
@Test
public void testExpressionAlphaConstraint() {
// DROOLS-7075
- Prototype testPrototype = prototype( "test" );
+ PrototypeFact testPrototype = prototype( "test" ).asFact();
PrototypeVariable testV = variable(testPrototype);
Rule rule = rule( "alpha" )
@@ -186,14 +184,14 @@ public class FactTemplateTest {
KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );
KieSession ksession = kieBase.newKieSession();
- Fact testFact = createMapBasedFact(testPrototype);
- testFact.set( "fieldA", 12 );
- testFact.set( "fieldB", 8 );
+ PrototypeFactInstance testFact = testPrototype.newInstance();
+ testFact.put("fieldA", 12 );
+ testFact.put("fieldB", 8 );
FactHandle fh = ksession.insert( testFact );
assertThat(ksession.fireAllRules()).isEqualTo(0);
- testFact.set( "fieldC", 5 );
+ testFact.put("fieldC", 5 );
ksession.update(fh, testFact, "fieldC");
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@@ -201,7 +199,7 @@ public class FactTemplateTest {
@Test
public void testExistsField() {
// DROOLS-7075
- Prototype testPrototype = prototype( "test" );
+ PrototypeFact testPrototype = prototype( "test" ).asFact();
PrototypeVariable testV = variable(testPrototype);
Rule rule = rule( "alpha" )
@@ -217,20 +215,20 @@ public class FactTemplateTest {
KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );
KieSession ksession = kieBase.newKieSession();
- Fact testFact = createMapBasedFact(testPrototype);
- testFact.set( "fieldB", 8 );
+ PrototypeFactInstance testFact = testPrototype.newInstance();
+ testFact.put("fieldB", 8 );
FactHandle fh = ksession.insert( testFact );
assertThat(ksession.fireAllRules()).isEqualTo(0);
- testFact.set( "fieldA", null );
+ testFact.put("fieldA", null );
ksession.update(fh, testFact, "fieldA");
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@Test
public void testNotNull() {
- Prototype personFact = prototype( "org.drools.Person" );
+ PrototypeFact personFact = prototype( "org.drools.Person" ).asFact();
PrototypeVariable markV = variable(personFact);
Rule rule = rule("alpha")
@@ -247,14 +245,14 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact unknown = createMapBasedFact(personFact);
- unknown.set( "age", 40 );
+ PrototypeFactInstance unknown = personFact.newInstance();
+ unknown.put("age", 40 );
ksession.insert( unknown );
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact mark = createMapBasedFact(personFact);
- mark.set( "name", "Mark" );
- mark.set( "age", 40 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 40 );
ksession.insert( mark );
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@@ -263,7 +261,7 @@ public class FactTemplateTest {
public void testBeta() {
Result result = new Result();
- Prototype personFact = prototype( "org.drools.Person", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.Person").withField("name").withField("age").asFact();
PrototypeVariable markV = variable( personFact );
PrototypeVariable olderV = variable( personFact );
@@ -283,19 +281,19 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- assertThat(hasFactTemplateObjectType(ksession, "Person")).isTrue();
+ assertThat(hasPrototypeObjectType(ksession, "org.drools.Person")).isTrue();
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", 37 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 37 );
- Fact edson = createMapBasedFact( personFact );
- edson.set( "name", "Edson" );
- edson.set( "age", 35 );
+ PrototypeFactInstance edson = personFact.newInstance();
+ edson.put("name", "Edson" );
+ edson.put("age", 35 );
- Fact mario = createMapBasedFact( personFact );
- mario.set( "name", "Mario" );
- mario.set( "age", 40 );
+ PrototypeFactInstance mario = personFact.newInstance();
+ mario.put("name", "Mario" );
+ mario.put("age", 40 );
FactHandle markFH = ksession.insert(mark);
FactHandle edsonFH = ksession.insert(edson);
@@ -309,7 +307,7 @@ public class FactTemplateTest {
ksession.fireAllRules();
assertThat(result.getValue()).isNull();
- mark.set( "age", 34 );
+ mark.put("age", 34 );
ksession.update( markFH, mark );
ksession.fireAllRules();
@@ -319,7 +317,7 @@ public class FactTemplateTest {
@Test
public void testExpressionBetaConstraint() {
// DROOLS-7075
- Prototype testPrototype = prototype( "test" );
+ PrototypeFact testPrototype = prototype( "test" ).asFact();
PrototypeVariable test1V = variable(testPrototype);
PrototypeVariable test2V = variable(testPrototype);
@@ -338,24 +336,24 @@ public class FactTemplateTest {
KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );
KieSession ksession = kieBase.newKieSession();
- Fact testFact1 = createMapBasedFact(testPrototype);
- testFact1.set( "fieldA", 12 );
+ PrototypeFactInstance testFact1 = testPrototype.newInstance();
+ testFact1.put("fieldA", 12 );
FactHandle fh1 = ksession.insert( testFact1 );
- Fact testFact2 = createMapBasedFact(testPrototype);
- testFact2.set( "fieldB", 8 );
+ PrototypeFactInstance testFact2 = testPrototype.newInstance();
+ testFact2.put("fieldB", 8 );
FactHandle fh2 = ksession.insert( testFact2 );
assertThat(ksession.fireAllRules()).isEqualTo(0);
- testFact2.set( "fieldC", 5 );
+ testFact2.put("fieldC", 5 );
ksession.update(fh2, testFact2, "fieldC");
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@Test
public void testBetaMixingClassAndFact() {
- Prototype personFact = prototype( "org.drools.FactPerson", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.FactPerson").withField("name").withField("age").asFact();
PrototypeVariable markV = variable( personFact );
@@ -381,11 +379,11 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- assertThat(hasFactTemplateObjectType(ksession, "FactPerson")).isTrue();
-
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", 37 );
+ assertThat(hasPrototypeObjectType(ksession, "org.drools.FactPerson")).isTrue();
+
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 37 );
ksession.insert( mark );
@@ -398,14 +396,14 @@ public class FactTemplateTest {
assertThat(results).contains(new Result("Mario is older than Mark"));
}
- private boolean hasFactTemplateObjectType( KieSession ksession, String name ) {
- return getFactTemplateObjectTypeNode( ksession, name ) != null;
+ private boolean hasPrototypeObjectType(KieSession ksession, String name ) {
+ return getPrototypeObjectTypeNode(ksession, name ) != null;
}
- private ObjectTypeNode getFactTemplateObjectTypeNode( KieSession ksession, String name ) {
+ private ObjectTypeNode getPrototypeObjectTypeNode(KieSession ksession, String name ) {
EntryPointNode epn = ((InternalKnowledgeBase) ksession.getKieBase()).getRete().getEntryPointNodes().values().iterator().next();
for (ObjectTypeNode otn : epn.getObjectTypeNodes().values()) {
- if (otn.getObjectType() instanceof FactTemplateObjectType && (( FactTemplateObjectType ) otn.getObjectType()).getFactTemplate().getName().equals( name )) {
+ if (otn.getObjectType() instanceof PrototypeObjectType && ((PrototypeObjectType) otn.getObjectType()).getPrototype().getFullName().equals(name )) {
return otn;
}
}
@@ -414,7 +412,7 @@ public class FactTemplateTest {
@Test
public void testIndexedAlpha() {
- Prototype personFact = prototype( "org.drools.Person", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.Person").withField("name").withField("age").asFact();
PrototypeVariable personV = variable( personFact );
@@ -450,12 +448,12 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- ObjectTypeNode otn = getFactTemplateObjectTypeNode( ksession, "Person" );
+ ObjectTypeNode otn = getPrototypeObjectTypeNode(ksession, "org.drools.Person" );
assertThat(((CompositeObjectSinkAdapter) otn.getObjectSinkPropagator()).getHashedSinkMap().size()).isEqualTo(3);
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", 40 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 40 );
ksession.insert( mark );
ksession.fireAllRules();
@@ -467,7 +465,7 @@ public class FactTemplateTest {
@Test
public void testAccumulate() {
- Prototype personFact = prototype( "org.drools.Person", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.Person").withField("name").withField("age").asFact();
PrototypeVariable person = variable( personFact );
@@ -490,19 +488,19 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", 37 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 37 );
ksession.insert( mark );
- Fact edson = createMapBasedFact( personFact );
- edson.set( "name", "Edson" );
- edson.set( "age", 35 );
+ PrototypeFactInstance edson = personFact.newInstance();
+ edson.put("name", "Edson" );
+ edson.put("age", 35 );
ksession.insert( edson );
- Fact mario = createMapBasedFact( personFact );
- mario.set( "name", "Mario" );
- mario.set( "age", 40 );
+ PrototypeFactInstance mario = personFact.newInstance();
+ mario.put("name", "Mario" );
+ mario.put("age", 40 );
ksession.insert( mario );
ksession.fireAllRules();
@@ -511,8 +509,8 @@ public class FactTemplateTest {
@Test
public void testQuery() {
- Prototype customerFact = prototype( "customer" );
- Prototype addressFact = prototype( "address" );
+ PrototypeFact customerFact = prototype( "customer" ).asFact();
+ PrototypeFact addressFact = prototype( "address" ).asFact();
PrototypeVariable customerV = variable( customerFact, "c" );
PrototypeVariable addressV = variable( addressFact, "a" );
@@ -529,16 +527,16 @@ public class FactTemplateTest {
MaterializedViewChangedEventListener listener = new MaterializedViewChangedEventListener();
ksession.openLiveQuery("Q0", new Object[0], listener);
- Fact address1 = createMapBasedFact( addressFact );
- address1.set("id", "100001");
- address1.set("customer_id", "1001");
- address1.set("street", "42 Main Street");
+ PrototypeFactInstance address1 = addressFact.newInstance();
+ address1.put("id", "100001");
+ address1.put("customer_id", "1001");
+ address1.put("street", "42 Main Street");
FactHandle fhA1 = ksession.insert( address1 );
ksession.fireAllRules();
- Fact customer1 = createMapBasedFact( customerFact );
- customer1.set("id", "1001");
- customer1.set("first_name", "Sally");
+ PrototypeFactInstance customer1 = customerFact.newInstance();
+ customer1.put("id", "1001");
+ customer1.put("first_name", "Sally");
ksession.insert( customer1 );
ksession.fireAllRules();
@@ -546,10 +544,10 @@ public class FactTemplateTest {
assertThat(listener.updates).isEqualTo(0);
assertThat(listener.deletes).isEqualTo(0);
- Fact address2 = createMapBasedFact( addressFact );
- address2.set("id", "100002");
- address2.set("customer_id", "1001");
- address2.set("street", "11 Post Dr.");
+ PrototypeFactInstance address2 = addressFact.newInstance();
+ address2.put("id", "100002");
+ address2.put("customer_id", "1001");
+ address2.put("street", "11 Post Dr.");
ksession.insert( address2 );
ksession.fireAllRules();
@@ -592,7 +590,7 @@ public class FactTemplateTest {
@Test
public void testRetract() {
- Prototype personFact = prototype( "org.drools.Person" );
+ PrototypeFact personFact = prototype( "org.drools.Person" ).asFact();
PrototypeVariable markV = variable(personFact, "m");
Rule rule = rule( "alpha" )
@@ -610,9 +608,9 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
assertThat(ksession.fireAllRules()).isEqualTo(1);
- Fact mark = createMapBasedFact(personFact);
- mark.set( "name", "Mark" );
- mark.set( "age", 40 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 40 );
FactHandle fh = ksession.insert( mark );
assertThat(ksession.fireAllRules()).isEqualTo(0);
@@ -624,7 +622,7 @@ public class FactTemplateTest {
@Test
public void testUndefinedOnAlpha() {
// DROOLS-7192
- Prototype prototype = prototype( "org.X" );
+ PrototypeFact prototype = prototype( "org.X" ).asFact();
PrototypeVariable var1 = variable( prototype );
@@ -639,20 +637,20 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact f1 = createMapBasedFact( prototype );
- f1.set( "j", 2 );
+ PrototypeFactInstance f1 = prototype.newInstance();
+ f1.put("j", 2 );
ksession.insert(f1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f2 = createMapBasedFact( prototype );
- f2.set( "i", 3 );
+ PrototypeFactInstance f2 = prototype.newInstance();
+ f2.put("i", 3 );
ksession.insert(f2);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f3 = createMapBasedFact( prototype );
- f3.set( "i", null );
+ PrototypeFactInstance f3 = prototype.newInstance();
+ f3.put("i", null );
ksession.insert(f3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
@@ -661,7 +659,7 @@ public class FactTemplateTest {
@Test
public void testUndefinedOnBeta() {
// DROOLS-7192
- Prototype prototype = prototype( "org.X" );
+ PrototypeFact prototype = prototype( "org.X" ).asFact();
PrototypeVariable var1 = variable( prototype );
PrototypeVariable var2 = variable( prototype );
@@ -679,20 +677,20 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact f1 = createMapBasedFact( prototype );
- f1.set( "custom.expected_index", 2 );
+ PrototypeFactInstance f1 = prototype.newInstance();
+ f1.put("custom.expected_index", 2 );
ksession.insert(f1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f2 = createMapBasedFact( prototype );
- f2.set( "i", 3 );
+ PrototypeFactInstance f2 = prototype.newInstance();
+ f2.put("i", 3 );
ksession.insert(f2);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f3 = createMapBasedFact( prototype );
- f3.set( "i", 2 );
+ PrototypeFactInstance f3 = prototype.newInstance();
+ f3.put("i", 2 );
ksession.insert(f3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
@@ -701,7 +699,7 @@ public class FactTemplateTest {
@Test
public void testArrayAccess() {
// DROOLS-7194
- Prototype prototype = prototype( "org.X" );
+ PrototypeFact prototype = prototype( "org.X" ).asFact();
PrototypeVariable var1 = variable( prototype );
@@ -716,18 +714,18 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact f1 = createMapBasedFact( prototype );
- f1.set("i", List.of(3));
+ PrototypeFactInstance f1 = prototype.newInstance();
+ f1.put("i", List.of(3));
ksession.insert(f1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f2 = createMapBasedFact( prototype );
- f2.set( "i", Arrays.asList(1, 3, 5) );
+ PrototypeFactInstance f2 = prototype.newInstance();
+ f2.put("i", Arrays.asList(1, 3, 5) );
ksession.insert(f2);
assertThat(ksession.fireAllRules()).isEqualTo(1);
- Fact f3 = createMapBasedFact( prototype );
- f3.set( "i", new int[] {1, 3, 5} );
+ PrototypeFactInstance f3 = prototype.newInstance();
+ f3.put("i", new int[] {1, 3, 5} );
ksession.insert(f3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@@ -735,7 +733,7 @@ public class FactTemplateTest {
@Test
public void testArrayAccessWithOr() {
// DROOLS-7194
- Prototype prototype = prototype( "org.X" );
+ PrototypeFact prototype = prototype( "org.X" ).asFact();
PrototypeVariable var1 = variable( prototype );
@@ -750,18 +748,18 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact f1 = createMapBasedFact( prototype );
- f1.set("i", List.of(3));
+ PrototypeFactInstance f1 = prototype.newInstance();
+ f1.put("i", List.of(3));
ksession.insert(f1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f2 = createMapBasedFact( prototype );
- f2.set( "i", Arrays.asList(1, 3, 5) );
+ PrototypeFactInstance f2 = prototype.newInstance();
+ f2.put("i", Arrays.asList(1, 3, 5) );
ksession.insert(f2);
assertThat(ksession.fireAllRules()).isEqualTo(1);
- Fact f3 = createMapBasedFact( prototype );
- f3.set( "i", new int[] {1, 5, 3} );
+ PrototypeFactInstance f3 = prototype.newInstance();
+ f3.put("i", new int[] {1, 5, 3} );
ksession.insert(f3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@@ -769,7 +767,7 @@ public class FactTemplateTest {
@Test
public void testInnerArrayAccess() {
// DROOLS-7194
- Prototype prototype = prototype( "org.X" );
+ PrototypeFact prototype = prototype( "org.X" ).asFact();
PrototypeVariable var1 = variable( prototype );
@@ -784,18 +782,18 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact f1 = createMapBasedFact( prototype );
- f1.set("i", List.of(Map.of("a", 3)));
+ PrototypeFactInstance f1 = prototype.newInstance();
+ f1.put("i", List.of(Map.of("a", 3)));
ksession.insert(f1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f2 = createMapBasedFact( prototype );
- f2.set( "i", Arrays.asList(Map.of("a", 1), Map.of("b", 3), Map.of("c", 5)) );
+ PrototypeFactInstance f2 = prototype.newInstance();
+ f2.put("i", Arrays.asList(Map.of("a", 1), Map.of("b", 3), Map.of("c", 5)) );
ksession.insert(f2);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact f3 = createMapBasedFact( prototype );
- f3.set( "i", Arrays.asList(Map.of("c", 1), Map.of("a", 3), Map.of("b", 5)) );
+ PrototypeFactInstance f3 = prototype.newInstance();
+ f3.put("i", Arrays.asList(Map.of("c", 1), Map.of("a", 3), Map.of("b", 5)) );
ksession.insert(f3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@@ -805,7 +803,7 @@ public class FactTemplateTest {
// DROOLS-7223
Result result = new Result();
- Prototype stockTickPrototype = prototype( "org.drools.StockTick" );
+ PrototypeEvent stockTickPrototype = prototype("org.drools.StockTick" ).asEvent();
PrototypeVariable tick1Var = variable( stockTickPrototype );
PrototypeVariable tick2Var = variable( stockTickPrototype );
@@ -829,39 +827,39 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
- Event tick1 = createMapBasedEvent( stockTickPrototype );
- tick1.set( "name", "RedHat" );
- tick1.set( "value", 10 );
+ PrototypeEventInstance tick1 = stockTickPrototype.newInstance();
+ tick1.put("name", "RedHat" );
+ tick1.put("value", 10 );
ksession.insert(tick1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
clock.advanceTime( 3, TimeUnit.SECONDS );
- Event tick2 = createMapBasedEvent( stockTickPrototype );
- tick2.set( "name", "RedHat" );
- tick2.set( "value", 15 );
+ PrototypeEventInstance tick2 = stockTickPrototype.newInstance();
+ tick2.put("name", "RedHat" );
+ tick2.put("value", 15 );
ksession.insert(tick2);
assertThat(ksession.fireAllRules()).isEqualTo(0);
clock.advanceTime( 3, TimeUnit.SECONDS );
- Event tick3 = createMapBasedEvent( stockTickPrototype );
- tick3.set( "name", "test" );
- tick3.set( "value", 12 );
+ PrototypeEventInstance tick3 = stockTickPrototype.newInstance();
+ tick3.put("name", "test" );
+ tick3.put("value", 12 );
ksession.insert(tick3);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Event tick4 = createMapBasedEvent( stockTickPrototype );
- tick4.set( "name", "RedHat" );
- tick4.set( "value", 9 );
+ PrototypeEventInstance tick4 = stockTickPrototype.newInstance();
+ tick4.put("name", "RedHat" );
+ tick4.put("value", 9 );
ksession.insert(tick4);
assertThat(ksession.fireAllRules()).isEqualTo(0);
clock.advanceTime( 3, TimeUnit.SECONDS );
- Event tick5 = createMapBasedEvent( stockTickPrototype );
- tick5.set( "name", "RedHat" );
- tick5.set( "value", 14 );
+ PrototypeEventInstance tick5 = stockTickPrototype.newInstance();
+ tick5.put("name", "RedHat" );
+ tick5.put("value", 14 );
ksession.insert(tick5);
assertThat(ksession.fireAllRules()).isEqualTo(1);
@@ -869,9 +867,9 @@ public class FactTemplateTest {
clock.advanceTime( 6, TimeUnit.SECONDS );
- Event tick6 = createMapBasedEvent( stockTickPrototype );
- tick6.set( "name", "RedHat" );
- tick6.set( "value", 13 );
+ PrototypeEventInstance tick6 = stockTickPrototype.newInstance();
+ tick6.put("name", "RedHat" );
+ tick6.put("value", 13 );
ksession.insert(tick6);
assertThat(ksession.fireAllRules()).isEqualTo(1);
@@ -882,10 +880,10 @@ public class FactTemplateTest {
public void testUniqueEventInTimeWindow() {
Result result = new Result();
- Prototype stockTickPrototype = prototype( "org.drools.StockTick" );
+ PrototypeEvent stockTickPrototype = prototype( "org.drools.StockTick" ).asEvent();
PrototypeVariable tick1Var = variable( stockTickPrototype );
- Prototype controlPrototype = prototype( "org.drools.ControlEvent" );
+ PrototypeEvent controlPrototype = prototype( "org.drools.ControlEvent" ).asEvent();
PrototypeVariable controlVar = variable( controlPrototype );
Rule rule = rule( "stock" )
@@ -893,8 +891,8 @@ public class FactTemplateTest {
protoPattern(tick1Var).expr( "value", Index.ConstraintType.GREATER_THAN, 2 ),
not( protoPattern(controlVar).expr( "name", Index.ConstraintType.EQUAL, tick1Var, "name" ) ),
on(tick1Var).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype ).withExpiration(10, TimeUnit.SECONDS);
- controlEvent.set( "name", t1.get( "name" ) );
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance().withExpiration(10, TimeUnit.SECONDS);
+ controlEvent.put("name", t1.get("name" ) );
drools.insert(controlEvent);
result.setValue( t1.get( "name" ) + " worth " + t1.get( "value" ));
})
@@ -916,9 +914,9 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
- Event tick1 = createMapBasedEvent( stockTickPrototype );
- tick1.set( "name", "RedHat" );
- tick1.set( "value", 10 );
+ PrototypeEventInstance tick1 = stockTickPrototype.newInstance();
+ tick1.put("name", "RedHat" );
+ tick1.put("value", 10 );
ksession.insert(tick1);
assertThat(ksession.fireAllRules()).isEqualTo(2);
@@ -927,15 +925,15 @@ public class FactTemplateTest {
clock.advanceTime( 3, TimeUnit.SECONDS );
- Event tick2 = createMapBasedEvent( stockTickPrototype );
- tick2.set( "name", "RedHat" );
- tick2.set( "value", 12 );
+ PrototypeEventInstance tick2 = stockTickPrototype.newInstance();
+ tick2.put("name", "RedHat" );
+ tick2.put("value", 12 );
ksession.insert(tick2);
assertThat(ksession.fireAllRules()).isEqualTo(1);
- Event tickTest = createMapBasedEvent( stockTickPrototype );
- tickTest.set( "name", "test" );
- tickTest.set( "value", 42 );
+ PrototypeEventInstance tickTest = stockTickPrototype.newInstance();
+ tickTest.put("name", "test" );
+ tickTest.put("value", 42 );
FactHandle fhTest = ksession.insert(tickTest);
assertThat(ksession.fireAllRules()).isEqualTo(2);
@@ -944,18 +942,18 @@ public class FactTemplateTest {
clock.advanceTime( 4, TimeUnit.SECONDS );
- Event tick3 = createMapBasedEvent( stockTickPrototype );
- tick3.set( "name", "RedHat" );
- tick3.set( "value", 14 );
+ PrototypeEventInstance tick3 = stockTickPrototype.newInstance();
+ tick3.put("name", "RedHat" );
+ tick3.put("value", 14 );
ksession.insert(tick3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
assertThat(result.getValue()).isNull();
clock.advanceTime( 5, TimeUnit.SECONDS );
- Event tick4 = createMapBasedEvent( stockTickPrototype );
- tick4.set( "name", "RedHat" );
- tick4.set( "value", 15 );
+ PrototypeEventInstance tick4 = stockTickPrototype.newInstance();
+ tick4.put("name", "RedHat" );
+ tick4.put("value", 15 );
ksession.insert(tick4);
assertThat(ksession.fireAllRules()).isEqualTo(2);
@@ -967,7 +965,7 @@ public class FactTemplateTest {
// DROOLS-7244
Result result = new Result();
- Prototype controlPrototype = prototype( "org.drools.ControlEvent" );
+ PrototypeEvent controlPrototype = prototype( "org.drools.ControlEvent" ).asEvent();
PrototypeVariable controlVar1 = variable( controlPrototype );
PrototypeVariable controlVar2 = variable( controlPrototype );
@@ -990,8 +988,8 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
- Event tick1 = createMapBasedEvent( controlPrototype );
- tick1.set( "name", "start_R" );
+ PrototypeEventInstance tick1 = controlPrototype.newInstance();
+ tick1.put("name", "start_R" );
ksession.insert(tick1);
ksession.fireAllRules();
@@ -1011,10 +1009,10 @@ public class FactTemplateTest {
// DROOLS-7244
Result result = new Result();
- Prototype stockTickPrototype = prototype( "org.drools.StockTick" );
+ PrototypeEvent stockTickPrototype = prototype( "org.drools.StockTick" ).asEvent();
PrototypeVariable tick1Var = variable( stockTickPrototype );
- Prototype controlPrototype = prototype( "org.drools.ControlEvent" );
+ PrototypeEvent controlPrototype = prototype( "org.drools.ControlEvent" ).asEvent();
PrototypeVariable controlVar1 = variable( controlPrototype );
PrototypeVariable controlVar2 = variable( controlPrototype );
@@ -1023,9 +1021,9 @@ public class FactTemplateTest {
protoPattern(tick1Var).expr( "value", Index.ConstraintType.GREATER_THAN, 10 ),
not( protoPattern(controlVar1).expr( "name", Index.ConstraintType.EQUAL, "R1" ) ),
on(tick1Var).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype ).withExpiration(10, TimeUnit.SECONDS);
- controlEvent.set( "name", "R1" );
- controlEvent.set( "event", t1 );
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance().withExpiration(10, TimeUnit.SECONDS);
+ controlEvent.put("name", "R1" );
+ controlEvent.put("event", t1 );
System.out.println("insert: " + controlEvent);
drools.insert(controlEvent);
})
@@ -1036,9 +1034,9 @@ public class FactTemplateTest {
protoPattern(tick1Var).expr( "value", Index.ConstraintType.LESS_THAN, 5 ),
not( protoPattern(controlVar1).expr( "name", Index.ConstraintType.EQUAL, "R2" ) ),
on(tick1Var).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype ).withExpiration(10, TimeUnit.SECONDS);
- controlEvent.set( "name", "R2" );
- controlEvent.set( "event", t1 );
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance().withExpiration(10, TimeUnit.SECONDS);
+ controlEvent.put("name", "R2" );
+ controlEvent.put("event", t1 );
System.out.println("insert: " + controlEvent);
drools.insert(controlEvent);
})
@@ -1053,8 +1051,8 @@ public class FactTemplateTest {
accFunction(org.drools.core.base.accumulators.CountAccumulateFunction::new).as(resultCount)),
pattern(resultCount).expr(count -> count > 0),
on(resultCount).execute((drools, count) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype ).withExpiration(10, TimeUnit.SECONDS);
- controlEvent.set( "name", "start_R" );
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance().withExpiration(10, TimeUnit.SECONDS);
+ controlEvent.put("name", "start_R" );
System.out.println("insert: " + controlEvent);
drools.insert(controlEvent);
})
@@ -1067,8 +1065,8 @@ public class FactTemplateTest {
accFunction(org.drools.core.base.accumulators.CountAccumulateFunction::new).as(resultCount)),
pattern(resultCount).expr(count -> count == 2),
on(resultCount).execute((drools, count) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype ).withExpiration(10, TimeUnit.SECONDS);
- controlEvent.set( "name", "end_R" );
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance().withExpiration(10, TimeUnit.SECONDS);
+ controlEvent.put("name", "end_R" );
System.out.println("insert: " + controlEvent);
drools.insert(controlEvent);
})
@@ -1114,9 +1112,9 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
- Event tick1 = createMapBasedEvent( stockTickPrototype );
- tick1.set( "name", "RedHat" );
- tick1.set( "value", 7 );
+ PrototypeEventInstance tick1 = stockTickPrototype.newInstance();
+ tick1.put("name", "RedHat" );
+ tick1.put("value", 7 );
ksession.insert(tick1);
ksession.fireAllRules();
@@ -1124,9 +1122,9 @@ public class FactTemplateTest {
clock.advanceTime( 1, TimeUnit.SECONDS );
- Event tick2 = createMapBasedEvent( stockTickPrototype );
- tick2.set( "name", "RedHat" );
- tick2.set( "value", 17 );
+ PrototypeEventInstance tick2 = stockTickPrototype.newInstance();
+ tick2.put("name", "RedHat" );
+ tick2.put("value", 17 );
ksession.insert(tick2);
ksession.fireAllRules();
@@ -1134,9 +1132,9 @@ public class FactTemplateTest {
clock.advanceTime( 9, TimeUnit.SECONDS );
- Event tick3 = createMapBasedEvent( stockTickPrototype );
- tick3.set( "name", "RedHat" );
- tick3.set( "value", 3 );
+ PrototypeEventInstance tick3 = stockTickPrototype.newInstance();
+ tick3.put("name", "RedHat" );
+ tick3.put("value", 3 );
ksession.insert(tick3);
ksession.fireAllRules();
@@ -1144,9 +1142,9 @@ public class FactTemplateTest {
clock.advanceTime( 5, TimeUnit.SECONDS );
- Event tick4 = createMapBasedEvent( stockTickPrototype );
- tick4.set( "name", "RedHat" );
- tick4.set( "value", 2 );
+ PrototypeEventInstance tick4 = stockTickPrototype.newInstance();
+ tick4.put("name", "RedHat" );
+ tick4.put("value", 2 );
ksession.insert(tick4);
ksession.fireAllRules();
@@ -1166,7 +1164,7 @@ public class FactTemplateTest {
@Test
public void testListContains() {
// DROOLS-7259
- Prototype prototype = prototype( "org.X" );
+ PrototypeFact prototype = prototype( "org.X" ).asFact();
PrototypeVariable prototypeV = variable(prototype);
Rule rule = rule( "alpha" )
@@ -1183,16 +1181,16 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact fact1 = createMapBasedFact(prototype);
- fact1.set( "name", "fact1" );
- fact1.set( "ids", Arrays.asList(2, 4) );
+ PrototypeFactInstance fact1 = prototype.newInstance();
+ fact1.put("name", "fact1" );
+ fact1.put("ids", Arrays.asList(2, 4) );
ksession.insert(fact1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact fact2 = createMapBasedFact(prototype);
- fact2.set( "name", "fact2" );
- fact2.set( "ids", Arrays.asList(1, 3, 5) );
+ PrototypeFactInstance fact2 = prototype.newInstance();
+ fact2.put("name", "fact2" );
+ fact2.put("ids", Arrays.asList(1, 3, 5) );
ksession.insert(fact2);
assertThat(ksession.fireAllRules()).isEqualTo(1);
@@ -1205,10 +1203,10 @@ public class FactTemplateTest {
public void testCollectUniqueEventsAfterTimeWindow() {
Result result = new Result();
- Prototype stockTickPrototype = prototype( "org.drools.StockTick" );
+ PrototypeEvent stockTickPrototype = prototype( "org.drools.StockTick" ).asEvent();
PrototypeVariable tick1Var = variable( stockTickPrototype );
- Prototype controlPrototype = prototype( "org.drools.ControlEvent" );
+ PrototypeEvent controlPrototype = prototype( "org.drools.ControlEvent" ).asEvent();
PrototypeVariable controlVar1 = variable( controlPrototype );
PrototypeVariable controlVar2 = variable( controlPrototype );
PrototypeVariable controlVar3 = variable( controlPrototype );
@@ -1220,10 +1218,10 @@ public class FactTemplateTest {
protoPattern(tick1Var).expr( "value", Index.ConstraintType.GREATER_THAN, 2 ),
not( protoPattern(controlVar1).expr( "rule_name", Index.ConstraintType.EQUAL, "stock" ).expr( "name", Index.ConstraintType.EQUAL, tick1Var, "name" ) ),
on(tick1Var).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype );
- controlEvent.set( "name", t1.get( "name" ) );
- controlEvent.set( "event", t1 );
- controlEvent.set( "rule_name", "stock" );
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance();
+ controlEvent.put("name", t1.get("name" ) );
+ controlEvent.put("event", t1 );
+ controlEvent.put("rule_name", "stock" );
drools.insert(controlEvent);
drools.delete(t1);
})
@@ -1234,12 +1232,12 @@ public class FactTemplateTest {
protoPattern(controlVar1).expr( "rule_name", Index.ConstraintType.EQUAL, "stock" ),
not( protoPattern(controlVar2).expr( "end_once_after", Index.ConstraintType.EQUAL, "stock" ) ),
on(controlVar1).execute((drools, c1) -> {
- Event startControlEvent = createMapBasedEvent( controlPrototype ).withExpiration(10, TimeUnit.SECONDS);
- startControlEvent.set( "start_once_after", c1.get( "rule_name" ) );
+ PrototypeEventInstance startControlEvent = controlPrototype.newInstance().withExpiration(10, TimeUnit.SECONDS);
+ startControlEvent.put("start_once_after", c1.get("rule_name" ) );
drools.insert(startControlEvent);
- Event endControlEvent = createMapBasedEvent( controlPrototype );
- endControlEvent.set( "end_once_after", c1.get( "rule_name" ) );
+ PrototypeEventInstance endControlEvent = controlPrototype.newInstance();
+ endControlEvent.put("end_once_after", c1.get("rule_name" ) );
drools.insert(endControlEvent);
})
);
@@ -1252,7 +1250,7 @@ public class FactTemplateTest {
accFunction(org.drools.core.base.accumulators.CollectListAccumulateFunction::new, controlVar3).as(resultsVar)),
on(controlVar1, resultsVar).execute((drools, c1, results) -> {
drools.delete(c1);
- result.setValue(results.stream().peek(drools::delete).map(r -> ((PrototypeFact) r).get("event")).collect(Collectors.toList()));
+ result.setValue(results.stream().peek(drools::delete).map(r -> ((PrototypeFactInstance) r).get("event")).collect(Collectors.toList()));
})
);
@@ -1272,33 +1270,33 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession(conf, null);
SessionPseudoClock clock = ksession.getSessionClock();
- Event tick1 = createMapBasedEvent( stockTickPrototype );
- tick1.set( "name", "RedHat" );
- tick1.set( "value", 10 );
+ PrototypeEventInstance tick1 = stockTickPrototype.newInstance();
+ tick1.put("name", "RedHat" );
+ tick1.put("value", 10 );
ksession.insert(tick1);
assertThat(ksession.fireAllRules()).isEqualTo(2);
clock.advanceTime( 3, TimeUnit.SECONDS );
- Event tick2 = createMapBasedEvent( stockTickPrototype );
- tick2.set( "name", "RedHat" );
- tick2.set( "value", 12 );
+ PrototypeEventInstance tick2 = stockTickPrototype.newInstance();
+ tick2.put("name", "RedHat" );
+ tick2.put("value", 12 );
ksession.insert(tick2);
assertThat(ksession.fireAllRules()).isEqualTo(1);
assertThat(result.getValue()).isNull();
- Event tickTest = createMapBasedEvent( stockTickPrototype );
- tickTest.set( "name", "test" );
- tickTest.set( "value", 42 );
+ PrototypeEventInstance tickTest = stockTickPrototype.newInstance();
+ tickTest.put("name", "test" );
+ tickTest.put("value", 42 );
ksession.insert(tickTest);
assertThat(ksession.fireAllRules()).isEqualTo(1);
assertThat(result.getValue()).isNull();
clock.advanceTime( 4, TimeUnit.SECONDS );
- Event tick3 = createMapBasedEvent( stockTickPrototype );
- tick3.set( "name", "RedHat" );
- tick3.set( "value", 14 );
+ PrototypeEventInstance tick3 = stockTickPrototype.newInstance();
+ tick3.put("name", "RedHat" );
+ tick3.put("value", 14 );
ksession.insert(tick3);
assertThat(ksession.fireAllRules()).isEqualTo(1);
assertThat(result.getValue()).isNull();
@@ -1307,9 +1305,9 @@ public class FactTemplateTest {
assertThat(ksession.fireAllRules()).isEqualTo(1);
- List<PrototypeFact> events = (List<PrototypeFact>) result.getValue();
+ List<PrototypeFactInstance> events = (List<PrototypeFactInstance>) result.getValue();
assertThat(events).hasSize(2);
- for (PrototypeFact event : events) {
+ for (PrototypeFactInstance event : events) {
if (event.get("name").equals("RedHat")) {
assertThat(event.get("value")).isEqualTo(10);
} else if (event.get("name").equals("test")) {
@@ -1322,7 +1320,7 @@ public class FactTemplateTest {
@Test
public void testAddOnDifferentPrototypes() {
- Prototype testPrototype = prototype( "test" );
+ PrototypeFact testPrototype = prototype( "test" ).asFact();
PrototypeVariable test1V = variable(testPrototype);
PrototypeVariable test2V = variable(testPrototype);
PrototypeVariable test3V = variable(testPrototype);
@@ -1343,23 +1341,23 @@ public class FactTemplateTest {
KieBase kieBase = KieBaseBuilder.createKieBaseFromModel( model );
KieSession ksession = kieBase.newKieSession();
- Fact testFact1 = createMapBasedFact(testPrototype);
- testFact1.set( "i", 1 );
+ PrototypeFactInstance testFact1 = testPrototype.newInstance();
+ testFact1.put("i", 1 );
ksession.insert(testFact1);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact testFact2 = createMapBasedFact(testPrototype);
- testFact2.set( "i", 2 );
+ PrototypeFactInstance testFact2 = testPrototype.newInstance();
+ testFact2.put("i", 2 );
ksession.insert(testFact2);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact testFact3 = createMapBasedFact(testPrototype);
- testFact3.set( "i", 3 );
+ PrototypeFactInstance testFact3 = testPrototype.newInstance();
+ testFact3.put("i", 3 );
ksession.insert(testFact3);
assertThat(ksession.fireAllRules()).isEqualTo(0);
- Fact testFact4 = createMapBasedFact(testPrototype);
- testFact4.set( "i", 4 );
+ PrototypeFactInstance testFact4 = testPrototype.newInstance();
+ testFact4.put("i", 4 );
ksession.insert(testFact4);
assertThat(ksession.fireAllRules()).isEqualTo(1);
}
@@ -1367,7 +1365,7 @@ public class FactTemplateTest {
@Test
public void testComparisonWithDifferentNumericTypes() {
// DROOLS-7332
- Prototype personFact = prototype( "org.drools.FactPerson", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.FactPerson" ).withField("name").withField("age").asFact();
PrototypeVariable markV = variable( personFact );
@@ -1383,11 +1381,11 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- assertThat(hasFactTemplateObjectType(ksession, "FactPerson")).isTrue();
+ assertThat(hasPrototypeObjectType(ksession, "org.drools.FactPerson")).isTrue();
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", 18 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 18 );
ksession.insert( mark );
@@ -1400,7 +1398,7 @@ public class FactTemplateTest {
@Test
public void testEqualityWithDifferentNumericTypes() {
// DROOLS-7332
- Prototype personFact = prototype( "org.drools.FactPerson", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.FactPerson" ).withField("name").withField("age").asFact();
PrototypeVariable markV = variable( personFact );
@@ -1416,11 +1414,11 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- assertThat(hasFactTemplateObjectType(ksession, "FactPerson")).isTrue();
+ assertThat(hasPrototypeObjectType(ksession, "org.drools.FactPerson")).isTrue();
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", 18 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 18 );
ksession.insert( mark );
@@ -1433,7 +1431,7 @@ public class FactTemplateTest {
@Test
public void bigDecimalEqualityWithDifferentScale_shouldBeEqual() {
// DROOLS-7332
- Prototype personFact = prototype( "org.drools.FactPerson", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.FactPerson" ).withField("name").withField("age").asFact();
PrototypeVariable markV = variable( personFact );
@@ -1449,11 +1447,11 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- assertThat(hasFactTemplateObjectType(ksession, "FactPerson")).isTrue();
+ assertThat(hasPrototypeObjectType(ksession, "org.drools.FactPerson")).isTrue();
- Fact mark = createMapBasedFact( personFact );
- mark.set( "name", "Mark" );
- mark.set( "age", new BigDecimal("18.00") );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", new BigDecimal("18.00") );
ksession.insert( mark );
@@ -1466,7 +1464,7 @@ public class FactTemplateTest {
@Test
public void testMixFieldNameAndPrototypeExpr() {
// DROOLS-7517
- Prototype personFact = prototype( "org.drools.FactPerson", "name", "age" );
+ PrototypeFact personFact = prototype( "org.drools.FactPerson" ).withField("name").withField("age").asFact();
PrototypeVariable markV = variable( personFact );
@@ -1502,9 +1500,9 @@ public class FactTemplateTest {
KieSession ksession = kieBase.newKieSession();
- Fact mark = createMapBasedFact(personFact);
- mark.set( "name", "Mark" );
- mark.set( "age", 40 );
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 40 );
FactHandle fh = ksession.insert( mark );
assertThat(ksession.fireAllRules()).isEqualTo(2);
@@ -1522,7 +1520,7 @@ public class FactTemplateTest {
}
@Override
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
return prototype.getFieldValueExtractor(fieldName)::apply;
}
diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PrototypesAllowedTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PrototypesAllowedTest.java
new file mode 100644
index 0000000000..28c257ea97
--- /dev/null
+++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/PrototypesAllowedTest.java
@@ -0,0 +1,215 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.codegen.execmodel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.drools.model.Index;
+import org.drools.model.Model;
+import org.drools.model.Rule;
+import org.drools.model.codegen.ExecutableModelProject;
+import org.drools.model.impl.ModelImpl;
+import org.drools.model.prototype.PrototypeVariable;
+import org.drools.modelcompiler.KieBaseBuilder;
+import org.junit.Test;
+import org.kie.api.KieBase;
+import org.kie.api.conf.PrototypesOption;
+import org.kie.api.io.ResourceType;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
+import org.kie.api.runtime.KieSession;
+import org.kie.internal.utils.KieHelper;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.drools.model.DSL.on;
+import static org.drools.model.PatternDSL.rule;
+import static org.drools.model.prototype.PrototypeDSL.protoPattern;
+import static org.drools.model.prototype.PrototypeDSL.variable;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
+
+public class PrototypesAllowedTest {
+
+ @Test
+ public void testModel() {
+ PrototypeVariable personV = variable(prototype( "Person" ).asFact());
+
+ Rule rule = rule("adult" )
+ .build(
+ protoPattern(personV)
+ .expr("age", Index.ConstraintType.GREATER_OR_EQUAL, 18 ),
+ on(personV).execute(p -> p.put("adult", true))
+ );
+
+ Model model = new ModelImpl().addRule(rule );
+ KieBase kieBase = KieBaseBuilder.createKieBaseFromModel(model );
+
+ KieSession ksession = kieBase.newKieSession();
+
+ PrototypeFact personFact = prototype("Person").asFact();
+
+ PrototypeFactInstance sofia = personFact.newInstance();
+ sofia.put("name", "Sofia" );
+ sofia.put("age", 12 );
+
+ ksession.insert(sofia);
+ assertThat(ksession.fireAllRules()).isEqualTo(0);
+ assertThat(sofia.get("adult")).isNull();
+
+ PrototypeFactInstance mario = personFact.newInstance();
+ mario.put("name", "Mario" );
+ mario.put("age", 49 );
+
+ ksession.insert(mario);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ assertThat(mario.get("adult")).isEqualTo(true);
+ }
+
+ @Test
+ public void testPrototypeDrl() {
+ String str =
+ """
+ global java.util.List results
+ rule Adult when
+ $p : Person( age >= 18 )
+ then
+ $p.adult = true;
+ results.add($p.name);
+ end
+ """;
+
+ KieSession ksession = new KieHelper()
+ .addContent(str, ResourceType.DRL)
+ .build(ExecutableModelProject.class, PrototypesOption.ALLOWED)
+ .newKieSession();
+
+ List<String> results = new ArrayList<>();
+ ksession.setGlobal("results", results);
+
+ PrototypeFact personFact = prototype("Person").asFact();
+
+ PrototypeFactInstance sofia = personFact.newInstance();
+ sofia.put("name", "Sofia" );
+ sofia.put("age", 12 );
+
+ ksession.insert(sofia);
+ assertThat(ksession.fireAllRules()).isEqualTo(0);
+ assertThat(sofia.get("adult")).isNull();
+
+ PrototypeFactInstance mario = personFact.newInstance();
+ mario.put("name", "Mario" );
+ mario.put("age", 49 );
+
+ ksession.insert(mario);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ assertThat(mario.get("adult")).isEqualTo(true);
+
+ assertThat(results.size()).isEqualTo(1);
+ assertThat(results.get(0)).isEqualTo("Mario");
+ }
+
+ @Test
+ public void testJoin() {
+ String str =
+ """
+ package org.drools.prototype;
+
+ rule "R1"
+ when
+ $r : Result()
+ $p : Person(age >= 18)
+ then
+ $r.value = $p.name + " can drink";
+ end
+
+ rule "R2"
+ when
+ $r : Result()
+ $p : Person(age < 18)
+ then
+ $r.value = $p.name + " can NOT drink";
+ end
+ """;
+
+ KieSession ksession = new KieHelper()
+ .addContent(str, ResourceType.DRL)
+ .build(ExecutableModelProject.class, PrototypesOption.ALLOWED)
+ .newKieSession();
+
+ PrototypeFact personFact = prototype("Person").asFact();
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 17 );
+ ksession.insert(mark);
+
+ PrototypeFact resultFact = prototype("Result").asFact();
+ PrototypeFactInstance result = resultFact.newInstance();
+ ksession.insert(result);
+
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ assertEquals("Mark can NOT drink", result.get("value"));
+ }
+
+
+ @Test
+ public void testAccessMapFieldsInMvel() {
+ String str =
+ """
+ dialect "mvel"
+ import java.util.Map
+ global java.util.List results
+ rule Adult when
+ $p : Map( age >= 18 )
+ then
+ $p.adult = true;
+ results.add($p.name);
+ end
+ """;
+
+ KieSession ksession = new KieHelper()
+ .addContent(str, ResourceType.DRL)
+ .build(ExecutableModelProject.class)
+ .newKieSession();
+
+ List<String> results = new ArrayList<>();
+ ksession.setGlobal("results", results);
+
+ Map<String, Object> sofia = new HashMap<>();
+ sofia.put( "name", "Sofia" );
+ sofia.put( "age", 12 );
+
+ ksession.insert(sofia);
+ assertThat(ksession.fireAllRules()).isEqualTo(0);
+ assertThat(sofia.get("adult")).isNull();
+
+ Map<String, Object> mario = new HashMap<>();
+ mario.put( "name", "Mario" );
+ mario.put( "age", 49 );
+
+ ksession.insert(mario);
+ assertThat(ksession.fireAllRules()).isEqualTo(1);
+ assertThat(mario.get("adult")).isEqualTo(true);
+
+ assertThat(results.size()).isEqualTo(1);
+ assertThat(results.get(0)).isEqualTo("Mario");
+ }
+}
diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/SegmentPrototypeExpressionTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/SegmentPrototypeExpressionTest.java
index f723540d55..383a1a044f 100644
--- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/SegmentPrototypeExpressionTest.java
+++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/SegmentPrototypeExpressionTest.java
@@ -18,16 +18,15 @@
*/
package org.drools.model.codegen.execmodel;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeExpression;
-import org.drools.model.PrototypeFact;
+import org.drools.model.prototype.PrototypeExpression;
import org.junit.Test;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.drools.model.PrototypeDSL.prototype;
-import static org.drools.model.PrototypeExpression.fixedValue;
-import static org.drools.model.PrototypeExpression.prototypeField;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedFact;
+import static org.drools.model.prototype.PrototypeExpression.fixedValue;
+import static org.drools.model.prototype.PrototypeExpression.prototypeField;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
public class SegmentPrototypeExpressionTest {
@@ -36,11 +35,11 @@ public class SegmentPrototypeExpressionTest {
PrototypeExpression expr1 = prototypeField("fieldA");
PrototypeExpression expr2 = prototypeField("fieldB").add(prototypeField("fieldC")).sub(fixedValue(1));
- Prototype prototype = prototype("test");
- PrototypeFact testFact = (PrototypeFact) createMapBasedFact(prototype);
- testFact.set( "fieldA", 12 );
- testFact.set( "fieldB", 8 );
- testFact.set( "fieldC", 5 );
+ PrototypeFact prototype = prototype("test").asFact();
+ PrototypeFactInstance testFact = prototype.newInstance();
+ testFact.put("fieldA", 12 );
+ testFact.put("fieldB", 8 );
+ testFact.put("fieldC", 5 );
assertThat(expr1.asFunction(prototype).apply(testFact)).isEqualTo(expr2.asFunction(prototype).apply(testFact));
assertThat(expr1.getImpactedFields()).containsExactly("fieldA");
diff --git a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/ExpressionTyperTest.java b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/ExpressionTyperTest.java
index 29a0e20a66..0332dedb9c 100644
--- a/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/ExpressionTyperTest.java
+++ b/drools-model/drools-model-codegen/src/test/java/org/drools/model/codegen/execmodel/generator/ExpressionTyperTest.java
@@ -139,8 +139,8 @@ public class ExpressionTyperTest {
public void testAssignment() {
final TypedExpression expected = typedResult("total = total + $cheese.getPrice()", Integer.class);
final TypedExpression actual = toTypedExpression("total = total + $cheese.price", Object.class,
- new DeclarationSpec("$cheese", Cheese.class),
- new DeclarationSpec("total", Integer.class));
+ new TypedDeclarationSpec("$cheese", Cheese.class),
+ new TypedDeclarationSpec("total", Integer.class));
assertThat(actual).isEqualTo(expected);
}
@@ -173,7 +173,7 @@ public class ExpressionTyperTest {
@Test
public void mapAccessExpr2() {
final TypedExpression expected3 = typedResult("$p.getItems().get(\"type\")", Integer.class, "$p.items[\"type\"]");
- final TypedExpression actual3 = toTypedExpression("$p.items[\"type\"]", Object.class, new DeclarationSpec("$p", Person.class));
+ final TypedExpression actual3 = toTypedExpression("$p.items[\"type\"]", Object.class, new TypedDeclarationSpec("$p", Person.class));
assertThat(actual3).isEqualTo(expected3);
}
@@ -181,7 +181,7 @@ public class ExpressionTyperTest {
public void mapAccessExpr3() {
final TypedExpression expected = typedResult("$p.getItems().get(1)", Integer.class, "$p.items[1]");
final TypedExpression actual = toTypedExpression("$p.items[1]", Object.class,
- new DeclarationSpec("$p", Person.class));
+ new TypedDeclarationSpec("$p", Person.class));
assertThat(actual).isEqualTo(expected);
}
@@ -189,7 +189,7 @@ public class ExpressionTyperTest {
public void arrayAccessExprDeclaration() {
final TypedExpression expected = typedResult("$data.getValues().get(0)", Integer.class, "$data.values[0]");
final TypedExpression actual = toTypedExpression("$data.values[0]", Object.class,
- new DeclarationSpec("$data", Data.class));
+ new TypedDeclarationSpec("$data", Data.class));
assertThat(actual).isEqualTo(expected);
}
@@ -274,9 +274,9 @@ public class ExpressionTyperTest {
assertThat(typedExpression.getExpression().toString()).isEqualTo(expected);
}
- private TypedExpression toTypedExpression(String inputExpression, Class<?> patternType, DeclarationSpec... declarations) {
+ private TypedExpression toTypedExpression(String inputExpression, Class<?> patternType, TypedDeclarationSpec... declarations) {
- for(DeclarationSpec d : declarations) {
+ for(TypedDeclarationSpec d : declarations) {
ruleContext.addDeclaration(d);
}
Expression expression = DrlxParseUtil.parseExpression(inputExpression).getExpr();
@@ -294,8 +294,8 @@ public class ExpressionTyperTest {
return new TypedExpression(resultExpression, classResult, fieldName);
}
- private DeclarationSpec aPersonDecl(String $mark) {
- return new DeclarationSpec($mark, Person.class);
+ private TypedDeclarationSpec aPersonDecl(String $mark) {
+ return new TypedDeclarationSpec($mark, Person.class);
}
private void addInlineCastImport() {
diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/KiePackagesBuilder.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/KiePackagesBuilder.java
index af0d0dd5d9..3189e751f7 100644
--- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/KiePackagesBuilder.java
+++ b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/KiePackagesBuilder.java
@@ -44,7 +44,6 @@ import org.drools.base.definitions.InternalKnowledgePackage;
import org.drools.base.definitions.impl.KnowledgePackageImpl;
import org.drools.base.definitions.rule.impl.QueryImpl;
import org.drools.base.definitions.rule.impl.RuleImpl;
-import org.drools.base.facttemplates.FactTemplateObjectType;
import org.drools.base.rule.Accumulate;
import org.drools.base.rule.AsyncReceive;
import org.drools.base.rule.AsyncSend;
@@ -100,8 +99,6 @@ import org.drools.model.Global;
import org.drools.model.GroupByPattern;
import org.drools.model.Index;
import org.drools.model.Model;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeVariable;
import org.drools.model.Query;
import org.drools.model.Rule;
import org.drools.model.SingleConstraint;
@@ -161,7 +158,6 @@ import static org.drools.model.DSL.declarationOf;
import static org.drools.model.bitmask.BitMaskUtil.calculatePatternMask;
import static org.drools.model.functions.FunctionUtils.toFunctionN;
import static org.drools.model.impl.NamesGenerator.generateName;
-import static org.drools.modelcompiler.facttemplate.FactFactory.prototypeToFactTemplate;
import static org.drools.modelcompiler.util.EvaluationUtil.adaptBitMask;
import static org.drools.modelcompiler.util.TimerUtil.buildTimerExpression;
import static org.drools.modelcompiler.util.TypeDeclarationUtil.createTypeDeclaration;
@@ -1204,20 +1200,11 @@ public class KiePackagesBuilder {
}
ObjectType getObjectType( Variable patternVariable ) {
- return patternVariable instanceof PrototypeVariable ?
- getPrototypeObjectType( (( PrototypeVariable ) patternVariable).getPrototype() ) :
+ return patternVariable.isPrototype() ?
+ PrototypeService.get().getPrototypeObjectType( objectTypeCache, packages, this::createKiePackage, patternVariable ) :
getClassObjectType( patternVariable.getType() );
}
- private ObjectType getPrototypeObjectType( Prototype prototype ) {
- return objectTypeCache.computeIfAbsent( prototype.getFullName(), name -> {
- KnowledgePackageImpl pkg = (KnowledgePackageImpl) packages.computeIfAbsent( prototype.getPackage(), this::createKiePackage );
- FactTemplateObjectType objectType = new FactTemplateObjectType(prototypeToFactTemplate( prototype, pkg ));
- objectType.setEvent(prototype.isEvent());
- return objectType;
- } );
- }
-
private ObjectType getClassObjectType( Class<?> patternClass ) {
return objectTypeCache.computeIfAbsent( patternClass.getCanonicalName(), name -> {
boolean isEvent = false;
diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/PrototypeService.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/PrototypeService.java
new file mode 100644
index 0000000000..66953321d9
--- /dev/null
+++ b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/PrototypeService.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.modelcompiler;
+
+import java.util.Map;
+import java.util.function.Function;
+
+import org.drools.base.base.ObjectType;
+import org.drools.base.common.MissingDependencyException;
+import org.drools.base.definitions.InternalKnowledgePackage;
+import org.drools.model.Variable;
+import org.kie.api.internal.utils.KieService;
+
+public interface PrototypeService extends KieService {
+ String NO_PROTOTYPE = "You're trying to use the Prototypes without having imported it. Please add the module org.drools:drools-model-prototype to your classpath.";
+
+ ObjectType getPrototypeObjectType(Map<String, ObjectType> objectTypeCache, Map<String, InternalKnowledgePackage> packages, Function<String, InternalKnowledgePackage> packageCreator, Variable patternVariable );
+
+ class Holder {
+ private static final PrototypeService INSTANCE = KieService.load(PrototypeService.class);
+ }
+
+ static PrototypeService get() {
+ return present() ? PrototypeService.Holder.INSTANCE : throwExceptionForMissingPrototype();
+ }
+
+ static boolean present() {
+ return PrototypeService.Holder.INSTANCE != null;
+ }
+
+ static <T> T throwExceptionForMissingPrototype() {
+ throw new MissingDependencyException(NO_PROTOTYPE);
+ }
+}
diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/FactFactory.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/FactFactory.java
deleted file mode 100644
index c774491d5a..0000000000
--- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/FactFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.modelcompiler.facttemplate;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.drools.base.definitions.InternalKnowledgePackage;
-import org.drools.base.facttemplates.Event;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateImpl;
-import org.drools.base.facttemplates.FieldTemplate;
-import org.drools.base.facttemplates.FieldTemplateImpl;
-import org.drools.core.reteoo.CoreComponentFactory;
-import org.drools.model.Prototype;
-
-public class FactFactory {
-
- private static final Map<Prototype, FactTemplate> factTemplateCache = new ConcurrentHashMap<>();
-
- public static Fact createMapBasedFact(FactTemplate factTemplate) {
- return new HashMapFactImpl( factTemplate );
- }
-
- public static Fact createMapBasedFact(FactTemplate factTemplate, Map<String, Object> valuesMap) {
- return new HashMapFactImpl( factTemplate, valuesMap );
- }
-
- public static Fact createMapBasedFact(Prototype prototype) {
- return createMapBasedFact( prototypeToFactTemplate( prototype ) );
- }
-
- public static Fact createMapBasedFact(Prototype prototype, Map<String, Object> valuesMap) {
- return createMapBasedFact( prototypeToFactTemplate( prototype ), valuesMap );
- }
-
- public static Event createMapBasedEvent(FactTemplate factTemplate) {
- return new HashMapEventImpl( factTemplate );
- }
-
- public static Event createMapBasedEvent(FactTemplate factTemplate, Map<String, Object> valuesMap) {
- return new HashMapEventImpl( factTemplate, valuesMap );
- }
-
- public static Event createMapBasedEvent(Prototype prototype) {
- return createMapBasedEvent( prototypeToFactTemplate( prototype ) );
- }
-
- public static Event createMapBasedEvent(Prototype prototype, Map<String, Object> valuesMap) {
- return createMapBasedEvent( prototypeToFactTemplate( prototype ), valuesMap );
- }
-
- public static FactTemplate prototypeToFactTemplate( Prototype prototype ) {
- return factTemplateCache.computeIfAbsent(prototype, p -> prototypeToFactTemplate( p, CoreComponentFactory.get().createKnowledgePackage( p.getPackage() ) ) );
- }
-
- public static FactTemplate prototypeToFactTemplate( Prototype prototype, InternalKnowledgePackage pkg ) {
- FieldTemplate[] fieldTemplates = new FieldTemplate[prototype.getFieldNames().size()];
- int i = 0;
- for (String fieldName : prototype.getFieldNames()) {
- fieldTemplates[i++] = new FieldTemplateImpl( fieldName, prototype.getField(fieldName).getType() );
- }
- return new FactTemplateImpl( pkg, prototype.getName(), fieldTemplates );
- }
-}
diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/PrototypeFactFactoryImpl.java b/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/PrototypeFactFactoryImpl.java
deleted file mode 100644
index 65b1c1bfac..0000000000
--- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/PrototypeFactFactoryImpl.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.drools.modelcompiler.facttemplate;
-
-import java.util.Map;
-
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeFact;
-import org.drools.model.PrototypeFactFactory;
-
-public class PrototypeFactFactoryImpl implements PrototypeFactFactory {
-
- @Override
- public PrototypeFact createMapBasedFact(Prototype prototype) {
- return (PrototypeFact) FactFactory.createMapBasedFact(prototype);
- }
-
- @Override
- public PrototypeFact createMapBasedFact(Prototype prototype, Map<String, Object> valuesMap) {
- return (PrototypeFact) FactFactory.createMapBasedFact(prototype, valuesMap);
- }
-}
diff --git a/drools-model/drools-model-compiler/src/main/resources/META-INF/services/org.drools.model.PrototypeFactFactory b/drools-model/drools-model-compiler/src/main/resources/META-INF/services/org.drools.model.PrototypeFactFactory
deleted file mode 100644
index 04d13332a2..0000000000
--- a/drools-model/drools-model-compiler/src/main/resources/META-INF/services/org.drools.model.PrototypeFactFactory
+++ /dev/null
@@ -1 +0,0 @@
-org.drools.modelcompiler.facttemplate.PrototypeFactFactoryImpl
\ No newline at end of file
diff --git a/drools-model/drools-model-prototype/pom.xml b/drools-model/drools-model-prototype/pom.xml
new file mode 100644
index 0000000000..a274b5cb63
--- /dev/null
+++ b/drools-model/drools-model-prototype/pom.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-model</artifactId>
+ <version>999-SNAPSHOT</version>
+ </parent>
+
+ <name>Drools :: Canonical Model :: Prototype</name>
+ <artifactId>drools-model-prototype</artifactId>
+
+ <properties>
+ <java.module.name>org.drools.model.prototype</java.module.name>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-base</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-canonical-model</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.drools</groupId>
+ <artifactId>drools-model-compiler</artifactId>
+ </dependency>
+
+ <dependency><!-- For unit test logging: configure in src/test/resources/logback-test.xml -->
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.assertj</groupId>
+ <artifactId>assertj-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java
similarity index 76%
rename from drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java
rename to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java
index c9443cd479..1952375d11 100644
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeDSL.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeDSL.java
@@ -16,60 +16,48 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.model;
-
-import org.drools.model.functions.Function1;
-import org.drools.model.functions.Predicate1;
-import org.drools.model.functions.Predicate2;
-import org.drools.model.functions.Predicate3;
-import org.drools.model.functions.temporal.TemporalPredicate;
-import org.drools.model.impl.PrototypeImpl;
-import org.drools.model.impl.PrototypeVariableImpl;
+package org.drools.model.prototype;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.function.Function;
+
+import org.drools.model.AlphaIndex;
+import org.drools.model.BetaIndex;
+import org.drools.model.ConstraintOperator;
+import org.drools.model.Index;
+import org.drools.model.PatternDSL;
+import org.drools.model.functions.Function1;
+import org.drools.model.functions.Predicate1;
+import org.drools.model.functions.Predicate2;
+import org.drools.model.functions.Predicate3;
+import org.drools.model.functions.temporal.TemporalPredicate;
+import org.drools.model.prototype.impl.PrototypeVariableImpl;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeFactInstance;
import static java.util.UUID.randomUUID;
import static org.drools.model.PatternDSL.alphaIndexedBy;
import static org.drools.model.PatternDSL.betaIndexedBy;
import static org.drools.model.PatternDSL.reactOn;
-import static org.drools.model.PrototypeExpression.prototypeArrayItem;
-import static org.drools.model.PrototypeExpression.prototypeField;
+import static org.drools.model.prototype.PrototypeExpression.prototypeArrayItem;
+import static org.drools.model.prototype.PrototypeExpression.prototypeField;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
public class PrototypeDSL {
- public static final Prototype DEFAULT_PROTOTYPE = prototype("$DEFAULT_PROTOTYPE$");
+ static final PrototypeFact DEFAULT_PROTOTYPE = prototype("$DEFAULT_PROTOTYPE$").asFact();
- public static Prototype prototype(String name) {
- return new PrototypeImpl(name);
+ public static PrototypeFact prototypeFact(String name) {
+ return prototype(name).asFact();
}
- public static Prototype prototype(String name, String... fields) {
- return new PrototypeImpl(name, fields);
- }
-
- public static Prototype prototype(String name, Prototype.Field... fields) {
- return new PrototypeImpl(name, fields);
- }
-
- public static Prototype.Field field(String name) {
- return new PrototypeImpl.FieldImpl(name);
- }
-
- public static Prototype.Field field(String name, Function<PrototypeFact, Object> extractor) {
- return new PrototypeImpl.FieldImpl(name, extractor);
- }
-
- public static Prototype.Field field(String name, Class<?> type) {
- return new PrototypeImpl.FieldImpl(name, type);
- }
-
- public static Prototype.Field field(String name, Class<?> type, Function<PrototypeFact, Object> extractor) {
- return new PrototypeImpl.FieldImpl(name, type, extractor);
+ public static PrototypeEvent prototypeEvent(String name) {
+ return prototype(name).asEvent();
}
public static PrototypeVariable variable(Prototype prototype) {
@@ -84,7 +72,7 @@ public class PrototypeDSL {
return new PrototypePatternDefImpl(protoVar);
}
- public interface PrototypePatternDef extends PatternDSL.PatternDef<PrototypeFact> {
+ public interface PrototypePatternDef extends PatternDSL.PatternDef<PrototypeFactInstance> {
PrototypePatternDef expr(String fieldName, ConstraintOperator operator, Object value);
PrototypePatternDef expr(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right);
@@ -98,7 +86,7 @@ public class PrototypeDSL {
PrototypePatternDef or();
}
- public static class PrototypePatternDefImpl extends PatternDSL.PatternDefImpl<PrototypeFact> implements PrototypePatternDef {
+ public static class PrototypePatternDefImpl extends PatternDSL.PatternDefImpl<PrototypeFactInstance> implements PrototypePatternDef {
public PrototypePatternDefImpl(PrototypeVariable variable) {
super(variable);
}
@@ -133,7 +121,7 @@ public class PrototypeDSL {
}
Prototype prototype = getPrototype();
- Function1<PrototypeFact, Object> leftExtractor = left.asFunction(prototype);
+ Function1<PrototypeFactInstance, Object> leftExtractor = left.asFunction(prototype);
Set<String> reactOnFields = new HashSet<>();
reactOnFields.addAll(left.getImpactedFields());
@@ -147,10 +135,9 @@ public class PrototypeDSL {
return this;
}
- private static AlphaIndex createAlphaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Function1<PrototypeFact, Object> leftExtractor) {
- if (left.getIndexingKey().isPresent() && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType) {
+ private static AlphaIndex createAlphaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Function1<PrototypeFactInstance, Object> leftExtractor) {
+ if (left.getIndexingKey().isPresent() && right instanceof PrototypeExpression.FixedValue && operator instanceof Index.ConstraintType constraintType) {
String fieldName = left.getIndexingKey().get();
- Index.ConstraintType constraintType = (Index.ConstraintType) operator;
Prototype.Field field = prototype.getField(fieldName);
Object value = ((PrototypeExpression.FixedValue) right).getValue();
@@ -195,12 +182,11 @@ public class PrototypeDSL {
}
private BetaIndex createBetaIndex(PrototypeExpression left, ConstraintOperator operator, PrototypeExpression right, Prototype prototype, Prototype otherPrototype) {
- if (left.getIndexingKey().isPresent() && operator instanceof Index.ConstraintType && right.getIndexingKey().isPresent()) {
+ if (left.getIndexingKey().isPresent() && operator instanceof Index.ConstraintType constraintType && right.getIndexingKey().isPresent()) {
String fieldName = left.getIndexingKey().get();
- Index.ConstraintType constraintType = (Index.ConstraintType) operator;
Prototype.Field field = prototype.getField(fieldName);
- Function1<PrototypeFact, Object> extractor = left.asFunction(prototype);
- Function1<PrototypeFact, Object> otherExtractor = right.asFunction(otherPrototype);
+ Function1<PrototypeFactInstance, Object> extractor = left.asFunction(prototype);
+ Function1<PrototypeFactInstance, Object> otherExtractor = right.asFunction(otherPrototype);
Class<Object> fieldClass = (Class<Object>) (field != null && field.isTyped() ? field.getType() : Object.class);
return betaIndexedBy( fieldClass, constraintType, getFieldIndex(prototype, fieldName, field), extractor, otherExtractor );
@@ -210,13 +196,14 @@ public class PrototypeDSL {
@Override
public PrototypePatternDef expr(TemporalPredicate temporalPredicate, PrototypeVariable other) {
+ if (!getPrototype().isEvent() || !other.getPrototype().isEvent()) {
+ throw new UnsupportedOperationException("Use of temporal predicates is allowed only on events, not on facts.");
+ }
expr( randomUUID().toString(), other, temporalPredicate );
- getPrototype().setAsEvent(true);
- other.getPrototype().setAsEvent(true);
return this;
}
- private Predicate1<PrototypeFact> asPredicate1(Function1<PrototypeFact, Object> left, ConstraintOperator operator, Function1<PrototypeFact, Object> right) {
+ private Predicate1<PrototypeFactInstance> asPredicate1(Function1<PrototypeFactInstance, Object> left, ConstraintOperator operator, Function1<PrototypeFactInstance, Object> right) {
return p -> {
Object leftValue = left.apply(p);
Object rightValue = right.apply(p);
@@ -224,7 +211,7 @@ public class PrototypeDSL {
};
}
- private Predicate2<PrototypeFact, PrototypeFact> asPredicate2(Function1<PrototypeFact, Object> extractor, ConstraintOperator operator, Function1<PrototypeFact, Object> otherExtractor) {
+ private Predicate2<PrototypeFactInstance, PrototypeFactInstance> asPredicate2(Function1<PrototypeFactInstance, Object> extractor, ConstraintOperator operator, Function1<PrototypeFactInstance, Object> otherExtractor) {
return (p1, p2) -> {
Object leftValue = extractor.apply(p1);
Object rightValue = otherExtractor.apply(p2);
@@ -236,23 +223,21 @@ public class PrototypeDSL {
PrototypeVariable leftVar = getPrototypeVariable();
PrototypeVariable[] protoVars = findRightPrototypeVariables(right, leftVar);
- switch (protoVars.length) {
- case 2:
- expr( "expr:" + left + ":" + operator + ":" + right,
- protoVars[0], protoVars[1],
- asPredicate3(leftVar, left, operator, (PrototypeExpression.EvaluableExpression) right, protoVars)
- );
- break;
- default:
- throw new UnsupportedOperationException();
+ if (protoVars.length == 2) {
+ expr("expr:" + left + ":" + operator + ":" + right,
+ protoVars[0], protoVars[1],
+ asPredicate3(leftVar, left, operator, (PrototypeExpression.EvaluableExpression) right, protoVars)
+ );
+ } else {
+ throw new UnsupportedOperationException();
}
return this;
}
- private Predicate3<PrototypeFact, PrototypeFact, PrototypeFact> asPredicate3(PrototypeVariable leftVar, PrototypeExpression left, ConstraintOperator operator, PrototypeExpression.EvaluableExpression right, PrototypeVariable[] protoVars) {
+ private Predicate3<PrototypeFactInstance, PrototypeFactInstance, PrototypeFactInstance> asPredicate3(PrototypeVariable leftVar, PrototypeExpression left, ConstraintOperator operator, PrototypeExpression.EvaluableExpression right, PrototypeVariable[] protoVars) {
return (l, r1, r2) -> {
- Map<PrototypeVariable, PrototypeFact> factsMap = new HashMap<>();
+ Map<PrototypeVariable, PrototypeFactInstance> factsMap = new HashMap<>();
factsMap.put(leftVar, l);
factsMap.put(protoVars[0], r1);
factsMap.put(protoVars[1], r2);
@@ -281,12 +266,12 @@ public class PrototypeDSL {
}
}
- public static class PrototypeSubPatternDefImpl<T> extends PrototypePatternDefImpl {
+ public static class PrototypeSubPatternDefImpl extends PrototypePatternDefImpl {
private final PrototypePatternDefImpl parent;
private final PatternDSL.LogicalCombiner combiner;
public PrototypeSubPatternDefImpl(PrototypePatternDefImpl parent, PatternDSL.LogicalCombiner combiner ) {
- super((PrototypeVariable) parent.variable);
+ super((PrototypeVariable) parent.getFirstVariable());
this.parent = parent;
this.combiner = combiner;
}
@@ -296,7 +281,7 @@ public class PrototypeDSL {
if (combiner == PatternDSL.LogicalCombiner.OR) {
throw new UnsupportedOperationException();
}
- parent.items.add( new PatternDSL.CombinedPatternExprItem<>( combiner, this.getItems() ));
+ parent.getItems().add( new PatternDSL.CombinedPatternExprItem<>( combiner, this.getItems() ));
return parent;
}
@@ -305,7 +290,7 @@ public class PrototypeDSL {
if (combiner == PatternDSL.LogicalCombiner.AND) {
throw new UnsupportedOperationException();
}
- parent.items.add( new PatternDSL.CombinedPatternExprItem<>( combiner, this.getItems() ));
+ parent.getItems().add( new PatternDSL.CombinedPatternExprItem<>( combiner, this.getItems() ));
return parent;
}
}
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeExpression.java
similarity index 90%
rename from drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java
rename to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeExpression.java
index 4071ed05a7..26c1169dc3 100644
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeExpression.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeExpression.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.model;
+package org.drools.model.prototype;
import java.util.Arrays;
import java.util.Collection;
@@ -29,14 +29,16 @@ import java.util.Set;
import org.drools.model.functions.Function1;
import org.drools.model.functions.Function2;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
public interface PrototypeExpression {
interface EvaluableExpression {
- Object evaluate(Map<PrototypeVariable, PrototypeFact> factsMap);
+ Object evaluate(Map<PrototypeVariable, PrototypeFactInstance> factsMap);
}
- Function1<PrototypeFact, Object> asFunction(Prototype prototype);
+ Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype);
Collection<String> getImpactedFields();
@@ -104,7 +106,7 @@ public interface PrototypeExpression {
}
@Override
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
return x -> value;
}
@@ -123,7 +125,7 @@ public interface PrototypeExpression {
}
@Override
- public Object evaluate(Map<PrototypeVariable, PrototypeFact> factsMap) {
+ public Object evaluate(Map<PrototypeVariable, PrototypeFactInstance> factsMap) {
return value;
}
}
@@ -133,7 +135,7 @@ public interface PrototypeExpression {
INSTANCE;
@Override
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
return p -> p;
}
@@ -157,7 +159,7 @@ public interface PrototypeExpression {
}
@Override
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
return prototype.getFieldValueExtractor(fieldName)::apply;
}
@@ -200,7 +202,7 @@ public interface PrototypeExpression {
}
@Override
- public Object evaluate(Map<PrototypeVariable, PrototypeFact> factsMap) {
+ public Object evaluate(Map<PrototypeVariable, PrototypeFactInstance> factsMap) {
return protoVar.getPrototype().getFieldValueExtractor(getIndexingKey().get()).apply(factsMap.get(protoVar));
}
@@ -221,7 +223,7 @@ public interface PrototypeExpression {
}
@Override
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
return fact -> extractArrayItem( prototype.getFieldValueExtractor(fieldName).apply(fact) );
}
@@ -263,19 +265,21 @@ public interface PrototypeExpression {
this.first = first;
this.second = second;
}
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
- return first.asFunction(prototype).andThen(this::object2PrototypeFact).andThen(second.asFunction(prototype));
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
+ return first.asFunction(prototype).andThen(this::object2PrototypeFactInstance).andThen(second.asFunction(prototype));
}
- private PrototypeFact object2PrototypeFact(Object object) {
+ private PrototypeFactInstance object2PrototypeFactInstance(Object object) {
if (object == Prototype.UNDEFINED_VALUE) {
- return PrototypeFactFactory.get().createMapBasedFact(PrototypeDSL.DEFAULT_PROTOTYPE);
+ return PrototypeDSL.DEFAULT_PROTOTYPE.newInstance();
}
- if (object instanceof PrototypeFact) {
- return (PrototypeFact) object;
+ if (object instanceof PrototypeFactInstance) {
+ return (PrototypeFactInstance) object;
}
if (object instanceof Map) {
- return PrototypeFactFactory.get().createMapBasedFact(PrototypeDSL.DEFAULT_PROTOTYPE, (Map<String, Object>) object);
+ PrototypeFactInstance fact = PrototypeDSL.DEFAULT_PROTOTYPE.newInstance();
+ ((Map<String, Object>) object).forEach(fact::put);
+ return fact;
}
throw new UnsupportedOperationException("Cannot convert " + object + " into a Prototype");
}
@@ -392,8 +396,8 @@ public interface PrototypeExpression {
private final PrototypeExpression right;
@Override
- public Function1<PrototypeFact, Object> asFunction(Prototype prototype) {
- return (PrototypeFact fact) -> {
+ public Function1<PrototypeFactInstance, Object> asFunction(Prototype prototype) {
+ return (PrototypeFactInstance fact) -> {
Object leftValue = left.asFunction(prototype).apply(fact);
Object rightValue = right.asFunction(prototype).apply(fact);
return op.operator.apply(leftValue, rightValue);
@@ -426,7 +430,7 @@ public interface PrototypeExpression {
}
@Override
- public Object evaluate(Map<PrototypeVariable, PrototypeFact> factsMap) {
+ public Object evaluate(Map<PrototypeVariable, PrototypeFactInstance> factsMap) {
Object leftValue = ((EvaluableExpression) left).evaluate(factsMap);
Object rightValue = ((EvaluableExpression) right).evaluate(factsMap);
return op.operator.apply(leftValue, rightValue);
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeVariable.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeVariable.java
similarity index 78%
copy from drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeVariable.java
copy to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeVariable.java
index 9bba12c0a8..8f9fd5949b 100644
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/PrototypeVariable.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/PrototypeVariable.java
@@ -16,8 +16,17 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.model;
+package org.drools.model.prototype;
-public interface PrototypeVariable extends Variable<PrototypeFact> {
+import org.drools.model.Variable;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
+
+public interface PrototypeVariable extends Variable<PrototypeFactInstance> {
Prototype getPrototype();
+
+ @Override
+ default boolean isPrototype() {
+ return true;
+ }
}
diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/HashMapEventImpl.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/HashMapEventImpl.java
similarity index 71%
rename from drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/HashMapEventImpl.java
rename to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/HashMapEventImpl.java
index 0b0005f2a7..b929f0a632 100644
--- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/HashMapEventImpl.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/HashMapEventImpl.java
@@ -16,33 +16,33 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.modelcompiler.facttemplate;
+package org.drools.model.prototype.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
-import org.drools.base.facttemplates.Event;
-import org.drools.base.facttemplates.FactTemplate;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeEventInstance;
import static org.drools.model.functions.temporal.TimeUtil.unitToLong;
-public class HashMapEventImpl extends HashMapFactImpl implements Event {
+public class HashMapEventImpl extends HashMapFactImpl implements PrototypeEventInstance {
private long timestamp = -1;
private long expiration = Long.MAX_VALUE;
- public HashMapEventImpl(FactTemplate factTemplate) {
- this( factTemplate, new HashMap<>() );
+ public HashMapEventImpl(Prototype prototype) {
+ this( prototype, new HashMap<>() );
}
- public HashMapEventImpl(FactTemplate factTemplate, Map<String, Object> valuesMap) {
- super(factTemplate, valuesMap);
+ public HashMapEventImpl(Prototype prototype, Map<String, Object> valuesMap) {
+ super(prototype, valuesMap);
}
- public HashMapEventImpl(UUID uuid, FactTemplate factTemplate, Map<String, Object> valuesMap, long timestamp, long expiration) {
- super(uuid, factTemplate, valuesMap);
+ public HashMapEventImpl(UUID uuid, Prototype prototype, Map<String, Object> valuesMap, long timestamp, long expiration) {
+ super(uuid, prototype, valuesMap);
this.timestamp = timestamp;
this.expiration = expiration;
}
@@ -65,6 +65,6 @@ public class HashMapEventImpl extends HashMapFactImpl implements Event {
@Override
public String toString() {
- return "Event " + factTemplate.getName() + " with values = " + valuesMap;
+ return "Event " + prototype.getFullName() + " with values = " + valuesMap;
}
}
diff --git a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/HashMapFactImpl.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/HashMapFactImpl.java
similarity index 72%
rename from drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/HashMapFactImpl.java
rename to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/HashMapFactImpl.java
index f036180e22..ac085447cc 100644
--- a/drools-model/drools-model-compiler/src/main/java/org/drools/modelcompiler/facttemplate/HashMapFactImpl.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/HashMapFactImpl.java
@@ -16,38 +16,37 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.modelcompiler.facttemplate;
+package org.drools.model.prototype.impl;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.model.PrototypeFact;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
-public class HashMapFactImpl implements Fact, PrototypeFact, Serializable {
+public class HashMapFactImpl implements PrototypeFactInstance, Serializable {
protected final UUID uuid;
- protected final FactTemplate factTemplate;
+ protected final Prototype prototype;
protected final Map<String, Object> valuesMap;
- public HashMapFactImpl( FactTemplate factTemplate ) {
- this( factTemplate, new HashMap<>() );
+ public HashMapFactImpl( Prototype prototype ) {
+ this( prototype, new HashMap<>() );
}
- public HashMapFactImpl( FactTemplate factTemplate, Map<String, Object> valuesMap ) {
+ public HashMapFactImpl( Prototype prototype, Map<String, Object> valuesMap ) {
this.uuid = UUID.randomUUID();
- this.factTemplate = factTemplate;
+ this.prototype = prototype;
this.valuesMap = valuesMap;
}
- public HashMapFactImpl( UUID uuid, FactTemplate factTemplate, Map<String, Object> valuesMap ) {
+ public HashMapFactImpl( UUID uuid, Prototype prototype, Map<String, Object> valuesMap ) {
this.uuid = uuid;
- this.factTemplate = factTemplate;
+ this.prototype = prototype;
this.valuesMap = valuesMap;
}
@@ -56,8 +55,8 @@ public class HashMapFactImpl implements Fact, PrototypeFact, Serializable {
}
@Override
- public FactTemplate getFactTemplate() {
- return factTemplate;
+ public Prototype getPrototype() {
+ return prototype;
}
@Override
@@ -71,7 +70,7 @@ public class HashMapFactImpl implements Fact, PrototypeFact, Serializable {
}
@Override
- public void set( String name, Object value ) {
+ public void put(String name, Object value ) {
valuesMap.put(name, value);
}
@@ -82,7 +81,7 @@ public class HashMapFactImpl implements Fact, PrototypeFact, Serializable {
@Override
public String toString() {
- return "Fact " + factTemplate.getName() + " with values = " + valuesMap;
+ return "Fact " + prototype.getFullName() + " with values = " + valuesMap;
}
@Override
diff --git a/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeBuilderImpl.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeBuilderImpl.java
new file mode 100644
index 0000000000..bf5fad5e73
--- /dev/null
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeBuilderImpl.java
@@ -0,0 +1,82 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.prototype.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeBuilder;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
+
+public class PrototypeBuilderImpl implements PrototypeBuilder {
+
+ private final String name;
+
+ private final List<Prototype.Field> fields = new ArrayList<>();
+
+ public PrototypeBuilderImpl(String name) {
+ this.name = name;
+ }
+
+ @Override
+ public PrototypeBuilder withField(String name) {
+ fields.add(new PrototypeImpl.FieldImpl(name));
+ return this;
+ }
+
+ @Override
+ public PrototypeBuilder withField(String name, Function<PrototypeFactInstance, Object> extractor) {
+ fields.add(new PrototypeImpl.FieldImpl(name, extractor));
+ return this;
+ }
+
+ @Override
+ public PrototypeBuilder withField(String name, Class<?> type) {
+ fields.add(new PrototypeImpl.FieldImpl(name, type));
+ return this;
+ }
+
+ @Override
+ public PrototypeBuilder withField(String name, Class<?> type, Function<PrototypeFactInstance, Object> extractor) {
+ fields.add(new PrototypeImpl.FieldImpl(name, type, extractor));
+ return this;
+ }
+
+ @Override
+ public PrototypeFact asFact() {
+ return new PrototypeFactImpl( name, fields );
+ }
+
+ @Override
+ public PrototypeEvent asEvent() {
+ return new PrototypeEventImpl( name, fields );
+ }
+
+ public static class CreatorImpl implements PrototypeBuilder.Creator {
+
+ @Override
+ public PrototypeBuilder newPrototype(String name) {
+ return new PrototypeBuilderImpl(name);
+ }
+ }
+}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/Event.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeEventImpl.java
similarity index 62%
copy from drools-base/src/main/java/org/drools/base/facttemplates/Event.java
copy to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeEventImpl.java
index 8692847bdd..e591323c17 100644
--- a/drools-base/src/main/java/org/drools/base/facttemplates/Event.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeEventImpl.java
@@ -16,19 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.base.facttemplates;
+package org.drools.model.prototype.impl;
-import java.util.concurrent.TimeUnit;
+import java.util.List;
-public interface Event extends Fact {
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeEventInstance;
- long getTimestamp();
+public class PrototypeEventImpl extends PrototypeImpl implements PrototypeEvent {
- long getExpiration();
+ public PrototypeEventImpl(String name, List<Field> fields ) {
+ super(name, fields);
+ }
- Event withExpiration( long value, TimeUnit unit );
+ @Override
+ public PrototypeEventInstance newInstance() {
+ return new HashMapEventImpl(this);
+ }
- default boolean isEvent() {
+ @Override
+ public boolean isEvent() {
return true;
}
}
diff --git a/drools-base/src/main/java/org/drools/base/facttemplates/Fact.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeFactImpl.java
similarity index 62%
copy from drools-base/src/main/java/org/drools/base/facttemplates/Fact.java
copy to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeFactImpl.java
index 3073a652b5..44cc9c869f 100644
--- a/drools-base/src/main/java/org/drools/base/facttemplates/Fact.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeFactImpl.java
@@ -16,21 +16,26 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.base.facttemplates;
+package org.drools.model.prototype.impl;
-import java.util.Map;
+import java.util.List;
-public interface Fact {
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
- Object get(String name);
+public class PrototypeFactImpl extends PrototypeImpl implements PrototypeFact {
- void set(String name, Object value);
-
- Map<String, Object> asMap();
+ public PrototypeFactImpl( String name, List<Field> fields ) {
+ super(name, fields);
+ }
- FactTemplate getFactTemplate();
+ @Override
+ public PrototypeFactInstance newInstance() {
+ return new HashMapFactImpl(this);
+ }
- default boolean isEvent() {
+ @Override
+ public boolean isEvent() {
return false;
}
}
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/impl/PrototypeImpl.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeImpl.java
similarity index 63%
rename from drools-model/drools-canonical-model/src/main/java/org/drools/model/impl/PrototypeImpl.java
rename to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeImpl.java
index 002e2c3acf..989dafe042 100644
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/impl/PrototypeImpl.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeImpl.java
@@ -16,49 +16,59 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.model.impl;
+package org.drools.model.prototype.impl;
+import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
+import java.util.List;
import java.util.Objects;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.function.Function;
-import java.util.stream.Stream;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeFact;
+import org.drools.core.reteoo.CoreComponentFactory;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
import static org.drools.model.impl.RuleBuilder.DEFAULT_PACKAGE;
-public class PrototypeImpl implements Prototype {
+public abstract class PrototypeImpl implements Prototype, Serializable {
private final String pkg;
private final String name;
private final SortedMap<String, Field> fields;
- private boolean event;
+ public PrototypeImpl( String fulllName, List<Field> fields ) {
+ int lastDot = fulllName.lastIndexOf('.');
+ this.pkg = lastDot > 0 ? fulllName.substring(0, lastDot) : DEFAULT_PACKAGE;
+ this.name = lastDot > 0 ? fulllName.substring(lastDot+1) : fulllName;
+ this.fields = initFields(fields);
+ registerPrototype();
+ }
- public PrototypeImpl( String name ) {
- this(name, new Field[0]);
+ public PrototypeImpl( String pkg, String name, List<Field> fields ) {
+ this.pkg = pkg != null && !pkg.isEmpty() ? pkg : DEFAULT_PACKAGE;
+ this.name = name;
+ this.fields = initFields(fields);
+ registerPrototype();
}
- public PrototypeImpl( String name, String... fields ) {
- this(name, Stream.of(fields).map(FieldImpl::new).toArray(Field[]::new));
+ private void registerPrototype() {
+ CoreComponentFactory.get().createKnowledgePackage(pkg).addPrototype(this);
}
- public PrototypeImpl( String name, Field... fields ) {
- int lastDot = name.lastIndexOf('.');
- this.pkg = lastDot > 0 ? name.substring(0, lastDot) : DEFAULT_PACKAGE;
- this.name = lastDot > 0 ? name.substring(lastDot+1) : name;
- if (fields != null && fields.length > 0) {
- this.fields = new TreeMap<>();
+ private SortedMap<String, Field> initFields(List<Field> fields) {
+ final SortedMap<String, Field> sortedFields;
+ if (fields != null && !fields.isEmpty()) {
+ sortedFields = new TreeMap<>();
for (Field field : fields) {
- this.fields.put(field.getName(), field);
+ sortedFields.put(field.getName(), field);
}
} else {
- this.fields = Collections.emptySortedMap();
+ sortedFields = Collections.emptySortedMap();
}
+ return sortedFields;
}
@Override
@@ -77,7 +87,7 @@ public class PrototypeImpl implements Prototype {
}
@Override
- public Field getField(String name) {
+ public Prototype.Field getField(String name) {
return fields.get(name);
}
@@ -96,7 +106,7 @@ public class PrototypeImpl implements Prototype {
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (!(o instanceof PrototypeImpl)) return false;
PrototypeImpl prototype = (PrototypeImpl) o;
return pkg.equals(prototype.pkg) && name.equals(prototype.name) && fields.equals(prototype.fields);
}
@@ -106,18 +116,9 @@ public class PrototypeImpl implements Prototype {
return Objects.hash(pkg, name, fields);
}
- public boolean isEvent() {
- return event;
- }
-
- public PrototypeImpl setAsEvent(boolean event) {
- this.event = event;
- return this;
- }
-
- public static class FieldImpl implements Prototype.Field {
+ public static class FieldImpl implements Prototype.Field, Serializable {
private final String name;
- private final Function<PrototypeFact, Object> extractor;
+ private final Function<PrototypeFactInstance, Object> extractor;
private final boolean typed;
private final Class<?> type;
@@ -125,7 +126,7 @@ public class PrototypeImpl implements Prototype {
this(name, p -> p.get(name));
}
- public FieldImpl( String name, Function<PrototypeFact, Object> extractor ) {
+ public FieldImpl( String name, Function<PrototypeFactInstance, Object> extractor ) {
this.name = name;
this.extractor = extractor;
this.type = Object.class;
@@ -136,7 +137,7 @@ public class PrototypeImpl implements Prototype {
this(name, type, p -> p.get(name));
}
- public FieldImpl( String name, Class<?> type, Function<PrototypeFact, Object> extractor ) {
+ public FieldImpl( String name, Class<?> type, Function<PrototypeFactInstance, Object> extractor ) {
this.name = name;
this.extractor = extractor;
this.type = type;
@@ -149,7 +150,7 @@ public class PrototypeImpl implements Prototype {
}
@Override
- public Function<PrototypeFact, Object> getExtractor() {
+ public Function<PrototypeFactInstance, Object> getExtractor() {
return extractor;
}
diff --git a/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeServiceImpl.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeServiceImpl.java
new file mode 100644
index 0000000000..204084f7d6
--- /dev/null
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeServiceImpl.java
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.prototype.impl;
+
+import java.util.Map;
+import java.util.function.Function;
+
+import org.drools.base.base.ObjectType;
+import org.drools.base.definitions.InternalKnowledgePackage;
+import org.drools.base.definitions.impl.KnowledgePackageImpl;
+import org.drools.base.prototype.PrototypeObjectType;
+import org.drools.model.Variable;
+import org.drools.model.prototype.PrototypeVariable;
+import org.drools.modelcompiler.PrototypeService;
+import org.kie.api.prototype.Prototype;
+
+public class PrototypeServiceImpl implements PrototypeService {
+
+ public ObjectType getPrototypeObjectType(Map<String, ObjectType> objectTypeCache, Map<String, InternalKnowledgePackage> packages, Function<String, InternalKnowledgePackage> packageCreator, Variable patternVariable ) {
+ Prototype prototype = ((PrototypeVariable) patternVariable).getPrototype();
+ return objectTypeCache.computeIfAbsent( prototype.getFullName(), name -> {
+ KnowledgePackageImpl pkg = (KnowledgePackageImpl) packages.computeIfAbsent(prototype.getPackage(), packageCreator );
+ PrototypeObjectType objectType = new PrototypeObjectType(prototype);
+ objectType.setEvent(prototype.isEvent());
+ return objectType;
+ } );
+ }
+}
diff --git a/drools-model/drools-canonical-model/src/main/java/org/drools/model/impl/PrototypeVariableImpl.java b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeVariableImpl.java
similarity index 76%
rename from drools-model/drools-canonical-model/src/main/java/org/drools/model/impl/PrototypeVariableImpl.java
rename to drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeVariableImpl.java
index f1ca5d4a18..08c9c99120 100644
--- a/drools-model/drools-canonical-model/src/main/java/org/drools/model/impl/PrototypeVariableImpl.java
+++ b/drools-model/drools-model-prototype/src/main/java/org/drools/model/prototype/impl/PrototypeVariableImpl.java
@@ -16,23 +16,24 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.drools.model.impl;
+package org.drools.model.prototype.impl;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeFact;
-import org.drools.model.PrototypeVariable;
+import org.drools.model.impl.DeclarationImpl;
+import org.drools.model.prototype.PrototypeVariable;
+import org.kie.api.prototype.Prototype;
+import org.kie.api.prototype.PrototypeFactInstance;
-public class PrototypeVariableImpl extends DeclarationImpl<PrototypeFact> implements PrototypeVariable {
+public class PrototypeVariableImpl extends DeclarationImpl<PrototypeFactInstance> implements PrototypeVariable {
private final Prototype prototype;
public PrototypeVariableImpl( Prototype prototype ) {
- super( PrototypeFact.class );
+ super( PrototypeFactInstance.class );
this.prototype = prototype;
}
public PrototypeVariableImpl( Prototype prototype, String name ) {
- super( PrototypeFact.class, name );
+ super( PrototypeFactInstance.class, name );
this.prototype = prototype;
}
diff --git a/drools-model/drools-model-prototype/src/main/resources/META-INF/services/org.drools.modelcompiler.PrototypeService b/drools-model/drools-model-prototype/src/main/resources/META-INF/services/org.drools.modelcompiler.PrototypeService
new file mode 100644
index 0000000000..b3f7c20eee
--- /dev/null
+++ b/drools-model/drools-model-prototype/src/main/resources/META-INF/services/org.drools.modelcompiler.PrototypeService
@@ -0,0 +1 @@
+org.drools.model.prototype.impl.PrototypeServiceImpl
\ No newline at end of file
diff --git a/drools-model/drools-model-prototype/src/main/resources/META-INF/services/org.kie.api.prototype.PrototypeBuilder$Creator b/drools-model/drools-model-prototype/src/main/resources/META-INF/services/org.kie.api.prototype.PrototypeBuilder$Creator
new file mode 100644
index 0000000000..2910ba470f
--- /dev/null
+++ b/drools-model/drools-model-prototype/src/main/resources/META-INF/services/org.kie.api.prototype.PrototypeBuilder$Creator
@@ -0,0 +1 @@
+org.drools.model.prototype.impl.PrototypeBuilderImpl$CreatorImpl
\ No newline at end of file
diff --git a/drools-model/drools-model-prototype/src/test/java/org/drools/model/prototype/PrototypeFieldExtractorTest.java b/drools-model/drools-model-prototype/src/test/java/org/drools/model/prototype/PrototypeFieldExtractorTest.java
new file mode 100644
index 0000000000..0b081f3c43
--- /dev/null
+++ b/drools-model/drools-model-prototype/src/test/java/org/drools/model/prototype/PrototypeFieldExtractorTest.java
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.drools.model.prototype;
+
+import org.drools.base.prototype.PrototypeFieldExtractor;
+import org.drools.base.prototype.PrototypeObjectType;
+import org.drools.base.rule.Declaration;
+import org.drools.base.rule.Pattern;
+import org.drools.base.rule.accessor.ReadAccessor;
+import org.junit.Test;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
+
+public class PrototypeFieldExtractorTest {
+ @Test
+ public void testExtractor() {
+ PrototypeFact cheesePrototype = prototype("org.sore.Cheese").withField("name", String.class).withField("price", Integer.class).asFact();
+
+ final ReadAccessor extractName = new PrototypeFieldExtractor(cheesePrototype, "name" );
+ final ReadAccessor extractPrice = new PrototypeFieldExtractor(cheesePrototype, "price" );
+
+ PrototypeFactInstance stilton = cheesePrototype.newInstance();
+ stilton.put("name", "stilton" );
+ stilton.put("price", 200 );
+
+ assertThat(extractName.getValue(null, stilton)).isEqualTo("stilton");
+
+ assertThat(extractPrice.getValue(null, stilton)).isEqualTo(200);
+
+ assertThat(extractName.isNullValue(null, stilton)).isFalse();
+
+ stilton.put("name", null );
+
+ assertThat(extractName.isNullValue(null, stilton)).isTrue();
+ assertThat(extractPrice.isNullValue(null, stilton)).isFalse();
+
+ PrototypeFactInstance brie = cheesePrototype.newInstance();
+ brie.put("name", "brie" );
+ brie.put("price", 55 );
+
+ assertThat(extractName.getValue(null, brie)).isEqualTo("brie");
+
+ assertThat(extractPrice.getValue(null, brie)).isEqualTo(55);
+
+ assertThat(extractName.isNullValue(null, brie)).isFalse();
+
+ brie.put("name", null );
+
+ assertThat(extractName.isNullValue(null, brie)).isTrue();
+ assertThat(extractPrice.isNullValue(null, stilton)).isFalse();
+ }
+
+ @Test
+ public void testDeclaration() {
+ PrototypeFact cheesePrototype = prototype("org.sore.Cheese").withField("name", String.class).withField("price", Integer.class).asFact();
+ ReadAccessor extractName = new PrototypeFieldExtractor(cheesePrototype, "name" );
+ Pattern pattern = new Pattern( 0, new PrototypeObjectType(cheesePrototype) );
+ Declaration declaration = new Declaration( "typeOfCheese", extractName, pattern );
+
+ PrototypeFactInstance brie = cheesePrototype.newInstance();
+ brie.put("name", "brie" );
+ brie.put("price", 55 );
+
+ // Check we can extract Declarations correctly
+ assertThat(declaration.getValue(null, brie)).isEqualTo("brie");
+ }
+}
diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
index 7b31676cce..dd634bfcf1 100644
--- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
+++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/LHSPhase.java
@@ -35,6 +35,7 @@ import com.github.javaparser.ast.expr.EnclosedExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
@@ -54,6 +55,7 @@ import org.drools.mvelcompiler.ast.UnalteredTypedExpression;
import org.drools.mvelcompiler.ast.VariableDeclaratorTExpr;
import org.drools.mvelcompiler.context.Declaration;
import org.drools.mvelcompiler.context.MvelCompilerContext;
+import org.drools.mvelcompiler.util.TypeUtils;
import org.drools.util.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -132,7 +134,9 @@ public class LHSPhase implements DrlGenericVisitor<TypedExpression, Void> {
// a part of a larger FieldAccessExpr. e.g. [$p.address] of [$p.address.city]
return tryParseItAsGetter(n, fieldAccessScope)
.orElse(new UnalteredTypedExpression(n));
- } else if(parentIsArrayAccessExpr(n)) {
+ } else if (fieldAccessScope.getType().map(TypeUtils::isMapAccessField).orElse(false) && parentIsAssignExpr(n)) {
+ return new MapPutExprT(fieldAccessScope, new StringLiteralExpr(n.getName().toString()), rhsOrNull(), fieldAccessScope.getType());
+ } else if (parentIsArrayAccessExpr(n)) {
return tryParseItAsMap(n, fieldAccessScope)
.map(Optional::of)
.orElseGet(() -> tryParseItAsSetter(n, fieldAccessScope, getRHSType()))
@@ -378,6 +382,10 @@ public class LHSPhase implements DrlGenericVisitor<TypedExpression, Void> {
return n.getParentNode().filter(p -> p instanceof ArrayAccessExpr).isPresent();
}
+ private boolean parentIsAssignExpr(Node n) {
+ return n.getParentNode().filter(p -> p instanceof AssignExpr).isPresent();
+ }
+
private Class<?> getRHSType() {
return rhs
.flatMap(TypedExpression::getType)
diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/PreprocessCompiler.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/PreprocessCompiler.java
index 3db5bb46f5..35976cbb72 100644
--- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/PreprocessCompiler.java
+++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/PreprocessCompiler.java
@@ -24,13 +24,19 @@ import java.util.Set;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.VariableDeclarator;
+import com.github.javaparser.ast.expr.AssignExpr;
+import com.github.javaparser.ast.expr.Expression;
+import com.github.javaparser.ast.expr.FieldAccessExpr;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.StringLiteralExpr;
import com.github.javaparser.ast.expr.TextBlockLiteralExpr;
import com.github.javaparser.ast.stmt.BlockStmt;
import org.drools.mvel.parser.MvelParser;
+import org.drools.mvel.parser.ast.expr.DrlNameExpr;
import org.drools.mvel.parser.ast.expr.ModifyStatement;
+import org.drools.mvelcompiler.ast.MapGetExprT;
+import org.drools.mvelcompiler.ast.MapPutExprT;
import static com.github.javaparser.ast.NodeList.nodeList;
@@ -41,7 +47,7 @@ public class PreprocessCompiler {
private static final PreprocessPhase preprocessPhase = new PreprocessPhase();
- public CompiledBlockResult compile(String mvelBlock) {
+ public CompiledBlockResult compile(String mvelBlock, Set<String> prototypes) {
BlockStmt mvelExpression = MvelParser.parseBlock(mvelBlock);
@@ -53,9 +59,9 @@ public class PreprocessCompiler {
StringLiteralExpr stringLiteralExpr = preprocessPhase.replaceTextBlockWithConcatenatedStrings(e);
parentNode.ifPresent(p -> {
- if(p instanceof VariableDeclarator) {
+ if (p instanceof VariableDeclarator) {
((VariableDeclarator) p).setInitializer(stringLiteralExpr);
- } else if(p instanceof MethodCallExpr) {
+ } else if (p instanceof MethodCallExpr) {
// """exampleString""".formatted("arg0", 2);
((MethodCallExpr) p).setScope(stringLiteralExpr);
}
@@ -77,6 +83,38 @@ public class PreprocessCompiler {
s.remove();
});
+ if (!prototypes.isEmpty()) {
+ rewriteConsequenceForPrototype(mvelExpression, prototypes);
+ }
+
return new CompiledBlockResult(mvelExpression.getStatements()).setUsedBindings(usedBindings);
}
+
+ private void rewriteConsequenceForPrototype(BlockStmt ruleConsequence, Set<String> prototypes) {
+ for (AssignExpr assignExpr : ruleConsequence.findAll(AssignExpr.class)) {
+ if (assignExpr.getTarget().isFieldAccessExpr()) {
+ FieldAccessExpr fieldAccessExpr = assignExpr.getTarget().asFieldAccessExpr();
+ String assignedVariable = getAssignedVariable(fieldAccessExpr);
+ if (prototypes.contains(assignedVariable)) {
+ assignExpr.replace(new MapPutExprT(new NameExpr(assignedVariable), new StringLiteralExpr(fieldAccessExpr.getNameAsString()),
+ assignExpr.getValue(), Optional.empty()).toJavaExpression());
+ }
+ }
+ }
+
+ for (FieldAccessExpr fieldAccessExpr : ruleConsequence.findAll(FieldAccessExpr.class)) {
+ String assignedVariable = getAssignedVariable(fieldAccessExpr);
+ if (prototypes.contains(assignedVariable)) {
+ fieldAccessExpr.replace( new MapGetExprT(new NameExpr(assignedVariable), fieldAccessExpr.getNameAsString() ).toJavaExpression() );
+ }
+ }
+ }
+
+ private static String getAssignedVariable(FieldAccessExpr fieldAccessExpr) {
+ Expression scope = fieldAccessExpr.getScope();
+ if (scope instanceof DrlNameExpr drlName) {
+ return drlName.getName().toString();
+ }
+ return scope instanceof NameExpr ? scope.toString() : null;
+ }
}
diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
index 533fab5680..6751147ef9 100644
--- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
+++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/RHSPhase.java
@@ -22,7 +22,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
-import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -57,7 +56,6 @@ import org.drools.mvel.parser.ast.expr.BigDecimalLiteralExpr;
import org.drools.mvel.parser.ast.expr.BigIntegerLiteralExpr;
import org.drools.mvel.parser.ast.expr.DrlNameExpr;
import org.drools.mvel.parser.ast.expr.ListCreationLiteralExpression;
-import org.drools.mvel.parser.ast.expr.ListCreationLiteralExpressionElement;
import org.drools.mvel.parser.ast.expr.MapCreationLiteralExpression;
import org.drools.mvel.parser.ast.visitor.DrlGenericVisitor;
import org.drools.mvelcompiler.ast.BigDecimalArithmeticExprT;
@@ -76,6 +74,7 @@ import org.drools.mvelcompiler.ast.ListAccessExprT;
import org.drools.mvelcompiler.ast.ListExprT;
import org.drools.mvelcompiler.ast.LongLiteralExpressionT;
import org.drools.mvelcompiler.ast.MapExprT;
+import org.drools.mvelcompiler.ast.MapGetExprT;
import org.drools.mvelcompiler.ast.ObjectCreationExpressionT;
import org.drools.mvelcompiler.ast.SimpleNameTExpr;
import org.drools.mvelcompiler.ast.StringLiteralExpressionT;
@@ -84,6 +83,7 @@ import org.drools.mvelcompiler.ast.UnalteredTypedExpression;
import org.drools.mvelcompiler.context.Declaration;
import org.drools.mvelcompiler.context.MvelCompilerContext;
import org.drools.mvelcompiler.util.MethodResolutionUtils;
+import org.drools.mvelcompiler.util.TypeUtils;
import org.drools.mvelcompiler.util.VisitorContext;
import org.drools.util.ClassUtils;
import org.drools.util.MethodUtils.NullType;
@@ -236,6 +236,17 @@ public class RHSPhase implements DrlGenericVisitor<TypedExpression, VisitorConte
@Override
public TypedExpression visit(FieldAccessExpr n, VisitorContext arg) {
TypedExpression scope = n.getScope().accept(this, arg);
+ if (scope.getType().map(TypeUtils::isMapAccessField).orElse(false)) {
+ String key = n.getName().toString();
+
+ // "size" is an edge case and could mean both the size of the map and the value of the key "size".
+ // To keep backward compatibility it is necessary to assume that it is the size of the map,
+ // but this implies that at the moment it is not possible to read the value of the "size" key
+ // using the field access notation
+ if (!"size".equals(key)) {
+ return new MapGetExprT(scope, key);
+ }
+ }
return n.getName().accept(this, new VisitorContext(scope));
}
diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapGetExprT.java
similarity index 59%
copy from drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java
copy to drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapGetExprT.java
index f4c9b21c47..e5e809269f 100644
--- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java
+++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapGetExprT.java
@@ -25,22 +25,20 @@ import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.MethodCallExpr;
+import com.github.javaparser.ast.expr.StringLiteralExpr;
-import static org.drools.mvelcompiler.util.CoercionUtils.PUT_CALL;
-import static org.drools.mvelcompiler.util.CoercionUtils.coerceMapValueToString;
+public class MapGetExprT implements TypedExpression {
-public class MapPutExprT implements TypedExpression {
+ private final Expression name;
+ private final String key;
- private final TypedExpression name;
- private final Expression key;
- private final TypedExpression value;
- private final Optional<Type> type;
+ public MapGetExprT(TypedExpression name, String key) {
+ this((Expression) name.toJavaExpression(), key);
+ }
- public MapPutExprT(TypedExpression name, Expression key, TypedExpression value, Optional<Type> type) {
+ public MapGetExprT(Expression name, String key) {
this.name = name;
this.key = key;
- this.value = value;
- this.type = type;
}
@Override
@@ -50,11 +48,6 @@ public class MapPutExprT implements TypedExpression {
@Override
public Node toJavaExpression() {
- final Expression originalValue = (Expression) this.value.toJavaExpression();
- final Expression coercedValue = coerceMapValueToString(type, originalValue);
-
- return new MethodCallExpr((Expression) name.toJavaExpression(),
- PUT_CALL,
- NodeList.nodeList(key, coercedValue));
+ return new MethodCallExpr(name, "get", NodeList.nodeList(new StringLiteralExpr(key)));
}
}
diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java
index f4c9b21c47..59b769f4e4 100644
--- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java
+++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/ast/MapPutExprT.java
@@ -31,12 +31,16 @@ import static org.drools.mvelcompiler.util.CoercionUtils.coerceMapValueToString;
public class MapPutExprT implements TypedExpression {
- private final TypedExpression name;
+ private final Expression name;
private final Expression key;
- private final TypedExpression value;
+ private final Expression value;
private final Optional<Type> type;
public MapPutExprT(TypedExpression name, Expression key, TypedExpression value, Optional<Type> type) {
+ this((Expression) name.toJavaExpression(), key, (Expression) value.toJavaExpression(), type);
+ }
+
+ public MapPutExprT(Expression name, Expression key, Expression value, Optional<Type> type) {
this.name = name;
this.key = key;
this.value = value;
@@ -50,11 +54,7 @@ public class MapPutExprT implements TypedExpression {
@Override
public Node toJavaExpression() {
- final Expression originalValue = (Expression) this.value.toJavaExpression();
- final Expression coercedValue = coerceMapValueToString(type, originalValue);
-
- return new MethodCallExpr((Expression) name.toJavaExpression(),
- PUT_CALL,
- NodeList.nodeList(key, coercedValue));
+ final Expression coercedValue = coerceMapValueToString(type, value);
+ return new MethodCallExpr(name, PUT_CALL, NodeList.nodeList(key, coercedValue));
}
}
diff --git a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/TypeUtils.java b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/TypeUtils.java
index 4bdc85b263..90bd19f094 100644
--- a/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/TypeUtils.java
+++ b/drools-model/drools-mvel-compiler/src/main/java/org/drools/mvelcompiler/util/TypeUtils.java
@@ -18,10 +18,15 @@
*/
package org.drools.mvelcompiler.util;
+import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.Map;
import com.github.javaparser.StaticJavaParser;
+import org.kie.api.prototype.PrototypeFactInstance;
+
import static org.drools.util.ClassUtils.classFromType;
+import static org.drools.util.ClassUtils.rawType;
public class TypeUtils {
@@ -36,4 +41,18 @@ public class TypeUtils {
public static com.github.javaparser.ast.type.Type toJPType(Class<?> c) {
return StaticJavaParser.parseType(c.getCanonicalName());
}
+
+ public static boolean isMapAccessField(Type type) {
+ if (type instanceof Class c) {
+ return Map.class.isAssignableFrom(c);
+ }
+ if (type instanceof ParameterizedType p) {
+ if (!Map.class.isAssignableFrom(rawType(p.getRawType()))) {
+ return false;
+ }
+ Class<?> valueType = rawType(p.getActualTypeArguments()[1]);
+ return valueType == Object.class || Map.class.isAssignableFrom(valueType) || PrototypeFactInstance.class.isAssignableFrom(valueType);
+ }
+ return false;
+ }
}
diff --git a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java
index 7de5965da1..9604a49724 100644
--- a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java
+++ b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/MvelCompilerTest.java
@@ -1162,4 +1162,25 @@ public class MvelCompilerTest implements CompilerTest {
test(" { java.lang.String s = \"\"\"\n string content\n \"\"\"; }",
" { java.lang.String s = \"\"\"\n string content\n \"\"\"; }");
}
+
+ @Test
+ public void testReadMapField() {
+ test(ctx -> ctx.addDeclaration("$p", Map.class),
+ " { String name = $p.name; }",
+ " { java.lang.String name = (java.lang.String) ($p.get(\"name\")); }");
+ }
+
+ @Test
+ public void testWriteMapField() {
+ test(ctx -> ctx.addDeclaration("$p", Map.class),
+ " { $p.name = \"Mario\"; }",
+ " { $p.put(\"name\", \"Mario\"); }");
+ }
+
+ @Test
+ public void testReadAndWriteMapField() {
+ test(ctx -> ctx.addDeclaration("$a", Map.class).addDeclaration("$b", Map.class),
+ " { $a.name = $b.name; }",
+ " { $a.put(\"name\", $b.get(\"name\")); }");
+ }
}
\ No newline at end of file
diff --git a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/PreprocessCompilerTest.java b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/PreprocessCompilerTest.java
index 7d6af4e4d9..c02fc88b30 100644
--- a/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/PreprocessCompilerTest.java
+++ b/drools-model/drools-mvel-compiler/src/test/java/org/drools/mvelcompiler/PreprocessCompilerTest.java
@@ -18,6 +18,7 @@
*/
package org.drools.mvelcompiler;
+import java.util.Collections;
import java.util.function.Consumer;
import org.drools.Person;
@@ -114,7 +115,7 @@ public class PreprocessCompilerTest implements CompilerTest {
String inputExpression,
String expectedResult,
Consumer<CompiledBlockResult> resultAssert) {
- CompiledBlockResult compiled = new PreprocessCompiler().compile(inputExpression);
+ CompiledBlockResult compiled = new PreprocessCompiler().compile(inputExpression, Collections.emptySet());
assertThat(compiled.resultAsString()).isEqualToIgnoringWhitespace(expectedResult);
resultAssert.accept(compiled);
}
diff --git a/drools-model/pom.xml b/drools-model/pom.xml
index 95c0633c99..0051e5f802 100644
--- a/drools-model/pom.xml
+++ b/drools-model/pom.xml
@@ -39,9 +39,10 @@
<module>drools-codegen-common</module>
<module>drools-canonical-model</module>
<module>drools-model-compiler</module>
- <module>drools-model-codegen</module>
<module>drools-mvel-parser</module>
<module>drools-mvel-compiler</module>
+ <module>drools-model-prototype</module>
+ <module>drools-model-codegen</module>
</modules>
diff --git a/drools-mvel/src/main/java/org/drools/mvel/MVELKnowledgePackageImpl.java b/drools-mvel/src/main/java/org/drools/mvel/MVELKnowledgePackageImpl.java
index 3cbe03b069..0ee0a113cf 100644
--- a/drools-mvel/src/main/java/org/drools/mvel/MVELKnowledgePackageImpl.java
+++ b/drools-mvel/src/main/java/org/drools/mvel/MVELKnowledgePackageImpl.java
@@ -164,7 +164,7 @@ public class MVELKnowledgePackageImpl extends KnowledgePackageImpl {
out.writeObject(this.staticImports);
out.writeObject(this.functions);
out.writeObject(this.accumulateFunctions);
- out.writeObject(this.factTemplates);
+ out.writeObject(this.prototypes);
out.writeObject(this.globals);
out.writeBoolean(this.valid);
out.writeBoolean(this.needStreamMode);
@@ -212,7 +212,7 @@ public class MVELKnowledgePackageImpl extends KnowledgePackageImpl {
this.staticImports = (Set) in.readObject();
this.functions = (Map<String, Function>) in.readObject();
this.accumulateFunctions = (Map<String, AccumulateFunction>) in.readObject();
- this.factTemplates = (Map) in.readObject();
+ this.prototypes = (Map) in.readObject();
this.globals = (Map<String, Type>) in.readObject();
this.valid = in.readBoolean();
this.needStreamMode = in.readBoolean();
diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/java/org/drools/quarkus/test/TestableResource.java b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/java/org/drools/quarkus/test/TestableResource.java
index 2f2724fdf5..ce87188114 100644
--- a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/java/org/drools/quarkus/test/TestableResource.java
+++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/java/org/drools/quarkus/test/TestableResource.java
@@ -18,6 +18,15 @@
*/
package org.drools.quarkus.test;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import jakarta.inject.Inject;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
import org.kie.api.KieBase;
import org.kie.api.definition.KiePackage;
import org.kie.api.runtime.KieRuntimeBuilder;
@@ -25,15 +34,6 @@ import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.kie.api.time.SessionPseudoClock;
-import jakarta.inject.Inject;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Response;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@@ -100,7 +100,7 @@ public class TestableResource {
List<String> pkgNames = kBase.getKiePackages().stream().map(KiePackage::getName).collect(Collectors.toList());
assertThat(pkgNames)
- .containsExactlyInAnyOrder("org.drools.quarkus.test","org.drools.drl","org.drools.dtable","org.drools.cep","org.drools.tms","org.drools.probe","org.drools.yaml");
+ .containsExactlyInAnyOrder("defaultpkg","org.drools.quarkus.test","org.drools.drl","org.drools.dtable","org.drools.cep","org.drools.tms","org.drools.probe","org.drools.yaml","org.drools.prototype");
return Response.ok().build();
}
diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/META-INF/kmodule.xml b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/META-INF/kmodule.xml
index a090bae9e0..b5f9c8aec4 100644
--- a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/META-INF/kmodule.xml
+++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/META-INF/kmodule.xml
@@ -26,8 +26,11 @@
<kbase name="canDrinkKBDTable" packages="org.drools.dtable">
<ksession name="canDrinkKSDTable" />
</kbase>
- <kbase name="canDrinkKBDYaml" packages="org.drools.yaml">
- <ksession name="canDrinkKSDYaml" />
+ <kbase name="canDrinkKBYaml" packages="org.drools.yaml">
+ <ksession name="canDrinkKSYaml" />
+ </kbase>
+ <kbase name="canDrinkKBPrototype" packages="org.drools.prototype" prototypes="allowed">
+ <ksession name="canDrinkKSPrototype" />
</kbase>
<kbase name="cepKB" packages="org.drools.cep" eventProcessingMode="stream">
<ksession name="cepKS" clockType="pseudo"/>
diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties
new file mode 100644
index 0000000000..effa45048b
--- /dev/null
+++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/application.properties
@@ -0,0 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+drools.prototypes=allowed
\ No newline at end of file
diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/org/drools/prototype/CanDrink.drl.yaml b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/org/drools/prototype/CanDrink.drl.yaml
new file mode 100755
index 0000000000..bd1b9be2a1
--- /dev/null
+++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/main/resources/org/drools/prototype/CanDrink.drl.yaml
@@ -0,0 +1,22 @@
+name: org.drools.prototype
+rules:
+ - name: R1
+ when:
+ - given: Result
+ as: $r
+ - given: Person
+ as: $p
+ having:
+ - age >= 18
+ then: |
+ $r.value = $p.name + " can drink";
+ - name: R2
+ when:
+ - given: Result
+ as: $r
+ - given: Person
+ as: $p
+ having:
+ - age < 18
+ then: |
+ $r.value = $p.name + " can NOT drink";
diff --git a/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java b/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java
index 4a6806ccc0..96c380dd55 100644
--- a/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java
+++ b/drools-quarkus-extension/drools-quarkus-integration-test/src/test/java/org/drools/quarkus/test/RuntimeTest.java
@@ -18,18 +18,21 @@
*/
package org.drools.quarkus.test;
+import java.util.List;
+import java.util.stream.Collectors;
+
import io.quarkus.test.junit.QuarkusTest;
+import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;
import org.kie.api.definition.KiePackage;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
import org.kie.api.runtime.KieRuntimeBuilder;
import org.kie.api.runtime.KieSession;
-import jakarta.inject.Inject;
-import java.util.List;
-import java.util.stream.Collectors;
-
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
@QuarkusTest
public class RuntimeTest {
@@ -50,7 +53,7 @@ public class RuntimeTest {
@Test
public void testYamlEvaluation() {
- testSimpleDrl(runtimeBuilder.newKieSession("canDrinkKSDYaml"), "org.drools.yaml");
+ testSimpleDrl(runtimeBuilder.newKieSession("canDrinkKSYaml"), "org.drools.yaml");
}
private void testSimpleDrl(KieSession ksession, String assetPackage) {
@@ -66,4 +69,23 @@ public class RuntimeTest {
assertEquals("Mark can NOT drink", result.toString());
}
+
+ @Test
+ public void testPrototypeEvaluation() {
+ KieSession ksession = runtimeBuilder.newKieSession("canDrinkKSPrototype");
+
+ PrototypeFact personFact = prototype("Person" ).asFact();
+ PrototypeFactInstance mark = personFact.newInstance();
+ mark.put("name", "Mark" );
+ mark.put("age", 17 );
+ ksession.insert(mark);
+
+ PrototypeFact resultFact = prototype( "Result" ).asFact();
+ PrototypeFactInstance result = resultFact.newInstance();
+ ksession.insert(result);
+
+ ksession.fireAllRules();
+
+ assertEquals("Mark can NOT drink", result.get("value"));
+ }
}
diff --git a/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/DroolsQuarkusResourceUtils.java b/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/DroolsQuarkusResourceUtils.java
index 4aa6fee038..612dfeceb5 100644
--- a/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/DroolsQuarkusResourceUtils.java
+++ b/drools-quarkus-extension/drools-quarkus-util-deployment/src/main/java/org/drools/quarkus/util/deployment/DroolsQuarkusResourceUtils.java
@@ -19,6 +19,16 @@
package org.drools.quarkus.util.deployment;
import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
import io.quarkus.arc.deployment.GeneratedBeanBuildItem;
import io.quarkus.bootstrap.classloading.QuarkusClassLoader;
import io.quarkus.deployment.annotations.BuildProducer;
@@ -42,16 +52,6 @@ import org.kie.memorycompiler.JavaCompilerSettings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-import java.util.stream.Collectors;
-
import static org.drools.util.Config.getConfig;
import static org.kie.memorycompiler.KieMemoryCompiler.compileNoLoad;
@@ -93,6 +93,7 @@ public class DroolsQuarkusResourceUtils {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
DroolsModelBuildContext context = QuarkusDroolsModelBuildContext.builder()
.withClassLoader(classLoader)
+ .withApplicationProperties(appPaths.getResourceFiles())
.withClassAvailabilityResolver(className -> classAvailabilityResolver(index, className))
.withAppPaths(appPaths)
.build();
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceAfterTest.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceAfterTest.java
index daee3e6fb6..b511beb341 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceAfterTest.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceAfterTest.java
@@ -22,21 +22,21 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
-import org.drools.base.facttemplates.Event;
import org.drools.model.Global;
import org.drools.model.Index;
import org.drools.model.Model;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeDSL;
-import org.drools.model.PrototypeVariable;
import org.drools.model.Rule;
import org.drools.model.Variable;
import org.drools.model.impl.ModelImpl;
+import org.drools.model.prototype.PrototypeDSL;
+import org.drools.model.prototype.PrototypeVariable;
import org.drools.reliability.test.util.TimeAmount;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.api.conf.EventProcessingOption;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeEventInstance;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.conf.PersistedSessionOption;
@@ -48,14 +48,13 @@ import static org.drools.model.DSL.globalOf;
import static org.drools.model.DSL.not;
import static org.drools.model.DSL.on;
import static org.drools.model.PatternDSL.rule;
-import static org.drools.model.PrototypeDSL.protoPattern;
-import static org.drools.model.PrototypeDSL.variable;
-import static org.drools.model.PrototypeExpression.fixedValue;
-import static org.drools.model.PrototypeExpression.prototypeField;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedEvent;
+import static org.drools.model.prototype.PrototypeDSL.protoPattern;
+import static org.drools.model.prototype.PrototypeDSL.variable;
+import static org.drools.model.prototype.PrototypeExpression.fixedValue;
+import static org.drools.model.prototype.PrototypeExpression.prototypeField;
import static org.drools.reliability.test.util.PrototypeUtils.DEFAULT_PROTOTYPE_NAME;
import static org.drools.reliability.test.util.PrototypeUtils.SYNTHETIC_PROTOTYPE_NAME;
-import static org.drools.reliability.test.util.PrototypeUtils.getPrototype;
+import static org.drools.reliability.test.util.PrototypeUtils.getPrototypeEvent;
import static org.drools.reliability.test.util.PrototypeUtils.processResults;
@ExtendWith(BeforeAllMethodExtension.class)
@@ -68,7 +67,7 @@ class ReliabilityCepOnceAfterTest extends ReliabilityTestBasics {
* These rules are created in the same way as OnceAfterDefinition in drools-ansible-rulebook-integration
*/
private Model ruleModel() {
- Prototype controlPrototype = getPrototype(SYNTHETIC_PROTOTYPE_NAME);
+ PrototypeEvent controlPrototype = getPrototypeEvent(SYNTHETIC_PROTOTYPE_NAME);
PrototypeVariable controlVar1 = variable(controlPrototype, "c1");
PrototypeVariable controlVar2 = variable(controlPrototype, "c2");
PrototypeVariable controlVar3 = variable(controlPrototype, "c3");
@@ -94,20 +93,20 @@ class ReliabilityCepOnceAfterTest extends ReliabilityTestBasics {
);
// control rule (wrapping original event)
- PrototypeVariable originalEventVariable = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m");
+ PrototypeVariable originalEventVariable = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m");
rules.add(
rule(RULE_NAME + "_control").metadata(SYNTHETIC_RULE_TAG, true)
.build(
guardedPattern(originalEventVariable),
not(duplicateControlPattern(originalEventVariable)),
on(originalEventVariable).execute((drools, event) -> {
- Event controlEvent = createMapBasedEvent(controlPrototype);
- controlEvent.set("sensu.host", event.get("sensu.host")); // groupByAttributes
- controlEvent.set("sensu.process.type", event.get("sensu.process.type")); // groupByAttributes
- controlEvent.set("drools_rule_name", RULE_NAME);
- controlEvent.set("event", event);
- controlEvent.set("once_after_time_window", "10 minutes");
- controlEvent.set("events_in_window", 1);
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance();
+ controlEvent.put("sensu.host", event.get("sensu.host")); // groupByAttributes
+ controlEvent.put("sensu.process.type", event.get("sensu.process.type")); // groupByAttributes
+ controlEvent.put("drools_rule_name", RULE_NAME);
+ controlEvent.put("event", event);
+ controlEvent.put("once_after_time_window", "10 minutes");
+ controlEvent.put("events_in_window", 1);
drools.insert(controlEvent);
drools.delete(event);
})
@@ -122,13 +121,13 @@ class ReliabilityCepOnceAfterTest extends ReliabilityTestBasics {
protoPattern(controlVar1).expr("drools_rule_name", Index.ConstraintType.EQUAL, RULE_NAME),
not(protoPattern(controlVar2).expr("end_once_after", Index.ConstraintType.EQUAL, RULE_NAME)),
on(controlVar1).execute((drools, c1) -> {
- Event startControlEvent = createMapBasedEvent(controlPrototype)
+ PrototypeEventInstance startControlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- startControlEvent.set("start_once_after", RULE_NAME);
+ startControlEvent.put("start_once_after", RULE_NAME);
drools.insert(startControlEvent);
- Event endControlEvent = createMapBasedEvent(controlPrototype);
- endControlEvent.set("end_once_after", RULE_NAME);
+ PrototypeEventInstance endControlEvent = controlPrototype.newInstance();
+ endControlEvent.put("end_once_after", RULE_NAME);
drools.insert(endControlEvent);
})
)
@@ -142,7 +141,7 @@ class ReliabilityCepOnceAfterTest extends ReliabilityTestBasics {
guardedPattern(originalEventVariable),
duplicateControlPattern,
on(originalEventVariable, duplicateControlPattern.getFirstVariable()).execute((drools, event, control) -> {
- control.set("events_in_window", ((int) control.get("events_in_window")) + 1);
+ control.put("events_in_window", ((int) control.get("events_in_window")) + 1);
drools.delete(event);
})
)
@@ -158,7 +157,7 @@ class ReliabilityCepOnceAfterTest extends ReliabilityTestBasics {
// We group-by sensu.host and sensu.process.type
private static PrototypeDSL.PrototypePatternDef duplicateControlPattern(PrototypeVariable originalEventVariable) {
- return protoPattern(variable(getPrototype(SYNTHETIC_PROTOTYPE_NAME)))
+ return protoPattern(variable(getPrototypeEvent(SYNTHETIC_PROTOTYPE_NAME)))
.expr(prototypeField("sensu.host"), Index.ConstraintType.EQUAL, originalEventVariable, prototypeField("sensu.host")) // groupByAttributes
.expr(prototypeField("sensu.process.type"), Index.ConstraintType.EQUAL, originalEventVariable, prototypeField("sensu.process.type")) // groupByAttributes
.expr(prototypeField("drools_rule_name"), Index.ConstraintType.EQUAL, fixedValue(RULE_NAME));
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceWithinTest.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceWithinTest.java
index 5367eebdea..ec1ef9d23f 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceWithinTest.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepOnceWithinTest.java
@@ -22,22 +22,22 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
-import org.drools.base.facttemplates.Event;
import org.drools.model.DroolsEntryPoint;
import org.drools.model.Global;
import org.drools.model.Index;
import org.drools.model.Model;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeDSL;
-import org.drools.model.PrototypeVariable;
import org.drools.model.Rule;
import org.drools.model.impl.ModelImpl;
-import org.drools.modelcompiler.facttemplate.HashMapEventImpl;
+import org.drools.model.prototype.PrototypeDSL;
+import org.drools.model.prototype.PrototypeVariable;
+import org.drools.model.prototype.impl.HashMapEventImpl;
import org.drools.reliability.test.util.TimeAmount;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.api.conf.EventProcessingOption;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeEventInstance;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.conf.PersistedSessionOption;
@@ -47,14 +47,13 @@ import static org.drools.model.DSL.globalOf;
import static org.drools.model.DSL.not;
import static org.drools.model.DSL.on;
import static org.drools.model.PatternDSL.rule;
-import static org.drools.model.PrototypeDSL.protoPattern;
-import static org.drools.model.PrototypeDSL.variable;
-import static org.drools.model.PrototypeExpression.fixedValue;
-import static org.drools.model.PrototypeExpression.prototypeField;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedEvent;
+import static org.drools.model.prototype.PrototypeDSL.protoPattern;
+import static org.drools.model.prototype.PrototypeDSL.variable;
+import static org.drools.model.prototype.PrototypeExpression.fixedValue;
+import static org.drools.model.prototype.PrototypeExpression.prototypeField;
import static org.drools.reliability.test.util.PrototypeUtils.DEFAULT_PROTOTYPE_NAME;
import static org.drools.reliability.test.util.PrototypeUtils.SYNTHETIC_PROTOTYPE_NAME;
-import static org.drools.reliability.test.util.PrototypeUtils.getPrototype;
+import static org.drools.reliability.test.util.PrototypeUtils.getPrototypeEvent;
@ExtendWith(BeforeAllMethodExtension.class)
class ReliabilityCepOnceWithinTest extends ReliabilityTestBasics {
@@ -66,24 +65,24 @@ class ReliabilityCepOnceWithinTest extends ReliabilityTestBasics {
* These rules are created in the same way as OnceWithinDefinition in drools-ansible-rulebook-integration
*/
private Model ruleModel() {
- Prototype controlPrototype = getPrototype(SYNTHETIC_PROTOTYPE_NAME);
+ PrototypeEvent controlPrototype = getPrototypeEvent(SYNTHETIC_PROTOTYPE_NAME);
Global<List> global = globalOf(List.class, "defaultpkg", "results");
List<Rule> rules = new ArrayList<>();
// main rule (match only once for grouped events within 10 minutes)
TimeAmount timeAmount = TimeAmount.parseTimeAmount("10 minutes");
- PrototypeVariable originalEventVariable = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m");
+ PrototypeVariable originalEventVariable = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m");
rules.add(rule(RULE_NAME).metadata(RULE_TYPE_TAG, KEYWORD)
.build(
guardedPattern(originalEventVariable),
not(duplicateControlPattern(originalEventVariable)),
on(originalEventVariable, global).execute((drools, event, globalResults) -> {
- Event controlEvent = createMapBasedEvent(controlPrototype)
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- controlEvent.set("sensu.host", event.get("sensu.host")); // groupByAttributes
- controlEvent.set("sensu.process.type", event.get("sensu.process.type")); // groupByAttributes
- controlEvent.set("drools_rule_name", RULE_NAME);
+ controlEvent.put("sensu.host", event.get("sensu.host")); // groupByAttributes
+ controlEvent.put("sensu.process.type", event.get("sensu.process.type")); // groupByAttributes
+ controlEvent.put("drools_rule_name", RULE_NAME);
drools.insert(controlEvent);
globalResults.add(event);
drools.delete(event);
@@ -110,7 +109,7 @@ class ReliabilityCepOnceWithinTest extends ReliabilityTestBasics {
// We group-by sensu.host and sensu.process.type
private static PrototypeDSL.PrototypePatternDef duplicateControlPattern(PrototypeVariable originalEventVariable) {
- return protoPattern(variable(getPrototype(SYNTHETIC_PROTOTYPE_NAME)))
+ return protoPattern(variable(getPrototypeEvent(SYNTHETIC_PROTOTYPE_NAME)))
.expr(prototypeField("sensu.host"), Index.ConstraintType.EQUAL, originalEventVariable, prototypeField("sensu.host")) // groupByAttributes
.expr(prototypeField("sensu.process.type"), Index.ConstraintType.EQUAL, originalEventVariable, prototypeField("sensu.process.type")) // groupByAttributes
.expr(prototypeField("drools_rule_name"), Index.ConstraintType.EQUAL, fixedValue(RULE_NAME));
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimeWindowTest.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimeWindowTest.java
index e0e1bbf1b2..df5099e75e 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimeWindowTest.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimeWindowTest.java
@@ -25,9 +25,9 @@ import java.util.concurrent.TimeUnit;
import org.drools.model.Global;
import org.drools.model.Index;
import org.drools.model.Model;
-import org.drools.model.PrototypeVariable;
import org.drools.model.Rule;
import org.drools.model.impl.ModelImpl;
+import org.drools.model.prototype.PrototypeVariable;
import org.drools.reliability.test.util.TimeAmount;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
@@ -41,10 +41,10 @@ import static org.drools.model.DSL.after;
import static org.drools.model.DSL.globalOf;
import static org.drools.model.DSL.on;
import static org.drools.model.PatternDSL.rule;
-import static org.drools.model.PrototypeDSL.protoPattern;
-import static org.drools.model.PrototypeDSL.variable;
+import static org.drools.model.prototype.PrototypeDSL.protoPattern;
+import static org.drools.model.prototype.PrototypeDSL.variable;
import static org.drools.reliability.test.util.PrototypeUtils.DEFAULT_PROTOTYPE_NAME;
-import static org.drools.reliability.test.util.PrototypeUtils.getPrototype;
+import static org.drools.reliability.test.util.PrototypeUtils.getPrototypeEvent;
@ExtendWith(BeforeAllMethodExtension.class)
class ReliabilityCepTimeWindowTest extends ReliabilityTestBasics {
@@ -61,9 +61,9 @@ class ReliabilityCepTimeWindowTest extends ReliabilityTestBasics {
// main rule (all events should be matched within +- 5 minutes each other)
TimeAmount timeAmount = TimeAmount.parseTimeAmount("5 minutes");
- PrototypeVariable var0 = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m_0");
- PrototypeVariable var1 = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m_1");
- PrototypeVariable var2 = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m_2");
+ PrototypeVariable var0 = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m_0");
+ PrototypeVariable var1 = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m_1");
+ PrototypeVariable var2 = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m_2");
rules.add(
rule( RULE_NAME )
.build(
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimedOutTest.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimedOutTest.java
index f6fd3c37c8..ecb34ecbff 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimedOutTest.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityCepTimedOutTest.java
@@ -22,20 +22,20 @@ import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
-import org.drools.base.facttemplates.Event;
import org.drools.model.Global;
import org.drools.model.Index;
import org.drools.model.Model;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeVariable;
import org.drools.model.Rule;
import org.drools.model.Variable;
import org.drools.model.impl.ModelImpl;
+import org.drools.model.prototype.PrototypeVariable;
import org.drools.reliability.test.util.TimeAmount;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.kie.api.conf.EventProcessingOption;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeEventInstance;
import org.kie.api.runtime.conf.ClockTypeOption;
import org.kie.api.runtime.conf.PersistedSessionOption;
import org.kie.api.runtime.rule.RuleContext;
@@ -50,14 +50,13 @@ import static org.drools.model.DSL.not;
import static org.drools.model.DSL.on;
import static org.drools.model.PatternDSL.pattern;
import static org.drools.model.PatternDSL.rule;
-import static org.drools.model.PrototypeDSL.protoPattern;
-import static org.drools.model.PrototypeDSL.variable;
-import static org.drools.model.PrototypeExpression.prototypeField;
-import static org.drools.model.PrototypeExpression.thisPrototype;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedEvent;
+import static org.drools.model.prototype.PrototypeDSL.protoPattern;
+import static org.drools.model.prototype.PrototypeDSL.variable;
+import static org.drools.model.prototype.PrototypeExpression.prototypeField;
+import static org.drools.model.prototype.PrototypeExpression.thisPrototype;
import static org.drools.reliability.test.util.PrototypeUtils.DEFAULT_PROTOTYPE_NAME;
import static org.drools.reliability.test.util.PrototypeUtils.SYNTHETIC_PROTOTYPE_NAME;
-import static org.drools.reliability.test.util.PrototypeUtils.getPrototype;
+import static org.drools.reliability.test.util.PrototypeUtils.getPrototypeEvent;
@ExtendWith(BeforeAllMethodExtension.class)
class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
@@ -69,11 +68,11 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
* These rules are created in the same way as TimedOutDefinition in drools-ansible-rulebook-integration
*/
private Model ruleModel() {
- Prototype controlPrototype = getPrototype(SYNTHETIC_PROTOTYPE_NAME);
+ PrototypeEvent controlPrototype = getPrototypeEvent(SYNTHETIC_PROTOTYPE_NAME);
PrototypeVariable controlVar1 = variable(controlPrototype, "c1");
PrototypeVariable controlVar2 = variable(controlPrototype, "c2");
PrototypeVariable controlVar3 = variable(controlPrototype, "c3");
- PrototypeVariable eventVar = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "e");
+ PrototypeVariable eventVar = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "e");
Variable<Long> resultCount = declarationOf( Long.class, "count" );
Global<List> global = globalOf(List.class, "defaultpkg", "results");
@@ -102,7 +101,7 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
// sub-rule 0
String subRuleName0 = rulePrefix + "0";
- PrototypeVariable patternVariable0 = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m_0");
+ PrototypeVariable patternVariable0 = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m_0");
rules.add(
rule( subRuleName0 ).metadata(SYNTHETIC_RULE_TAG, true)
.build(
@@ -111,11 +110,11 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
not( protoPattern(controlVar1)
.expr( "rulename", Index.ConstraintType.EQUAL, subRuleName0 ) ),
on(patternVariable0).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype )
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- controlEvent.set( "rulename", subRuleName0 );
- controlEvent.set( "event", t1 );
- controlEvent.set( "binding", ((RuleContext) drools).getMatch().getDeclarationIds().get(0) );
+ controlEvent.put("rulename", subRuleName0 );
+ controlEvent.put("event", t1 );
+ controlEvent.put("binding", ((RuleContext) drools).getMatch().getDeclarationIds().get(0) );
drools.insert(controlEvent);
})
)
@@ -123,7 +122,7 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
// sub-rule 1
String subRuleName1 = rulePrefix + "1";
- PrototypeVariable patternVariable1 = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m_1");
+ PrototypeVariable patternVariable1 = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m_1");
rules.add(
rule( subRuleName1 ).metadata(SYNTHETIC_RULE_TAG, true)
.build(
@@ -132,11 +131,11 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
not( protoPattern(controlVar1)
.expr( "rulename", Index.ConstraintType.EQUAL, subRuleName1 ) ),
on(patternVariable1).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype )
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- controlEvent.set( "rulename", subRuleName1 );
- controlEvent.set( "event", t1 );
- controlEvent.set( "binding", ((RuleContext) drools).getMatch().getDeclarationIds().get(0) );
+ controlEvent.put("rulename", subRuleName1 );
+ controlEvent.put("event", t1 );
+ controlEvent.put("binding", ((RuleContext) drools).getMatch().getDeclarationIds().get(0) );
drools.insert(controlEvent);
})
)
@@ -144,7 +143,7 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
// sub-rule 2
String subRuleName2 = rulePrefix + "2";
- PrototypeVariable patternVariable2 = variable(getPrototype(DEFAULT_PROTOTYPE_NAME), "m_2");
+ PrototypeVariable patternVariable2 = variable(getPrototypeEvent(DEFAULT_PROTOTYPE_NAME), "m_2");
rules.add(
rule( subRuleName2 ).metadata(SYNTHETIC_RULE_TAG, true)
.build(
@@ -153,11 +152,11 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
not( protoPattern(controlVar1)
.expr( "rulename", Index.ConstraintType.EQUAL, subRuleName2 ) ),
on(patternVariable2).execute((drools, t1) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype )
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- controlEvent.set( "rulename", subRuleName2 );
- controlEvent.set( "event", t1 );
- controlEvent.set( "binding", ((RuleContext) drools).getMatch().getDeclarationIds().get(0) );
+ controlEvent.put("rulename", subRuleName2 );
+ controlEvent.put("event", t1 );
+ controlEvent.put("binding", ((RuleContext) drools).getMatch().getDeclarationIds().get(0) );
drools.insert(controlEvent);
})
)
@@ -170,11 +169,11 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
not( protoPattern(controlVar1).expr( "rulename", Index.ConstraintType.EQUAL, startTag ) ),
protoPattern(controlVar2).expr( p -> ((String)p.get("rulename")).startsWith(rulePrefix) ),
on(controlVar2).execute((drools, firstEvent) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype )
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- controlEvent.set( "rulename", startTag );
- controlEvent.set( "event", firstEvent.get("event") );
- controlEvent.set( "binding", firstEvent.get("binding") );
+ controlEvent.put("rulename", startTag );
+ controlEvent.put("event", firstEvent.get("event") );
+ controlEvent.put("binding", firstEvent.get("binding") );
drools.insert(controlEvent);
})
)
@@ -189,9 +188,9 @@ class ReliabilityCepTimedOutTest extends ReliabilityTestBasics {
accFunction(org.drools.core.base.accumulators.CountAccumulateFunction::new).as(resultCount)),
pattern(resultCount).expr(count -> count == 3),
on(resultCount).execute((drools, count) -> {
- Event controlEvent = createMapBasedEvent( controlPrototype )
+ PrototypeEventInstance controlEvent = controlPrototype.newInstance()
.withExpiration(timeAmount.getAmount(), timeAmount.getTimeUnit());
- controlEvent.set( "rulename", endTag );
+ controlEvent.put("rulename", endTag );
drools.insert(controlEvent);
})
)
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityTestBasics.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityTestBasics.java
index 4864e9bb3b..cefcf88e4d 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityTestBasics.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/ReliabilityTestBasics.java
@@ -18,7 +18,14 @@
*/
package org.drools.reliability.test;
-import org.drools.base.facttemplates.Event;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
+
import org.drools.core.ClassObjectFilter;
import org.drools.kiesession.session.StatefulKnowledgeSessionImpl;
import org.drools.model.Model;
@@ -41,6 +48,7 @@ import org.kie.api.KieServices;
import org.kie.api.conf.KieBaseOption;
import org.kie.api.conf.Option;
import org.kie.api.io.ResourceType;
+import org.kie.api.prototype.PrototypeEventInstance;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.KieSessionConfiguration;
import org.kie.api.runtime.conf.KieSessionOption;
@@ -52,14 +60,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.test.domain.Person;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Optional;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Stream;
-
import static org.drools.reliability.infinispan.InfinispanStorageManagerFactory.INFINISPAN_STORAGE_MARSHALLER;
import static org.drools.reliability.infinispan.InfinispanStorageManagerFactory.INFINISPAN_STORAGE_MODE;
import static org.drools.reliability.test.util.PrototypeUtils.createEvent;
@@ -502,27 +502,27 @@ public abstract class ReliabilityTestBasics {
}
private void insertSensuEvent(String host, String type) {
- Event sensu = createEvent();
- sensu.set("sensu.host", host);
- sensu.set("sensu.process.type", type);
+ PrototypeEventInstance sensu = createEvent();
+ sensu.put("sensu.host", host);
+ sensu.put("sensu.process.type", type);
sessions.get(0).insert(sensu);
}
protected void insertMatchingSensuProcessStatusEvent(String status) {
- Event sensu = createEvent();
- sensu.set("sensu.process.status", status);
+ PrototypeEventInstance sensu = createEvent();
+ sensu.put("sensu.process.status", status);
sessions.get(0).insert(sensu);
}
protected void insertMatchingPingTimeoutEvent(boolean timeout) {
- Event ping = createEvent();
- ping.set("ping.timeout", timeout);
+ PrototypeEventInstance ping = createEvent();
+ ping.put("ping.timeout", timeout);
sessions.get(0).insert(ping);
}
protected void insertMatchingSensuStoragePercentEvent(int percent) {
- Event sensu = createEvent();
- sensu.set("sensu.storage.percent", percent);
+ PrototypeEventInstance sensu = createEvent();
+ sensu.put("sensu.storage.percent", percent);
sessions.get(0).insert(sensu);
}
}
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/proto/HashMapEventImplAdaptor.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/proto/HashMapEventImplAdaptor.java
index 8ebbf46d99..dfa7386f23 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/proto/HashMapEventImplAdaptor.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/proto/HashMapEventImplAdaptor.java
@@ -21,15 +21,14 @@ package org.drools.reliability.test.proto;
import java.util.Map;
import java.util.UUID;
-import org.drools.modelcompiler.facttemplate.HashMapEventImpl;
+import org.drools.model.prototype.impl.HashMapEventImpl;
import org.drools.reliability.infinispan.proto.ProtoStreamUtils;
import org.infinispan.protostream.annotations.ProtoAdapter;
import org.infinispan.protostream.annotations.ProtoFactory;
import org.infinispan.protostream.annotations.ProtoField;
import org.infinispan.protostream.types.protobuf.AnySchema;
-import static org.drools.modelcompiler.facttemplate.FactFactory.prototypeToFactTemplate;
-import static org.drools.reliability.test.util.PrototypeUtils.getPrototype;
+import static org.drools.reliability.test.util.PrototypeUtils.getPrototypeEvent;
/**
* This adopter resides in test module, because main drools-reliability-infinispan module does not have dependency on drools-model-compiler module.
@@ -40,7 +39,7 @@ public class HashMapEventImplAdaptor {
@ProtoFactory
HashMapEventImpl create(String uuid, String factTemplate, AnySchema.Any valuesMapObject, long timestamp, long expiration) {
Map<String, Object> valuesMap = (Map<String, Object>) ProtoStreamUtils.fromAnySchema(valuesMapObject);
- return new HashMapEventImpl(UUID.fromString(uuid), prototypeToFactTemplate(getPrototype(factTemplate)), valuesMap, timestamp, expiration);
+ return new HashMapEventImpl(UUID.fromString(uuid), getPrototypeEvent(factTemplate), valuesMap, timestamp, expiration);
}
@ProtoField(1)
@@ -50,13 +49,12 @@ public class HashMapEventImplAdaptor {
@ProtoField(2)
String getFactTemplate(HashMapEventImpl event) {
- return event.getFactTemplate().getName();
+ return event.getPrototype().getName();
}
@ProtoField(number = 3, required = true)
AnySchema.Any getValuesMapObject(HashMapEventImpl event) {
- Map<String, Object> map = event.asMap();
- return ProtoStreamUtils.toAnySchema(map);
+ return ProtoStreamUtils.toAnySchema(event);
}
@ProtoField(number = 4, defaultValue = "-1")
diff --git a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/util/PrototypeUtils.java b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/util/PrototypeUtils.java
index 0af1e11917..fcca0e35a3 100644
--- a/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/util/PrototypeUtils.java
+++ b/drools-reliability/drools-reliability-tests/src/test/java/org/drools/reliability/test/util/PrototypeUtils.java
@@ -23,38 +23,42 @@ import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import org.drools.base.facttemplates.Event;
-import org.drools.model.Prototype;
-import org.drools.model.PrototypeDSL;
-import org.drools.model.PrototypeFact;
+import org.kie.api.prototype.PrototypeEvent;
+import org.kie.api.prototype.PrototypeEventInstance;
+import org.kie.api.prototype.PrototypeFact;
-import static org.drools.modelcompiler.facttemplate.FactFactory.createMapBasedEvent;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
public class PrototypeUtils {
public static final String DEFAULT_PROTOTYPE_NAME = "DROOLS_PROTOTYPE";
public static final String SYNTHETIC_PROTOTYPE_NAME = "DROOLS_SYNTHETIC_PROTOTYPE";
- private static final Map<String, Prototype> prototypes = new HashMap<>();
+ private static final Map<String, PrototypeFact> prototypeFacts = new HashMap<>();
+ private static final Map<String, PrototypeEvent> prototypeEvents = new HashMap<>();
private PrototypeUtils() {
// It is not allowed to create instances of util classes.
}
- public static Event createControlEvent() {
- return createMapBasedEvent(getPrototype(SYNTHETIC_PROTOTYPE_NAME));
+ public static PrototypeEventInstance createControlEvent() {
+ return getPrototypeEvent(SYNTHETIC_PROTOTYPE_NAME).newInstance();
}
- public static Prototype getPrototype(String name) {
- return prototypes.computeIfAbsent(name, PrototypeDSL::prototype);
+ public static PrototypeFact getPrototypeFact(String name) {
+ return prototypeFacts.computeIfAbsent(name, n -> prototype(n).asFact());
}
- public static void processResults(List<Object> globalResults, List<Event> controlResults) {
- List<Object> events = controlResults.stream().map(r -> ((PrototypeFact) r).get("event")).collect(Collectors.toList());
+ public static PrototypeEvent getPrototypeEvent(String name) {
+ return prototypeEvents.computeIfAbsent(name, n -> prototype(n).asEvent());
+ }
+
+ public static void processResults(List<Object> globalResults, List<PrototypeEventInstance> controlResults) {
+ List<Object> events = controlResults.stream().map(r -> r.get("event")).collect(Collectors.toList());
globalResults.addAll(events);
}
- public static Event createEvent() {
- return createMapBasedEvent(getPrototype(DEFAULT_PROTOTYPE_NAME));
+ public static PrototypeEventInstance createEvent() {
+ return getPrototypeEvent(DEFAULT_PROTOTYPE_NAME).newInstance();
}
}
diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/conf/KnowledgeBaseConfigurationTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/conf/KnowledgeBaseConfigurationTest.java
index e11b772569..37a3d20a34 100644
--- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/conf/KnowledgeBaseConfigurationTest.java
+++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/compiler/conf/KnowledgeBaseConfigurationTest.java
@@ -26,6 +26,7 @@ import org.kie.api.KieServices;
import org.kie.api.conf.BetaRangeIndexOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.conf.RemoveIdentitiesOption;
import org.kie.api.conf.SequentialOption;
import org.kie.api.runtime.rule.ConsequenceExceptionHandler;
@@ -215,6 +216,25 @@ public class KnowledgeBaseConfigurationTest {
// checking the string based getProperty() method
assertThat(config.getProperty(EqualityBehaviorOption.PROPERTY_NAME)).isEqualTo("identity");
}
+
+ @Test
+ public void testPrototypesConfiguration() {
+ // setting the option using the type safe method
+ config.setOption(PrototypesOption.ALLOWED);
+
+ // checking the type safe getOption() method
+ assertThat(config.getOption(PrototypesOption.KEY)).isEqualTo(PrototypesOption.ALLOWED);
+ // checking the string based getProperty() method
+ assertThat(config.getProperty(PrototypesOption.PROPERTY_NAME)).isEqualTo("allowed");
+
+ // setting the options using the string based setProperty() method
+ config.setProperty( PrototypesOption.PROPERTY_NAME, "disabled" );
+
+ // checking the type safe getOption() method
+ assertThat(config.getOption(PrototypesOption.KEY)).isEqualTo(PrototypesOption.DISABLED);
+ // checking the string based getProperty() method
+ assertThat(config.getProperty(PrototypesOption.PROPERTY_NAME)).isEqualTo("disabled");
+ }
@Test
public void testSequentialAgendaConfiguration() {
diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/Misc2Test.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/Misc2Test.java
index 703589b82d..908566b6ef 100644
--- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/Misc2Test.java
+++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/integrationtests/Misc2Test.java
@@ -57,10 +57,6 @@ import org.drools.core.common.Memory;
import org.drools.core.common.NodeMemories;
import org.drools.base.definitions.InternalKnowledgePackage;
import org.drools.base.definitions.rule.impl.RuleImpl;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateImpl;
-import org.drools.base.facttemplates.FieldTemplate;
-import org.drools.base.facttemplates.FieldTemplateImpl;
import org.drools.core.impl.InternalRuleBase;
import org.drools.core.reteoo.CoreComponentFactory;
import org.drools.core.reteoo.LeftInputAdapterNode;
@@ -6556,31 +6552,6 @@ public class Misc2Test {
assertThat(list).isEqualTo(Arrays.asList(42, 99));
}
- @Test
- public void testFactTemplates() {
- // DROOLS-600
- String drl = "package com.testfacttemplate;" +
- " rule \"test rule\" " +
- " dialect \"mvel\" " +
- " when " +
- " $test : TestFactTemplate( status == 1 ) " +
- " then " +
- " System.out.println( \"Hello World\" ); " +
- " end ";
-
- InternalKnowledgePackage kPackage = CoreComponentFactory.get().createKnowledgePackage( "com.testfacttemplate" );
- FieldTemplate fieldTemplate = new FieldTemplateImpl( "status", Integer.class );
- FactTemplate factTemplate = new FactTemplateImpl(kPackage, "TestFactTemplate", fieldTemplate);
-
- KnowledgeBuilderImpl kBuilder = new KnowledgeBuilderImpl(kPackage );
- StringReader rule = new StringReader( drl );
- try {
- kBuilder.addPackageFromDrl(rule);
- } catch (Exception e) {
- throw new RuntimeException( e );
- }
- }
-
@Test
public void testBitwiseOperator() {
// DROOLS-585
diff --git a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/rule/PatternTest.java b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/rule/PatternTest.java
index 1a4538d18e..1b5a5da372 100644
--- a/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/rule/PatternTest.java
+++ b/drools-test-coverage/test-compiler-integration/src/test/java/org/drools/mvel/rule/PatternTest.java
@@ -19,63 +19,49 @@
package org.drools.mvel.rule;
import org.drools.base.base.ClassObjectType;
-import org.drools.base.definitions.InternalKnowledgePackage;
-import org.drools.base.facttemplates.Fact;
-import org.drools.base.facttemplates.FactTemplate;
-import org.drools.base.facttemplates.FactTemplateImpl;
-import org.drools.base.facttemplates.FactTemplateObjectType;
-import org.drools.base.facttemplates.FieldTemplate;
-import org.drools.base.facttemplates.FieldTemplateImpl;
-import org.drools.core.reteoo.CoreComponentFactory;
+import org.drools.base.base.ObjectType;
+import org.drools.base.prototype.PrototypeObjectType;
import org.drools.base.rule.Declaration;
import org.drools.base.rule.Pattern;
import org.drools.base.rule.accessor.ReadAccessor;
-import org.drools.base.base.ObjectType;
import org.drools.core.test.model.Cheese;
import org.junit.Test;
+import org.kie.api.prototype.PrototypeFact;
+import org.kie.api.prototype.PrototypeFactInstance;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.kie.api.prototype.PrototypeBuilder.prototype;
public class PatternTest {
@Test
- public void testDeclarationsObjectType() throws Exception {
+ public void testDeclarationsObjectType() {
final ObjectType type = new ClassObjectType( Cheese.class );
- final Pattern col = new Pattern( 0,
- type,
- "foo" );
+ final Pattern col = new Pattern( 0, type, "foo" );
final Declaration dec = col.getDeclaration();
final ReadAccessor ext = dec.getExtractor();
assertThat(ext.getExtractToClass()).isEqualTo(Cheese.class);
- final Cheese stilton = new Cheese( "stilton",
- 42 );
+ final Cheese stilton = new Cheese( "stilton", 42 );
assertThat(dec.getValue(null, stilton)).isEqualTo(stilton);
}
@Test
- public void testDeclarationsFactTemplate() throws Exception {
-
- InternalKnowledgePackage pkg = CoreComponentFactory.get().createKnowledgePackage( "org.store" );
- final FieldTemplate cheeseName = new FieldTemplateImpl( "name", String.class );
- final FieldTemplate cheesePrice = new FieldTemplateImpl( "price", Integer.class );
- final FieldTemplate[] fields = new FieldTemplate[]{cheeseName, cheesePrice};
- final FactTemplate cheese = new FactTemplateImpl( pkg, "Cheese", fields );
+ public void testDeclarationsPrototype() {
+ PrototypeFact cheese = prototype("org.store.Cheese").withField("name", String.class).withField("price", Integer.class).asFact();
- final ObjectType type = new FactTemplateObjectType( cheese );
+ final ObjectType type = new PrototypeObjectType(cheese );
- final Pattern col = new Pattern( 0,
- type,
- "foo" );
+ final Pattern col = new Pattern( 0, type, "foo" );
final Declaration dec = col.getDeclaration();
final ReadAccessor ext = dec.getExtractor();
- assertThat(ext.getExtractToClass()).isEqualTo(Fact.class);
+ assertThat(ext.getExtractToClass()).isEqualTo(PrototypeFactInstance.class);
- final Fact stilton = cheese.createFact();
- stilton.set( "name", "stilton" );
- stilton.set( "price", Integer.valueOf( 200 ) );
+ PrototypeFactInstance stilton = cheese.newInstance();
+ stilton.put("name", "stilton" );
+ stilton.put("price", Integer.valueOf(200 ) );
assertThat(dec.getValue(null, stilton)).isEqualTo(stilton);
}
diff --git a/drools-traits/src/main/java/org/drools/traits/core/definitions/impl/TraitKnowledgePackageImpl.java b/drools-traits/src/main/java/org/drools/traits/core/definitions/impl/TraitKnowledgePackageImpl.java
index c7c6c392a7..65c0119297 100644
--- a/drools-traits/src/main/java/org/drools/traits/core/definitions/impl/TraitKnowledgePackageImpl.java
+++ b/drools-traits/src/main/java/org/drools/traits/core/definitions/impl/TraitKnowledgePackageImpl.java
@@ -103,7 +103,7 @@ public class TraitKnowledgePackageImpl extends MVELKnowledgePackageImpl {
out.writeObject(this.staticImports);
out.writeObject(this.functions);
out.writeObject(this.accumulateFunctions);
- out.writeObject(this.factTemplates);
+ out.writeObject(this.prototypes);
out.writeObject(this.globals);
out.writeBoolean(this.valid);
out.writeBoolean(this.needStreamMode);
@@ -141,7 +141,7 @@ public class TraitKnowledgePackageImpl extends MVELKnowledgePackageImpl {
this.staticImports = (Set) in.readObject();
this.functions = (Map<String, Function>) in.readObject();
this.accumulateFunctions = (Map<String, AccumulateFunction>) in.readObject();
- this.factTemplates = (Map) in.readObject();
+ this.prototypes = (Map) in.readObject();
this.globals = (Map<String, Type>) in.readObject();
this.valid = in.readBoolean();
this.needStreamMode = in.readBoolean();
diff --git a/drools-xml-support/src/main/java/org/drools/xml/support/converters/KBaseConverter.java b/drools-xml-support/src/main/java/org/drools/xml/support/converters/KBaseConverter.java
index 6b157916c3..22c6b1c3e4 100644
--- a/drools-xml-support/src/main/java/org/drools/xml/support/converters/KBaseConverter.java
+++ b/drools-xml-support/src/main/java/org/drools/xml/support/converters/KBaseConverter.java
@@ -34,6 +34,7 @@ import org.kie.api.conf.DeclarativeAgendaOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.conf.KieBaseMutabilityOption;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.conf.SequentialOption;
import org.kie.api.conf.SessionsPoolOption;
@@ -54,6 +55,9 @@ public class KBaseConverter extends AbstractXStreamConverter {
if ( kBase.getEventProcessingMode() != null ) {
writer.addAttribute( "eventProcessingMode", kBase.getEventProcessingMode().getMode() );
}
+ if ( kBase.getPrototypes() != null ) {
+ writer.addAttribute( "prototypes", kBase.getPrototypes().toString().toLowerCase() );
+ }
if ( kBase.getEqualsBehavior() != null ) {
writer.addAttribute( "equalsBehavior", kBase.getEqualsBehavior().toString().toLowerCase() );
}
@@ -133,6 +137,11 @@ public class KBaseConverter extends AbstractXStreamConverter {
kBase.setEventProcessingMode( EventProcessingOption.determineEventProcessingMode( eventMode ) );
}
+ String prototypes = reader.getAttribute( "prototypes" );
+ if ( prototypes != null ) {
+ kBase.setPrototypes( PrototypesOption.determinePrototypesOption(prototypes) );
+ }
+
String equalsBehavior = reader.getAttribute( "equalsBehavior" );
if ( equalsBehavior != null ) {
kBase.setEqualsBehavior( EqualityBehaviorOption.determineEqualityBehavior( equalsBehavior ) );
diff --git a/kie-api/src/main/java/org/kie/api/builder/model/KieBaseModel.java b/kie-api/src/main/java/org/kie/api/builder/model/KieBaseModel.java
index 6898c2fc6c..e39e2d90a0 100644
--- a/kie-api/src/main/java/org/kie/api/builder/model/KieBaseModel.java
+++ b/kie-api/src/main/java/org/kie/api/builder/model/KieBaseModel.java
@@ -27,6 +27,7 @@ import org.kie.api.conf.DeclarativeAgendaOption;
import org.kie.api.conf.EqualityBehaviorOption;
import org.kie.api.conf.EventProcessingOption;
import org.kie.api.conf.KieBaseMutabilityOption;
+import org.kie.api.conf.PrototypesOption;
import org.kie.api.conf.SequentialOption;
import org.kie.api.conf.SessionsPoolOption;
@@ -110,6 +111,17 @@ public interface KieBaseModel {
*/
KieBaseModel setEqualsBehavior(EqualityBehaviorOption equalsBehaviour);
+ /**
+ * Sets the PrototypesOption for this KieBaseModel.
... 382 lines suppressed ...
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org