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 / AbstractCodeToStringConverter.java @ 44139

History | View | Annotate | Download (7.02 KB)

1
package org.gvsig.expressionevaluator.spi;
2

    
3
import org.gvsig.expressionevaluator.CodeToStringConverter;
4
import java.util.HashMap;
5
import java.util.HashSet;
6
import java.util.Map;
7
import java.util.Set;
8
import org.gvsig.expressionevaluator.Code;
9
import org.gvsig.expressionevaluator.Code.Caller;
10
import org.gvsig.expressionevaluator.Code.Constant;
11
import org.gvsig.expressionevaluator.Code.Identifier;
12
import org.gvsig.expressionevaluator.Code.Method;
13
import org.gvsig.expressionevaluator.Codes;
14
import org.gvsig.tools.exception.BaseException;
15
import org.gvsig.tools.visitor.VisitCanceledException;
16
import org.gvsig.tools.visitor.Visitor;
17

    
18
/**
19
 *
20
 * @author jjdelcerro
21
 */
22
public class AbstractCodeToStringConverter implements CodeToStringConverter {
23

    
24
    private final Code code;
25
    protected Set<String> supportedFunctionsNames;
26
    protected Map<String, String> translatedFunctionsNames;
27

    
28
    public AbstractCodeToStringConverter() {
29
        this(null);
30
    }
31
    
32
    public AbstractCodeToStringConverter(Code code) {
33
        this.supportedFunctionsNames = new HashSet<>();
34
        this.translatedFunctionsNames = new HashMap<>();
35
        this.code = code;
36
    }
37

    
38
    protected final void addSupportedFunction(String name) {
39
        this.supportedFunctionsNames.add(name.toLowerCase());
40
    }
41

    
42
    protected final void addSupportedFunction(String name, String outputName) {
43
        this.supportedFunctionsNames.add(name.toLowerCase());
44
        this.translatedFunctionsNames.put(name.toLowerCase(), outputName);
45
    }
46

    
47
    protected final boolean isFunctionSupported(String functionName) {
48
        functionName = functionName.toLowerCase();
49
        for (String name : supportedFunctionsNames) {
50
            if (functionName.equals(name)) {
51
                return true;
52
            }
53
        }
54
        return false;
55
    }
56

    
57
    protected final String translateFunctionName(String functionName) {
58
        return this.translatedFunctionsNames.getOrDefault(functionName, functionName);
59
    }
60

    
61
    @Override
62
    public boolean isValid() {
63
        if( code == null ) {
64
            return false;
65
        }
66
        return this.isValid(code);
67
    }
68

    
69
    @SuppressWarnings("UseSpecificCatch")
70
    @Override
71
    public boolean isValid(Code code) {
72
        try {
73
            code.accept(new Visitor() {
74
                @Override
75
                public void visit(Object o) throws VisitCanceledException, BaseException {
76
                    Code code = (Code) o;
77
                    switch (code.code()) {
78
                        case Code.CALLER:
79
                            Caller caller = (Caller) code;
80
                            if (!isFunctionSupported(caller.name())) {
81
                                throw new UnsupportedOperationException("Function '" + caller.name() + "' not supported.");
82
                            }
83
                        case Code.CONSTANT:
84
                        case Code.IDENTIFIER:
85
                            break;
86
                            
87
                        case Code.METHOD:
88
                            throw new UnsupportedOperationException("Method call not supported.");
89
                            
90
                        default:
91
                            throw new UnsupportedOperationException("Code type not supported.");
92
                    }
93
                }
94
            });
95
            return true;
96
        } catch (Exception ex) {
97
            return false;
98
        }
99
    }
100

    
101
    @Override
102
    public String toString() {
103
        if( code == null ) {
104
            return null;
105
        }
106
        return this.toString(code);
107
    }
108

    
109
    @Override
110
    public String toString(Code code) {
111
        switch (code.code()) {
112
            case Code.CONSTANT:
113
                return constantToString((Constant) code);
114

    
115
            case Code.IDENTIFIER:
116
                return identifierToString((Identifier) code);
117

    
118
            case Code.CALLER:
119
                return callerToString((Caller) code);
120

    
121
            case Code.METHOD:
122
                return methodToString((Method) code);
123

    
124
            default:
125
                return "";
126
        }
127
    }
128

    
129
    protected String callerToString(Caller code) {
130
        switch (code.type()) {
131
            case Caller.BINARY_OPERATOR:
132
                if (!this.isFunctionSupported(code.name())) {
133
                    throw new UnsupportedOperationException("Operator '" + code.name() + "' not supported.");
134
                }
135
                return binaryOperatorToString(code.name(), code.args().get(0), code.args().get(1));
136

    
137
            case Caller.UNARY_OPERATOR:
138
                if (!this.isFunctionSupported(code.name())) {
139
                    throw new UnsupportedOperationException("Operator '" + code.name() + "' not supported.");
140
                }
141
                return unaryOperatorToString(code.name(), code.args().get(0));
142

    
143
            case Caller.FUNCTION:
144
            default:
145
                if (!this.isFunctionSupported(code.name())) {
146
                    throw new UnsupportedOperationException("Function '" + code.name() + "' not supported.");
147
                }
148
                String fname = this.translateFunctionName(code.name());
149
                return functionToString(fname, code.args());
150

    
151
        }
152
    }
153

    
154
    protected String constantToString(Constant code) {
155
        return code.toString();
156
    }
157

    
158
    protected String identifierToString(Identifier code) {
159
        return "\"" + code.name() + "\"";
160
    }
161

    
162
    protected String methodToString(Method code) {
163
        throw new UnsupportedOperationException("Method call not supported (method name '" + code.name() + "').");
164
    }
165

    
166
    protected String binaryOperatorToString(String name, Code oper1, Code oper2) {
167
        if (oper1.code() == Code.CONSTANT || oper1.code() == Code.IDENTIFIER) {
168
            if (oper2.code() == Code.CONSTANT || oper2.code() == Code.IDENTIFIER) {
169
                return this.toString(oper1) + " " + name + " " + this.toString(oper2);
170
            } else {
171
                return this.toString(oper1) + " " + name + " (" + this.toString(oper2) + ")";
172
            }
173
        } else if (oper2.code() == Code.CONSTANT || oper2.code() == Code.IDENTIFIER) {
174
            return "(" + this.toString(oper1) + ") " + name + " " + this.toString(oper2);
175
        }
176
        return "(" + this.toString(oper1) + ") " + name + " (" + this.toString(oper2) + ")";
177
    }
178

    
179
    protected String unaryOperatorToString(String name, Code oper) {
180
        if (oper.code() == Code.CONSTANT || oper.code() == Code.IDENTIFIER) {
181
            return name + " " + this.toString(oper);
182
        }
183
        return name + " (" + this.toString(oper) + ")";
184
    }
185

    
186
    protected String functionToString(String functionName, Codes args) {
187
        StringBuilder builder = new StringBuilder();
188
        builder.append(functionName);
189
        builder.append("(");
190
        boolean firstArg = true;
191
        for (Code arg : args) {
192
            if (firstArg) {
193
                firstArg = false;
194
                builder.append(this.toString(arg));
195
            } else {
196
                builder.append(", ");
197
                builder.append(this.toString(arg));
198
            }
199
        }
200
        builder.append(")");
201
        return builder.toString();
202
    }
203

    
204
}