use of org.drools.compiler.compiler.BoundIdentifiers in project drools by kiegroup.
the class DialectUtil method fixBlockDescr.
public static String fixBlockDescr(final RuleBuildContext context, final JavaAnalysisResult analysis, Map<String, Declaration> decls, List<JavaBlockDescr> blocks) {
MVELDialect mvel = (MVELDialect) context.getDialect("mvel");
String originalCode = analysis.getAnalyzedExpr();
BoundIdentifiers bindings = analysis.getBoundIdentifiers();
// sorting exit points for correct order iteration
Collections.sort(blocks, new Comparator<JavaBlockDescr>() {
public int compare(JavaBlockDescr o1, JavaBlockDescr o2) {
return o1.getStart() - o2.getStart();
}
});
StringBuilder consequence = new StringBuilder();
int lastAdded = 0;
for (JavaBlockDescr block : blocks) {
if (block.getEnd() == 0 || block.getEnd() > originalCode.length()) {
// do nothing, it was incorrectly parsed, but this error should be picked up else where
continue;
}
// adding chunk
consequence.append(originalCode.substring(lastAdded, block.getStart() - 1));
lastAdded = block.getEnd();
switch(block.getType()) {
case MODIFY:
case UPDATE:
case DELETE:
rewriteDescr(context, originalCode, mvel, consequence, block, bindings, decls);
break;
case ENTRY:
case EXIT:
case CHANNEL:
rewriteInterfacePoint(context, originalCode, consequence, (JavaInterfacePointsDescr) block);
break;
case INSERT:
parseInsertDescr(context, block);
default:
consequence.append(originalCode.substring(block.getStart() - 1, lastAdded));
}
}
consequence.append(originalCode.substring(lastAdded));
return consequence.toString();
}
use of org.drools.compiler.compiler.BoundIdentifiers in project drools by kiegroup.
the class PatternBuilder method getFieldReadAccessor.
public static InternalReadAccessor getFieldReadAccessor(final RuleBuildContext context, final BaseDescr descr, final Pattern pattern, final ObjectType objectType, String fieldName, final AcceptsReadAccessor target, final boolean reportError) {
// 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.
InternalReadAccessor reader;
if (ValueType.FACTTEMPLATE_TYPE.equals(objectType.getValueType())) {
// @todo use accessor cache
final FactTemplate factTemplate = ((FactTemplateObjectType) objectType).getFactTemplate();
reader = new FactTemplateFieldExtractor(factTemplate, factTemplate.getFieldTemplateIndex(fieldName));
if (target != null) {
target.setReadAccessor(reader);
}
return reader;
}
boolean isGetter = getterRegexp.matcher(fieldName).matches();
if (isGetter) {
fieldName = fieldName.substring(3, fieldName.indexOf('(')).trim();
}
if (isGetter || identifierRegexp.matcher(fieldName).matches()) {
Declaration decl = context.getDeclarationResolver().getDeclarations(context.getRule()).get(fieldName);
if (decl != null && decl.getExtractor() instanceof ClassFieldReader && "this".equals(((ClassFieldReader) decl.getExtractor()).getFieldName())) {
return decl.getExtractor();
}
try {
reader = context.getPkg().getClassFieldAccessorStore().getReader(objectType.getClassName(), fieldName, target);
} catch (final Exception e) {
if (reportError && context.isTypesafe()) {
DialectUtil.copyErrorLocation(e, descr);
registerDescrBuildError(context, descr, e, "Unable to create Field Extractor for '" + fieldName + "'" + e.getMessage());
}
// if there was an error, set the reader back to null
reader = null;
} finally {
if (reportError) {
Collection<KnowledgeBuilderResult> results = context.getPkg().getClassFieldAccessorStore().getWiringResults(objectType.getClassType(), fieldName);
if (!results.isEmpty()) {
for (KnowledgeBuilderResult res : results) {
if (res.getSeverity() == ResultSeverity.ERROR) {
context.addError(new DroolsErrorWrapper(res));
} else {
context.addWarning(new DroolsWarningWrapper(res));
}
}
}
}
}
} else {
// we need MVEL extractor for expressions
Dialect dialect = context.getDialect();
try {
MVELDialect mvelDialect = (MVELDialect) context.getDialect("mvel");
context.setDialect(mvelDialect);
final AnalysisResult analysis = context.getDialect().analyzeExpression(context, descr, fieldName, new BoundIdentifiers(pattern, context, Collections.EMPTY_MAP, objectType.getClassType()));
if (analysis == null) {
// something bad happened
if (reportError) {
registerDescrBuildError(context, descr, "Unable to analyze expression '" + fieldName + "'");
}
return null;
}
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
if (!usedIdentifiers.getDeclrClasses().isEmpty()) {
if (reportError && descr instanceof BindingDescr) {
registerDescrBuildError(context, descr, "Variables can not be used inside bindings. Variable " + usedIdentifiers.getDeclrClasses().keySet() + " is being used in binding '" + fieldName + "'");
}
return null;
}
reader = context.getPkg().getClassFieldAccessorStore().getMVELReader(context.getPkg().getName(), objectType.getClassName(), fieldName, context.isTypesafe(), ((MVELAnalysisResult) analysis).getReturnType());
MVELDialectRuntimeData data = (MVELDialectRuntimeData) context.getPkg().getDialectRuntimeRegistry().getDialectData("mvel");
((MVELCompileable) reader).compile(data, context.getRule());
data.addCompileable((MVELCompileable) reader);
} catch (final Exception e) {
int dotPos = fieldName.indexOf('.');
String varName = dotPos > 0 ? fieldName.substring(0, dotPos).trim() : fieldName;
if (context.getKnowledgeBuilder().getGlobals().containsKey(varName)) {
return null;
}
if (reportError) {
DialectUtil.copyErrorLocation(e, descr);
registerDescrBuildError(context, descr, e, "Unable to create reader for '" + fieldName + "':" + e.getMessage());
}
// if there was an error, set the reader back to null
reader = null;
} finally {
context.setDialect(dialect);
}
}
return reader;
}
use of org.drools.compiler.compiler.BoundIdentifiers in project drools by kiegroup.
the class MVELAccumulateBuilder method getUsedDeclarations.
private Declaration[] getUsedDeclarations(Map<String, Declaration> decls, AnalysisResult analysis) {
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
List<Declaration> usedDeclarations = new ArrayList<Declaration>();
for (String id : usedIdentifiers.getDeclrClasses().keySet()) {
if (decls.containsKey(id)) {
usedDeclarations.add(decls.get(id));
}
}
if (!usedDeclarations.isEmpty()) {
Collections.sort(usedDeclarations, SortDeclarations.instance);
}
return usedDeclarations.toArray(new Declaration[usedDeclarations.size()]);
}
use of org.drools.compiler.compiler.BoundIdentifiers in project drools by kiegroup.
the class MVELConsequenceBuilder method build.
public void build(final RuleBuildContext context, String consequenceName) {
// pushing consequence LHS into the stack for variable resolution
context.getDeclarationResolver().pushOnBuildStack(context.getRule().getLhs());
try {
MVELDialect dialect = (MVELDialect) context.getDialect("mvel");
final RuleDescr ruleDescr = context.getRuleDescr();
String text = (RuleImpl.DEFAULT_CONSEQUENCE_NAME.equals(consequenceName)) ? (String) ruleDescr.getConsequence() : (String) ruleDescr.getNamedConsequences().get(consequenceName);
text = processMacros(text);
Map<String, Declaration> decls = context.getDeclarationResolver().getDeclarations(context.getRule());
AnalysisResult analysis = dialect.analyzeBlock(context, text, new BoundIdentifiers(DeclarationScopeResolver.getDeclarationClasses(decls), context, Collections.EMPTY_MAP, KnowledgeHelper.class), null, "drools", KnowledgeHelper.class);
if (analysis == null) {
// something bad happened, issue already logged in errors
return;
}
final BoundIdentifiers usedIdentifiers = analysis.getBoundIdentifiers();
final Declaration[] declarations = new Declaration[usedIdentifiers.getDeclrClasses().size()];
String[] declrStr = new String[declarations.length];
int j = 0;
for (String str : usedIdentifiers.getDeclrClasses().keySet()) {
declrStr[j] = str;
declarations[j++] = decls.get(str);
}
Arrays.sort(declarations, SortDeclarations.instance);
for (int i = 0; i < declrStr.length; i++) {
declrStr[i] = declarations[i].getIdentifier();
}
context.getRule().setRequiredDeclarationsForConsequence(consequenceName, declrStr);
MVELCompilationUnit unit = dialect.getMVELCompilationUnit(text, analysis, declarations, null, null, context, "drools", KnowledgeHelper.class, false, MVELCompilationUnit.Scope.CONSEQUENCE);
MVELConsequence expr = new MVELConsequence(unit, dialect.getId(), consequenceName);
if (RuleImpl.DEFAULT_CONSEQUENCE_NAME.equals(consequenceName)) {
context.getRule().setConsequence(expr);
} else {
context.getRule().addNamedConsequence(consequenceName, 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 'consequence': " + e.getMessage() + " '" + context.getRuleDescr().getConsequence() + "'"));
}
}
use of org.drools.compiler.compiler.BoundIdentifiers in project drools by kiegroup.
the class JavaExprAnalyzer method analyze.
/**
* Analyze an expression.
*
* @param availableIdentifiers
* Total set of declarations available.
* @param result
* The AST for the expression.
*
* @return The <code>Set</code> of declarations used by the expression.
*
* @throws RecognitionException
* If an error occurs in the parser.
*/
private JavaAnalysisResult analyze(JavaAnalysisResult result, BoundIdentifiers availableIdentifiers) throws RecognitionException {
final Set<String> identifiers = result.getIdentifiers();
final Set<String> notBound = new HashSet<String>(identifiers);
Map<String, Class<?>> usedDecls = new HashMap<String, Class<?>>();
Map<String, Class<?>> usedGlobals = new HashMap<String, Class<?>>();
Map<String, EvaluatorWrapper> usedOperators = new HashMap<String, EvaluatorWrapper>();
for (Entry<String, Class<?>> entry : availableIdentifiers.getDeclrClasses().entrySet()) {
if (identifiers.contains(entry.getKey())) {
usedDecls.put(entry.getKey(), entry.getValue());
notBound.remove(entry.getKey());
}
}
for (String identifier : identifiers) {
Class<?> type = availableIdentifiers.resolveVarType(identifier);
if (type != null) {
usedGlobals.put(identifier, type);
notBound.remove(identifier);
}
}
for (Map.Entry<String, EvaluatorWrapper> op : availableIdentifiers.getOperators().entrySet()) {
if (identifiers.contains(op.getKey())) {
usedOperators.put(op.getKey(), op.getValue());
notBound.remove(op.getKey());
}
}
BoundIdentifiers boundIdentifiers = new BoundIdentifiers(usedDecls, availableIdentifiers.getContext(), usedOperators, availableIdentifiers.getThisClass());
boundIdentifiers.setGlobals(usedGlobals);
result.setBoundIdentifiers(boundIdentifiers);
result.setNotBoundedIdentifiers(notBound);
return result;
}
Aggregations