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

History | View | Annotate | Download (7.32 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.Expression;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
13
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
14
import org.gvsig.expressionevaluator.Function;
15
import org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable;
16
import org.gvsig.fmap.dal.feature.Feature;
17
import org.gvsig.tools.evaluator.AbstractEvaluator;
18
import org.gvsig.tools.evaluator.Evaluator;
19
import org.gvsig.tools.evaluator.EvaluatorData;
20
import org.gvsig.tools.evaluator.EvaluatorException;
21
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
22
import org.gvsig.tools.evaluator.EvaluatorWithDescriptions;
23
import org.gvsig.tools.exception.BaseException;
24
import org.gvsig.tools.visitor.VisitCanceledException;
25
import org.gvsig.tools.visitor.Visitor;
26
import org.gvsig.tools.lang.Cloneable;
27

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

    
33
    private static class DescriptionAdapter implements Description {
34

    
35
        Function function;
36

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

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

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

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

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

    
74
    }
75

    
76
    private FeatureSymbolTable featureSymbolTable;
77
    private Compiler compiler;
78
    private Interpreter interpreter;
79
    private Code code;
80
    private Expression expression;
81
    private Description[] availableOperators;
82
    private Description[] availableFunctions;
83

    
84
    public DefaultExpressionEvaluator(String source) {
85
        this.featureSymbolTable = new DefaultFeatureSymbolTable();
86
        this.expression = ExpressionEvaluatorLocator.getManager().createExpression();
87
        this.expression.setPhrase(source);
88
    }
89

    
90
    public DefaultExpressionEvaluator(Expression expression) {
91
        this.expression = expression;
92
        this.featureSymbolTable = new DefaultFeatureSymbolTable(
93
                expression.getUserScript(), 
94
                expression.getScripts()
95
        );
96
    }
97

    
98
    @Override
99
    public Object evaluate(EvaluatorData data) throws EvaluatorException {
100
        if (this.code == null) {
101
            this.compile();
102
        }
103
        Interpreter theInterpreter = this.getInterpreter();
104
        theInterpreter.getSymbolTable().addSymbolTable(this.featureSymbolTable);
105

    
106
        this.featureSymbolTable.setFeature((Feature) data);
107
        Object v = this.interpreter.run(code);
108
        return v;
109
    }
110

    
111
    @Override
112
    public String getName() {
113
        return "Genereric expression";
114
    }
115

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

    
139
    @Override
140
    public Description[] getAvailableOperators() {
141
        if (availableOperators == null) {
142
            List<Description> l = new ArrayList<>();
143
            for (Function function : getSymbolTable()) {
144
                if (function.isOperator()) {
145
                    l.add(new DescriptionAdapter(function));
146
                }
147
            }
148
            this.availableOperators = l.toArray(new Description[l.size()]);
149
        }
150
        return availableOperators;
151
    }
152

    
153
    @Override
154
    public Description[] getAvailableFunctions() {
155
        if (availableFunctions == null) {
156
            List<Description> l = new ArrayList<>();
157
            for (Function function : getSymbolTable()) {
158
                if (!function.isOperator()) {
159
                    l.add(new DescriptionAdapter(function));
160
                }
161
            }
162
            this.availableFunctions = l.toArray(new Description[l.size()]);
163
        }
164
        return availableFunctions;
165
    }
166

    
167
    private SymbolTable getSymbolTable() {
168
        return this.getInterpreter().getSymbolTable();
169
    }
170

    
171
    private Interpreter getInterpreter() {
172
        if (this.interpreter == null) {
173
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
174
            this.interpreter = manager.createInterpreter();
175
            this.interpreter.setAccuracy(ExpressionEvaluatorLocator.getManager().getAccuracy());
176
        }
177
        return interpreter;
178
    }
179

    
180
    private Compiler getCompiler() {
181
        if (this.compiler == null) {
182
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
183
            this.compiler = manager.createCompiler();
184
        }
185
        return compiler;
186
    }
187

    
188
    private Code compile() {
189
        if (this.code == null) {
190
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
191
            this.code = this.getCompiler().compileExpression(expression.getPhrase());
192
        }
193
        return code;
194
    }
195

    
196
    @Override
197
    public Evaluator clone() throws CloneNotSupportedException {
198
        DefaultExpressionEvaluator other = (DefaultExpressionEvaluator) super.clone();
199
        other.code = this.code;
200
        other.expression = this.expression.clone();
201
        other.availableFunctions = null;
202
        other.availableOperators = null;
203

    
204
        if (this.featureSymbolTable != null) {
205
            other.featureSymbolTable = this.featureSymbolTable.clone();
206
        }
207
        if (this.compiler != null) {
208
            other.compiler = this.compiler.clone();
209
        }
210
        if (this.interpreter != null) {
211
            other.interpreter = this.interpreter.clone();
212
        }
213
        return other;
214
    }
215

    
216
}