Statistics
| Revision:

svn-gvsig-desktop / 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 @ 44389

History | View | Annotate | Download (4.39 KB)

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

    
3
import java.util.ArrayList;
4
import java.util.Arrays;
5
import java.util.List;
6
import org.apache.commons.lang3.Range;
7
import org.gvsig.expressionevaluator.Code;
8
import org.gvsig.expressionevaluator.Codes;
9
import org.gvsig.expressionevaluator.Function;
10
import org.gvsig.expressionevaluator.Interpreter;
11
import org.gvsig.expressionevaluator.spi.AbstractFunction;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
13
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
14
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
15
import org.gvsig.expressionevaluator.MutableSymbolTable;
16
import org.gvsig.expressionevaluator.SymbolTable;
17

    
18
public class CreateFnFunction extends AbstractFunction {
19
    
20
    public static final String NAME = "CREATE_FUNCTION";
21

    
22
    public CreateFnFunction() {
23
        super(Function.GROUP_PROGRAMMING, 
24
                NAME, 
25
                Range.between(2, 3),
26
                null,
27
                null,
28
                null,
29
                "Object",
30
                false
31
        );
32
    }
33

    
34
    @Override
35
    public boolean useArgumentsInsteadObjects() {
36
        return true;
37
    }
38

    
39
    @Override
40
    public boolean allowConstantFolding() {
41
        return false;
42
    }
43
    
44
    @Override
45
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
46
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
47
    }
48
    
49
    @Override
50
    public Object call(Interpreter interpreter, Codes args) throws Exception {
51
        // FNAME, PARAM-NAMES, BODY
52
        if( !(interpreter.getSymbolTable() instanceof MutableSymbolTable) ) {
53
            throw new ExpressionRuntimeException("The use of user functions require a mutable symbol table.");
54
        }
55
        MutableSymbolTable symbolTable = (MutableSymbolTable) interpreter.getSymbolTable();
56
        
57
        String name;
58
        List<String> argNames;
59
        Code body;
60
        switch(args.size()) {
61
            case 2:
62
                name = (String) getObject(interpreter, args, 0);
63
                argNames = null;
64
                body = args.get(1);
65
                break;
66
            case 3:
67
                name = (String) getObject(interpreter, args, 0);
68
                if( args.get(1)==null ) {
69
                    argNames = null;
70
                } else {
71
                    argNames = (List<String>) getObject(interpreter, args, 1);
72
                }
73
                body = args.get(2);
74
                break;
75
            default:
76
                throw new ExpressionRuntimeException("Incorrect number of arguments");
77
        }
78
        
79
        Function fn = new UserFunction(name, argNames, body);
80
        symbolTable.addFunction(fn);
81
        return fn;
82
    }
83
    
84
    private static class UserFunction extends AbstractFunction {
85

    
86
        private final Code body;
87
        private final List<String> argNames;
88

    
89
        public UserFunction(String name, List<String> argNames, Code body) {
90
            super(GROUP_OTHER, name, Range.between(0, Integer.MAX_VALUE));
91
            this.argNames = argNames;
92
            this.body = body;
93
        }
94
        
95
        @Override
96
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
97
            Object value;
98
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
99
            MutableSymbolTable localSymbolTable = manager.createSymbolTable();
100
            
101
            List $args = new ArrayList();
102
            if( args != null ) {
103
                $args.addAll(Arrays.asList(args));
104
            }
105
            localSymbolTable.setVar("$ARGS", $args);
106
            
107
            int max;
108
            if( this.argNames==null ) {
109
                max = 0;
110
            } else {
111
                max = Math.min(this.argNames.size(), args.length);
112
            }
113
            for (int i = 0; i < max; i++) {
114
                localSymbolTable.setVar(this.argNames.get(i), args[i]);
115
            }
116
            SymbolTable savedSymbolTable = interpreter.getSymbolTable();
117
            localSymbolTable.addSymbolTable(savedSymbolTable);
118
            try {
119
                interpreter.setSymbolTable(localSymbolTable);
120
                value = interpreter.run(this.body);
121
            } finally {
122
                interpreter.setSymbolTable(savedSymbolTable);
123
            }
124
            return value;
125
        }
126
        
127
    }
128
    
129
}