All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.tsl2.nano.incubation.specification.rules.Rule Maven / Gradle / Ivy

Go to download

TSL2 Framework Specification (Pools of descripted and runnable Actions and Rules, Generic Tree)

There is a newer version: 2.5.1
Show newest version
/*
 * File: $HeadURL$
 * Id  : $Id$
 * 
 * created by: Tom, Thomas Schneider
 * created on: 30.11.2013
 * 
 * Copyright: (c) Thomas Schneider 2013, all rights reserved
 */
package de.tsl2.nano.incubation.specification.rules;

import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.simpleframework.xml.core.Commit;

import de.tsl2.nano.core.ENV;
import de.tsl2.nano.core.log.LogFactory;
import de.tsl2.nano.incubation.specification.ParType;
import de.tsl2.nano.util.operation.NumericConditionOperator;
import de.tsl2.nano.util.operation.Operator;

/**
 * rule engine using operators (see {@link Operator}) for numeric and boolean values. rules can reference other rules
 * through using '§' + name.
 * 

* every rule defines parameters and an operation. the parameters will be checked against the arguments given on * {@link #execute(Map)}. additionally, there may be constraints for value ranges. Example: * *

 * rule = new Rule<BigDecimal>("test", "A ? (x1 + 1) : (x2 * 2)", MapUtil.asMap("A",
 *     ParType.BOOLEAN,
 *     "x1",
 *     ParType.NUMBER,
 *     "x2",
 *     ParType.NUMBER));
 * rule.addConstraint("x1", new Constraint(BigDecimal.class, new BigDecimal(0), new BigDecimal(1)));
 * BigDecimal r2 = rule.execute(MapUtil.asMap("A", false, "x1", new BigDecimal(1), "x2", new BigDecimal(2)));
 * 
 * or
 * 
 *         Rule ruleWithImport = new Rule("test-import", "A ? 1 + §test : (x2 * 3)", MapUtil.asMap("A",
 *             Boolean.class,
 *             "x1",
 *             BigDecimal.class,
 *             "x2",
 *             BigDecimal.class));
 * 
 * 
 * 
 * 
* * @author Tom, Thomas Schneider * @version $Revision$ */ public class Rule extends AbstractRule { /** serialVersionUID */ private static final long serialVersionUID = 8557708958880364123L; private static final Log LOG = LogFactory.getLog(Rule.class); public static final String KEY_RESULT = Operator.KEY_RESULT; transient NumericConditionOperator operator; /** * constructor only to be used by deserializing */ public Rule() { } /** * constructor * * @param operation * @param parameter */ public Rule(String name, String operation, LinkedHashMap parameter) { super(name, operation, parameter); } /** * executes the given rule, checking the given arguments. * @param arguments rule input * @return evaluation result */ @SuppressWarnings("unchecked") @Override public T run(Map arguments, Object... extArgs) { if (!initialized) { importSubRules(); } arguments = checkedArguments(arguments, ENV.get("app.mode.strict", false)); operator.reset(); //in generics it is not possible to cast from Map(String,?) to Map(CharSequence, ?) Object a = arguments; //calculate the numeric and boolean operations LOG.debug("running rule <" + toString() + "> on arguments: " + a); T result = (T) operator.eval((CharSequence)getOperation(), (Map) a); checkConstraint(Operator.KEY_RESULT, result); return result; } @Override @Commit protected void initDeserializing() { super.initDeserializing(); //TODO: should we enable configuring the numeric operator through xml? this.operator = new NumericConditionOperator(); importSubRules(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy