001: package org.drools.decisiontable.parser;
002:
003: /*
004: * Copyright 2005 JBoss Inc
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018: import java.io.Reader;
019: import java.io.StringReader;
020: import java.util.HashMap;
021: import java.util.Iterator;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.drools.RuleBase;
026: import org.drools.RuleBaseFactory;
027: import org.drools.StatefulSession;
028: import org.drools.compiler.PackageBuilder;
029: import org.drools.decisiontable.model.Condition;
030: import org.drools.decisiontable.model.Consequence;
031: import org.drools.decisiontable.model.DRLOutput;
032: import org.drools.decisiontable.model.Global;
033: import org.drools.decisiontable.model.Import;
034: import org.drools.decisiontable.model.Rule;
035: import org.drools.decisiontable.model.SnippetBuilder;
036: import org.drools.rule.Package;
037:
038: /**
039: *
040: * @author <a href="mailto:stevearoonie@gmail.com">Steven Williams</a>
041: *
042: * Create a rule base for the set of rule templates in the
043: * TemplateContainer. These rules are used internally by the
044: * engine to generate the actual decision table rules based on
045: * which columns have been filled in.
046: *
047: * Basically, if a rule template requires columns A and B then
048: * the template rule base will generate a rule with columns A and B
049: * as the LHS and a RHS which triggers the rule to be generated.
050: * ie.
051: * rule "template1"
052: * when
053: * r : Row()
054: * Cell(row == r, column == "column1")
055: * Cell(row == r, column == "column2")
056: * then
057: * generator.generate( "template1", r);
058: * end
059: *
060: */
061: public class DefaultTemplateRuleBase implements TemplateRuleBase {
062: private RuleBase ruleBase;
063:
064: public DefaultTemplateRuleBase(final TemplateContainer tc) {
065: ruleBase = readRule(getDTRules(tc.getTemplates()));
066: }
067:
068: /* (non-Javadoc)
069: * @see org.drools.decisiontable.parser.TemplateRuleBase#newWorkingMemory()
070: */
071: public StatefulSession newStatefulSession() {
072: return ruleBase.newStatefulSession();
073: }
074:
075: /**
076: *
077: * @param templates
078: * @return
079: */
080: private String getDTRules(Map templates) {
081: org.drools.decisiontable.model.Package p = new org.drools.decisiontable.model.Package(
082: "org.drools.decisiontable.parser");
083: addImports(p);
084: addGlobals(p);
085: int i = 1;
086: for (Iterator it = templates.values().iterator(); it.hasNext();) {
087: RuleTemplate template = (RuleTemplate) it.next();
088:
089: createTemplateRule(p, i++, template);
090: }
091: DRLOutput out = new DRLOutput();
092: p.renderDRL(out);
093: return out.getDRL();
094:
095: }
096:
097: private void createTemplateRule(
098: org.drools.decisiontable.model.Package p, int index,
099: RuleTemplate template) {
100: Rule rule = new Rule(template.getName(), null, index);
101: Condition condition = new Condition();
102: condition.setSnippet("r : Row()");
103: rule.addCondition(condition);
104: createColumnConditions(template, rule);
105: createNotColumnConditions(template, rule);
106: rule.addConsequence(createConsequence(template));
107: p.addRule(rule);
108: }
109:
110: private void createNotColumnConditions(RuleTemplate template,
111: Rule rule) {
112: String[] templateNotColumns = template.getNotColumns();
113: for (int j = 0; j < templateNotColumns.length; j++) {
114: rule
115: .addCondition(createNotCondition(templateNotColumns[j]));
116: }
117: }
118:
119: private void createColumnConditions(RuleTemplate template, Rule rule) {
120: List templateColumns = template.getColumns();
121: for (Iterator it1 = templateColumns.iterator(); it1.hasNext();) {
122: String column = (String) it1.next();
123: rule.addCondition(createCondition(column));
124: }
125: }
126:
127: private void addGlobals(org.drools.decisiontable.model.Package p) {
128: Global global = new Global();
129: global.setClassName(DefaultGenerator.class.getName());
130: global.setIdentifier("generator");
131: p.addVariable(global);
132: }
133:
134: private void addImports(org.drools.decisiontable.model.Package p) {
135: Import drlImport1 = new Import();
136: drlImport1.setClassName(Map.class.getName());
137: Import drlImport2 = new Import();
138: drlImport2.setClassName(HashMap.class.getName());
139: p.addImport(drlImport1);
140: p.addImport(drlImport2);
141: }
142:
143: private Consequence createConsequence(RuleTemplate template) {
144: StringBuffer action = new StringBuffer();
145: action.append("generator.generate( \"");
146: action.append(template.getName()).append("\", r);");
147: final Consequence consequence = new Consequence();
148: consequence.setSnippet(action.toString());
149: return consequence;
150: }
151:
152: private Condition createCondition(final String value) {
153: SnippetBuilder snip = new SnippetBuilder(
154: "Cell(row == r, column == \"$param\")");
155: String result = snip.build(value);
156: Condition condition = new Condition();
157: condition.setSnippet(result);
158: return condition;
159: }
160:
161: private Condition createNotCondition(final String value) {
162: SnippetBuilder snip = new SnippetBuilder(
163: "not Cell(row == r, column == \"$param\")");
164: String result = snip.build(value);
165: Condition condition = new Condition();
166: condition.setSnippet(result);
167: return condition;
168: }
169:
170: private RuleBase readRule(String drl) {
171: try {
172: System.out.println(drl);
173: // read in the source
174: Reader source = new StringReader(drl);
175: PackageBuilder builder = new PackageBuilder();
176: builder.addPackageFromDrl(source);
177: Package pkg = builder.getPackage();
178:
179: // add the package to a rulebase (deploy the rule package).
180: RuleBase ruleBase = RuleBaseFactory.newRuleBase();
181: ruleBase.addPackage(pkg);
182: return ruleBase;
183:
184: } catch (Exception e) {
185: throw new RuntimeException(e);
186: }
187: }
188:
189: }
|