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());
}
}
}
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;
}
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);
}
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;
}
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);
}
}
}
Aggregations