[jboss-svn-commits] JBL Code SVN: r6045 - in labs/jbossrules/trunk/drools-compiler/src: main/java/org/drools/compiler main/java/org/drools/semantics/java test/java/org/drools test/java/org/drools/integrationtests test/java/org/drools/semantics/java test/resources/org/drools/integrationtests
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Thu Aug 31 12:53:39 EDT 2006
Author: mark.proctor at jboss.com
Date: 2006-08-31 12:53:31 -0400 (Thu, 31 Aug 2006)
New Revision: 6045
Added:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/StaticMethodFunctionResolver.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Func.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods2.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/StaticMethodFunctionResolverTest.java
labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ImportFunctions.drl
Modified:
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/FunctionFixer.java
labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java
labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/FunctionFixerTest.java
Log:
JBRULES-468 import functions from static methods
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/compiler/PackageBuilder.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -51,8 +51,11 @@
import org.drools.rule.Rule;
import org.drools.semantics.java.ClassTypeResolver;
import org.drools.semantics.java.FunctionBuilder;
+import org.drools.semantics.java.FunctionFixer;
import org.drools.semantics.java.PackageStore;
import org.drools.semantics.java.RuleBuilder;
+import org.drools.semantics.java.StaticMethodFunctionResolver;
+import org.drools.spi.FunctionResolver;
import org.drools.spi.TypeResolver;
import org.drools.xml.XmlPackageReader;
import org.xml.sax.SAXException;
@@ -72,7 +75,9 @@
private PackageBuilderConfiguration configuration;
private Map errorHandlers;
private List generatedClassList;
- private ClassTypeResolver typeResolver;
+ private TypeResolver typeResolver;
+ private FunctionFixer functionFixer;
+ private FunctionResolver functionResolver;
private ClassFieldExtractorCache classFieldExtractorCache;
/**
@@ -91,7 +96,7 @@
null );
}
- public PackageBuilder(PackageBuilderConfiguration configuration) {
+ public PackageBuilder(final PackageBuilderConfiguration configuration) {
this( null,
configuration );
}
@@ -148,7 +153,8 @@
try {
xmlReader.read( reader );
} catch ( final SAXException e ) {
- throw new DroolsParserException( e.toString(), e.getCause() );
+ throw new DroolsParserException( e.toString(),
+ e.getCause() );
}
addPackage( xmlReader.getPackageDescr() );
@@ -219,10 +225,10 @@
}
private void validateUniqueRuleNames(final PackageDescr packageDescr) {
- Set names = new HashSet();
- for ( Iterator iter = packageDescr.getRules().iterator(); iter.hasNext(); ) {
- RuleDescr rule = (RuleDescr) iter.next();
- String name = rule.getName();
+ final Set names = new HashSet();
+ for ( final Iterator iter = packageDescr.getRules().iterator(); iter.hasNext(); ) {
+ final RuleDescr rule = (RuleDescr) iter.next();
+ final String name = rule.getName();
if ( names.contains( name ) ) {
this.results.add( new ParserError( "Duplicate rule name: " + name,
rule.getLine(),
@@ -251,6 +257,10 @@
pkg.addImport( (String) it.next() );
}
+ for ( final Iterator it = packageDescr.getFunctionImports().iterator(); it.hasNext(); ) {
+ pkg.addFunctionImport( (String) it.next() );
+ }
+
final TypeResolver typeResolver = new ClassTypeResolver( imports,
pkg.getPackageCompilationData().getClassLoader() );
@@ -280,9 +290,9 @@
private void addClassCompileTask(final String className,
final String text,
final MemoryResourceReader src,
- ErrorHandler handler) {
+ final ErrorHandler handler) {
- String fileName = className.replace( '.',
+ final String fileName = className.replace( '.',
'/' ) + ".java";
src.add( fileName,
text.getBytes() );
@@ -294,6 +304,8 @@
private void addFunction(final FunctionDescr functionDescr) {
final FunctionBuilder buidler = new FunctionBuilder();
+ this.pkg.addFunction( functionDescr.getName() );
+
addClassCompileTask( this.pkg.getName() + "." + ucFirst( functionDescr.getName() ),
buidler.build( this.pkg,
functionDescr ),
@@ -304,16 +316,16 @@
}
private void addFactTemplate(final FactTemplateDescr factTemplateDescr) {
- List fields = new ArrayList();
+ final List fields = new ArrayList();
int index = 0;
for ( final Iterator it = factTemplateDescr.getFields().iterator(); it.hasNext(); ) {
- FieldTemplateDescr fieldTemplateDescr = (FieldTemplateDescr) it.next();
+ final FieldTemplateDescr fieldTemplateDescr = (FieldTemplateDescr) it.next();
FieldTemplate fieldTemplate = null;
try {
fieldTemplate = new FieldTemplateImpl( fieldTemplateDescr.getName(),
index++,
getTypeResolver().resolveType( fieldTemplateDescr.getClassType() ) );
- } catch ( ClassNotFoundException e ) {
+ } catch ( final ClassNotFoundException e ) {
this.results.add( new FieldTemplateError( this.pkg,
fieldTemplateDescr,
null,
@@ -322,7 +334,7 @@
fields.add( fieldTemplate );
}
- FactTemplate factTemplate = new FactTemplateImpl( this.pkg,
+ final FactTemplate factTemplate = new FactTemplateImpl( this.pkg,
factTemplateDescr.getName(),
(FieldTemplate[]) fields.toArray( new FieldTemplate[fields.size()] ) );
}
@@ -336,7 +348,8 @@
ruleDescr.setClassName( ucFirst( ruleClassName ) );
final RuleBuilder builder = new RuleBuilder( getTypeResolver(),
- classFieldExtractorCache );
+ getFunctionFixer(),
+ this.classFieldExtractorCache );
builder.build( this.pkg,
ruleDescr );
@@ -361,15 +374,31 @@
*/
private TypeResolver getTypeResolver() {
if ( this.typeResolver == null ) {
- typeResolver = new ClassTypeResolver( pkg.getImports(),
- pkg.getPackageCompilationData().getClassLoader() );
+ this.typeResolver = new ClassTypeResolver( this.pkg.getImports(),
+ this.pkg.getPackageCompilationData().getClassLoader() );
// make an automatic import for the current package
- typeResolver.addImport( pkg.getName() + ".*" );
- typeResolver.addImport( "java.lang.*" );
+ this.typeResolver.addImport( this.pkg.getName() + ".*" );
+ this.typeResolver.addImport( "java.lang.*" );
}
return this.typeResolver;
}
+ private FunctionResolver getFunctionResolver() {
+ if ( this.functionResolver == null ) {
+ this.functionResolver = new StaticMethodFunctionResolver( this.pkg.getFunctionImports(),
+ getTypeResolver() );
+ }
+
+ return this.functionResolver;
+ }
+
+ private FunctionFixer getFunctionFixer() {
+ if ( this.functionFixer == null ) {
+ this.functionFixer = new FunctionFixer(this.pkg, getFunctionResolver() );
+ }
+ return this.functionFixer;
+ }
+
/**
* This will setup the semantic components of the rule for compiling later on.
* It will not actually call the compiler
@@ -430,30 +459,30 @@
* code.
*/
private void compileAll() {
- String[] classes = new String[this.generatedClassList.size()];
+ final String[] classes = new String[this.generatedClassList.size()];
this.generatedClassList.toArray( classes );
final CompilationResult result = this.compiler.compile( classes,
- src,
+ this.src,
this.packageStoreWrapper,
this.pkg.getPackageCompilationData().getClassLoader() );
//this will sort out the errors based on what class/file they happened in
if ( result.getErrors().length > 0 ) {
for ( int i = 0; i < result.getErrors().length; i++ ) {
- CompilationProblem err = result.getErrors()[i];
+ final CompilationProblem err = result.getErrors()[i];
- ErrorHandler handler = (ErrorHandler) this.errorHandlers.get( err.getFileName() );
+ final ErrorHandler handler = (ErrorHandler) this.errorHandlers.get( err.getFileName() );
if ( handler instanceof RuleErrorHandler ) {
- RuleErrorHandler rh = (RuleErrorHandler) handler;
+ final RuleErrorHandler rh = (RuleErrorHandler) handler;
}
handler.addError( err );
}
- Collection errors = this.errorHandlers.values();
- for ( Iterator iter = errors.iterator(); iter.hasNext(); ) {
- ErrorHandler handler = (ErrorHandler) iter.next();
+ final Collection errors = this.errorHandlers.values();
+ for ( final Iterator iter = errors.iterator(); iter.hasNext(); ) {
+ final ErrorHandler handler = (ErrorHandler) iter.next();
if ( handler.isInError() ) {
if ( !(handler instanceof RuleInvokerErrorHandler) ) {
this.results.add( handler.getError() );
@@ -530,20 +559,22 @@
}
private void loadCompiler() {
- switch ( configuration.getCompiler() ) {
+ switch ( this.configuration.getCompiler() ) {
case PackageBuilderConfiguration.JANINO : {
- if ( !"1.4".equals( configuration.getJavaLanguageLevel() ) ) throw new RuntimeDroolsException( "Incompatible Java language level with selected compiler" );
- compiler = JavaCompilerFactory.getInstance().createCompiler( "janino" );
+ if ( !"1.4".equals( this.configuration.getJavaLanguageLevel() ) ) {
+ throw new RuntimeDroolsException( "Incompatible Java language level with selected compiler" );
+ }
+ this.compiler = JavaCompilerFactory.getInstance().createCompiler( "janino" );
break;
}
case PackageBuilderConfiguration.ECLIPSE :
default : {
- EclipseJavaCompilerSettings eclipseSettings = new EclipseJavaCompilerSettings();
+ final EclipseJavaCompilerSettings eclipseSettings = new EclipseJavaCompilerSettings();
eclipseSettings.getMap().put( "org.eclipse.jdt.core.compiler.codegen.targetPlatform",
- configuration.getJavaLanguageLevel() );
+ this.configuration.getJavaLanguageLevel() );
eclipseSettings.getMap().put( "org.eclipse.jdt.core.compiler.source",
- configuration.getJavaLanguageLevel() );
- compiler = new EclipseJavaCompiler( eclipseSettings );
+ this.configuration.getJavaLanguageLevel() );
+ this.compiler = new EclipseJavaCompiler( eclipseSettings );
break;
}
}
@@ -575,16 +606,16 @@
* that originally spawned the code to be compiled.
*/
public abstract static class ErrorHandler {
- private List errors = new ArrayList();
+ private final List errors = new ArrayList();
protected String message;
private boolean inError = false;
/** This needes to be checked if there is infact an error */
public boolean isInError() {
- return inError;
+ return this.inError;
}
- public void addError(CompilationProblem err) {
+ public void addError(final CompilationProblem err) {
this.errors.add( err );
this.inError = true;
}
@@ -603,11 +634,11 @@
* Its not 1 to 1 with reported errors.
*/
protected CompilationProblem[] collectCompilerProblems() {
- if ( errors.size() == 0 ) {
+ if ( this.errors.size() == 0 ) {
return null;
} else {
- CompilationProblem[] list = new CompilationProblem[errors.size()];
- errors.toArray( list );
+ final CompilationProblem[] list = new CompilationProblem[this.errors.size()];
+ this.errors.toArray( list );
return list;
}
}
@@ -618,19 +649,19 @@
private PatternDescr descr;
private Rule rule;
- public RuleErrorHandler(PatternDescr ruleDescr,
- Rule rule,
- String message) {
+ public RuleErrorHandler(final PatternDescr ruleDescr,
+ final Rule rule,
+ final String message) {
this.descr = ruleDescr;
this.rule = rule;
this.message = message;
}
public DroolsError getError() {
- return new RuleError( rule,
- descr,
+ return new RuleError( this.rule,
+ this.descr,
collectCompilerProblems(),
- message );
+ this.message );
}
}
@@ -641,9 +672,9 @@
*/
public static class RuleInvokerErrorHandler extends RuleErrorHandler {
- public RuleInvokerErrorHandler(PatternDescr ruleDescr,
- Rule rule,
- String message) {
+ public RuleInvokerErrorHandler(final PatternDescr ruleDescr,
+ final Rule rule,
+ final String message) {
super( ruleDescr,
rule,
message );
@@ -654,20 +685,20 @@
private FunctionDescr descr;
- public FunctionErrorHandler(FunctionDescr functionDescr,
- String message) {
+ public FunctionErrorHandler(final FunctionDescr functionDescr,
+ final String message) {
this.descr = functionDescr;
this.message = message;
}
public DroolsError getError() {
- return new FunctionError( descr,
+ return new FunctionError( this.descr,
collectCompilerProblems(),
- message );
+ this.message );
}
}
- private static JavaCompiler cachedJavaCompiler = null;
+ private static final JavaCompiler cachedJavaCompiler = null;
}
\ No newline at end of file
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/FunctionFixer.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/FunctionFixer.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/FunctionFixer.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -21,6 +21,9 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.drools.spi.FunctionResolver;
+import org.drools.rule.Package;
+
/**
* This horrific utility adds in the function class name (which is the same as the functions method name)
* into the RHS guts of a rule. It has to tip toe around method calls, new declarations and other
@@ -35,10 +38,20 @@
*/
public class FunctionFixer {
- static Pattern FUNCTION = Pattern.compile( "(\\S*\\s*|\\.\\s*)\\b([\\S&&[^\\.\\(\\)]]+)\\s*\\(([^)]*)\\)",
- Pattern.DOTALL );
- static final Set KEYWORDS = getJavaKeywords();
+ static Pattern FUNCTION = Pattern.compile( "(\\S*\\s*|\\.\\s*)\\b([\\S&&[^\\.\\(\\)]]+)\\s*\\(([^)]*)\\)",
+ Pattern.DOTALL );
+ static final Set KEYWORDS = getJavaKeywords();
+ private final FunctionResolver resolver;
+
+ private final Package pkg;
+
+ public FunctionFixer(Package pkg,
+ FunctionResolver resolver) {
+ this.resolver = resolver;
+ this.pkg = pkg;
+ }
+
public String fix(final String raw) {
//return raw;
return fix( raw,
@@ -59,7 +72,7 @@
// instead of just using matcher.end(), grow the endIndex
// as necessary to close all '(' in the matched String
final int endIndex = findEndParenthesis( raw,
- matcher );
+ matcher );
if ( endIndex < 0 ) {
// this means that the first '(' is inside quotes - jump it and try again
startIndex = matcher.start( 3 );
@@ -95,13 +108,22 @@
function = matcher.group( 2 ).trim();
// if we have a reserved work, DO NOT TOUCH !
// if we have no function name, DO NOT TOUCH !
- if ( function == null ||
- function.length() == 0 ||
- FunctionFixer.KEYWORDS.contains( function ) ) {
+ if ( function == null || function.length() == 0 || FunctionFixer.KEYWORDS.contains( function ) ) {
function = raw.substring( matcher.start( 2 ),
matcher.start( 3 ) - 1 );
} else {
- function = ucFirst( function ) + "." + function;
+ int countParams = 0;
+ for ( int i = 0, length = params.length(); i < length; i++ ) {
+ if ( params.charAt( i ) == ',' ) {
+ countParams++;
+ }
+ }
+ if ( this.pkg.getFunctions().contains( function ) ) {
+ function = ucFirst( function ) + "." + function;
+ } else {
+ function = resolver.resolveFunction( function,
+ countParams + 1 ) + "." + function;
+ }
}
}
Modified: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/RuleBuilder.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -29,7 +29,6 @@
import org.antlr.stringtemplate.StringTemplateGroup;
import org.antlr.stringtemplate.language.AngleBracketTemplateLexer;
import org.drools.RuntimeDroolsException;
-import org.drools.base.ClassFieldExtractor;
import org.drools.base.ClassFieldExtractorCache;
import org.drools.base.ClassObjectType;
import org.drools.base.FieldFactory;
@@ -56,11 +55,9 @@
import org.drools.lang.descr.DeclarativeInvokerDescr;
import org.drools.lang.descr.EvalDescr;
import org.drools.lang.descr.ExistsDescr;
-import org.drools.lang.descr.FieldAccessDescr;
import org.drools.lang.descr.FieldBindingDescr;
import org.drools.lang.descr.FieldConstraintDescr;
import org.drools.lang.descr.FromDescr;
-import org.drools.lang.descr.FunctionCallDescr;
import org.drools.lang.descr.LiteralRestrictionDescr;
import org.drools.lang.descr.MethodAccessDescr;
import org.drools.lang.descr.NotDescr;
@@ -97,7 +94,6 @@
import org.drools.rule.VariableRestriction;
import org.drools.spi.DataProvider;
import org.drools.spi.Evaluator;
-import org.drools.spi.Extractor;
import org.drools.spi.FieldExtractor;
import org.drools.spi.FieldValue;
import org.drools.spi.ObjectType;
@@ -143,16 +139,19 @@
AngleBracketTemplateLexer.class );
private static final KnowledgeHelperFixer knowledgeHelperFixer = new KnowledgeHelperFixer();
- private static final FunctionFixer functionFixer = new FunctionFixer();
+
+ private final FunctionFixer functionFixer;
// @todo move to an interface so it can work as a decorator
private final JavaExprAnalyzer analyzer = new JavaExprAnalyzer();
private ClassFieldExtractorCache classFieldExtractorCache;
- public RuleBuilder(TypeResolver resolver,
- ClassFieldExtractorCache cache) {
+ public RuleBuilder(final TypeResolver typeResolver,
+ final FunctionFixer functionFixer,
+ final ClassFieldExtractorCache cache) {
this.classFieldExtractorCache = cache;
- this.typeResolver = resolver;
+ this.typeResolver = typeResolver;
+ this.functionFixer = functionFixer;
this.errors = new ArrayList();
}
@@ -410,7 +409,7 @@
ObjectType objectType = null;
- FactTemplate factTemplate = this.pkg.getFactTemplate( columnDescr.getObjectType() );
+ final FactTemplate factTemplate = this.pkg.getFactTemplate( columnDescr.getObjectType() );
if ( factTemplate != null ) {
objectType = new FactTemplateObjectType( factTemplate );
@@ -477,7 +476,7 @@
if ( fieldConstraintDescr.getRestrictions().size() == 1 ) {
final Object object = fieldConstraintDescr.getRestrictions().get( 0 );
- Restriction restriction = buildRestriction( extractor,
+ final Restriction restriction = buildRestriction( extractor,
fieldConstraintDescr,
(RestrictionDescr) object );
if ( restriction == null ) {
@@ -499,7 +498,7 @@
return;
}
- List orList = new ArrayList();
+ final List orList = new ArrayList();
List andList = null;
RestrictionDescr currentRestriction = null;
@@ -509,7 +508,7 @@
List previousList = null;
for ( final Iterator it = fieldConstraintDescr.getRestrictions().iterator(); it.hasNext(); ) {
- Object object = it.next();
+ final Object object = it.next();
// Process an and/or connective
if ( object instanceof RestrictionConnectiveDescr ) {
@@ -550,7 +549,7 @@
// Can't have an 'and' connective with one child, so add directly to the or list
orList.add( andList.get( 0 ) );
} else {
- Restriction restrictions = new AndCompositeRestriction( (Restriction[]) andList.toArray( new Restriction[andList.size()] ) );
+ final Restriction restrictions = new AndCompositeRestriction( (Restriction[]) andList.toArray( new Restriction[andList.size()] ) );
orList.add( restrictions );
}
andList = null;
@@ -568,7 +567,7 @@
currentRestriction = (RestrictionDescr) object;
}
- Restriction restriction = buildRestriction( extractor,
+ final Restriction restriction = buildRestriction( extractor,
fieldConstraintDescr,
currentRestriction );
currentList.add( restriction );
@@ -599,9 +598,9 @@
restrictions ) );
}
- private Restriction buildRestriction(FieldExtractor extractor,
- FieldConstraintDescr fieldConstraintDescr,
- RestrictionDescr restrictionDescr) {
+ private Restriction buildRestriction(final FieldExtractor extractor,
+ final FieldConstraintDescr fieldConstraintDescr,
+ final RestrictionDescr restrictionDescr) {
Restriction restriction = null;
if ( restrictionDescr instanceof LiteralRestrictionDescr ) {
restriction = buildRestriction( extractor,
@@ -765,7 +764,7 @@
st.setAttribute( "methodName",
className );
- final String returnValueText = RuleBuilder.functionFixer.fix( returnValueRestrictionDescr.getText() );
+ final String returnValueText = this.functionFixer.fix( returnValueRestrictionDescr.getText() );
st.setAttribute( "text",
returnValueText );
@@ -857,7 +856,7 @@
st.setAttribute( "methodName",
className );
- final String predicateText = RuleBuilder.functionFixer.fix( predicateDescr.getText() );
+ final String predicateText = this.functionFixer.fix( predicateDescr.getText() );
st.setAttribute( "text",
predicateText );
@@ -897,20 +896,20 @@
predicateDescr );
}
- private From build(FromDescr fromDescr) {
- Column column = build( fromDescr.getReturnedColumn() );
+ private From build(final FromDescr fromDescr) {
+ final Column column = build( fromDescr.getReturnedColumn() );
- DeclarativeInvokerDescr invokerDescr = fromDescr.getDataSource();
+ final DeclarativeInvokerDescr invokerDescr = fromDescr.getDataSource();
DataProvider dataProvider = null;
if ( invokerDescr.getClass() == MethodAccessDescr.class ) {
- MethodAccessDescr methodAccessor = (MethodAccessDescr) invokerDescr;
+ final MethodAccessDescr methodAccessor = (MethodAccessDescr) invokerDescr;
ValueHandler instanceValueHandler = null;
- String variableName = methodAccessor.getVariableName();
- if ( declarations.containsKey( variableName ) ) {
- instanceValueHandler = new DeclarationVariable( (Declaration) declarations.get( variableName ) );
+ final String variableName = methodAccessor.getVariableName();
+ if ( this.declarations.containsKey( variableName ) ) {
+ instanceValueHandler = new DeclarationVariable( (Declaration) this.declarations.get( variableName ) );
} else if ( this.pkg.getGlobals().containsKey( variableName ) ) {
instanceValueHandler = new GlobalVariable( variableName,
(Class) this.pkg.getGlobals().get( variableName ) );
@@ -918,10 +917,10 @@
throw new IllegalArgumentException( "The variable name [" + variableName + "] was not a global or declaration." );
}
- List arguments = ((MethodAccessDescr) invokerDescr).getArguments();
- List valueHandlers = new ArrayList();
+ final List arguments = ((MethodAccessDescr) invokerDescr).getArguments();
+ final List valueHandlers = new ArrayList();
- for ( Iterator iter = arguments.iterator(); iter.hasNext(); ) {
+ for ( final Iterator iter = arguments.iterator(); iter.hasNext(); ) {
valueHandlers.add( buildValueHandler( (ArgumentValueDescr) iter.next() ) );
// if ( desc.getType() == ArgumentValueDescr.VARIABLE ) {
// if ( this.declarations.containsKey( desc.getValue() ) ) {
@@ -939,7 +938,7 @@
// }
}
- MethodInvoker invoker = new MethodInvoker( methodAccessor.getMethodName(),
+ final MethodInvoker invoker = new MethodInvoker( methodAccessor.getMethodName(),
instanceValueHandler,
(ValueHandler[]) valueHandlers.toArray( new ValueHandler[valueHandlers.size()] ) );
dataProvider = new MethodDataProvider( invoker );
@@ -961,11 +960,11 @@
dataProvider );
}
- private ValueHandler buildValueHandler(ArgumentValueDescr descr) {
+ private ValueHandler buildValueHandler(final ArgumentValueDescr descr) {
ValueHandler valueHandler = null;
if ( descr.getType() == ArgumentValueDescr.VARIABLE ) {
if ( this.declarations.containsKey( descr.getValue() ) ) {
- valueHandler = new DeclarationVariable( (Declaration) declarations.get( descr.getValue() ) );
+ valueHandler = new DeclarationVariable( (Declaration) this.declarations.get( descr.getValue() ) );
} else if ( this.pkg.getGlobals().containsKey( descr.getValue() ) ) {
valueHandler = new GlobalVariable( (String) descr.getValue(),
(Class) this.pkg.getGlobals().get( descr.getValue() ) );
@@ -973,22 +972,22 @@
throw new IllegalArgumentException( "Uknown variable: " + descr.getValue() );
}
} else if ( descr.getType() == ArgumentValueDescr.MAP ) {
- ArgumentValueDescr.KeyValuePairDescr[] pairs = (ArgumentValueDescr.KeyValuePairDescr[]) descr.getValue();
- List list = new ArrayList( pairs.length );
+ final ArgumentValueDescr.KeyValuePairDescr[] pairs = (ArgumentValueDescr.KeyValuePairDescr[]) descr.getValue();
+ final List list = new ArrayList( pairs.length );
for ( int i = 0, length = pairs.length; i < length; i++ ) {
list.add( new MapValue.KeyValuePair( buildValueHandler( pairs[i].getKey() ),
buildValueHandler( pairs[i].getValue() ) ) );
}
valueHandler = new MapValue( (MapValue.KeyValuePair[]) list.toArray( new MapValue.KeyValuePair[pairs.length] ) );
- } else if (descr.getType() == ArgumentValueDescr.LIST ) {
- List args = (List) descr.getValue();
- List handlers = new ArrayList(args.size());
- for ( Iterator iter = args.iterator(); iter.hasNext(); ) {
- ArgumentValueDescr arg = (ArgumentValueDescr) iter.next();
- handlers.add( buildValueHandler( arg ) );
- }
- valueHandler = new ListValue(handlers);
+ } else if ( descr.getType() == ArgumentValueDescr.LIST ) {
+ final List args = (List) descr.getValue();
+ final List handlers = new ArrayList( args.size() );
+ for ( final Iterator iter = args.iterator(); iter.hasNext(); ) {
+ final ArgumentValueDescr arg = (ArgumentValueDescr) iter.next();
+ handlers.add( buildValueHandler( arg ) );
+ }
+ valueHandler = new ListValue( handlers );
} else {
// handling a literal
valueHandler = new LiteralValue( (String) descr.getValue(),
@@ -1022,7 +1021,7 @@
st.setAttribute( "methodName",
className );
- final String evalText = RuleBuilder.functionFixer.fix( evalDescr.getText() );
+ final String evalText = this.functionFixer.fix( evalDescr.getText() );
st.setAttribute( "text",
evalText );
@@ -1080,7 +1079,7 @@
(String[]) usedIdentifiers[1].toArray( new String[usedIdentifiers[1].size()] ),
ruleDescr.getConsequence() );
st.setAttribute( "text",
- RuleBuilder.functionFixer.fix( RuleBuilder.knowledgeHelperFixer.fix( ruleDescr.getConsequence() ) ) );
+ this.functionFixer.fix( RuleBuilder.knowledgeHelperFixer.fix( ruleDescr.getConsequence() ) ) );
this.methods.add( st.toString() );
@@ -1143,7 +1142,7 @@
}
buffer.append( "public class " + ucFirst( this.ruleDescr.getClassName() ) + " {" + lineSeparator );
- buffer.append( " private static final long serialVersionUID = 7952983928232702826L;" + lineSeparator );
+ buffer.append( " private static final long serialVersionUID = 320L;" + lineSeparator );
for ( int i = 0, size = this.methods.size() - 1; i < size; i++ ) {
buffer.append( this.methods.get( i ) + lineSeparator );
@@ -1199,12 +1198,12 @@
if ( objectType.getValueType() == ValueType.FACTTEMPLATE_TYPE ) {
//@todo use extractor cache
- FactTemplate factTemplate = ((FactTemplateObjectType) objectType).getFactTemplate();
+ final FactTemplate factTemplate = ((FactTemplateObjectType) objectType).getFactTemplate();
extractor = new FactTemplateFieldExtractor( factTemplate,
factTemplate.getFieldTemplateIndex( fieldName ) );
} else {
try {
- extractor = classFieldExtractorCache.getExtractor( ((ClassObjectType) objectType).getClassType(),
+ extractor = this.classFieldExtractorCache.getExtractor( ((ClassObjectType) objectType).getClassType(),
fieldName );
} catch ( final RuntimeDroolsException e ) {
this.errors.add( new RuleError( this.rule,
Added: labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/StaticMethodFunctionResolver.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/StaticMethodFunctionResolver.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/main/java/org/drools/semantics/java/StaticMethodFunctionResolver.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -0,0 +1,73 @@
+package org.drools.semantics.java;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.xpath.functions.FuncId;
+import org.drools.RuntimeDroolsException;
+import org.drools.spi.FunctionResolver;
+import org.drools.spi.TypeResolver;
+
+public class StaticMethodFunctionResolver
+ implements
+ FunctionResolver {
+
+ private final List functionImports;
+
+ private final TypeResolver typeResolver;
+
+ public StaticMethodFunctionResolver(final List imports,
+ final TypeResolver typeResolver) {
+ this.functionImports = imports;
+
+ this.typeResolver = typeResolver;
+ }
+
+ public void addFunctionImport(String functionImport) {
+ this.functionImports.add( functionImport );
+
+ }
+
+ public List getFunctionImports() {
+ return this.functionImports;
+ }
+
+ public String resolveFunction(String functionName,
+ int numberOfArgs) {
+ for ( Iterator it = this.functionImports.iterator(); it.hasNext(); ) {
+ String functionImport = (String) it.next();
+
+ // find the last '.' so we can separte the method/* from the package and Class
+ int lastDot = functionImport.lastIndexOf( '.' );
+ String name = functionImport.substring( lastDot );
+
+ // if a functionImport imports the function name directly, i.e not using *, then only go further if they match.
+ if ( !name.endsWith( "*" ) && !!functionName.equals( name ) ) {
+ continue;
+ }
+
+ Class clazz;
+ try {
+ clazz = typeResolver.resolveType( functionImport.substring( 0,
+ lastDot ) );
+ } catch ( ClassNotFoundException e ) {
+ // todo : must be a better way so we don't have to try/catch each resolveType call
+ throw new RuntimeDroolsException( e );
+ }
+ Method[] methods = clazz.getMethods();
+ for ( int i = 0, length = methods.length; i < length; i++ ) {
+ if ( (methods[i].getModifiers() & Modifier.STATIC) == Modifier.STATIC && (methods[i].getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC && methods[i].getName().equals( functionName )
+ && methods[i].getParameterTypes().length == numberOfArgs ) {
+ return clazz.getName().replace( '$',
+ '.' );
+ }
+ }
+ }
+ throw new RuntimeDroolsException( "unable to find the function '" + functionName + "'" );
+ }
+
+}
Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Func.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Func.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/Func.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -0,0 +1,15 @@
+package org.drools;
+
+public class Func {
+ public static void func() {
+
+ }
+
+ public static void func(String string) {
+
+ }
+
+ public static void func(String x, String y) {
+
+ }
+}
Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -0,0 +1,13 @@
+package org.drools;
+
+public class StaticMethods {
+
+ public static String getString1(String string) {
+ return string;
+ }
+
+ public static String getString2(String string) {
+ return string;
+ }
+
+}
Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods2.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods2.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/StaticMethods2.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -0,0 +1,7 @@
+package org.drools;
+
+public class StaticMethods2 {
+ public static String getString3(String string, Integer integer) {
+ return string + integer;
+ }
+}
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/integrationtests/IntegrationCases.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -796,7 +796,29 @@
assertEquals( 1,
list.size() );
}
+
+ public void testImportFunctions() throws Exception {
+ final PackageBuilder builder = new PackageBuilder();
+ builder.addPackageFromDrl( new InputStreamReader( getClass().getResourceAsStream( "test_ImportFunctions.drl" ) ) );
+ final Package pkg = builder.getPackage();
+ final RuleBase ruleBase = getRuleBase();
+ ruleBase.addPackage( pkg );
+ final WorkingMemory workingMemory = ruleBase.newWorkingMemory();
+ Cheese cheese = new Cheese( "stilton", 15 );
+ workingMemory.assertObject( cheese );
+ List list = new ArrayList();
+ workingMemory.setGlobal( "list", list );
+ workingMemory.fireAllRules();
+
+ assertEquals( 4, list.size() );
+
+ assertEquals( "rule1", list.get( 0 ) );
+ assertEquals( "rule2", list.get( 1 ) );
+ assertEquals( "rule3", list.get( 2 ) );
+ assertEquals( "rule4", list.get( 3 ) );
+ }
+
public void testBasicFrom() throws Exception {
final PackageBuilder builder = new PackageBuilder();
Modified: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/FunctionFixerTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/FunctionFixerTest.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/FunctionFixerTest.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -16,98 +16,103 @@
* limitations under the License.
*/
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.spi.TypeResolver;
+import org.drools.rule.Package;
+
import junit.framework.TestCase;
public class FunctionFixerTest extends TestCase {
- private static final FunctionFixer fixer = new FunctionFixer();
+ private FunctionFixer fixer;
+
+ public void setUp() {
+ List list = new ArrayList();
+ list.add( "org.drools.*" );
+ TypeResolver typeResolver = new ClassTypeResolver( list );
+ Package pkg = new Package("testPackage");
+ pkg.addFunction( "addFive" );
+ pkg.addFunction( "foo" );
+ pkg.addFunction( "bar" );
+
+ list = new ArrayList();
+ list.add( "Func.*" );
+ this.fixer = new FunctionFixer( pkg, new StaticMethodFunctionResolver(list, typeResolver) );
+ }
public void testSimple() {
- final FunctionFixer fixer = new FunctionFixer();
- assertEquals( "Func.func()",
+ assertEquals( "org.drools.Func.func()",
fixer.fix( "func( )" ) );
}
public void testSimpleWithPArams() {
- final FunctionFixer fixer = new FunctionFixer();
- assertEquals( "Func.func(yyy, iii)",
+ assertEquals( "org.drools.Func.func(yyy, iii)",
fixer.fix( "func(yyy, iii)" ) );
}
public void testMoreComplex() {
- final FunctionFixer fixer = new FunctionFixer();
- assertEquals( "xxx Func.func(yyy, iii) yyy",
+ assertEquals( "xxx org.drools.Func.func(yyy, iii) yyy",
fixer.fix( "xxx func(yyy, iii) yyy" ) );
}
public void testLeaveAloneNew() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "new Integer (5)",
fixer.fix( "new Integer (5)" ) );
}
public void testLeaveAloneDrools() {
- final FunctionFixer fixer = new FunctionFixer();
- assertEquals( "xxx drools.org(iii) Func.func(yyy, iii) yyy",
+ assertEquals( "xxx drools.org(iii) org.drools.Func.func(yyy, iii) yyy",
fixer.fix( "xxx drools.org(iii) func(yyy, iii) yyy" ) );
}
- public void testWorkWithDotAll() {
- final FunctionFixer fixer = new FunctionFixer();
+ public void testWorkWithDotAll() {
assertEquals( "\n\t\n\tAddFive.addFive(list) ;",
fixer.fix( "\n\t\n\taddFive ( list ) ;" ) );
}
public void testWithDollarSigns() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "\nFoo.foo($list);",
fixer.fix( "\nfoo($list);" ) );
}
public void testReservedWordsInJava() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "\nfor(int i=0; i < 2; i++) { /*do noithing*/ }",
fixer.fix( "\nfor(int i=0; i < 2; i++) { /*do noithing*/ }" ) );
}
public void testMultipleInABracket() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "if (Foo.foo(bar)) { Bar.bar(baz); }",
fixer.fix( "if (foo(bar)) { bar(baz); }" ) );
}
public void testInBrackets() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "if (Foo.foo(bar))",
fixer.fix( "if (foo(bar))" ) );
}
public void testAlreadyAdded() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "Foo.foo(bar)",
fixer.fix( "Foo.foo(bar)" ) );
}
public void testInString() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "\"if (foo(bar))\"",
fixer.fix( "\"if (foo(bar))\"" ) );
}
public void testComplexWithBrackets() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "System.out.println(\"foo(\" + Foo.foo(bar) + Bar.bar(baz)",
fixer.fix( "System.out.println(\"foo(\" + foo(bar) + bar(baz)" ) );
}
public void testXPath() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "foo.executeXpath(\"//node1/node2/text()\")",
fixer.fix("foo.executeXpath(\"//node1/node2/text()\")" ) );
}
public void testExpressionGrouping() {
- final FunctionFixer fixer = new FunctionFixer();
assertEquals( "while((foo = bar.baz()) != null)",
fixer.fix( "while((foo = bar.baz()) != null)" ) );
}
Added: labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/StaticMethodFunctionResolverTest.java
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/StaticMethodFunctionResolverTest.java 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/java/org/drools/semantics/java/StaticMethodFunctionResolverTest.java 2006-08-31 16:53:31 UTC (rev 6045)
@@ -0,0 +1,26 @@
+package org.drools.semantics.java;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.drools.spi.FunctionResolver;
+import org.drools.spi.TypeResolver;
+
+import junit.framework.TestCase;
+
+public class StaticMethodFunctionResolverTest extends TestCase {
+ public void test1() {
+ List list = new ArrayList();
+ list.add( "org.drools.StaticMethods" );
+ TypeResolver typeResolver = new ClassTypeResolver( list );
+
+
+ list = new ArrayList();
+ list.add( "StaticMethods.*" );
+ FunctionResolver functionResolver = new StaticMethodFunctionResolver( list, typeResolver );
+
+ System.out.println( functionResolver.resolveFunction( "getString", 1 ) );
+
+
+ }
+}
Added: labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ImportFunctions.drl
===================================================================
--- labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ImportFunctions.drl 2006-08-31 16:26:48 UTC (rev 6044)
+++ labs/jbossrules/trunk/drools-compiler/src/test/resources/org/drools/integrationtests/test_ImportFunctions.drl 2006-08-31 16:53:31 UTC (rev 6045)
@@ -0,0 +1,45 @@
+package org.drools.test;
+
+import function org.drools.StaticMethods.*;
+import function org.drools.StaticMethods2.getString3;
+
+import org.drools.Cheese;
+
+global java.util.List list;
+
+function String getString4( String string ) {
+ return string;
+}
+
+rule "test rule1"
+ salience 30
+ when
+ Cheese()
+ then
+ list.add( getString1( "rule1" ) );
+end
+
+rule "test rule2"
+ salience 20
+ when
+ Cheese( type == ( getString2("stilton") ) );
+ then
+ list.add( getString3( "rule", new Integer( 2 ) ) );
+end
+
+rule "test rule3"
+ salience 10
+ when
+ Cheese( $type : type);
+ eval( $type.equals( getString1( "stilton" ) ) );
+ then
+ list.add( getString2( "rule3" ) );
+end
+
+rule "test rule4"
+ salience 0
+ when
+ Cheese();
+ then
+ list.add( getString4( "rule4" ) );
+end
\ No newline at end of file
More information about the jboss-svn-commits
mailing list