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

History | View | Annotate | Download (8.07 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
import org.gvsig.fmap.dal.feature.FeatureType;
30

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

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

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

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

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

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

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

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

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

    
180
}