Search in sources :

Example 1 with ClassFieldReader

use of org.drools.core.base.ClassFieldReader in project drools by kiegroup.

the class MVELTest method testNewConstructor.

@Test
public void testNewConstructor() {
    final String str = "" + "package org.drools.compiler.test \n" + "import " + Person.class.getCanonicalName() + "\n" + "import " + Address.class.getCanonicalName() + "\n" + "global java.util.List list \n" + "rule \"show\" \n" + "when  \n" + "    $m : Person( address == new Address('s1')) \n" + "then \n" + "    list.add('r1'); \n" + "end \n";
    final KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
    kbuilder.add(ResourceFactory.newByteArrayResource(str.getBytes()), ResourceType.DRL);
    if (kbuilder.hasErrors()) {
        fail(kbuilder.getErrors().toString());
    }
    final InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
    kbase.addPackages(kbuilder.getKnowledgePackages());
    final KieSession ksession = createKnowledgeSession(kbase);
    final List list = new ArrayList();
    ksession.setGlobal("list", list);
    final Person p = new Person("yoda");
    p.setAddress(new Address("s1"));
    ksession.insert(p);
    ksession.fireAllRules();
    assertEquals("r1", list.get(0));
    // Check it was built with MVELReturnValueExpression constraint
    final List<ObjectTypeNode> nodes = ((InternalKnowledgeBase) kbase).getRete().getObjectTypeNodes();
    ObjectTypeNode node = null;
    for (final ObjectTypeNode n : nodes) {
        if (((ClassObjectType) n.getObjectType()).getClassType() == Person.class) {
            node = n;
            break;
        }
    }
    final AlphaNode alphanode = (AlphaNode) node.getObjectSinkPropagator().getSinks()[0];
    final AlphaNodeFieldConstraint constraint = alphanode.getConstraint();
    if (constraint instanceof MvelConstraint) {
        assertTrue(((MvelConstraint) constraint).getFieldExtractor() instanceof ClassFieldReader);
        final FieldValue r = ((MvelConstraint) constraint).getField();
        assertEquals(p.getAddress(), r.getValue());
    }
}
Also used : Address(org.drools.compiler.Address) ArrayList(java.util.ArrayList) ObjectTypeNode(org.drools.core.reteoo.ObjectTypeNode) MvelConstraint(org.drools.core.rule.constraint.MvelConstraint) AlphaNode(org.drools.core.reteoo.AlphaNode) KnowledgeBuilder(org.kie.internal.builder.KnowledgeBuilder) AlphaNodeFieldConstraint(org.drools.core.spi.AlphaNodeFieldConstraint) ClassFieldReader(org.drools.core.base.ClassFieldReader) MVELObjectClassFieldReader(org.drools.core.base.extractors.MVELObjectClassFieldReader) StatelessKieSession(org.kie.api.runtime.StatelessKieSession) KieSession(org.kie.api.runtime.KieSession) ArrayList(java.util.ArrayList) List(java.util.List) FieldValue(org.drools.core.spi.FieldValue) Person(org.drools.compiler.Person) InternalKnowledgeBase(org.drools.core.impl.InternalKnowledgeBase) Test(org.junit.Test)

Example 2 with ClassFieldReader

use of org.drools.core.base.ClassFieldReader 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;
}
Also used : FactTemplateFieldExtractor(org.drools.core.facttemplates.FactTemplateFieldExtractor) BindingDescr(org.drools.compiler.lang.descr.BindingDescr) MVELCompileable(org.drools.core.base.mvel.MVELCompileable) DroolsErrorWrapper(org.drools.compiler.compiler.DroolsErrorWrapper) MVELDialect(org.drools.compiler.rule.builder.dialect.mvel.MVELDialect) DroolsParserException(org.drools.compiler.compiler.DroolsParserException) AnalysisResult(org.drools.compiler.compiler.AnalysisResult) MVELAnalysisResult(org.drools.compiler.rule.builder.dialect.mvel.MVELAnalysisResult) BoundIdentifiers(org.drools.compiler.compiler.BoundIdentifiers) MVELDialectRuntimeData(org.drools.core.rule.MVELDialectRuntimeData) MVELAnalysisResult(org.drools.compiler.rule.builder.dialect.mvel.MVELAnalysisResult) ClassFieldReader(org.drools.core.base.ClassFieldReader) InternalReadAccessor(org.drools.core.spi.InternalReadAccessor) Dialect(org.drools.compiler.compiler.Dialect) MVELDialect(org.drools.compiler.rule.builder.dialect.mvel.MVELDialect) JavaDialect(org.drools.compiler.rule.builder.dialect.java.JavaDialect) FactTemplateObjectType(org.drools.core.facttemplates.FactTemplateObjectType) DroolsWarningWrapper(org.drools.compiler.compiler.DroolsWarningWrapper) Declaration(org.drools.core.rule.Declaration) TypeDeclaration(org.drools.core.rule.TypeDeclaration) FactTemplate(org.drools.core.facttemplates.FactTemplate) KnowledgeBuilderResult(org.kie.internal.builder.KnowledgeBuilderResult)

Example 3 with ClassFieldReader

use of org.drools.core.base.ClassFieldReader in project drools by kiegroup.

the class PatternBuilder method buildRuleBindings.

protected void buildRuleBindings(RuleBuildContext context, PatternDescr patternDescr, Pattern pattern, BindingDescr fieldBindingDescr, TypeDeclaration typeDeclaration) {
    if (context.getDeclarationResolver().isDuplicated(context.getRule(), fieldBindingDescr.getVariable(), null)) {
        processDuplicateBindings(fieldBindingDescr.isUnification(), patternDescr, pattern, fieldBindingDescr, fieldBindingDescr.getBindingField(), fieldBindingDescr.getVariable(), context);
        if (fieldBindingDescr.isUnification()) {
            return;
        }
    }
    Declaration declr = pattern.addDeclaration(fieldBindingDescr.getVariable());
    final InternalReadAccessor extractor = getFieldReadAccessor(context, fieldBindingDescr, pattern, fieldBindingDescr.getBindingField(), declr, true);
    if (extractor == null) {
        registerDescrBuildError(context, patternDescr, "Field Reader does not exist for declaration '" + fieldBindingDescr.getVariable() + "' in '" + fieldBindingDescr + "' in the rule '" + context.getRule().getName() + "'");
        return;
    }
    declr.setReadAccessor(extractor);
    if (typeDeclaration != null && extractor instanceof ClassFieldReader) {
        addFieldToPatternWatchlist(pattern, typeDeclaration, ((ClassFieldReader) extractor).getFieldName());
    }
}
Also used : ClassFieldReader(org.drools.core.base.ClassFieldReader) InternalReadAccessor(org.drools.core.spi.InternalReadAccessor) Declaration(org.drools.core.rule.Declaration) TypeDeclaration(org.drools.core.rule.TypeDeclaration)

Example 4 with ClassFieldReader

use of org.drools.core.base.ClassFieldReader in project drools by kiegroup.

the class ObjectTypeNodeParser method traverseHashedAlphaNodes.

private void traverseHashedAlphaNodes(ObjectHashMap hashedAlphaNodes, NetworkHandler handler) {
    if (hashedAlphaNodes != null && hashedAlphaNodes.size() > 0) {
        AlphaNode firstAlpha = getFirstAlphaNode(hashedAlphaNodes);
        ClassFieldReader hashedFieldReader = getClassFieldReaderForHashedAlpha(firstAlpha);
        // start the hashed alphas
        handler.startHashedAlphaNodes(hashedFieldReader);
        Iterator iter = hashedAlphaNodes.iterator();
        for (ObjectHashMap.ObjectEntry entry = (ObjectHashMap.ObjectEntry) iter.next(); entry != null; entry = (ObjectHashMap.ObjectEntry) iter.next()) {
            CompositeObjectSinkAdapter.HashKey hashKey = (CompositeObjectSinkAdapter.HashKey) entry.getKey();
            AlphaNode alphaNode = (AlphaNode) entry.getValue();
            handler.startHashedAlphaNode(alphaNode, hashKey.getObjectValue());
            // traverse the propagator for each alpha
            traversePropagator(alphaNode.getObjectSinkPropagator(), handler);
            handler.endHashedAlphaNode(alphaNode, hashKey.getObjectValue());
        }
        // end of the hashed alphas
        handler.endHashedAlphaNodes(hashedFieldReader);
    }
}
Also used : ClassFieldReader(org.drools.core.base.ClassFieldReader) Iterator(org.drools.core.util.Iterator) ObjectHashMap(org.drools.core.util.ObjectHashMap)

Example 5 with ClassFieldReader

use of org.drools.core.base.ClassFieldReader in project drools by kiegroup.

the class FieldConstraintTest method testLiteralConstraint.

/**
 * <pre>
 *
 *                ( Cheese (type &quot;cheddar&quot;) )
 *
 * </pre>
 *
 * This is currently the same as using a ReturnValueConstraint just that it
 * doesn't need any requiredDeclarations
 */
@Test
public void testLiteralConstraint() {
    InternalKnowledgeBase kBase = (InternalKnowledgeBase) KnowledgeBaseFactory.newKnowledgeBase();
    StatefulKnowledgeSessionImpl ksession = (StatefulKnowledgeSessionImpl) kBase.newKieSession();
    final ClassFieldReader extractor = store.getReader(Cheese.class, "type");
    final MvelConstraint constraint = new MvelConstraintTestUtil("type == \"cheddar\"", FieldFactory.getInstance().getFieldValue("cheddar"), extractor);
    final Cheese cheddar = new Cheese("cheddar", 5);
    final InternalFactHandle cheddarHandle = (InternalFactHandle) ksession.insert(cheddar);
    // check constraint
    assertTrue(constraint.isAllowed(cheddarHandle, ksession));
    final Cheese stilton = new Cheese("stilton", 5);
    final InternalFactHandle stiltonHandle = (InternalFactHandle) ksession.insert(stilton);
    // check constraint
    assertFalse(constraint.isAllowed(stiltonHandle, ksession));
}
Also used : ClassFieldReader(org.drools.core.base.ClassFieldReader) StatefulKnowledgeSessionImpl(org.drools.core.impl.StatefulKnowledgeSessionImpl) MvelConstraint(org.drools.core.rule.constraint.MvelConstraint) Cheese(org.drools.core.test.model.Cheese) InternalFactHandle(org.drools.core.common.InternalFactHandle) InternalKnowledgeBase(org.drools.core.impl.InternalKnowledgeBase) Test(org.junit.Test)

Aggregations

ClassFieldReader (org.drools.core.base.ClassFieldReader)14 Test (org.junit.Test)8 MvelConstraint (org.drools.core.rule.constraint.MvelConstraint)7 Cheese (org.drools.core.test.model.Cheese)7 InternalFactHandle (org.drools.core.common.InternalFactHandle)6 InternalKnowledgeBase (org.drools.core.impl.InternalKnowledgeBase)6 FieldValue (org.drools.core.spi.FieldValue)5 IOException (java.io.IOException)4 DefaultFactHandle (org.drools.core.common.DefaultFactHandle)4 RuleImpl (org.drools.core.definitions.rule.impl.RuleImpl)4 MvelConstraintTestUtil (org.drools.core.rule.MvelConstraintTestUtil)4 ObjectInput (java.io.ObjectInput)3 ObjectOutput (java.io.ObjectOutput)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 WorkingMemory (org.drools.core.WorkingMemory)3 ClassFieldAccessorCache (org.drools.core.base.ClassFieldAccessorCache)3 ClassFieldAccessorStore (org.drools.core.base.ClassFieldAccessorStore)3 ClassObjectType (org.drools.core.base.ClassObjectType)3 KnowledgePackageImpl (org.drools.core.definitions.impl.KnowledgePackageImpl)3