use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class ASMConsequenceBuilder method createConsequenceBytecode.
protected byte[] createConsequenceBytecode(RuleBuildContext ruleContext, final Map<String, Object> consequenceContext) {
final InvokerDataProvider data = new InvokerContext(consequenceContext);
final String name = (String) consequenceContext.get("consequenceName");
final Declaration[] declarations = (Declaration[]) consequenceContext.get("declarations");
final ClassGenerator generator = InvokerGenerator.createInvokerClassGenerator(data, ruleContext).setInterfaces(Consequence.class, CompiledInvoker.class);
generator.addMethod(ACC_PUBLIC, "getName", generator.methodDescr(String.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
push(name);
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(null, KnowledgeHelper.class, WorkingMemory.class), new String[] { "java/lang/Exception" }, new GeneratorHelper.EvaluateMethod() {
public void body(MethodVisitor mv) {
// Tuple tuple = knowledgeHelper.getTuple();
mv.visitVarInsn(ALOAD, 1);
invokeInterface(KnowledgeHelper.class, "getTuple", Tuple.class);
mv.visitVarInsn(ASTORE, 3);
// Declaration[] declarations = ((RuleTerminalNode)knowledgeHelper.getMatch().getTuple().getTupleSink()).getDeclarations();
mv.visitVarInsn(ALOAD, 1);
invokeInterface(KnowledgeHelper.class, "getMatch", Activation.class);
invokeInterface(Activation.class, "getTuple", Tuple.class);
invokeInterface(Tuple.class, "getTupleSink", Sink.class);
cast(RuleTerminalNode.class);
invokeVirtual(RuleTerminalNode.class, "getRequiredDeclarations", Declaration[].class);
mv.visitVarInsn(ASTORE, 4);
final String[] globals = data.getGlobals();
final String[] globalTypes = data.getGlobalTypes();
final Boolean[] notPatterns = (Boolean[]) consequenceContext.get("notPatterns");
int[] paramsPos = new int[declarations.length];
int offset = 5;
for (int i = 0; i < declarations.length; i++) {
int factPos = offset;
int objPos = ++offset;
paramsPos[i] = factPos;
// Object obj[i] = tuple.get(declarations[i]);
// org.kie.spi.Tuple
mv.visitVarInsn(ALOAD, 3);
// org.kie.rule.Declaration[]
mv.visitVarInsn(ALOAD, 4);
// i
push(i);
// declarations[i]
mv.visitInsn(AALOAD);
invokeInterface(Tuple.class, "get", InternalFactHandle.class, Declaration.class);
// fact[i]
mv.visitVarInsn(ASTORE, factPos);
// declarations[i].getValue((org.kie.common.InternalWorkingMemory)workingMemory, obj[i] );
// org.kie.rule.Declaration[]
mv.visitVarInsn(ALOAD, 4);
// i
push(i);
// declarations[i]
mv.visitInsn(AALOAD);
// WorkingMemory
mv.visitVarInsn(ALOAD, 2);
cast(InternalWorkingMemory.class);
// fact[i]
mv.visitVarInsn(ALOAD, factPos);
invokeInterface(InternalFactHandle.class, "getObject", Object.class);
String readMethod = declarations[i].getNativeReadMethodName();
boolean isObject = readMethod.equals("getValue");
String returnedType = isObject ? "Ljava/lang/Object;" : typeDescr(declarations[i].getTypeName());
mv.visitMethodInsn(INVOKEVIRTUAL, Declaration.class.getName().replace('.', '/'), readMethod, "(L" + InternalWorkingMemory.class.getName().replace('.', '/') + ";Ljava/lang/Object;)" + returnedType);
if (isObject)
mv.visitTypeInsn(CHECKCAST, internalName(declarations[i].getTypeName()));
// obj[i]
offset += store(objPos, declarations[i].getTypeName());
if (notPatterns[i]) {
mv.visitVarInsn(ALOAD, 1);
invokeInterface(KnowledgeHelper.class, "getWorkingMemory", WorkingMemory.class);
loadAsObject(objPos);
invokeInterface(WorkingMemory.class, "getFactHandle", FactHandle.class, Object.class);
cast(InternalFactHandle.class);
mv.visitVarInsn(ASTORE, factPos);
}
}
// @{ruleClassName}.@{methodName}(KnowledgeHelper, @foreach{declr : declarations} Object, FactHandle @end)
StringBuilder consequenceMethodDescr = new StringBuilder("(L" + KnowledgeHelper.class.getName().replace('.', '/') + ";");
// KnowledgeHelper
mv.visitVarInsn(ALOAD, 1);
for (int i = 0; i < declarations.length; i++) {
// obj[i]
load(paramsPos[i] + 1);
// fact[i]
mv.visitVarInsn(ALOAD, paramsPos[i]);
consequenceMethodDescr.append(typeDescr(declarations[i].getTypeName())).append("L" + FactHandle.class.getName().replace('.', '/') + ";");
}
// @foreach{type : globalTypes, identifier : globals} @{type} @{identifier} = ( @{type} ) workingMemory.getGlobal( "@{identifier}" );
for (int i = 0; i < globals.length; i++) {
// WorkingMemory
mv.visitVarInsn(ALOAD, 2);
push(globals[i]);
invokeInterface(WorkingMemory.class, "getGlobal", Object.class, String.class);
mv.visitTypeInsn(CHECKCAST, internalName(globalTypes[i]));
consequenceMethodDescr.append(typeDescr(globalTypes[i]));
}
consequenceMethodDescr.append(")V");
mv.visitMethodInsn(INVOKESTATIC, data.getInternalRuleClassName(), data.getMethodName(), consequenceMethodDescr.toString());
mv.visitInsn(RETURN);
}
});
return generator.generateBytecode();
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class ASMReturnValueStubBuilder method createStubReturnValue.
private void createStubReturnValue(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
generator.setInterfaces(ReturnValueStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "returnValue", ReturnValueExpression.class);
generator.addMethod(ACC_PUBLIC, "createContext", generator.methodDescr(Object.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
mv.visitInsn(ACONST_NULL);
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "replaceDeclaration", generator.methodDescr(null, Declaration.class, Declaration.class)).addMethod(ACC_PUBLIC, "evaluate", generator.methodDescr(FieldValue.class, Object.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class), new String[] { "java/lang/Exception" }, new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
Label syncStart = new Label();
Label syncEnd = new Label();
Label l1 = new Label();
Label l2 = new Label();
mv.visitTryCatchBlock(syncStart, l1, l2, null);
Label l3 = new Label();
mv.visitTryCatchBlock(l2, l3, l2, null);
getFieldFromThis("returnValue", ReturnValueExpression.class);
mv.visitJumpInsn(IFNONNULL, syncEnd);
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(DUP);
mv.visitVarInsn(ASTORE, 7);
// synchronized(this) {
mv.visitInsn(MONITORENTER);
mv.visitLabel(syncStart);
getFieldFromThis("returnValue", ReturnValueExpression.class);
// if (returnValue == null) ...
Label ifNotInitialized = new Label();
mv.visitJumpInsn(IFNONNULL, ifNotInitialized);
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 5);
invokeStatic(ReturnValueGenerator.class, "generate", null, ReturnValueStub.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class);
mv.visitLabel(ifNotInitialized);
mv.visitVarInsn(ALOAD, 7);
mv.visitInsn(MONITOREXIT);
mv.visitLabel(l1);
mv.visitJumpInsn(GOTO, syncEnd);
mv.visitLabel(l2);
mv.visitVarInsn(ASTORE, 8);
mv.visitVarInsn(ALOAD, 7);
mv.visitInsn(MONITOREXIT);
mv.visitLabel(l3);
mv.visitVarInsn(ALOAD, 8);
mv.visitInsn(ATHROW);
mv.visitLabel(syncEnd);
// } end of synchronized
getFieldFromThis("returnValue", ReturnValueExpression.class);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 3);
mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 5);
mv.visitVarInsn(ALOAD, 6);
invokeInterface(ReturnValueExpression.class, "evaluate", FieldValue.class, Object.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class);
mv.visitInsn(ARETURN);
}
}).addMethod(ACC_PUBLIC, "setReturnValue", generator.methodDescr(null, ReturnValueExpression.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
putFieldInThisFromRegistry("returnValue", ReturnValueExpression.class, 1);
mv.visitInsn(RETURN);
}
});
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class TemporalEvaluatorFactoryTest method getContextEntry.
private VariableContextEntry getContextEntry(final Evaluator evaluator, final InternalReadAccessor extractor, final ValueType valueType, final Object[] row, final boolean left) {
final Declaration declaration = new Declaration("test", extractor, null);
final ValueType coerced = evaluator.getCoercedValueType();
if (evaluator.isTemporal()) {
if (evaluator instanceof BeforeEvaluatorDefinition.BeforeEvaluator || evaluator instanceof MeetsEvaluatorDefinition.MeetsEvaluator) {
LeftStartRightEndContextEntry context = new LeftStartRightEndContextEntry(extractor, declaration, evaluator);
if (left) {
context.timestamp = ((EventFactHandle) row[2]).getStartTimestamp();
} else {
context.timestamp = ((EventFactHandle) row[0]).getEndTimestamp();
}
return context;
}
if (evaluator instanceof AfterEvaluatorDefinition.AfterEvaluator || evaluator instanceof MetByEvaluatorDefinition.MetByEvaluator) {
LeftEndRightStartContextEntry context = new LeftEndRightStartContextEntry(extractor, declaration, evaluator);
if (left) {
context.timestamp = ((EventFactHandle) row[2]).getEndTimestamp();
} else {
context.timestamp = ((EventFactHandle) row[0]).getStartTimestamp();
}
return context;
}
// else
TemporalVariableContextEntry context = new TemporalVariableContextEntry(extractor, declaration, evaluator);
if (left) {
context.startTS = ((EventFactHandle) row[2]).getStartTimestamp();
context.endTS = ((EventFactHandle) row[2]).getEndTimestamp();
} else {
context.startTS = ((EventFactHandle) row[0]).getStartTimestamp();
context.endTS = ((EventFactHandle) row[0]).getEndTimestamp();
}
return context;
}
if (coerced.isIntegerNumber()) {
final LongVariableContextEntry context = new LongVariableContextEntry(extractor, declaration, evaluator);
if (row[2] == null) {
context.leftNull = true;
} else {
context.left = ((Number) row[2]).longValue();
}
if (row[0] == null) {
context.rightNull = true;
} else {
context.right = ((Number) row[0]).longValue();
}
return context;
} else if (coerced.isChar()) {
final CharVariableContextEntry context = new CharVariableContextEntry(extractor, declaration, evaluator);
if (row[2] == null) {
context.leftNull = true;
} else {
context.left = ((Character) row[2]).charValue();
}
if (row[0] == null) {
context.rightNull = true;
} else {
context.right = ((Character) row[0]).charValue();
}
return context;
} else if (coerced.isBoolean()) {
final BooleanVariableContextEntry context = new BooleanVariableContextEntry(extractor, declaration, evaluator);
if (row[2] == null) {
context.leftNull = true;
} else {
context.left = ((Boolean) row[2]).booleanValue();
}
if (row[0] == null) {
context.rightNull = true;
} else {
context.right = ((Boolean) row[0]).booleanValue();
}
return context;
} else if (coerced.isFloatNumber()) {
final DoubleVariableContextEntry context = new DoubleVariableContextEntry(extractor, declaration, evaluator);
if (row[2] == null) {
context.leftNull = true;
} else {
context.left = ((Number) row[2]).doubleValue();
}
if (row[0] == null) {
context.rightNull = true;
} else {
context.right = ((Number) row[0]).doubleValue();
}
return context;
} else {
final ObjectVariableContextEntry context = new ObjectVariableContextEntry(extractor, declaration, evaluator);
if (row[2] == null) {
context.leftNull = true;
} else {
context.left = row[2];
}
if (row[0] == null) {
context.rightNull = true;
} else {
context.right = row[0];
}
return context;
}
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class BaseMannersTest method getContinueProcessing.
/**
* <pre>
* rule continue() {
* Context context;
* when {
* context : Context( state == Context.CHECK_DONE )
* } then {
* context.setState( Context.ASSIGN_SEATS );
* }
* }
* </pre>
* @return
* @throws InvalidRuleException
*/
private RuleImpl getContinueProcessing() throws InvalidRuleException {
final RuleImpl rule = new RuleImpl("continueProcessng");
// -----------
// context : Context( state == Context.CHECK_DONE )
// -----------
final Pattern contextPattern = new Pattern(0, this.contextType, "context");
contextPattern.addConstraint(getLiteralConstraint(contextPattern, "state", Context.CHECK_DONE));
rule.addPattern(contextPattern);
final Declaration contextDeclaration = rule.getDeclaration("context");
// ------------
// context.setName( Context.ASSIGN_SEATS );
// ------------
final Consequence consequence = new Consequence() {
public void evaluate(KnowledgeHelper drools, WorkingMemory workingMemory) throws ConsequenceException {
try {
RuleImpl rule = drools.getRule();
LeftTuple tuple = (LeftTuple) drools.getTuple();
Context context = (Context) drools.get(contextDeclaration);
context.setState(Context.ASSIGN_SEATS);
drools.update(tuple.get(contextDeclaration), context);
// System.err.println( "continue processing" );
} catch (Exception e) {
e.printStackTrace();
throw new ConsequenceException(e);
}
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
public void writeExternal(ObjectOutput out) throws IOException {
}
public String getName() {
return "default";
}
};
rule.setConsequence(consequence);
return rule;
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class BaseMannersTest method getAllDone.
/**
* <pre>
* rule all_done() {
* Context context;
* when {
* context : Context( state == Context.PRINT_RESULTS )
* } then {
* }
* }
* </pre>
*
* @return
* @throws InvalidRuleException
*/
private RuleImpl getAllDone() throws InvalidRuleException {
final RuleImpl rule = new RuleImpl("alldone");
// -----------
// context : Context( state == Context.PRINT_RESULTS )
// -----------
final Pattern contextPattern = new Pattern(0, this.contextType);
contextPattern.addConstraint(getLiteralConstraint(contextPattern, "state", Context.PRINT_RESULTS));
rule.addPattern(contextPattern);
final Declaration contextDeclaration = rule.getDeclaration("context");
// ------------
//
// ------------
final Consequence consequence = new Consequence() {
public void evaluate(KnowledgeHelper drools, WorkingMemory workingMemory) throws ConsequenceException {
try {
System.err.println("all done");
} catch (Exception e) {
throw new ConsequenceException(e);
}
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
}
public void writeExternal(ObjectOutput out) throws IOException {
}
public String getName() {
return "default";
}
};
rule.setConsequence(consequence);
return rule;
}
Aggregations