Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.impl / src / main / java / org / gvsig / fmap / dal / impl / expressionevaluator / DefaultExpressionEvaluator.java @ 43983

History | View | Annotate | Download (6.5 KB)

1
package org.gvsig.fmap.dal.impl.expressionevaluator;
2

    
3
import java.util.ArrayList;
4
import java.util.HashSet;
5
import java.util.List;
6
import java.util.Set;
7
import org.gvsig.expressionevaluator.Code;
8
import org.gvsig.expressionevaluator.Interpreter;
9
import org.gvsig.expressionevaluator.SymbolTable;
10
import org.gvsig.expressionevaluator.Compiler;
11
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
13
import org.gvsig.expressionevaluator.Function;
14
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
15
import org.gvsig.fmap.dal.feature.Feature;
16
import org.gvsig.tools.evaluator.AbstractEvaluator;
17
import org.gvsig.tools.evaluator.Evaluator;
18
import org.gvsig.tools.evaluator.EvaluatorData;
19
import org.gvsig.tools.evaluator.EvaluatorException;
20
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
21
import org.gvsig.tools.evaluator.EvaluatorWithDescriptions;
22
import org.gvsig.tools.exception.BaseException;
23
import org.gvsig.tools.visitor.VisitCanceledException;
24
import org.gvsig.tools.visitor.Visitor;
25
import org.gvsig.tools.lang.Cloneable;
26

    
27
public class DefaultExpressionEvaluator 
28
        extends AbstractEvaluator 
29
        implements EvaluatorWithDescriptions, Cloneable 
30
    {
31

    
32
    private static class DescriptionAdapter implements Description {
33

    
34
        Function function;
35

    
36
        public DescriptionAdapter(Function function) {
37
            this.function = function;
38
        }
39

    
40
        @Override
41
        public String getName() {
42
            return this.function.name();
43
        }
44

    
45
        @Override
46
        public String getDescription() {
47
            return this.function.description();
48
        }
49

    
50
        @Override
51
        public String getTemplate() {
52
            return this.function.template();
53
        }
54

    
55
        @Override
56
        public int getDataTypeCategories() {
57
            switch (this.function.group()) {
58
                case Function.GROUP_STRING:
59
                    return Description.DATATYPE_CATEGORY_STRING;
60
                case Function.GROUP_BOOLEAN:
61
                    return Description.DATATYPE_CATEGORY_BOOLEAN;
62
                case Function.GROUP_DATETIME:
63
                    return Description.DATATYPE_CATEGORY_DATETIME;
64
                case Function.GROUP_NUMERIC:
65
                    return Description.DATATYPE_CATEGORY_NUMBER;
66
                case Function.GROUP_OGC:
67
                    return Description.DATATYPE_CATEGORY_ALL;
68
                default:
69
                    return Description.DATATYPE_CATEGORY_ALL;
70
            }
71
        }
72

    
73
    }
74

    
75
    private FeatureSymbolTable featureSymbolTable;
76
    private Compiler compiler;
77
    private Interpreter interpreter;
78
    private Code code;
79
    private String source;
80
    private Description[] availableOperators;
81
    private Description[] availableFunctions;
82

    
83
    public DefaultExpressionEvaluator(String source) {
84
        this.featureSymbolTable = new DefaultFeatureSymbolTable();
85
        this.source = source;
86
    }
87

    
88
    private void compile() {
89
        this.code = this.compiler.compileExpression(source);
90
    }
91

    
92
    @Override
93
    public Object evaluate(EvaluatorData data) throws EvaluatorException {
94
        if (this.code == null) {
95
            this.compile();
96
        }
97
        Interpreter theInterpreter = this.getInterpreter();
98
        theInterpreter.getSymbolTable().addSymbolTable(this.featureSymbolTable);
99

    
100
        this.featureSymbolTable.setFeature((Feature) data);
101
        Object v = this.interpreter.run(code);
102
        return v;
103
    }
104

    
105
    @Override
106
    public String getName() {
107
        return "Genereric expression";
108
    }
109

    
110
    @Override
111
    public EvaluatorFieldsInfo getFieldsInfo() {
112
        final Set<String> names = new HashSet<>();
113
        try {
114
            this.code.accept(new Visitor() {
115
                @Override
116
                public void visit(Object code) throws VisitCanceledException, BaseException {
117
                    if (code instanceof Code.Identifier) {
118
                        Code.Identifier identifier = (Code.Identifier) code;
119
                        names.add(identifier.name());
120
                    }
121
                }
122
            });
123
            EvaluatorFieldsInfo info = new EvaluatorFieldsInfo();
124
            for (String name : names) {
125
                info.addFieldValue(name);
126
            }
127
            return info;
128
        } catch (BaseException ex) {
129
            throw new RuntimeException("Can't calculate fields information.", ex);
130
        }
131
    }
132

    
133
    @Override
134
    public Description[] getAvailableOperators() {
135
        if (availableOperators == null) {
136
            List<Description> l = new ArrayList<>();
137
            for (Function function : getSymbolTable()) {
138
                if (function.isOperator()) {
139
                    l.add(new DescriptionAdapter(function));
140
                }
141
            }
142
            this.availableOperators = l.toArray(new Description[l.size()]);
143
        }
144
        return availableOperators;
145
    }
146

    
147
    @Override
148
    public Description[] getAvailableFunctions() {
149
        if (availableFunctions == null) {
150
            List<Description> l = new ArrayList<>();
151
            for (Function function : getSymbolTable()) {
152
                if (!function.isOperator()) {
153
                    l.add(new DescriptionAdapter(function));
154
                }
155
            }
156
            this.availableFunctions = l.toArray(new Description[l.size()]);
157
        }
158
        return availableFunctions;
159
    }
160

    
161
    private SymbolTable getSymbolTable() {
162
        return this.getInterpreter().getSymbolTable();
163
    }
164

    
165
    private Interpreter getInterpreter() {
166
        if (this.interpreter == null) {
167
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
168
            this.interpreter = manager.createInterpreter();
169
            this.interpreter.setAccuracy(ExpressionEvaluatorLocator.getManager().getAccuracy());
170
        }
171
        return interpreter;
172
    }
173

    
174
    @Override
175
    public Evaluator clone() throws CloneNotSupportedException {
176
        DefaultExpressionEvaluator other = (DefaultExpressionEvaluator) super.clone();
177
        other.code = this.code;
178
        other.source = this.source;
179
        other.availableFunctions = null;
180
        other.availableOperators = null;
181

    
182
        if (this.featureSymbolTable != null) {
183
            // evaluatorData don't support clone.
184
            other.featureSymbolTable = this.featureSymbolTable.clone();
185
        }
186
        if (this.compiler != null) {
187
            other.compiler = this.compiler.clone();
188
        }
189
        if (this.interpreter != null) {
190
            other.interpreter = this.interpreter.clone();
191
        }
192
        return other;
193
    }
194

    
195
}