Revision 44533 trunk/org.gvsig.desktop/org.gvsig.desktop.library/org.gvsig.expressionevaluator/org.gvsig.expressionevaluator.lib/org.gvsig.expressionevaluator.lib.impl/src/main/java/org/gvsig/expressionevaluator/impl/function/programming/CreateFnFunction.java

View differences:

CreateFnFunction.java
1 1
package org.gvsig.expressionevaluator.impl.function.programming;
2 2

  
3
import java.lang.reflect.Method;
3 4
import java.util.ArrayList;
4 5
import java.util.Arrays;
5 6
import java.util.List;
7
import java.util.Objects;
6 8
import org.apache.commons.lang3.Range;
9
import org.apache.commons.lang3.StringUtils;
7 10
import org.gvsig.expressionevaluator.Code;
8 11
import org.gvsig.expressionevaluator.Codes;
9 12
import org.gvsig.expressionevaluator.Function;
......
14 17
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
15 18
import org.gvsig.expressionevaluator.MutableSymbolTable;
16 19
import org.gvsig.expressionevaluator.SymbolTable;
20
import org.gvsig.tools.ToolsLocator;
21
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
22
import org.gvsig.tools.script.Script;
23
import org.gvsig.tools.script.ScriptManager;
17 24

  
18 25
public class CreateFnFunction extends AbstractFunction {
19 26
    
......
22 29
    public CreateFnFunction() {
23 30
        super(Function.GROUP_PROGRAMMING, 
24 31
                NAME, 
25
                Range.between(2, 3),
32
                Range.between(2, 6),
26 33
                null,
27 34
                null,
28 35
                null,
......
56 63
        
57 64
        String name;
58 65
        List<String> argNames;
59
        Code body;
66
        Code body = null;
67
        String script_path = null;
68
        String script_function = null;
69
        String language = null;
60 70
        switch(args.size()) {
61 71
            case 2:
62 72
                name = (String) getObject(interpreter, args, 0);
......
72 82
                }
73 83
                body = args.get(2);
74 84
                break;
85
            case 6:
86
                name = (String) getObject(interpreter, args, 0);
87
                if( args.get(1)==null ) {
88
                    argNames = null;
89
                } else {
90
                    argNames = (List<String>) getObject(interpreter, args, 1);
91
                }
92
                body = args.get(2);
93
                script_path = Objects.toString(args.get(2),null);
94
                script_function = Objects.toString(args.get(3),null);
95
                language = Objects.toString(args.get(4),null);
96
                break;
75 97
            default:
76 98
                throw new ExpressionRuntimeException("Incorrect number of arguments");
77 99
        }
78
        
79
        Function fn = new UserFunction(name, argNames, body);
80
        symbolTable.addFunction(fn);
81
        return fn;
100
        Function fn;
101
        if( body!=null ) {
102
            fn = new UserFunction(name, argNames, body);
103
            symbolTable.addFunction(fn);
104
            return fn;
105
        }
106
        if( StringUtils.isBlank(script_path) || StringUtils.isBlank(script_function) ) {
107
            throw new ExpressionRuntimeException("boydy and, script path or script function, are empty.");
108
        }
109
        if( StringUtils.isBlank(language) ) {
110
            language = "script";
111
        }
112
        switch(language.toLowerCase()) {
113
            case "script":
114
                fn = new ExternalFunction(name, script_path, script_function);
115
                symbolTable.addFunction(fn);
116
                return fn;
117
            case "java":
118
                fn = new JavaFunction(name, script_path, script_function);
119
                symbolTable.addFunction(fn);
120
                return fn;
121
        }
122
        throw new ExpressionRuntimeException("Unsupported language '"+language+".");
82 123
    }
83 124
    
84 125
    private static class UserFunction extends AbstractFunction {
......
126 167
        
127 168
    }
128 169
    
170
    private static class ExternalFunction extends AbstractFunction {
171

  
172
        private final String script_path;
173
        private final String script_function;
174

  
175
        public ExternalFunction(String name, String script_path, String script_function) {
176
            super(GROUP_OTHER, name, Range.between(0, Integer.MAX_VALUE));
177
            this.script_path = script_path;
178
            this.script_function = script_function;
179
        }
180
        
181
        @Override
182
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
183
            ScriptManager scriptManager = ToolsLocator.getScriptManager();
184
            ExpressionEvaluatorManager expressionManager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
185
            ResourcesStorage resourcesStorage = expressionManager.getScriptsResourcesStorage();
186
            Script sc = scriptManager.loadScript(resourcesStorage, script_path);
187
            if( sc == null ) {
188
                throw new ExpressionRuntimeException("Can't locate '"+this.script_path+"'.");
189
            }
190
            Object r = sc.invokeFunction(this.script_function, args);
191
            return r;
192
        }
193
        
194
    }
195

  
196
    private static class JavaFunction extends AbstractFunction {
197

  
198
        private final String fullClassName;
199
        private final String methodName;
200

  
201
        public JavaFunction(String name, String fullClassName, String methodName) {
202
            super(GROUP_OTHER, name, Range.between(0, Integer.MAX_VALUE));
203
            this.fullClassName = fullClassName;
204
            this.methodName = methodName;
205
        }
206
        
207
        @Override
208
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
209
            Class[] parameterTypes = new Class[args.length];
210
            for (int i = 0; i < args.length; i++) {
211
                if( args[i]==null ) {
212
                    parameterTypes[i] = null;
213
                } else {
214
                    parameterTypes[i] = args[i].getClass();
215
                }
216
            }
217
            Class<?> theClass = Class.forName(this.fullClassName);
218
            Method method = theClass.getMethod(this.methodName, parameterTypes);
219
            Object value = method.invoke(null, args);
220
            return value;
221
        }
222
        
223
    }
224

  
129 225
}

Also available in: Unified diff