use of org.drools.core.spi.InternalReadAccessor in project drools by kiegroup.
the class BaseClassFieldAccessorFactoryTest method testAbstract.
@Test
public void testAbstract() throws Exception {
final InternalReadAccessor ex = store.getReader(TestAbstract.class, "something");
assertEquals(2, ex.getIndex());
assertEquals("foo", ex.getValue(null, new TestAbstractImpl()));
}
use of org.drools.core.spi.InternalReadAccessor in project drools by kiegroup.
the class QueryElementBuilder method build.
@SuppressWarnings("unchecked")
public RuleConditionElement build(RuleBuildContext context, BaseDescr descr, QueryImpl query) {
PatternDescr patternDescr = (PatternDescr) descr;
Declaration[] params = query.getParameters();
List<BaseDescr> args = (List<BaseDescr>) patternDescr.getDescrs();
List<Declaration> requiredDeclarations = new ArrayList<Declaration>();
ObjectType argsObjectType = ClassObjectType.ObjectArray_ObjectType;
InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class);
Pattern pattern = new Pattern(context.getNextPatternId(), 0, argsObjectType, null);
if (!StringUtils.isEmpty(patternDescr.getIdentifier())) {
if (query.isAbductive()) {
Declaration declr = context.getDeclarationResolver().getDeclaration(patternDescr.getIdentifier());
if (declr != null && !patternDescr.isUnification()) {
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Duplicate declaration " + patternDescr.getIdentifier() + ", unable to bind abducted value"));
}
} else {
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query binding is not supported by non-abductive queries : " + patternDescr.getIdentifier()));
}
}
boolean addAbductiveReturnArgument = query.isAbductive() && !StringUtils.isEmpty(patternDescr.getIdentifier()) && args.size() < params.length;
if (addAbductiveReturnArgument) {
ExprConstraintDescr extraDescr = new ExprConstraintDescr(patternDescr.getIdentifier());
extraDescr.setPosition(patternDescr.getConstraint().getDescrs().size());
extraDescr.setType(ExprConstraintDescr.Type.POSITIONAL);
args.add(extraDescr);
}
QueryArgument[] arguments = new QueryArgument[params.length];
// Deal with the constraints, both positional and bindings
for (BaseDescr base : args) {
String expression = null;
boolean isPositional = false;
boolean isBinding = false;
BindingDescr bind = null;
ConstraintConnectiveDescr result = null;
if (base instanceof BindingDescr) {
bind = (BindingDescr) base;
expression = bind.getVariable() + (bind.isUnification() ? " := " : " : ") + bind.getExpression();
isBinding = true;
} else {
if (base instanceof ExprConstraintDescr) {
ExprConstraintDescr ecd = (ExprConstraintDescr) base;
expression = ecd.getExpression();
isPositional = ecd.getType() == ExprConstraintDescr.Type.POSITIONAL;
} else {
expression = base.getText();
}
result = parseExpression(context, patternDescr, expression);
if (result == null) {
// error, can't parse expression.
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Unable to parse constraint: \n" + expression));
continue;
}
isBinding = result.getDescrs().size() == 1 && result.getDescrs().get(0) instanceof BindingDescr;
if (isBinding) {
bind = (BindingDescr) result.getDescrs().get(0);
}
}
if ((!isPositional) && (!isBinding)) {
// error, can't have non binding slots.
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query's must use positional or bindings, not field constraints:\n" + expression));
} else if (isPositional && isBinding) {
// error, can't have positional binding slots.
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query's can't use positional bindings:\n" + expression));
} else if (isPositional) {
processPositional(context, query, params, arguments, requiredDeclarations, arrayReader, pattern, base, expression, result);
} else {
// it is binding
processBinding(context, descr, params, arguments, requiredDeclarations, arrayReader, pattern, bind);
}
}
List<Integer> varIndexList = new ArrayList<Integer>();
for (int i = 0; i < arguments.length; i++) {
if (!(arguments[i] instanceof QueryArgument.Declr)) {
if (arguments[i] instanceof QueryArgument.Var) {
varIndexList.add(i);
}
continue;
}
Class actual = ((QueryArgument.Declr) arguments[i]).getArgumentClass();
Declaration formalArgument = query.getParameters()[i];
Class formal = formalArgument.getDeclarationClass();
// input argument require a broader type, while output types require a narrower type, so we check for both.
if (!ClassUtils.isTypeCompatibleWithArgumentType(actual, formal) && !ClassUtils.isTypeCompatibleWithArgumentType(formal, actual)) {
context.addError(new DescrBuildError(context.getParentDescr(), descr, null, "Query is being invoked with known argument of type " + actual + " at position " + i + ", but the expected query argument is of type " + formal));
}
}
return new QueryElement(pattern, query.getName(), arguments, toIntArray(varIndexList), requiredDeclarations.toArray(new Declaration[requiredDeclarations.size()]), !patternDescr.isQuery(), query.isAbductive());
}
use of org.drools.core.spi.InternalReadAccessor in project drools by kiegroup.
the class PatternBuilder method createDeclarationObject.
protected static Declaration createDeclarationObject(final RuleBuildContext context, final String identifier, final String expr, final Pattern pattern) {
final BindingDescr implicitBinding = new BindingDescr(identifier, expr);
final Declaration declaration = new Declaration(identifier, null, pattern, true);
InternalReadAccessor extractor = getFieldReadAccessor(context, implicitBinding, pattern, implicitBinding.getExpression(), declaration, false);
if (extractor == null) {
return null;
}
declaration.setReadAccessor(extractor);
return declaration;
}
use of org.drools.core.spi.InternalReadAccessor in project drools by kiegroup.
the class PatternBuilder method buildConstraintForPattern.
protected Constraint buildConstraintForPattern(final RuleBuildContext context, final Pattern pattern, final RelationalExprDescr relDescr, String expr, String value1, String value2, boolean isConstant, Map<String, OperatorDescr> aliases) {
InternalReadAccessor extractor = getFieldReadAccessor(context, relDescr, pattern, value1, null, true);
if (extractor == null) {
return null;
}
int dotPos = value1.indexOf('.');
if (dotPos > 0) {
String part0 = value1.substring(0, dotPos).trim();
if ("this".equals(part0.trim())) {
value1 = value1.substring(dotPos + 1);
} else if (pattern.getDeclaration() != null && part0.equals(pattern.getDeclaration().getIdentifier())) {
value1 = value1.substring(dotPos + 1);
expr = expr.substring(dotPos + 1);
}
}
ValueType vtype = extractor.getValueType();
String operator = relDescr.getOperator().trim();
LiteralRestrictionDescr restrictionDescr = buildLiteralRestrictionDescr(context, relDescr, value2, operator, isConstant);
if (restrictionDescr != null) {
FieldValue field = getFieldValue(context, vtype, restrictionDescr.getText().trim());
if (field != null) {
Constraint constraint = getConstraintBuilder(context).buildLiteralConstraint(context, pattern, vtype, field, expr, value1, operator, value2, extractor, restrictionDescr, aliases);
if (constraint != null) {
return constraint;
}
}
}
value2 = context.getDeclarationResolver().normalizeValueForUnit(value2);
Declaration declr = null;
if (value2.indexOf('(') < 0 && value2.indexOf('.') < 0 && value2.indexOf('[') < 0) {
declr = context.getDeclarationResolver().getDeclaration(value2);
if (declr == null) {
// trying to create implicit declaration
final Pattern thisPattern = (Pattern) context.getDeclarationResolver().peekBuildStack();
declr = createDeclarationObject(context, value2, thisPattern);
}
}
Declaration[] declarations = null;
if (declr == null) {
String[] parts = value2.split("\\.");
if (parts.length == 2) {
if ("this".equals(parts[0].trim())) {
declr = createDeclarationObject(context, parts[1].trim(), (Pattern) context.getDeclarationResolver().peekBuildStack());
value2 = parts[1].trim();
} else {
declr = context.getDeclarationResolver().getDeclaration(parts[0].trim());
// if a declaration exists, then it may be a variable direct property access
if (declr != null) {
if (declr.isPatternDeclaration()) {
// TODO: no need to extract inner declaration when using mvel constraint
declarations = new Declaration[] { declr };
declr = createDeclarationObject(context, parts[1].trim(), declr.getPattern());
value2 = parts[1].trim();
} else {
// we will later fallback to regular predicates, so don't raise error
return null;
}
}
}
}
}
if (declarations == null) {
if (declr != null) {
declarations = new Declaration[] { declr };
} else {
declarations = getDeclarationsForReturnValue(context, relDescr, operator, value2);
if (declarations == null) {
return null;
}
}
}
return getConstraintBuilder(context).buildVariableConstraint(context, pattern, expr, declarations, value1, relDescr.getOperatorDescr(), value2, extractor, declr, relDescr, aliases);
}
use of org.drools.core.spi.InternalReadAccessor in project drools by kiegroup.
the class KiePackagesBuilder method buildQueryPattern.
private RuleConditionElement buildQueryPattern(RuleContext ctx, QueryCallPattern queryPattern) {
Pattern pattern = new Pattern(ctx.getNextPatternIndex(), 0, ClassObjectType.ObjectArray_ObjectType, null);
InternalReadAccessor arrayReader = new SelfReferenceClassFieldReader(Object[].class);
QueryArgument[] arguments = new QueryArgument[queryPattern.getArguments().length];
List<Integer> varIndexList = new ArrayList<>();
List<Declaration> requiredDeclarations = new ArrayList<>();
for (int i = 0; i < queryPattern.getArguments().length; i++) {
Argument arg = queryPattern.getArguments()[i];
if (arg instanceof Variable) {
Variable var = ((Variable) arg);
Declaration decl = ctx.getDeclaration(var);
if (decl != null) {
requiredDeclarations.add(decl);
arguments[i] = new QueryArgument.Declr(decl);
} else {
ArrayElementReader reader = new ArrayElementReader(arrayReader, i, arg.getType());
pattern.addDeclaration(var.getName()).setReadAccessor(reader);
arguments[i] = QueryArgument.VAR;
varIndexList.add(i);
}
} else if (arg instanceof Value) {
arguments[i] = new QueryArgument.Literal(((Value) arg).getValue());
} else {
throw new UnsupportedOperationException();
}
}
return new QueryElement(pattern, queryPattern.getQuery().getName(), arguments, varIndexList.stream().mapToInt(i -> i).toArray(), requiredDeclarations.toArray(new Declaration[requiredDeclarations.size()]), queryPattern.isOpen(), // TODO: query.isAbductive() );
false);
}
Aggregations