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

History | View | Annotate | Download (8.39 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.StringUtils;
13
import org.gvsig.expressionevaluator.Function;
14
import org.gvsig.expressionevaluator.MutableSymbolTable;
15
import org.gvsig.expressionevaluator.SymbolTable;
16
import org.gvsig.tools.util.GetItemByKey;
17

    
18
/**
19
 *
20
 * @author jjdelcerro
21
 */
22
public abstract class AbstractSymbolTable implements SymbolTable, GetItemByKey<String, Object> {
23

    
24
    private final String name;
25

    
26

    
27
    protected Map<String, Object> vars;
28

    
29
    protected List<SymbolTable> symbolTables;
30
    protected Map<String, Function> functions;
31
    protected Map<String, Function> functionAlias;
32

    
33
    public AbstractSymbolTable() {
34
        this(null);
35
    }
36
    
37
    public AbstractSymbolTable(String name) {
38
        if( name == null ) {
39
            this.name = "Anonymous";
40
        } else {
41
            this.name = name;
42
        }
43
        this.symbolTables = new ArrayList<>();
44
        this.vars = null;
45
        this.functions = null;
46
        this.functionAlias = null;
47
    }
48

    
49
    @Override
50
    public String getName() {
51
        return name;
52
    }
53

    
54
    public void addFunction(Function function) {
55
        if (function == null) {
56
            throw new IllegalArgumentException("function can't be null");
57
        }
58
        this.getFunctions().put(function.name().toUpperCase(), function);
59
        List<String> aliases = function.aliases();
60
        if( aliases == null || aliases.isEmpty() ) {
61
            return;
62
        }
63
        Map<String, Function> theFunctionAlias = this.getFunctionAlias();
64
        for (String alias : aliases) {
65
            if( alias!=null ) {
66
                theFunctionAlias.put(alias, function);
67
            }
68
        }
69
    }
70
    
71
    public void addFunctions(Collection<Function> functions) {
72
        for (Function function : functions) {
73
            this.addFunction(function);
74
        }
75
    }
76

    
77
    public void removeFunction(String name) {
78
        if( StringUtils.isEmpty(name) ) {
79
            throw new IllegalArgumentException("name can't be null");
80
        }
81
        this.functions.remove(name.toUpperCase());
82
    }
83
    
84
    @Override
85
    public boolean addSymbolTable(SymbolTable symbolTable) {
86
        if( symbolTable==null ) {
87
          throw new IllegalArgumentException("Invalid symbol table (null)");
88
        }
89
        if (this.symbolTables.contains(symbolTable)) {
90
            return false;
91
        }
92
        this.symbolTables.add(0,symbolTable);
93
        return true;
94
    }
95

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

    
114
    public void setVar(String name, Object value) {
115
        if( StringUtils.isEmpty(name) ) {
116
            throw new IllegalArgumentException("name can't be null");
117
        }
118
        this.getVars().put(name.toUpperCase(), value);
119
    }
120

    
121
    public void removeVar(String name) {
122
        if( StringUtils.isEmpty(name) ) {
123
            throw new IllegalArgumentException("name can't be null");
124
        }
125
        this.getVars().remove(name.toUpperCase());
126
    }
127

    
128
    protected Map<String, Function> getFunctions() {
129
        if (this.functions == null) {
130
            this.functions = new HashMap<>();
131
        }
132
        return this.functions;
133
    }
134

    
135
    protected Map<String, Function> getFunctionAlias() {
136
        if (this.functionAlias == null) {
137
            this.functionAlias = new HashMap<>();
138
        }
139
        return this.functionAlias;
140
    }
141

    
142
    @Override
143
    public boolean exists(String name) {
144
        if (StringUtils.isEmpty(name)) {
145
            return false;
146
        }
147
        if (this.getVars().containsKey(name.toUpperCase())) {
148
            return true;
149
        }
150
        if( StringUtils.equalsIgnoreCase(name, "$symboltable") )  {
151
            return true;
152
        }
153
        for (SymbolTable other : this.symbolTables) {
154
            if (other.exists(name)) {
155
                return true;
156
            }
157
        }
158
        return false;
159
    }
160

    
161
    @Override
162
    public Object value(String name) {
163
        if (StringUtils.isEmpty(name)) {
164
            return null;
165
        }
166
        name = name.toUpperCase();
167
        if (this.getVars().containsKey(name)) {
168
            return this.getVars().get(name);
169
        }
170
        if( name.equals("$SYMBOLTABLE") ) {
171
            return this;
172
        }
173
        for (SymbolTable other : this.symbolTables) {
174
            if (other.exists(name)) {
175
                return other.value(name);
176
            }
177
            if( StringUtils.equalsIgnoreCase(name, other.getName())) {
178
                return other;
179
            }
180
        }
181
        return null;
182
    }
183

    
184
    @Override
185
    public Object get(String name) {
186
        return this.value(name);
187
    }
188
    
189
    @Override
190
    public Function function(String name) {
191
        if (StringUtils.isEmpty(name)) {
192
            return null;
193
        }
194
        if (this.functions != null) {
195
            name = name.toUpperCase();
196
            if (this.functions.containsKey(name)) {
197
                return this.functions.get(name);
198
            }
199
        }
200
        if (this.functionAlias != null) {
201
            name = name.toUpperCase();
202
            if (this.functionAlias.containsKey(name)) {
203
                return this.functionAlias.get(name);
204
            }
205
        }
206
        for (SymbolTable other : this.symbolTables) {
207
            Function fn = other.function(name);
208
            if (fn != null) {
209
                return fn;
210
            }
211
        }
212
        return null;
213
    }
214

    
215
    @Override
216
    public Collection<String> variables() {
217
        Set<String> theVars = new HashSet<>();
218
        for (SymbolTable symbolTable : this.symbolTables) {
219
            theVars.addAll(symbolTable.variables());
220
        }
221
        theVars.addAll(this.localvariables());
222
        return Collections.unmodifiableCollection(theVars);
223
    }
224

    
225
    @Override
226
    public Collection<Function> functions() {
227
        Set<Function> theFunctions = new HashSet<>();
228
        for (SymbolTable symbolTable : this.symbolTables) {
229
            theFunctions.addAll(symbolTable.functions());
230
        }
231
        if (this.functions != null) {
232
            theFunctions.addAll(this.functions.values());
233
        }
234
        return Collections.unmodifiableCollection(theFunctions);
235
    }
236

    
237
    @Override
238
    public Collection<Function> localfunctions() {
239
        if( this.functions == null ) {
240
            return Collections.EMPTY_LIST;
241
        }
242
        return Collections.unmodifiableCollection(this.functions.values());
243
    }
244

    
245
    @Override
246
    public Collection<String> localvariables() {
247
        if( this.getVars().isEmpty()) {
248
            return Collections.EMPTY_LIST;
249
        }
250
        return Collections.unmodifiableCollection(this.vars.keySet());
251
    }
252

    
253
    @Override
254
    public Iterator<Function> iterator() {
255
        return this.functions().iterator();
256
    }
257

    
258
    @Override
259
    public SymbolTable clone() throws CloneNotSupportedException {
260
        AbstractSymbolTable other = (AbstractSymbolTable) super.clone();
261
        if( this instanceof MutableSymbolTable ) {
262
            if( this.vars!=null ) {
263
                other.vars = new HashMap<>(this.vars);
264
            }
265
            if( this.functions!=null ) {
266
                other.functions = new HashMap<>(this.functions);
267
            }
268
            if( this.functionAlias!=null ) {
269
                other.functionAlias = new HashMap<>(this.functionAlias);
270
            }
271
        }
272
        other.symbolTables = new ArrayList<>();
273
        if( this.symbolTables!=null ) {
274
            for (SymbolTable symbolTable : this.symbolTables) {
275
                other.symbolTables.add(symbolTable.clone());
276
            }
277
        }
278
        return other;
279
    }
280

    
281
    @Override
282
    public boolean isSQLCompatible(String name) {
283
        Function f = function(name);
284
        if( f!=null ) {
285
            return f.isSQLCompatible();
286
        }
287
        return true;
288
    }
289

    
290
    public List<SymbolTable> getSymbolTables() {
291
        return Collections.unmodifiableList(symbolTables);
292
    }
293

    
294
    @Override
295
    public String toString() {
296
        return this.name;
297
    }
298

    
299
}