001: package org.drools.rule.builder.dialect.mvel;
002:
003: import java.io.InputStreamReader;
004: import java.io.Serializable;
005: import java.util.HashMap;
006: import java.util.Map;
007: import java.util.Properties;
008:
009: import junit.framework.Assert;
010: import junit.framework.TestCase;
011:
012: import org.drools.Cheese;
013: import org.drools.RuleBase;
014: import org.drools.RuleBaseFactory;
015: import org.drools.WorkingMemory;
016: import org.drools.base.ClassObjectType;
017: import org.drools.base.DefaultKnowledgeHelper;
018: import org.drools.base.mvel.MVELConsequence;
019: import org.drools.base.mvel.MVELDebugHandler;
020: import org.drools.common.AgendaItem;
021: import org.drools.common.InternalFactHandle;
022: import org.drools.common.PropagationContextImpl;
023: import org.drools.compiler.Dialect;
024: import org.drools.compiler.DialectConfiguration;
025: import org.drools.compiler.DrlParser;
026: import org.drools.compiler.DroolsParserException;
027: import org.drools.compiler.PackageBuilder;
028: import org.drools.compiler.PackageBuilderConfiguration;
029: import org.drools.lang.descr.PackageDescr;
030: import org.drools.lang.descr.RuleDescr;
031: import org.drools.reteoo.ReteTuple;
032: import org.drools.rule.Declaration;
033: import org.drools.rule.Package;
034: import org.drools.rule.Pattern;
035: import org.drools.rule.Rule;
036: import org.drools.rule.builder.RuleBuildContext;
037: import org.drools.rule.builder.RuleBuilder;
038: import org.drools.spi.ObjectType;
039: import org.drools.spi.PatternExtractor;
040: import org.mvel.ExpressionCompiler;
041: import org.mvel.ParserContext;
042:
043: public class MVELConsequenceBuilderTest extends TestCase {
044:
045: public void setUp() {
046: }
047:
048: public void testSimpleExpression() throws Exception {
049: final Package pkg = new Package("pkg1");
050: final RuleDescr ruleDescr = new RuleDescr("rule 1");
051: ruleDescr
052: .setConsequence("modify (cheese) {price = 5 };\nretract (cheese)");
053:
054: PackageBuilder pkgBuilder = new PackageBuilder(pkg);
055: final PackageBuilderConfiguration conf = pkgBuilder
056: .getPackageBuilderConfiguration();
057: MVELDialect mvelDialect = (MVELDialect) ((DialectConfiguration) conf
058: .getDialectConfiguration("mvel")).getDialect();
059:
060: final InstrumentedBuildContent context = new InstrumentedBuildContent(
061: conf, pkg, ruleDescr, conf.getDialectRegistry(),
062: mvelDialect);
063:
064: final InstrumentedDeclarationScopeResolver declarationResolver = new InstrumentedDeclarationScopeResolver();
065:
066: final ObjectType cheeseObjeectType = new ClassObjectType(
067: Cheese.class);
068:
069: final Pattern pattern = new Pattern(0, cheeseObjeectType);
070:
071: final PatternExtractor extractor = new PatternExtractor(
072: cheeseObjeectType);
073:
074: final Declaration declaration = new Declaration("cheese",
075: extractor, pattern);
076: final Map map = new HashMap();
077: map.put("cheese", declaration);
078: declarationResolver.setDeclarations(map);
079: context.setDeclarationResolver(declarationResolver);
080:
081: final MVELConsequenceBuilder builder = new MVELConsequenceBuilder();
082: builder.build(context);
083:
084: final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
085: final WorkingMemory wm = ruleBase.newStatefulSession();
086:
087: final Cheese cheddar = new Cheese("cheddar", 10);
088: final InternalFactHandle f0 = (InternalFactHandle) wm
089: .insert(cheddar);
090: final ReteTuple tuple = new ReteTuple(f0);
091:
092: final AgendaItem item = new AgendaItem(0, tuple, 10,
093: new PropagationContextImpl(1, 1, null, null), context
094: .getRule(), null);
095: final DefaultKnowledgeHelper kbHelper = new DefaultKnowledgeHelper(
096: wm);
097: kbHelper.setActivation(item);
098: context.getRule().getConsequence().evaluate(kbHelper, wm);
099:
100: assertEquals(5, cheddar.getPrice());
101: }
102:
103: public void testKnowledgeHelper() {
104:
105: }
106:
107: public void testImperativeCodeError() throws Exception {
108: final Package pkg = new Package("pkg1");
109: final RuleDescr ruleDescr = new RuleDescr("rule 1");
110: ruleDescr
111: .setConsequence("if (cheese.price == 10) { cheese.price = 5; }");
112:
113: Properties properties = new Properties();
114: properties.setProperty("drools.dialect.default", "mvel");
115: PackageBuilderConfiguration cfg1 = new PackageBuilderConfiguration(
116: properties);
117: MVELDialect mvelDialect = (MVELDialect) cfg1
118: .getDefaultDialect();
119: final PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
120:
121: final InstrumentedBuildContent context = new InstrumentedBuildContent(
122: conf, pkg, ruleDescr, conf.getDialectRegistry(),
123: mvelDialect);
124:
125: final InstrumentedDeclarationScopeResolver declarationResolver = new InstrumentedDeclarationScopeResolver();
126:
127: final ObjectType cheeseObjeectType = new ClassObjectType(
128: Cheese.class);
129:
130: final Pattern pattern = new Pattern(0, cheeseObjeectType);
131:
132: final PatternExtractor extractor = new PatternExtractor(
133: cheeseObjeectType);
134:
135: final Declaration declaration = new Declaration("cheese",
136: extractor, pattern);
137: final Map map = new HashMap();
138: map.put("cheese", declaration);
139: declarationResolver.setDeclarations(map);
140: context.setDeclarationResolver(declarationResolver);
141:
142: final MVELConsequenceBuilder builder = new MVELConsequenceBuilder();
143: builder.build(context);
144:
145: final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
146: final WorkingMemory wm = ruleBase.newStatefulSession();
147:
148: final Cheese cheddar = new Cheese("cheddar", 10);
149: final InternalFactHandle f0 = (InternalFactHandle) wm
150: .insert(cheddar);
151: final ReteTuple tuple = new ReteTuple(f0);
152:
153: final AgendaItem item = new AgendaItem(0, tuple, 10, null,
154: context.getRule(), null);
155: final DefaultKnowledgeHelper kbHelper = new DefaultKnowledgeHelper(
156: wm);
157: kbHelper.setActivation(item);
158: try {
159: context.getRule().getConsequence().evaluate(kbHelper, wm);
160: fail("should throw an exception, as 'if' is not allowed");
161: } catch (Exception e) {
162:
163: }
164:
165: assertEquals(10, cheddar.getPrice());
166: }
167:
168: /**
169: * Just like MVEL command line, we can allow expressions to span lines, with optional ";"
170: * seperating expressions. If its needed a ";" can be thrown in, but if not, a new line is fine.
171: *
172: * However, when in the middle of unbalanced brackets, a new line means nothing.
173: *
174: * @throws Exception
175: */
176: public void testLineSpanOptionalSemis() throws Exception {
177:
178: String simpleEx = "foo\nbar\nbaz";
179: MVELConsequenceBuilder cons = new MVELConsequenceBuilder();
180: assertEquals("foo;\nbar;\nbaz", MVELConsequenceBuilder
181: .delimitExpressions(simpleEx));
182:
183: String ex = "foo (\n bar \n)\nbar;\nyeah;\nman\nbaby";
184: assertEquals("foo (\n bar \n);\nbar;\nyeah;\nman;\nbaby",
185: MVELConsequenceBuilder.delimitExpressions(ex));
186:
187: ex = "foo {\n bar \n}\nbar; \nyeah;\nman\nbaby";
188: assertEquals("foo {\n bar \n};\nbar; \nyeah;\nman;\nbaby",
189: MVELConsequenceBuilder.delimitExpressions(ex));
190:
191: ex = "foo [\n bar \n]\nbar; x\nyeah();\nman[42]\nbaby;ca chiga;\nend";
192: assertEquals(
193: "foo [\n bar \n];\nbar; x;\nyeah();\nman[42];\nbaby;ca chiga;\nend",
194: MVELConsequenceBuilder.delimitExpressions(ex));
195:
196: ex = " \n\nfoo [\n bar \n]\n\n\nbar; x\n \nyeah();\nman[42]\nbaby;ca chiga;\nend";
197: assertEquals(
198: " \n\nfoo [\n bar \n];\n\n\nbar; x;\n \nyeah();\nman[42];\nbaby;ca chiga;\nend",
199: MVELConsequenceBuilder.delimitExpressions(ex));
200:
201: }
202:
203: public void testMVELDebugSymbols() throws DroolsParserException {
204:
205: MVELDebugHandler.setDebugMode(true);
206:
207: try {
208: final DrlParser parser = new DrlParser();
209: final PackageDescr pkgDescr = parser
210: .parse(new InputStreamReader(getClass()
211: .getResourceAsStream("mvel_rule.drl")));
212:
213: // just checking there is no parsing errors
214: Assert.assertFalse(parser.getErrors().toString(), parser
215: .hasErrors());
216:
217: final Package pkg = new Package("org.drools");
218:
219: final RuleDescr ruleDescr = (RuleDescr) pkgDescr.getRules()
220: .get(0);
221:
222: final RuleBuilder builder = new RuleBuilder();
223:
224: final PackageBuilder pkgBuilder = new PackageBuilder(pkg);
225: final PackageBuilderConfiguration conf = pkgBuilder
226: .getPackageBuilderConfiguration();
227: Dialect dialect = pkgBuilder
228: .getPackageBuilderConfiguration()
229: .getDialectRegistry().getDialectConfiguration(
230: "mvel").getDialect();
231:
232: RuleBuildContext context = new RuleBuildContext(conf, pkg,
233: ruleDescr, conf.getDialectRegistry(), dialect);
234:
235: builder.build(context);
236:
237: Assert.assertTrue(context.getErrors().toString(), context
238: .getErrors().isEmpty());
239:
240: final Rule rule = context.getRule();
241:
242: MVELConsequence mvelCons = (MVELConsequence) rule
243: .getConsequence();
244: String s = org.mvel.debug.DebugTools.decompile(mvelCons
245: .getCompExpr());
246:
247: int fromIndex = 0;
248: int count = 0;
249: while ((fromIndex = s
250: .indexOf("DEBUG_SYMBOL", fromIndex + 1)) > -1) {
251: count++;
252: }
253: assertEquals(4, count);
254: } finally {
255: MVELDebugHandler.setDebugMode(false);
256: }
257:
258: }
259:
260: public void testX() {
261: String expr = "System.out.println( \"a1\" );\n"
262: + "System.out.println( \"a2\" );\n"
263: + "System.out.println( \"a3\" );\n"
264: + "System.out.println( \"a4\" );\n";
265:
266: ExpressionCompiler compiler = new ExpressionCompiler(expr);
267:
268: ParserContext context = new ParserContext();
269: context.addImport("System", System.class);
270: context.setStrictTypeEnforcement(true);
271: //context.setDebugSymbols( true );
272: context.setSourceFile("mysource");
273:
274: compiler.setDebugSymbols(true);
275:
276: Serializable compiledExpression = compiler.compile(context);
277:
278: String s = org.mvel.debug.DebugTools
279: .decompile(compiledExpression);
280:
281: System.out.println("s " + s);
282:
283: int fromIndex = 0;
284: int count = 0;
285: while ((fromIndex = s.indexOf("DEBUG_SYMBOL", fromIndex + 1)) > -1) {
286: count++;
287: }
288: assertEquals(4, count);
289:
290: }
291: }
|