use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class MVELDialect method getMVELCompilationUnit.
public MVELCompilationUnit getMVELCompilationUnit(final String expression, final AnalysisResult analysis, Declaration[] previousDeclarations, Declaration[] localDeclarations, final Map<String, Class<?>> otherInputVariables, final PackageBuildContext context, String contextIndeifier, Class kcontextClass, boolean readLocalsFromTuple, MVELCompilationUnit.Scope scope) {
Map<String, Class> resolvedInputs = new LinkedHashMap<String, Class>();
List<String> ids = new ArrayList<String>();
if (analysis.getBoundIdentifiers().getThisClass() != null || (localDeclarations != null && localDeclarations.length > 0)) {
Class cls = analysis.getBoundIdentifiers().getThisClass();
ids.add("this");
resolvedInputs.put("this", // the only time cls is null is in accumumulate's acc/reverse
(cls != null) ? cls : Object.class);
}
ids.add(contextIndeifier);
resolvedInputs.put(contextIndeifier, kcontextClass);
ids.add("kcontext");
resolvedInputs.put("kcontext", kcontextClass);
if (scope.hasRule()) {
ids.add("rule");
resolvedInputs.put("rule", Rule.class);
}
List<String> strList = new ArrayList<String>();
for (String identifier : analysis.getIdentifiers()) {
Class<?> type = analysis.getBoundIdentifiers().resolveVarType(identifier);
if (type != null) {
strList.add(identifier);
ids.add(identifier);
resolvedInputs.put(identifier, type);
}
}
String[] globalIdentifiers = strList.toArray(new String[strList.size()]);
strList.clear();
for (String op : analysis.getBoundIdentifiers().getOperators().keySet()) {
strList.add(op);
ids.add(op);
resolvedInputs.put(op, context.getConfiguration().getComponentFactory().getExpressionProcessor().getEvaluatorWrapperClass());
}
EvaluatorWrapper[] operators = new EvaluatorWrapper[strList.size()];
for (int i = 0; i < operators.length; i++) {
operators[i] = analysis.getBoundIdentifiers().getOperators().get(strList.get(i));
}
if (previousDeclarations != null) {
for (Declaration decl : previousDeclarations) {
if (analysis.getBoundIdentifiers().getDeclrClasses().containsKey(decl.getIdentifier())) {
ids.add(decl.getIdentifier());
resolvedInputs.put(decl.getIdentifier(), decl.getDeclarationClass());
}
}
}
if (localDeclarations != null) {
for (Declaration decl : localDeclarations) {
if (analysis.getBoundIdentifiers().getDeclrClasses().containsKey(decl.getIdentifier())) {
ids.add(decl.getIdentifier());
resolvedInputs.put(decl.getIdentifier(), decl.getDeclarationClass());
}
}
}
// "not bound" identifiers could be drools, kcontext and rule
// but in the case of accumulate it could be vars from the "init" section.
// String[] otherIdentifiers = otherInputVariables == null ? new String[]{} : new String[otherInputVariables.size()];
strList = new ArrayList<String>();
if (otherInputVariables != null) {
MVELAnalysisResult mvelAnalysis = (MVELAnalysisResult) analysis;
for (Entry<String, Class<?>> stringClassEntry : otherInputVariables.entrySet()) {
if ((!analysis.getNotBoundedIdentifiers().contains(stringClassEntry.getKey()) && !mvelAnalysis.getMvelVariables().keySet().contains(stringClassEntry.getKey())) || "rule".equals(stringClassEntry.getKey())) {
// and rule was already included
continue;
}
ids.add(stringClassEntry.getKey());
strList.add(stringClassEntry.getKey());
resolvedInputs.put(stringClassEntry.getKey(), stringClassEntry.getValue());
}
}
String[] otherIdentifiers = strList.toArray(new String[strList.size()]);
String[] inputIdentifiers = new String[resolvedInputs.size()];
String[] inputTypes = new String[resolvedInputs.size()];
int i = 0;
for (String id : ids) {
inputIdentifiers[i] = id;
inputTypes[i++] = resolvedInputs.get(id).getName();
}
String name;
if (context != null && context.getPkg() != null && context.getPkg().getName() != null) {
if (context instanceof RuleBuildContext) {
name = context.getPkg().getName() + "." + ((RuleBuildContext) context).getRuleDescr().getClassName();
} else {
name = context.getPkg().getName() + ".Unknown";
}
} else {
name = "Unknown";
}
return new MVELCompilationUnit(name, expression, globalIdentifiers, operators, previousDeclarations, localDeclarations, otherIdentifiers, inputIdentifiers, inputTypes, languageLevel, ((MVELAnalysisResult) analysis).isTypesafe(), readLocalsFromTuple);
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class MVELSalienceBuilder method build.
public void build(RuleBuildContext context) {
boolean typesafe = context.isTypesafe();
// pushing consequence LHS into the stack for variable resolution
context.getDeclarationResolver().pushOnBuildStack(context.getRule().getLhs());
try {
// This builder is re-usable in other dialects, so specify by name
MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule());
MVELAnalysisResult analysis = (MVELAnalysisResult) dialect.analyzeExpression(context, context.getRuleDescr(), context.getRuleDescr().getSalience(), new BoundIdentifiers(DeclarationScopeResolver.getDeclarationClasses(decls), context));
context.setTypesafe(analysis.isTypesafe());
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
int i = usedIdentifiers.getDeclrClasses().keySet().size();
Declaration[] previousDeclarations = new Declaration[i];
i = 0;
for (String id : usedIdentifiers.getDeclrClasses().keySet()) {
previousDeclarations[i++] = decls.get(id);
}
Arrays.sort(previousDeclarations, SortDeclarations.instance);
MVELCompilationUnit unit = dialect.getMVELCompilationUnit(context.getRuleDescr().getSalience(), analysis, previousDeclarations, null, null, context, "drools", KnowledgeHelper.class, false, MVELCompilationUnit.Scope.EXPRESSION);
MVELSalienceExpression expr = new MVELSalienceExpression(unit, dialect.getId());
context.getRule().setSalience(KiePolicyHelper.isPolicyEnabled() ? new SafeSalience(expr) : expr);
MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
data.addCompileable(context.getRule(), expr);
expr.compile(data, context.getRule());
} catch (final Exception e) {
copyErrorLocation(e, context.getRuleDescr());
context.addError(new DescrBuildError(context.getParentDescr(), context.getRuleDescr(), null, "Unable to build expression for 'salience' : " + e.getMessage() + "'" + context.getRuleDescr().getSalience() + "'"));
} finally {
context.setTypesafe(typesafe);
}
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class PatternBuilder method createImplicitBindings.
public static void createImplicitBindings(final RuleBuildContext context, final Pattern pattern, final Set<String> unboundIdentifiers, final BoundIdentifiers boundIdentifiers, final List<Declaration> factDeclarations) {
for (Iterator<String> it = unboundIdentifiers.iterator(); it.hasNext(); ) {
String identifier = it.next();
Declaration declaration = createDeclarationObject(context, identifier, pattern);
// that we would need to know about
if (declaration != null) {
factDeclarations.add(declaration);
// implicit bindings need to be added to "local" declarations, as they are nolonger unbound
boundIdentifiers.getDeclrClasses().put(identifier, declaration.getDeclarationClass());
it.remove();
}
}
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class QueryBuilder method build.
public Pattern build(final RuleBuildContext context, final QueryDescr queryDescr) {
ObjectType queryObjectType = ClassObjectType.DroolsQuery_ObjectType;
final Pattern pattern = new Pattern(context.getNextPatternId(), // offset is 0 by default
0, queryObjectType, null);
final InternalReadAccessor extractor = PatternBuilder.getFieldReadAccessor(context, queryDescr, pattern, "name", null, true);
final QueryNameConstraint constraint = new QueryNameConstraint(extractor, queryDescr.getName());
PatternBuilder.registerReadAccessor(context, queryObjectType, "name", constraint);
// adds appropriate constraint to the pattern
pattern.addConstraint(constraint);
ObjectType argsObjectType = ClassObjectType.DroolsQuery_ObjectType;
InternalReadAccessor arrayExtractor = PatternBuilder.getFieldReadAccessor(context, queryDescr, null, argsObjectType, "elements", null, true);
QueryImpl query = ((QueryImpl) context.getRule());
String[] params;
String[] types;
int numParams = queryDescr.getParameters().length;
if (query.isAbductive()) {
params = Arrays.copyOf(queryDescr.getParameters(), queryDescr.getParameters().length + 1);
types = Arrays.copyOf(queryDescr.getParameterTypes(), queryDescr.getParameterTypes().length + 1);
} else {
params = queryDescr.getParameters();
types = queryDescr.getParameterTypes();
}
Declaration[] declarations = new Declaration[params.length];
Class<?> abductionReturnKlass = null;
if (query.isAbductive()) {
Abductive abductive = queryDescr.getTypedAnnotation(Abductive.class);
abductionReturnKlass = abductive.target();
params[numParams] = "";
types[numParams] = abductionReturnKlass.getName();
}
int i = 0;
try {
for (i = 0; i < params.length; i++) {
Declaration declr = pattern.addDeclaration(params[i]);
// this bit is different, notice its the ArrayElementReader that we wire up to, not the declaration.
ArrayElementReader reader = new ArrayElementReader(arrayExtractor, i, context.getDialect().getTypeResolver().resolveType(types[i]));
PatternBuilder.registerReadAccessor(context, argsObjectType, "elements", reader);
declr.setReadAccessor(reader);
declarations[i] = declr;
}
query.setParameters(declarations);
} catch (ClassNotFoundException e) {
context.addError(new DescrBuildError(context.getParentDescr(), queryDescr, e, "Unable to resolve type '" + types[i] + " for parameter" + params[i]));
}
context.setPrefixPattern(pattern);
if (query.isAbductive()) {
String returnName = "";
try {
AnnotationDescr ann = queryDescr.getAnnotation(Abductive.class);
Object[] argsVal = ((Object[]) ann.getValue("args"));
String[] args = argsVal != null ? Arrays.copyOf(argsVal, argsVal.length, String[].class) : null;
returnName = types[numParams];
ObjectType objectType = new ClassObjectType(abductionReturnKlass, false);
objectType = context.getPkg().getClassFieldAccessorStore().wireObjectType(objectType, (AbductiveQuery) query);
((AbductiveQuery) query).setReturnType(objectType, params, args, declarations);
} catch (NoSuchMethodException e) {
context.addError(new DescrBuildError(context.getParentDescr(), queryDescr, e, "Unable to resolve abducible constructor for type : " + returnName + " with types " + Arrays.toString(types)));
} catch (IllegalArgumentException e) {
context.addError(new DescrBuildError(context.getParentDescr(), queryDescr, e, e.getMessage()));
}
}
return pattern;
}
use of org.drools.core.rule.Declaration in project drools by kiegroup.
the class ASMPredicateStubBuilder method createStubPredicate.
private void createStubPredicate(final ClassGenerator generator, final InvokerDataProvider data, final Map vars) {
generator.setInterfaces(PredicateStub.class, CompiledInvoker.class).addField(ACC_PRIVATE + ACC_VOLATILE, "predicate", PredicateExpression.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, "evaluate", generator.methodDescr(Boolean.TYPE, InternalFactHandle.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("predicate", PredicateExpression.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("predicate", PredicateExpression.class);
// if (predicate == 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);
// ... PredicateGenerator.generate(this, tuple, declarations, declarations, workingMemory)
invokeStatic(PredicateGenerator.class, "generate", null, PredicateStub.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("predicate", PredicateExpression.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(PredicateExpression.class, "evaluate", Boolean.TYPE, InternalFactHandle.class, Tuple.class, Declaration[].class, Declaration[].class, WorkingMemory.class, Object.class);
mv.visitInsn(IRETURN);
}
}).addMethod(ACC_PUBLIC, "setPredicate", generator.methodDescr(null, PredicateExpression.class), new ClassGenerator.MethodBody() {
public void body(MethodVisitor mv) {
putFieldInThisFromRegistry("predicate", PredicateExpression.class, 1);
mv.visitInsn(RETURN);
}
});
}
Aggregations