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 @ 44215

History | View | Annotate | Download (7.35 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 boolean addSymbolTable(SymbolTable symbolTable) {
91
        if (this.symbolTables.contains(symbolTable)) {
92
            return false;
93
        }
94
        this.symbolTables.add(symbolTable);
95
        return true;
96
    }
97

    
98
    @Override
99
    public boolean containsSymbolTable(SymbolTable symbolTable) {
100
        return this.symbolTables.contains(symbolTable);
101
    }
102
    
103
    @Override
104
    public boolean removeSymbolTable(SymbolTable symbolTable) {
105
        boolean n = this.symbolTables.remove(symbolTable);
106
        return n;
107
    }
108
    
109
    protected Map<String, Object> getVars() {
110
        if (this.vars == null) {
111
            this.vars = new HashMap<>();
112
        }
113
        return this.vars;
114
    }
115

    
116
    protected Map<String, Function> getFunctions() {
117
        if (this.functions == null) {
118
            this.functions = new HashMap<>();
119
        }
120
        return this.functions;
121
    }
122

    
123
    protected Map<String, Function> getFunctionAlias() {
124
        if (this.functionAlias == null) {
125
            this.functionAlias = new HashMap<>();
126
        }
127
        return this.functionAlias;
128
    }
129

    
130
    protected List<Script> getScripts() {
131
        if (this.scripts == null) {
132
            this.scripts = new ArrayList<>();
133
        }
134
        return this.scripts;
135
    }
136

    
137
    @Override
138
    public boolean exists(String name) {
139
        if (StringUtils.isEmpty(name)) {
140
            return false;
141
        }
142
        if (this.vars != null) {
143
            if (this.vars.containsKey(name.toUpperCase())) {
144
                return true;
145
            }
146
        }
147
        for (SymbolTable other : this.symbolTables) {
148
            if (other.exists(name)) {
149
                return true;
150
            }
151
        }
152
        return false;
153
    }
154

    
155
    @Override
156
    public Object value(String name) {
157
        if (StringUtils.isEmpty(name)) {
158
            return null;
159
        }
160
        if (this.vars != null) {
161
            name = name.toUpperCase();
162
            if (this.vars.containsKey(name)) {
163
                return this.vars.get(name);
164
            }
165
        }
166
        for (SymbolTable other : this.symbolTables) {
167
            if (other.exists(name)) {
168
                return other.value(name);
169
            }
170
        }
171
        return null;
172
    }
173

    
174
    @Override
175
    public Function function(String name) {
176
        if (StringUtils.isEmpty(name)) {
177
            return null;
178
        }
179
        if (this.functions != null) {
180
            name = name.toUpperCase();
181
            if (this.functions.containsKey(name)) {
182
                return this.functions.get(name);
183
            }
184
        }
185
        if (this.functionAlias != null) {
186
            name = name.toUpperCase();
187
            if (this.functionAlias.containsKey(name)) {
188
                return this.functionAlias.get(name);
189
            }
190
        }
191
        for (SymbolTable other : this.symbolTables) {
192
            Function fn = other.function(name);
193
            if (fn != null) {
194
                if (fn instanceof ScriptFunction) {
195
                    continue;
196
                }
197
                return fn;
198
            }
199
        }
200
        if (this.scripts == null || this.scripts.isEmpty()) {
201
            return null;
202
        }
203
        return new ScriptFunction(name);
204
    }
205

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

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

    
230
    @Override
231
    public Collection<Script> scripts() {
232
        Set<Script> theScripts = new HashSet<>();
233
        for (SymbolTable symbolTable : this.symbolTables) {
234
            theScripts.addAll(symbolTable.scripts());
235
        }
236
        if (this.scripts != null) {
237
            theScripts.addAll(this.scripts);
238
        }
239
        return Collections.unmodifiableCollection(theScripts);
240
    }
241

    
242
    @Override
243
    public Iterator<Function> iterator() {
244
        return this.functions().iterator();
245
    }
246

    
247
    @Override
248
    public SymbolTable clone() throws CloneNotSupportedException {
249
        SymbolTable other = (SymbolTable) super.clone();
250
        return other;
251
    }
252

    
253
    @Override
254
    public boolean isSQLCompatible(String name) {
255
        Function f = function(name);
256
        if( f!=null ) {
257
            return f.isSQLCompatible();
258
        }
259
        return true;
260
    }
261

    
262
}