public List<String> getDeclarationIds() { List<String> decls = new ArrayList<String>(); for (Declaration decl : this.declarations) { decls.add(decl.getIdentifier()); } return Collections.unmodifiableList(decls); }
private void initDeclarations() { Map<String, Declaration> declMap = subrule.getOuterDeclarations(); this.allDeclarations = declMap.values().toArray(new Declaration[declMap.size()]); this.requiredDeclarations = new Declaration[query.getParameters().length]; int i = 0; for (Declaration declr : query.getParameters()) { this.requiredDeclarations[i++] = declMap.get(declr.getIdentifier()); } }
@Override public XpathConstraint clone() { XpathConstraint clone = new XpathConstraint(this.chunks); if (declaration != null) { clone.setDeclaration(declaration.clone()); } if (xpathStartDeclaration != null) { clone.setXpathStartDeclaration(xpathStartDeclaration.clone()); } return clone; }
private boolean checkProcessInstance(Activation activation, long processInstanceId) { final Map<String, Declaration> declarations = activation.getSubRule().getOuterDeclarations(); for (Declaration declaration : declarations.values()) { if ("processInstance".equals(declaration.getIdentifier())) { Object value = declaration.getValue(workingMemory, activation.getTuple().get(declaration).getObject()); if (value instanceof ProcessInstance) { return ((ProcessInstance) value).getId() == processInstanceId; } } } return true; }
public String[] getIdentifiers() { if (identifiers != null) { return identifiers; } Declaration[] parameters = this.results.getParameters(); Set<String> set = new HashSet<String>(); for (Declaration declr : parameters) { set.add(declr.getIdentifier()); } Collection<Declaration> declrCollection = new ArrayList(results.getDeclarations(0).values()); for (Iterator<Declaration> it = declrCollection.iterator(); it.hasNext(); ) { Declaration declr = it.next(); if (set.contains(declr.getIdentifier())) { it.remove(); } } String[] declrs = new String[parameters.length + declrCollection.size()]; int i = 0; for (Declaration declr : parameters) { declrs[i++] = declr.getIdentifier(); } for (Declaration declr : declrCollection) { declrs[i++] = declr.getIdentifier(); } identifiers = declrs; return identifiers; }
protected boolean checkProcessInstance(Activation activation) { final Map<?, ?> declarations = activation.getSubRule().getOuterDeclarations(); for (Iterator<?> it = declarations.values().iterator(); it.hasNext(); ) { Declaration declaration = (Declaration) it.next(); if ("processInstance".equals(declaration.getIdentifier()) || "org.kie.api.runtime.process.WorkflowProcessInstance" .equals(declaration.getTypeName())) { Object value = declaration.getValue( ((StatefulKnowledgeSessionImpl) getProcessInstance().getKnowledgeRuntime()) .getInternalWorkingMemory(), ((InternalFactHandle) activation.getTuple().get(declaration)).getObject()); if (value instanceof ProcessInstance) { return ((ProcessInstance) value).getId() == getProcessInstance().getId(); } } } return true; }
public BetaNodeFieldConstraint getBoundVariableConstraint( final Class clazz, final String fieldName, final Declaration declaration, final String evaluatorString) throws IntrospectionException { final InternalReadAccessor extractor = store.getReader(clazz, fieldName, getClass().getClassLoader()); String expression = fieldName + " " + evaluatorString + " " + declaration.getIdentifier(); return new MvelConstraintTestUtil(expression, declaration, extractor); }
@Override public Iterator getResults( Tuple leftTuple, InternalWorkingMemory wm, PropagationContext ctx, Object providerContext) { InternalFactHandle fh = leftTuple.getFactHandle(); Object obj = fh.getObject(); if (obj instanceof DroolsQuery) { obj = ((DroolsQuery) obj).getElements()[declaration.getPattern().getOffset()]; } return xpathEvaluator.evaluate(wm, leftTuple, obj).iterator(); }
private void processPositional( RuleBuildContext context, Query query, Declaration[] params, List<Integer> declrIndexes, List<Integer> varIndexes, List<Object> arguments, List<Declaration> requiredDeclarations, InternalReadAccessor arrayReader, Pattern pattern, BaseDescr base, String expression, ConstraintConnectiveDescr result) { int position = ((ExprConstraintDescr) base).getPosition(); if (position >= arguments.size()) { context.addError( new DescrBuildError( context.getParentDescr(), base, null, "Unable to parse query '" + query.getName() + "', as postion " + (position - 1) + " for expression '" + expression + "' does not exist on query size " + arguments.size())); return; } if (isVariable(expression)) { // is this already bound? Declaration declr = context.getDeclarationResolver().getDeclaration(query, expression); if (declr != null) { // it exists, so it's an input arguments.set(position, declr); declrIndexes.add(position); requiredDeclarations.add(declr); } else { // it doesn't exist, so it's an output arguments.set(position, Variable.v); varIndexes.add(position); declr = pattern.addDeclaration(expression); // this bit is different, notice its the ArrayElementReader that we wire up to, not the // declaration. ArrayElementReader reader = new ArrayElementReader( arrayReader, position, params[position].getExtractor().getExtractToClass()); declr.setReadAccessor(reader); } } else { // it's an expression and thus an input MVELDumper.MVELDumperContext mvelCtx = new MVELDumper.MVELDumperContext(); String rewrittenExpr = context.getCompilerFactory().getExpressionProcessor().dump(result, mvelCtx); arguments.set(position, MVEL.eval(rewrittenExpr)); // for now we just work with literals } }
@SuppressWarnings("unchecked") private void processBinding( RuleBuildContext context, BaseDescr descr, Declaration[] params, List<Integer> declrIndexes, List<Integer> varIndexes, List<Object> arguments, List<Declaration> requiredDeclarations, InternalReadAccessor arrayReader, Pattern pattern, BindingDescr bind, ConstraintConnectiveDescr result) { Declaration declr = context.getDeclarationResolver().getDeclaration(context.getRule(), bind.getVariable()); if (declr != null) { // check right maps to a slot, otherwise we can't reverse this and should error int pos = getPos(bind.getExpression(), params); if (pos >= 0) { // slot exist, reverse and continue String slot = bind.getExpression(); String var = bind.getVariable(); bind.setVariable(slot); bind.setExpression(var); } else { // else error, we cannot find the slot to unify against } } // left does not already exist, is it a slot? int pos = getPos(bind.getVariable(), params); if (pos >= 0) { // it's an input on a slot, is the input using bindings? declr = context.getDeclarationResolver().getDeclaration(context.getRule(), bind.getExpression()); if (declr != null) { arguments.set(pos, declr); declrIndexes.add(pos); requiredDeclarations.add(declr); } else { // it must be a literal/expression // it's an expression and thus an input DrlExprParser parser = new DrlExprParser(context.getConfiguration().getLanguageLevel()); ConstraintConnectiveDescr bresult = parser.parse(bind.getExpression()); if (parser.hasErrors()) { for (DroolsParserException error : parser.getErrors()) { context.addError( new DescrBuildError( context.getParentDescr(), descr, null, "Unable to parser pattern expression:\n" + error.getMessage())); } return; } MVELDumper.MVELDumperContext mvelCtx = new MVELDumper.MVELDumperContext(); String expr = context.getCompilerFactory().getExpressionProcessor().dump(bresult, mvelCtx); try { Object o = MVEL.eval(expr); arguments.set(pos, o); // for now we just work with literals } catch (Exception e) { context.addError( new DescrBuildError( context.getParentDescr(), descr, null, "Unable to compile expression:\n" + expr)); } } } else { // this is creating a new output binding // we know it doesn't exist, as we already checked for left == var declr = pattern.addDeclaration(bind.getVariable()); pos = getPos(bind.getExpression(), params); if (pos < 0) { // error this must be a binding on a slot context.addError( new DescrBuildError( context.getParentDescr(), descr, null, "named argument does not exist:\n" + bind.getExpression())); return; } // this bit is different, notice its the ArrayElementReader that we wire up to, not the // declaration. ArrayElementReader reader = new ArrayElementReader(arrayReader, pos, params[pos].getExtractor().getExtractToClass()); // Should the reader be registered like the others? Probably yes... // PatternBuilder.registerReadAccessor( ); declr.setReadAccessor(reader); varIndexes.add(pos); arguments.set(pos, Variable.v); } }
public void execute(Map<String, Object> context, List<String[]> args) { BuildContext buildContext = (BuildContext) context.get("BuildContext"); if (args.size() >= 1) { // The first argument list is the node parameters String[] a = args.get(0); String name = a[0]; String leftInput = a[1]; String rightInput = a[2]; String sourceType = a[3]; String expr = a[4]; Class cls = null; LeftTupleSource leftTupleSource; if (leftInput.startsWith("mock")) { leftTupleSource = new MockTupleSource(buildContext.getNextId()); } else { leftTupleSource = (LeftTupleSource) context.get(leftInput); } ObjectSource rightObjectSource; if (rightInput.startsWith("mock")) { String type = rightInput.substring(5, rightInput.length() - 1); try { cls = reteTesterHelper.getTypeResolver().resolveType(type); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } rightObjectSource = new MockObjectSource(buildContext.getNextId()); } else { rightObjectSource = (ObjectSource) context.get(rightInput); ObjectSource source = rightObjectSource; while (!(source instanceof ObjectTypeNode)) { source = source.getParentObjectSource(); } cls = ((ClassObjectType) ((ObjectTypeNode) source).getObjectType()).getClassType(); } Pattern sourcePattern; Pattern resultPattern; try { sourcePattern = reteTesterHelper.getPattern(0, sourceType); // we always use the accumulate function "sum", so return type is always Number resultPattern = reteTesterHelper.getPattern(buildContext.getNextId(), Number.class.getName()); } catch (Exception e) { throw new IllegalArgumentException( "Not possible to process arguments: " + Arrays.toString(a)); } List<BetaNodeFieldConstraint> list = new ArrayList<BetaNodeFieldConstraint>(); AlphaNodeFieldConstraint[] alphaResultConstraint = new AlphaNodeFieldConstraint[0]; // the following arguments are constraints for (int i = 1; i < args.size(); i++) { a = args.get(i); String type = a[0]; String fieldName = a[1]; String operator = a[2]; String val = a[3]; if ("source".equals(type)) { Declaration declr = (Declaration) context.get(val); try { BetaNodeFieldConstraint sourceBetaConstraint = this.reteTesterHelper.getBoundVariableConstraint(cls, fieldName, declr, operator); list.add(sourceBetaConstraint); } catch (IntrospectionException e) { throw new IllegalArgumentException(); } } else if ("result".equals(type)) { alphaResultConstraint = new AlphaNodeFieldConstraint[1]; try { alphaResultConstraint[0] = this.reteTesterHelper.getLiteralConstraint(resultPattern, fieldName, operator, val); } catch (IntrospectionException e) { throw new IllegalArgumentException( "Unable to configure alpha constraint: " + Arrays.toString(a), e); } } } BetaConstraints betaSourceConstraints; switch (list.size()) { case 0: betaSourceConstraints = new EmptyBetaConstraints(); break; case 1: betaSourceConstraints = new SingleBetaConstraints( list.get(0), buildContext.getKnowledgeBase().getConfiguration()); break; case 2: betaSourceConstraints = new DoubleBetaConstraints( list.toArray(new BetaNodeFieldConstraint[2]), buildContext.getKnowledgeBase().getConfiguration()); break; case 3: betaSourceConstraints = new TripleBetaConstraints( list.toArray(new BetaNodeFieldConstraint[2]), buildContext.getKnowledgeBase().getConfiguration()); break; case 4: betaSourceConstraints = new QuadroupleBetaConstraints( list.toArray(new BetaNodeFieldConstraint[2]), buildContext.getKnowledgeBase().getConfiguration()); break; default: betaSourceConstraints = new DefaultBetaConstraints( list.toArray(new BetaNodeFieldConstraint[2]), buildContext.getKnowledgeBase().getConfiguration()); break; } MVELDialectRuntimeData data = (MVELDialectRuntimeData) buildContext .getKnowledgeBase() .getPackage(buildContext.getRule().getPackageName()) .getDialectRuntimeRegistry() .getDialectData("mvel"); data.onAdd(null, buildContext.getKnowledgeBase().getRootClassLoader()); // MvelD data = (MVELDialectRuntimeData) buildContext.getRuleBase().getPackage( // buildContext.getRule().getName() ).getDialectRuntimeRegistry().getDialectData( "mvel" ); NodeTestCase testCase = (NodeTestCase) context.get("TestCase"); try { for (String imp : testCase.getImports()) { if (imp.endsWith(".*")) { data.addPackageImport(imp.substring(0, imp.lastIndexOf('.'))); } else { // classImports.add( imp ); cls = data.getRootClassLoader().loadClass(imp); data.addImport(cls.getSimpleName(), cls); } } } catch (Exception e) { throw new RuntimeException("Unable to load class", e); } Declaration decl = (Declaration) context.get(expr); // build an external function executor MVELCompilationUnit compilationUnit = new MVELCompilationUnit( name, expr, new String[] {}, // global identifiers new EvaluatorWrapper[] {}, // operator identifiers new Declaration[] {}, // previous declarations new Declaration[] {decl}, // local declarations new String[] {}, // other identifiers new String[] { "this", "drools", "kcontext", "rule", decl.getIdentifier() }, // input identifiers new String[] { Object.class.getName(), KnowledgeHelper.class.getName(), KnowledgeHelper.class.getName(), Rule.class.getName(), decl.getValueType().getClassType().getName() }, // input types 4, false, false); AccumulateFunction accFunction = new SumAccumulateFunction(); Accumulator accumulator = new MVELAccumulatorFunctionExecutor(compilationUnit, accFunction); ((MVELCompileable) accumulator).compile(data); Accumulate accumulate = new SingleAccumulate( sourcePattern, new Declaration[] {}, // required declaration accumulator); AccumulateNode accNode = new AccumulateNode( buildContext.getNextId(), leftTupleSource, rightObjectSource, alphaResultConstraint, betaSourceConstraints, new EmptyBetaConstraints(), accumulate, false, buildContext); accNode.attach(buildContext); context.put(name, accNode); } else { StringBuilder msgBuilder = new StringBuilder(); msgBuilder.append("Can not parse AccumulateNode step arguments: \n"); for (String[] arg : args) { msgBuilder.append(" "); msgBuilder.append(Arrays.toString(arg)); msgBuilder.append("\n"); } throw new IllegalArgumentException(msgBuilder.toString()); } }
private Accumulator[] buildExternalFunctions( final RuleBuildContext context, final AccumulateDescr accumDescr, MVELDialect dialect, Map<String, Declaration> decls, Map<String, Declaration> sourceOuterDeclr, BoundIdentifiers boundIds, boolean readLocalsFromTuple) { Accumulator[] accumulators; List<AccumulateFunctionCallDescr> functions = accumDescr.getFunctions(); accumulators = new Accumulator[functions.size()]; // creating the custom array reader InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class, "this"); int index = 0; Pattern pattern = (Pattern) context.getDeclarationResolver().peekBuildStack(); for (AccumulateFunctionCallDescr func : functions) { // build an external function executor AccumulateFunction function = context.getConfiguration().getAccumulateFunction(func.getFunction()); if (function == null) { // might have been imported in the package function = context .getKnowledgeBuilder() .getPackage() .getAccumulateFunctions() .get(func.getFunction()); } if (function == null) { context.addError( new DescrBuildError( accumDescr, context.getRuleDescr(), null, "Unknown accumulate function: '" + func.getFunction() + "' on rule '" + context.getRuleDescr().getName() + "'. All accumulate functions must be registered before building a resource.")); return null; } final AnalysisResult analysis = dialect.analyzeExpression( context, accumDescr, func.getParams().length > 0 ? func.getParams()[0] : "\"\"", boundIds); MVELCompilationUnit unit = dialect.getMVELCompilationUnit( func.getParams().length > 0 ? func.getParams()[0] : "\"\"", analysis, getUsedDeclarations(decls, analysis), getUsedDeclarations(sourceOuterDeclr, analysis), null, context, "drools", KnowledgeHelper.class, readLocalsFromTuple, MVELCompilationUnit.Scope.CONSTRAINT); accumulators[index] = new MVELAccumulatorFunctionExecutor(unit, function); // if there is a binding, create the binding if (func.getBind() != null) { if (context .getDeclarationResolver() .isDuplicated(context.getRule(), func.getBind(), function.getResultType().getName())) { if (!func.isUnification()) { context.addError( new DescrBuildError( context.getParentDescr(), accumDescr, null, "Duplicate declaration for variable '" + func.getBind() + "' in the rule '" + context.getRule().getName() + "'")); } else { Declaration inner = context.getDeclarationResolver().getDeclaration(context.getRule(), func.getBind()); Constraint c = new MvelConstraint( Collections.singletonList(context.getPkg().getName()), accumDescr.isMultiFunction() ? "this[ " + index + " ] == " + func.getBind() : "this == " + func.getBind(), new Declaration[] {inner}, null, IndexUtil.ConstraintType.EQUAL, context .getDeclarationResolver() .getDeclaration(context.getRule(), func.getBind()), accumDescr.isMultiFunction() ? new ArrayElementReader(arrayReader, index, function.getResultType()) : new SelfReferenceClassFieldReader(function.getResultType(), "this"), true); ((MutableTypeConstraint) c).setType(Constraint.ConstraintType.BETA); pattern.addConstraint(c); index++; } } else { Declaration declr = pattern.addDeclaration(func.getBind()); if (accumDescr.isMultiFunction()) { declr.setReadAccessor( new ArrayElementReader(arrayReader, index, function.getResultType())); } else { declr.setReadAccessor( new SelfReferenceClassFieldReader(function.getResultType(), "this")); } } } index++; } return accumulators; }
public Object getDeclarationValue(String variableName) { Declaration decl = ((RuleImpl) this.rule).getDeclaration(variableName); return decl.getValue( null, ((InternalFactHandle) factHandles.get(decl.getPattern().getOffset())).getObject()); }
public void setDeclaration(Declaration declaration) { declaration.setReadAccessor(getReadAccessor()); this.declaration = declaration; }