Search in sources :

Example 1 with RuleFactory

use of org.knime.base.node.rules.engine.RuleFactory in project knime-core by knime.

the class RuleEngine2PortsSimpleNodeDialog method updateErrorsAndWarnings.

/**
 * Updates the errors table, the warning text area and the computed outcome type.
 */
protected void updateErrorsAndWarnings() {
    m_errorsModel.setRowCount(0);
    hideErrors();
    m_warnings.setText("");
    m_outcomeType.setIcon(DataType.getMissingCell().getType().getIcon());
    // Checking data from second input port
    final int ruleIdx = getRules() == null ? -1 : getRules().getSpec().findColumnIndex(m_ruleColumn.getSelectedColumn());
    final int outcomeIdx = getRules() == null ? -1 : getRules().getSpec().findColumnIndex(m_outcomeColumn.getSelectedColumn());
    if (getRules() != null && isSpecAvailable() && ruleIdx >= 0) {
        RuleFactory factory = ruleFactory();
        long lineNo = 0;
        boolean wasCatchAll = false;
        final boolean firstHit = isFirstHit();
        List<Rule> rules = new ArrayList<>();
        for (DataRow dataRow : getRules()) {
            ++lineNo;
            DataCell ruleCell = dataRow.getCell(ruleIdx);
            if (ruleCell.isMissing()) {
                // String cellValue = "?";
                // if (ruleCell instanceof MissingValue) {
                // cellValue += " (" + ((MissingValue)ruleCell).getError() + ")";
                // }
                m_errorsModel.addRow(new Object[] { dataRow.getKey(), ruleCell, "Missing cell" });
                showErrors();
            }
            if (ruleCell instanceof StringValue) {
                StringValue ruleSV = (StringValue) ruleCell;
                String ruleText = ruleSV.getStringValue().replaceAll("[\r\n]+", " ");
                if (outcomeIdx >= 0) {
                    DataCell outcome = dataRow.getCell(outcomeIdx);
                    String outcomeString;
                    try {
                        outcomeString = m_settings.asStringFailForMissing(outcome);
                    } catch (InvalidSettingsException e) {
                        outcomeString = "?";
                    }
                    if (m_ruleType.onlyBooleanOutcome()) {
                        if ("\"TRUE\"".equalsIgnoreCase(outcomeString)) {
                            outcomeString = "TRUE";
                        } else if ("\"FALSE\"".equalsIgnoreCase(outcomeString)) {
                            outcomeString = "FALSE";
                        }
                    }
                    ruleText += " => " + outcomeString;
                }
                try {
                    Rule rule = factory.parse(ruleText, getDataSpec(), getAvailableFlowVariables());
                    rules.add(rule);
                    String origWarning = !m_warnings.getText().isEmpty() ? m_warnings.getText() + "\n" : "";
                    Condition cond = rule.getCondition();
                    if (cond.isEnabled()) {
                        // not comment
                        if (cond.isCatchAll() && !wasCatchAll && firstHit && lineNo < getRules().size()) {
                            m_warnings.setText(origWarning + "No rules will match after line " + lineNo + " (" + dataRow.getKey() + "). Because of rule: " + ruleText);
                        }
                        wasCatchAll |= cond.isCatchAll() && firstHit;
                        if (!wasCatchAll && cond.isConstantFalse()) {
                            m_warnings.setText(origWarning + "The rule in line " + lineNo + " (" + dataRow.getKey() + ") will never match: " + ruleText);
                        }
                    }
                } catch (ParseException e) {
                    m_errorsModel.addRow(new Object[] { dataRow.getKey(), ruleText, e.getMessage() });
                    showErrors();
                }
            } else {
                // Missings were handled previously
                if (!ruleCell.isMissing()) {
                    m_errorsModel.addRow(new Object[] { dataRow.getKey(), ruleCell.toString(), "Wrong type: " + ruleCell.getType() });
                }
            }
        }
        final DataColumnSpec outcomeSpec = m_outcomeColumn.getSelectedColumnAsSpec();
        DataType dataType = RuleEngineNodeModel.computeOutputType(rules, outcomeSpec == null ? StringCell.TYPE : outcomeSpec.getType(), m_ruleType, getSettings().isDisallowLongOutputForCompatibility());
        if (dataType != null) {
            m_outcomeType.setIcon(dataType.getIcon());
        }
    }
}
Also used : Condition(org.knime.base.node.rules.engine.Condition) RuleFactory(org.knime.base.node.rules.engine.RuleFactory) ArrayList(java.util.ArrayList) DataRow(org.knime.core.data.DataRow) DataColumnSpec(org.knime.core.data.DataColumnSpec) InvalidSettingsException(org.knime.core.node.InvalidSettingsException) DataCell(org.knime.core.data.DataCell) DataType(org.knime.core.data.DataType) PortObject(org.knime.core.node.port.PortObject) Rule(org.knime.base.node.rules.engine.Rule) ParseException(java.text.ParseException) StringValue(org.knime.core.data.StringValue)

Example 2 with RuleFactory

use of org.knime.base.node.rules.engine.RuleFactory in project knime-core by knime.

the class RuleEngineFilter2PortsNodeModel method parseRules.

/**
 * Parses all rules in the from the table (assuming {@link #rules()} is safe to call, like
 * {@link #createStreamableOperator(PartitionInfo, PortObjectSpec[])} or
 * {@link #execute(BufferedDataTable[], ExecutionContext)} was called before).
 *
 * @param spec the spec of the table on which the rules are applied.
 * @param nodeType The type of the node from this method is called.
 * @return a list of parsed rules
 * @throws ParseException if a rule cannot be parsed
 * @since 2.12
 */
@Override
protected List<Rule> parseRules(final DataTableSpec spec, final RuleNodeSettings nodeType) throws ParseException {
    ArrayList<Rule> rules = new ArrayList<Rule>();
    final Map<String, FlowVariable> availableFlowVariables = getAvailableFlowVariables();
    // SimpleRuleParser ruleParser = new SimpleRuleParser(spec, availableFlowVariables);
    RuleFactory factory = RuleFactory.getInstance(nodeType).cloned();
    factory.disableMissingComparisons();
    factory.disableNaNComparisons();
    int line = 0;
    for (String s : rules()) {
        ++line;
        try {
            final Rule rule = factory.parse(s, spec, availableFlowVariables);
            if (rule.getCondition().isEnabled()) {
                rules.add(rule);
            }
        } catch (ParseException e) {
            throw Util.addContext(e, s, line);
        }
    }
    return rules;
}
Also used : RuleFactory(org.knime.base.node.rules.engine.RuleFactory) ArrayList(java.util.ArrayList) Rule(org.knime.base.node.rules.engine.Rule) ParseException(java.text.ParseException) FlowVariable(org.knime.core.node.workflow.FlowVariable)

Example 3 with RuleFactory

use of org.knime.base.node.rules.engine.RuleFactory in project knime-core by knime.

the class RuleEngine2PortsNodeModel method computeRearrangerWithoutPMML.

/**
 * @param spec
 * @param rules
 * @param flowVars
 * @param ruleIdx
 * @param outcomeIdx
 * @param outputColumnName
 * @return
 * @throws InterruptedException
 * @throws InvalidSettingsException
 */
private Pair<ColumnRearranger, PortObject> computeRearrangerWithoutPMML(final DataTableSpec spec, final RowInput rules, final Map<String, FlowVariable> flowVars, final int ruleIdx, final int outcomeIdx, final String outputColumnName) throws InterruptedException, InvalidSettingsException {
    PortObject po;
    ColumnRearranger ret;
    RuleFactory factory = RuleFactory.getInstance(RuleNodeSettings.RuleEngine).cloned();
    po = InactiveBranchPortObject.INSTANCE;
    ret = new ColumnRearranger(spec);
    factory.disableMissingComparisons();
    factory.disableNaNComparisons();
    final List<Rule> ruleList = new ArrayList<>();
    int lineNo = 0;
    DataRow ruleRow;
    while ((ruleRow = rules.poll()) != null) {
        lineNo++;
        DataCell cell = ruleRow.getCell(ruleIdx);
        CheckUtils.checkSetting(!cell.isMissing(), "Missing rule in row: " + ruleRow.getKey());
        if (cell instanceof StringValue) {
            StringValue sv = (StringValue) cell;
            String ruleText = sv.getStringValue();
            if (outcomeIdx >= 0) {
                try {
                    ruleText += " => " + m_settings.asStringFailForMissing(ruleRow.getCell(outcomeIdx));
                } catch (InvalidSettingsException e) {
                    if (RuleSupport.isComment(ruleText)) {
                        ruleText += " => ?";
                    } else {
                        throw e;
                    }
                }
            }
            try {
                Rule rule = factory.parse(ruleText, spec, flowVars);
                if (rule.getCondition().isEnabled()) {
                    ruleList.add(rule);
                }
            } catch (ParseException e) {
                ParseException error = Util.addContext(e, ruleText, lineNo);
                throw new InvalidSettingsException("Wrong rule in line: " + ruleRow.getKey() + "\n" + error.getMessage(), error);
            }
        } else {
            CheckUtils.checkSetting(false, "Wrong type (" + cell.getType() + ") of rule: " + cell + "\nin row: " + ruleRow.getKey());
        }
    }
    // unfortunately we cannot compute the domain and limits of the output column.
    final DataType outType = RuleEngineNodeModel.computeOutputType(ruleList, computeOutcomeType(rules.getDataTableSpec()), RuleNodeSettings.RuleEngine, m_settings.isDisallowLongOutputForCompatibility());
    final MutableLong rowIndex = new MutableLong();
    final ExecutionMonitor exec = new ExecutionMonitor();
    final boolean disallowLongOutputForCompatibility = m_settings.isDisallowLongOutputForCompatibility();
    VariableProvider.SingleCellFactoryProto fac = new VariableProvider.SingleCellFactoryProto(new DataColumnSpecCreator(outputColumnName, outType).createSpec()) {

        @Override
        public DataCell getCell(final DataRow row) {
            setProgress(rowIndex.longValue(), m_rowCount, row.getKey(), exec);
            rowIndex.increment();
            return RuleEngineNodeModel.getRulesOutcome(outType, row, ruleList, disallowLongOutputForCompatibility, this);
        }

        @Override
        public Object readVariable(final String name, final Class<?> type) {
            return RuleEngine2PortsNodeModel.this.readVariable(name, type);
        }

        @Deprecated
        @Override
        public int getRowCount() {
            return RuleEngine2PortsNodeModel.this.getRowCount();
        }

        @Override
        public long getRowCountLong() {
            return RuleEngine2PortsNodeModel.this.getRowCountLong();
        }
    };
    if (m_settings.isReplaceColumn()) {
        ret.replace(fac, outputColumnName);
    } else {
        ret.append(fac);
    }
    return Pair.create(ret, po);
}
Also used : DataColumnSpecCreator(org.knime.core.data.DataColumnSpecCreator) RuleFactory(org.knime.base.node.rules.engine.RuleFactory) ArrayList(java.util.ArrayList) DataRow(org.knime.core.data.DataRow) MutableLong(org.apache.commons.lang3.mutable.MutableLong) ColumnRearranger(org.knime.core.data.container.ColumnRearranger) InvalidSettingsException(org.knime.core.node.InvalidSettingsException) VariableProvider(org.knime.base.node.rules.engine.VariableProvider) FlowVariableProvider(org.knime.ext.sun.nodes.script.calculator.FlowVariableProvider) DataCell(org.knime.core.data.DataCell) DataType(org.knime.core.data.DataType) Rule(org.knime.base.node.rules.engine.Rule) SimpleRule(org.dmg.pmml.SimpleRuleDocument.SimpleRule) ParseException(java.text.ParseException) StringValue(org.knime.core.data.StringValue) ExecutionMonitor(org.knime.core.node.ExecutionMonitor) PortObject(org.knime.core.node.port.PortObject) PMMLPortObject(org.knime.core.node.port.pmml.PMMLPortObject) InactiveBranchPortObject(org.knime.core.node.port.inactive.InactiveBranchPortObject)

Example 4 with RuleFactory

use of org.knime.base.node.rules.engine.RuleFactory in project knime-core by knime.

the class RuleEngineVariable2PortsNodeModel method parseRules.

/**
 * Parses all rules from {@code rulesTable}.
 *
 * @param rulesTable The input rules table.
 * @return a list of parsed rules
 * @throws ParseException if a rule cannot be parsed
 * @throws InvalidSettingsException Missing values in outcomes are not supported.
 */
protected List<Rule> parseRules(final BufferedDataTable rulesTable) throws ParseException, InvalidSettingsException {
    ArrayList<Rule> rules = new ArrayList<Rule>();
    final Map<String, FlowVariable> availableFlowVariables = getAvailableFlowVariables();
    final RuleFactory factory = RuleFactory.getInstance(RuleNodeSettings.VariableRule).cloned();
    factory.disableNaNComparisons();
    final DataTableSpec spec = new DataTableSpec();
    int line = 0;
    for (String s : rules(rulesTable, m_settings, RuleNodeSettings.VariableRule)) {
        ++line;
        try {
            final Rule rule = factory.parse(s, spec, availableFlowVariables);
            if (rule.getCondition().isEnabled()) {
                rules.add(rule);
            }
        } catch (ParseException e) {
            throw Util.addContext(e, s, line);
        }
    }
    return rules;
}
Also used : DataTableSpec(org.knime.core.data.DataTableSpec) RuleFactory(org.knime.base.node.rules.engine.RuleFactory) ArrayList(java.util.ArrayList) Rule(org.knime.base.node.rules.engine.Rule) ParseException(java.text.ParseException) FlowVariable(org.knime.core.node.workflow.FlowVariable)

Example 5 with RuleFactory

use of org.knime.base.node.rules.engine.RuleFactory in project knime-core by knime.

the class RuleEngineVariable2PortsNodeModel method validateRules.

/**
 * @param rules The rules from a settings.
 * @throws InvalidSettingsException Parsing failed.
 */
protected void validateRules(final Iterable<String> rules) throws InvalidSettingsException {
    RuleFactory ruleFactory = RuleFactory.getInstance(RuleNodeSettings.VariableRule).cloned();
    ruleFactory.disableFlowVariableChecks();
    for (String rule : rules) {
        try {
            ruleFactory.parse(rule, null, getAvailableInputFlowVariables());
        } catch (ParseException e) {
            throw new InvalidSettingsException(e.getMessage(), e);
        }
    }
}
Also used : RuleFactory(org.knime.base.node.rules.engine.RuleFactory) InvalidSettingsException(org.knime.core.node.InvalidSettingsException) ParseException(java.text.ParseException)

Aggregations

ParseException (java.text.ParseException)6 RuleFactory (org.knime.base.node.rules.engine.RuleFactory)6 ArrayList (java.util.ArrayList)4 Rule (org.knime.base.node.rules.engine.Rule)4 InvalidSettingsException (org.knime.core.node.InvalidSettingsException)4 FlowVariable (org.knime.core.node.workflow.FlowVariable)3 DataCell (org.knime.core.data.DataCell)2 DataRow (org.knime.core.data.DataRow)2 DataType (org.knime.core.data.DataType)2 StringValue (org.knime.core.data.StringValue)2 PortObject (org.knime.core.node.port.PortObject)2 MutableLong (org.apache.commons.lang3.mutable.MutableLong)1 SimpleRule (org.dmg.pmml.SimpleRuleDocument.SimpleRule)1 Condition (org.knime.base.node.rules.engine.Condition)1 RuleEngineSettings (org.knime.base.node.rules.engine.RuleEngineSettings)1 VariableProvider (org.knime.base.node.rules.engine.VariableProvider)1 DataColumnSpec (org.knime.core.data.DataColumnSpec)1 DataColumnSpecCreator (org.knime.core.data.DataColumnSpecCreator)1 DataTableSpec (org.knime.core.data.DataTableSpec)1 ColumnRearranger (org.knime.core.data.container.ColumnRearranger)1