use of org.drools.core.facttemplates.FactTemplateFieldExtractor 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;
}
Aggregations