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 / expressionevaluator / impl / function / dataaccess / AbstractSelectFunction.java @ 47777

History | View | Annotate | Download (10.2 KB)

1
package org.gvsig.expressionevaluator.impl.function.dataaccess;
2

    
3
import java.util.ArrayList;
4
import java.util.HashSet;
5
import java.util.List;
6
import java.util.Objects;
7
import java.util.Set;
8
import org.apache.commons.lang3.Range;
9
import org.apache.commons.lang3.StringUtils;
10
import org.apache.commons.lang3.tuple.ImmutablePair;
11
import org.apache.commons.lang3.tuple.Pair;
12
import org.gvsig.expressionevaluator.Code;
13
import org.gvsig.expressionevaluator.Code.Callable;
14
import org.gvsig.expressionevaluator.CodeBuilder;
15
import org.gvsig.expressionevaluator.Codes;
16
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_$HOSTEXPRESSION;
17
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_GETATTR;
18
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
19
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
20
import org.gvsig.expressionevaluator.ExpressionUtils;
21
import org.gvsig.expressionevaluator.Interpreter;
22
import org.gvsig.expressionevaluator.SymbolTable;
23
import org.gvsig.expressionevaluator.spi.AbstractFunction;
24
import org.gvsig.fmap.dal.DALLocator;
25
import org.gvsig.fmap.dal.DataManager;
26
import org.gvsig.fmap.dal.DataStore;
27
import static org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable.SYMBOL_CURRENT_TABLE;
28
import org.gvsig.fmap.dal.expressionevaluator.TableAttributeHandler;
29
import org.gvsig.fmap.dal.feature.FeatureStore;
30
import org.gvsig.fmap.dal.feature.FeatureType;
31

    
32
/**
33
 *
34
 * @author gvSIG Team
35
 */
36
@SuppressWarnings("UseSpecificCatch")
37
public abstract class AbstractSelectFunction extends AbstractFunction {
38

    
39
    protected AbstractSelectFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType, boolean sqlCompatible) {
40
        super(group, name, argc, description, template, descriptionArgs, returnType, sqlCompatible);
41
    }
42

    
43
    protected AbstractSelectFunction(String group, String name, Range argc, String description, String template, String[] descriptionArgs, String returnType) {
44
        super(group, name, argc, description, template, descriptionArgs, returnType);
45
    }
46

    
47
    protected String getIdentifier(Codes args, int argn) {
48
        Code id_code = (Code) args.get(argn);
49
        if( id_code == null ) {
50
            return null;
51
        }
52
        if (id_code instanceof Code.Identifier) {
53
            return ((Code.Identifier) id_code).name();
54
        } else if (id_code instanceof Code.Constant) {
55
            Code.Constant storeName_const = (Code.Constant) id_code;
56
            if (storeName_const.value() instanceof CharSequence) {
57
                return storeName_const.value().toString();
58
            }
59
        }
60
        throw new ExpressionRuntimeException("Invalid identifier (" + Objects.toString(id_code) + ") in function '" + this.name() + "'.");
61
    }
62

    
63
    protected Code getWhereCode(Codes args, int argn) {
64
        Code where = args.get(argn);
65
        if (where.code() == Code.CONSTANT) {
66
            if (((Code.Constant) where).value() == null) {
67
                where = null;
68
            }
69
        }
70
        return where;
71
    }
72

    
73
    protected Callable getTupleOrNull(Codes args, int argn) {
74
        Code code = args.get(argn);
75
        if (code.code() == Code.CONSTANT) {
76
            if (((Code.Constant) code).value() != null) {
77
                throw new ExpressionRuntimeException("Tupple or null expected in argument " + argn + " of function '" + this.name() + "'.");
78
            }
79
            return null;
80
        }
81
        if (code.code() != Code.CALLABLE) {
82
            throw new ExpressionRuntimeException("Tupple or null expected in argument " + argn + " of function '" + this.name() + "'.");
83
        }
84
        Callable caller = (Callable) code;
85
        if (!StringUtils.equalsIgnoreCase(FUNCTION_TUPLE, caller.name())) {
86
            throw new ExpressionRuntimeException("Tupple or null expected in argument " + argn + " of function '" + this.name() + "'.");
87
        }
88
        return caller;
89
    }
90

    
91
    protected Code removeOuterTablesReferences(Interpreter interpreter, Code where, FeatureType currentType) {
92
        try {
93
            SymbolTable symbolTable = interpreter.getSymbolTable();
94
            TableAttributeHandler table = (TableAttributeHandler) symbolTable.value(SYMBOL_CURRENT_TABLE);
95
            List<Pair<Code, Code>> replaces = new ArrayList<>();
96
            CodeBuilder codeBuilder = ExpressionUtils.createCodeBuilder();
97
            final Set<Code> replacesToASkip = new HashSet<>();
98
            Code where2 = where.clone();
99
            where2.accept((Object o) -> {
100
                if (o == null) {
101
                    return;
102
                }
103
                Code code = (Code) o;
104
                switch (code.code()) {
105
                    case Code.CALLABLE:
106
                        Code.Callable caller = (Code.Callable) code;
107
                        if (StringUtils.equalsIgnoreCase(caller.name(), FUNCTION_GETATTR)) {
108
                            Codes args = caller.parameters();
109
                            Code arg0 = args.get(0);
110
                            Code arg1 = args.get(1);
111
                            replacesToASkip.add(arg1);
112
                            if (arg0 instanceof Code.Identifier && arg1 instanceof Code.Constant) {
113
                                Object tt = symbolTable.value(((Code.Identifier) arg0).name());
114
                                if (tt instanceof TableAttributeHandler
115
                                        && StringUtils.equalsIgnoreCase(((TableAttributeHandler) tt).getName(), table.getName())) {
116
                                    String columnName = Objects.toString(((Code.Constant) arg1).value(), null);
117
                                    if (columnName != null) {
118
                                        Object value = table.get(columnName);
119
                                        replaces.add(
120
                                                new ImmutablePair<>(
121
                                                        caller,
122
                                                        codeBuilder.constant(value)
123
                                                )
124
                                        );
125
                                    }
126
                                }
127
                            }
128
                        }
129
                        break;
130
                }
131
            });
132
            where2.accept((Object o) -> {
133
                if (o == null) {
134
                    return;
135
                }
136
                Code code = (Code) o;
137
                if (replacesToASkip.contains(code)) {
138
                    return;
139
                }
140
                switch (code.code()) {
141
                    case Code.IDENTIFIER:
142
                        Code.Identifier id = (Code.Identifier) code;
143
                        if (currentType.getAttributeDescriptor(id.name()) == null && symbolTable.exists(id.name())) {
144
                            Object value = symbolTable.value(id.name());
145
                            replaces.add(
146
                                    new ImmutablePair<>(
147
                                            id,
148
                                            codeBuilder.constant(value)
149
                                    )
150
                            );
151
                        }
152
                        break;
153
                }
154
            });
155
            if (replaces.isEmpty()) {
156
                return where;
157
            }
158
            for (Pair<Code, Code> replace : replaces) {
159
                if (replace != null) {
160
                    where2.replace(replace.getLeft(), replace.getRight());
161
                }
162
            }
163
            return where2;
164
        } catch (Exception ex) {
165
            throw new ExpressionRuntimeException("Can't remove references to outer tables.", ex);
166
        }
167
    }
168

    
169
    protected Code replaceLocalVariables(Interpreter interpreter, Code expression, FeatureType currentType) {
170
        try {
171
            SymbolTable symbolTable = interpreter.getSymbolTable();
172
            TableAttributeHandler table = (TableAttributeHandler) symbolTable.value(SYMBOL_CURRENT_TABLE);
173
            List<Pair<Code, Code>> replaces = new ArrayList<>();
174
            CodeBuilder codeBuilder = ExpressionUtils.createCodeBuilder();
175
            Code expression2 = expression.clone();
176
            expression2.accept((Object o) -> {
177
                if (o == null) {
178
                    return;
179
                }
180
                Code code = (Code) o;
181
                switch (code.code()) {
182
                    case Code.IDENTIFIER:
183
                        Code.Identifier id = (Code.Identifier) code;
184
                        if (currentType.getAttributeDescriptor(id.name()) == null && symbolTable.exists(id.name())) {
185
                            Object value = symbolTable.value(id.name());
186
                            replaces.add(
187
                                    new ImmutablePair<>(
188
                                            id,
189
                                            codeBuilder.constant(value)
190
                                    )
191
                            );
192
                        }
193
                        break;
194
                }
195
            });
196
            if (replaces.isEmpty()) {
197
                return expression;
198
            }
199
            for (Pair<Code, Code> replace : replaces) {
200
                if (replace != null) {
201
                    expression2.replace(replace.getLeft(), replace.getRight());
202
                }
203
            }
204
            return expression2;
205
        } catch (Exception ex) {
206
            throw new ExpressionRuntimeException("Can't remove references to outer tables.", ex);
207
        }
208
    }
209

    
210
    protected DataStore getStore(String storeName) {
211
        DataManager dataManager = DALLocator.getDataManager();
212
        DataStore store = dataManager.getStoresRepository().getStore(storeName);
213
        return store;
214
    }
215

    
216
    protected FeatureStore getFeatureStore(String storeName) {
217
        DataManager dataManager = DALLocator.getDataManager();
218
        DataStore store = dataManager.getStoresRepository().getStore(storeName);
219
        if (store instanceof FeatureStore) {
220
            return (FeatureStore) store;
221
        }
222
        return null;
223
    }
224

    
225
    protected boolean isHostExpression(Code code) {
226
        if( code.code()!=Code.CALLABLE ) {
227
            return false;
228
        }
229
        return StringUtils.equalsIgnoreCase(FUNCTION_$HOSTEXPRESSION, ((Callable)code).name());
230
    }
231
}