Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.lib / org.gvsig.expressionevaluator.lib.api / src / main / java / org / gvsig / expressionevaluator / spi / AbstractSymbolTable.java @ 44139

History | View | Annotate | Download (6.82 KB)

1
package org.gvsig.expressionevaluator.spi;
2

    
3
import java.util.ArrayList;
4
import java.util.Collection;
5
import java.util.Collections;
6
import java.util.HashMap;
7
import java.util.HashSet;
8
import java.util.Iterator;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Set;
12
import org.apache.commons.lang3.Range;
13
import org.apache.commons.lang3.StringUtils;
14
import org.gvsig.expressionevaluator.Function;
15
import org.gvsig.expressionevaluator.Interpreter;
16
import org.gvsig.expressionevaluator.SymbolTable;
17
import org.gvsig.tools.script.Script;
18

    
19
/**
20
 *
21
 * @author jjdelcerro
22
 */
23
public abstract class AbstractSymbolTable implements SymbolTable {
24

    
25
    private final String name;
26

    
27
    private class ScriptFunction extends AbstractFunction {
28

    
29
        public ScriptFunction(String funcName) {
30
            super("Script", funcName, Range.between(1, Integer.MAX_VALUE));
31
        }
32

    
33
        @Override
34
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
35
            for (Script script : scripts()) {
36
                try {
37
                    return script.invokeFunction(this.name(), args);
38
                } catch (NoSuchMethodException ex) {
39
                    // Si la funcion no existe en el script pasamos al siguiente
40
                    // script.
41
                }
42
            }
43
            throw new NoSuchMethodException("Can't locate funcion '" + this.name() + "'.");
44
        }
45

    
46
    }
47

    
48
    protected final List<SymbolTable> symbolTables;
49
    protected Map<String, Object> vars;
50
    protected Map<String, Function> functions;
51
    protected Map<String, Function> functionAlias;
52
    protected List<Script> scripts;
53

    
54
    public AbstractSymbolTable() {
55
        this(null);
56
    }
57
    
58
    public AbstractSymbolTable(String name) {
59
        this.name = name;
60
        this.symbolTables = new ArrayList<>();
61
        this.vars = null;
62
        this.functions = null;
63
        this.functionAlias = null;
64
        this.scripts = null;
65
    }
66

    
67
    @Override
68
    public String getName() {
69
        return name;
70
    }
71

    
72
    protected void addFunction(Function function) {
73
        if (function == null) {
74
            throw new IllegalArgumentException("function can't be null");
75
        }
76
        this.getFunctions().put(function.name().toUpperCase(), function);
77
        List<String> aliases = function.aliases();
78
        if( aliases == null || aliases.isEmpty() ) {
79
            return;
80
        }
81
        Map<String, Function> theFunctionAlias = this.getFunctionAlias();
82
        for (String alias : aliases) {
83
            if( alias!=null ) {
84
                theFunctionAlias.put(alias, function);
85
            }
86
        }
87
    }
88
    
89
    @Override
90
    public void addSymbolTable(SymbolTable symbolTable) {
91
        if (this.symbolTables.contains(symbolTable)) {
92
            return;
93
        }
94
        this.symbolTables.add(symbolTable);
95
    }
96

    
97
    protected Map<String, Object> getVars() {
98
        if (this.vars == null) {
99
            this.vars = new HashMap<>();
100
        }
101
        return this.vars;
102
    }
103

    
104
    protected Map<String, Function> getFunctions() {
105
        if (this.functions == null) {
106
            this.functions = new HashMap<>();
107
        }
108
        return this.functions;
109
    }
110

    
111
    protected Map<String, Function> getFunctionAlias() {
112
        if (this.functionAlias == null) {
113
            this.functionAlias = new HashMap<>();
114
        }
115
        return this.functionAlias;
116
    }
117

    
118
    protected List<Script> getScripts() {
119
        if (this.scripts == null) {
120
            this.scripts = new ArrayList<>();
121
        }
122
        return this.scripts;
123
    }
124

    
125
    @Override
126
    public boolean exists(String name) {
127
        if (StringUtils.isEmpty(name)) {
128
            return false;
129
        }
130
        if (this.vars != null) {
131
            if (this.vars.containsKey(name.toUpperCase())) {
132
                return true;
133
            }
134
        }
135
        for (SymbolTable other : this.symbolTables) {
136
            if (other.exists(name)) {
137
                return true;
138
            }
139
        }
140
        return false;
141
    }
142

    
143
    @Override
144
    public Object value(String name) {
145
        if (StringUtils.isEmpty(name)) {
146
            return null;
147
        }
148
        if (this.vars != null) {
149
            name = name.toUpperCase();
150
            if (this.vars.containsKey(name)) {
151
                return this.vars.get(name);
152
            }
153
        }
154
        for (SymbolTable other : this.symbolTables) {
155
            if (other.exists(name)) {
156
                return other.value(name);
157
            }
158
        }
159
        return null;
160
    }
161

    
162
    @Override
163
    public Function function(String name) {
164
        if (StringUtils.isEmpty(name)) {
165
            return null;
166
        }
167
        if (this.functions != null) {
168
            name = name.toUpperCase();
169
            if (this.functions.containsKey(name)) {
170
                return this.functions.get(name);
171
            }
172
        }
173
        if (this.functionAlias != null) {
174
            name = name.toUpperCase();
175
            if (this.functionAlias.containsKey(name)) {
176
                return this.functionAlias.get(name);
177
            }
178
        }
179
        for (SymbolTable other : this.symbolTables) {
180
            Function fn = other.function(name);
181
            if (fn != null) {
182
                if (fn instanceof ScriptFunction) {
183
                    continue;
184
                }
185
                return fn;
186
            }
187
        }
188
        if (this.scripts == null || this.scripts.isEmpty()) {
189
            return null;
190
        }
191
        return new ScriptFunction(name);
192
    }
193

    
194
    @Override
195
    public Collection<String> variables() {
196
        Set<String> theVars = new HashSet<>();
197
        for (SymbolTable symbolTable : this.symbolTables) {
198
            theVars.addAll(symbolTable.variables());
199
        }
200
        if (this.vars != null) {
201
            theVars.addAll(this.vars.keySet());
202
        }
203
        return Collections.unmodifiableCollection(theVars);
204
    }
205

    
206
    @Override
207
    public Collection<Function> functions() {
208
        Set<Function> theFunctions = new HashSet<>();
209
        for (SymbolTable symbolTable : this.symbolTables) {
210
            theFunctions.addAll(symbolTable.functions());
211
        }
212
        if (this.functions != null) {
213
            theFunctions.addAll(this.functions.values());
214
        }
215
        return Collections.unmodifiableCollection(theFunctions);
216
    }
217

    
218
    @Override
219
    public Collection<Script> scripts() {
220
        Set<Script> theScripts = new HashSet<>();
221
        for (SymbolTable symbolTable : this.symbolTables) {
222
            theScripts.addAll(symbolTable.scripts());
223
        }
224
        if (this.scripts != null) {
225
            theScripts.addAll(this.scripts);
226
        }
227
        return Collections.unmodifiableCollection(theScripts);
228
    }
229

    
230
    @Override
231
    public Iterator<Function> iterator() {
232
        return this.functions().iterator();
233
    }
234

    
235
    @Override
236
    public SymbolTable clone() throws CloneNotSupportedException {
237
        SymbolTable other = (SymbolTable) super.clone();
238
        return other;
239
    }
240

    
241
}