001: package org.drools.rule.builder.dialect.java;
002:
003: import java.io.BufferedReader;
004: import java.io.IOException;
005: import java.io.InputStreamReader;
006: import java.io.StringReader;
007: import java.util.HashMap;
008: import java.util.Iterator;
009: import java.util.LinkedList;
010: import java.util.List;
011: import java.util.Map;
012:
013: import org.drools.RuntimeDroolsException;
014: import org.drools.base.TypeResolver;
015: import org.drools.compiler.FunctionError;
016: import org.drools.lang.descr.FunctionDescr;
017: import org.drools.rule.LineMappings;
018: import org.drools.rule.Package;
019: import org.drools.rule.builder.FunctionBuilder;
020: import org.drools.util.StringUtils;
021: import org.mvel.TemplateInterpreter;
022:
023: public class JavaFunctionBuilder implements FunctionBuilder {
024:
025: // private static final StringTemplateGroup functionGroup = new StringTemplateGroup( new InputStreamReader( JavaFunctionBuilder.class.getResourceAsStream( "javaFunction.stg" ) ),
026: // AngleBracketTemplateLexer.class );
027:
028: private static final String template = StringUtils
029: .readFileAsString(new InputStreamReader(
030: JavaFunctionBuilder.class
031: .getResourceAsStream("javaFunction.mvel")));
032:
033: public JavaFunctionBuilder() {
034:
035: }
036:
037: /* (non-Javadoc)
038: * @see org.drools.rule.builder.dialect.java.JavaFunctionBuilder#build(org.drools.rule.Package, org.drools.lang.descr.FunctionDescr, org.codehaus.jfdi.interpreter.TypeResolver, java.util.Map)
039: */
040: public String build(final Package pkg,
041: final FunctionDescr functionDescr,
042: final TypeResolver typeResolver, final Map lineMappings,
043: final List errors) {
044:
045: final Map vars = new HashMap();
046:
047: vars.put("package", pkg.getName());
048:
049: vars.put("imports", pkg.getImports());
050:
051: final List staticImports = new LinkedList();
052: for (Iterator it = pkg.getStaticImports().iterator(); it
053: .hasNext();) {
054: final String staticImport = (String) it.next();
055: if (!staticImport.startsWith(functionDescr.getClassName())) {
056: staticImports.add(staticImport);
057: }
058: }
059: vars.put("staticImports", staticImports);
060:
061: vars.put("className", StringUtils.ucFirst(functionDescr
062: .getName()));
063:
064: vars.put("methodName", functionDescr.getName());
065:
066: vars.put("returnType", functionDescr.getReturnType());
067:
068: vars.put("parameterTypes", functionDescr.getParameterTypes());
069:
070: vars.put("parameterNames", functionDescr.getParameterNames());
071:
072: // Check that all the parameters are resolvable
073: final Map params = new HashMap();
074: final List names = functionDescr.getParameterNames();
075: final List types = functionDescr.getParameterTypes();
076: try {
077: for (int i = 0, size = names.size(); i < size; i++) {
078: params.put(names.get(i), typeResolver
079: .resolveType((String) types.get(i)));
080: }
081: } catch (final ClassNotFoundException e) {
082: errors.add(new FunctionError(functionDescr, e,
083: "unable to resolve type while building function"));
084: }
085:
086: vars.put("text", functionDescr.getText());
087:
088: final String text = TemplateInterpreter.evalToString(template,
089: vars);
090:
091: //System.out.println( text );
092:
093: final BufferedReader reader = new BufferedReader(
094: new StringReader(text));
095: String line = null;
096: final String lineStartsWith = " public static "
097: + functionDescr.getReturnType() + " "
098: + functionDescr.getName();
099: int offset = 0;
100: try {
101: while ((line = reader.readLine()) != null) {
102: offset++;
103: if (line.startsWith(lineStartsWith)) {
104: break;
105: }
106: }
107: functionDescr.setOffset(offset);
108: } catch (final IOException e) {
109: // won't ever happen, it's just reading over a string.
110: throw new RuntimeDroolsException(
111: "Error determining start offset with function");
112: }
113:
114: final String name = pkg.getName() + "."
115: + StringUtils.ucFirst(functionDescr.getName());
116: final LineMappings mapping = new LineMappings(name);
117: mapping.setStartLine(functionDescr.getLine());
118: mapping.setOffset(functionDescr.getOffset());
119: lineMappings.put(name, mapping);
120:
121: return text;
122:
123: }
124:
125: }
|