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

History | View | Annotate | Download (7.94 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_GETATTR;
17
import static org.gvsig.expressionevaluator.ExpressionBuilder.FUNCTION_TUPLE;
18
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
19
import org.gvsig.expressionevaluator.ExpressionUtils;
20
import org.gvsig.expressionevaluator.Interpreter;
21
import org.gvsig.expressionevaluator.SymbolTable;
22
import org.gvsig.expressionevaluator.spi.AbstractFunction;
23
import org.gvsig.fmap.dal.DALLocator;
24
import org.gvsig.fmap.dal.DataManager;
25
import org.gvsig.fmap.dal.DataStore;
26
import static org.gvsig.fmap.dal.expressionevaluator.FeatureSymbolTable.SYMBOL_CURRENT_TABLE;
27
import org.gvsig.fmap.dal.expressionevaluator.TableAttributeHandler;
28
import org.gvsig.fmap.dal.feature.FeatureStore;
29

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

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

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

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

    
58
    protected Code getWhereCode(Codes args, int argn) {
59
        Code where = args.get(argn);
60
        if (where.code() == Code.CONSTANT) {
61
            if (((Code.Constant) where).value() == null) {
62
                where = null;
63
            }
64
        }
65
        return where;
66
    }
67

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

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

    
164
    protected DataStore getStore(String storeName) {
165
        DataManager dataManager = DALLocator.getDataManager();
166
        DataStore store = dataManager.getStoresRepository().getStore(storeName);
167
        return store;
168
    }
169

    
170
    protected FeatureStore getFeatureStore(String storeName) {
171
        DataManager dataManager = DALLocator.getDataManager();
172
        DataStore store = dataManager.getStoresRepository().getStore(storeName);
173
        if (store instanceof FeatureStore) {
174
            return (FeatureStore) store;
175
        }
176
        return null;
177
    }
178

    
179
}