From: <jbo...@li...> - 2006-01-24 12:06:58
|
Author: mic...@jb... Date: 2006-01-24 07:06:36 -0500 (Tue, 24 Jan 2006) New Revision: 2189 Added: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/rule-with-expansion.drl Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Expander.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/ExpanderContext.java trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Parser.java trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/ParserTest.java Log: first cut of expanders. Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Expander.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Expander.java 2006-01-24 11:09:13 UTC (rev 2188) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Expander.java 2006-01-24 12:06:36 UTC (rev 2189) @@ -1,8 +1,17 @@ package org.drools.lang; /** - * Expanders provide just in time expansion for expressions in DRL. + * Expanders are extension points for expanding + * expressions in DRL at parse time. + * This is just-in-time translation, or macro expansion, or + * whatever you want. * + * The important thing is that it happens at the last possible moment, + * so any errors in expansion are included in the parsers errors. + * + * Just-in-time expansions may include complex pre-compilers, + * or just macros, and everything in between. + * * Expanders should ideally not make presumptions on any embedded semantic * language. For instance, java aware pre processing should be done in * drools-java semantic module, not in the parser itself. Expanders should @@ -13,4 +22,24 @@ */ public interface Expander { + /** + * The parser should call this on an expression/line that potentially needs expanding + * BEFORE it parses that line (as the line may change radically as the result of expansion). + * + * Expands the expression Just-In-Time for the parser. + * If the expression is not meant to be expanded, or if no + * appropriate expander is found, it will echo back the same + * expression. + * + * @param expression The "line" or expression to be expanded/pre-compiled. + * @param context The context of the current state of parsing. This can help + * the expander know if it needs to expand, what to do etc. + * + * If <code>isEnabled()</code> is false then it is not required to + * call this method. + */ + public String expand(String pattern, Parser context); + + + } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/ExpanderContext.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/ExpanderContext.java 2006-01-24 11:09:13 UTC (rev 2188) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/ExpanderContext.java 2006-01-24 12:06:36 UTC (rev 2189) @@ -1,77 +1,79 @@ package org.drools.lang; +import java.io.InputStream; import java.io.Serializable; -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import org.drools.lang.dsl.DefaultExpander; + /** - * Expanders are extension points for expanding - * expressions in DRL at parse time. - * This is just-in-time translation, or macro expansion, or - * whatever you want. + * Create instances of appropriate expanders based on name, and prior configuration of expanders. * - * The important thing is that it happens at the last possible moment, - * so any errors in expansion are included in the parsers errors. + * Expanders can be added to this programmatically, or they can be loaded from the classpath. * - * Just-in-time expansions may include complex pre-compilers, - * or just macros, and everything in between. - * * @author <a href="mailto:mic...@gm..."> Michael Neale</a> - * */ public class ExpanderContext implements Serializable { private static final long serialVersionUID = 1806461802987228880L; - private boolean enabled = true; + private Map expanders; + + private static final ExpanderContext INSTANCE = new ExpanderContext(); + + public static ExpanderContext getInstance() { + return INSTANCE; + } + + private ExpanderContext() { + expanders = new HashMap(); + } + + /** + * This registers an expander against a name for DRL files to use when compiling. + * The name appears as "use expander name" in DRL source. + * + * This can be called again to "refresh" an expander. + */ + public void registerExpander(Expander expander, String name) { + if (expanders.containsKey(name)) { + expanders.remove(name); + } + expanders.put(name, expander); + } + + /** + * This will load up the appropriate expander. + * The default expander is configured via a properties file. + */ + public Expander getExpander(String expanderName) { + + if (expanders.containsKey(expanderName)) return (Expander) expanders.get(expanderName); + + try { + InputStream stream = this.getClass().getResourceAsStream(expanderName); + if (stream == null) { + URL url = new URL(expanderName); + stream = url.openStream(); + } + + Properties props = new Properties(); + props.load(stream); + stream.close(); + + DefaultExpander expander = new DefaultExpander(props); + registerExpander(expander, expanderName); + return expander; + + } catch (Exception e) { + throw new IllegalArgumentException("Unable to load expander with name: " + expanderName); + } + } - private final Set expanders; - /** - * This indicates that at least one expander has been configured for - * this parser configuration. - */ - public boolean isEnabled() { - return enabled; - } - public void disable() { - this.enabled = false; - } - public ExpanderContext(Collection initialExpanders) { - this.expanders = new HashSet(initialExpanders); - } - public ExpanderContext() { - this.expanders = new HashSet(); - } - - public ExpanderContext addExpander(Expander exp) { - expanders.add(exp); - return this; - } - - /** - * The parser should call this on an expression/line that potentially needs expanding - * BEFORE it parses that line (as the line may change radically as the result of expansion). - * - * Expands the expression Just-In-Time for the parser. - * If the expression is not meant to be expanded, or if no - * appropriate expander is found, it will echo back the same - * expression. - * - * @param expression The "line" or expression to be expanded/pre-compiled. - * @param context The context of the current state of parsing. This can help - * the expander know if it needs to expand, what to do etc. - * - * If <code>isEnabled()</code> is false then it is not required to - * call this method. - */ - public CharSequence expand(CharSequence expression, Parser context) { - return expression; - } - - - } Modified: trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Parser.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Parser.java 2006-01-24 11:09:13 UTC (rev 2188) +++ trunk/labs/jbossrules/drools-core/src/main/java/org/drools/lang/Parser.java 2006-01-24 12:06:36 UTC (rev 2189) @@ -39,7 +39,7 @@ private String packageDeclaration; private List imports; - private String expanderName; + private Expander expander; private List rules; @@ -50,7 +50,7 @@ this.reader = new BufferedReader( reader ); this.imports = new ArrayList(); this.rules = new ArrayList(); - this.expanderName = null; + this.expander = null; this.lineNumber = 0; } @@ -66,8 +66,8 @@ return rules; } - String getExpanderName() { - return expanderName; + Expander getExpander() { + return expander; } public void parse() throws IOException, RuleConstructionException { @@ -126,7 +126,8 @@ if ( matcher.matches() ) { consumeDiscard(); - expanderName = matcher.group( 1 ); + String expanderName = matcher.group( 1 ); + expander = ExpanderContext.getInstance().getExpander(expanderName); return true; } @@ -244,12 +245,11 @@ } protected String expand(String pattern) { - //MN hook in here. Will only be called if it is honest to God expanding. - return pattern; + return expander.expand(pattern, this); } protected boolean expanding() { - return this.expanderName != null; + return this.expander != null; } protected void pattern(String pattern) { Modified: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/ParserTest.java =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/ParserTest.java 2006-01-24 11:09:13 UTC (rev 2188) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/ParserTest.java 2006-01-24 12:06:36 UTC (rev 2189) @@ -49,8 +49,13 @@ assertEquals( 1, parser.getRules().size() ); assertEquals( "find_seating", ((Rule)parser.getRules().get(0)).getName() ); - assertEquals(null, parser.getExpanderName()); + assertEquals(null, parser.getExpander()); } + + public void test_with_expander() throws Exception { + Parser parser = parser( "rule-with-expansion.drl" ); + parser.parse(); + } protected Parser parser(String name) { InputStream in = getClass().getResourceAsStream( name ); Added: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/rule-with-expansion.drl =================================================================== --- trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/rule-with-expansion.drl 2006-01-24 11:09:13 UTC (rev 2188) +++ trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/rule-with-expansion.drl 2006-01-24 12:06:36 UTC (rev 2189) @@ -0,0 +1,19 @@ +# Example DRL with expansion +# (ie "domain specific language") +# use expanders for domain specific and natural language extensions +use expander cheese.dsl + + +rule find_seating + when + #Bob is in atlanta + #Bob likes cheese + #There exists a Guest with name of "Michael" and sex of "Male" + >Guest( name == seatingRightGuestName, rightGuestSex:sex, rightGuestHobby:hobby ) + >Guest( leftGuestName:name , sex != rightGuestSex, hobby == rightGuestHobby ) + >count => Count() + #bind count to Count + then + #Send notification to Mark with message "hello" + >System.out.println("and this is code") +end \ No newline at end of file Property changes on: trunk/labs/jbossrules/drools-core/src/test/java/org/drools/lang/rule-with-expansion.drl ___________________________________________________________________ Name: svn:eol-style + native |