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 / feature / impl / DefaultFeatureQuery.java @ 46970
History | View | Annotate | Download (38.6 KB)
1 | 40559 | jjdelcerro | /**
|
---|---|---|---|
2 | * gvSIG. Desktop Geographic Information System.
|
||
3 | 40435 | jjdelcerro | *
|
4 | 40559 | jjdelcerro | * Copyright (C) 2007-2013 gvSIG Association.
|
5 | 40435 | jjdelcerro | *
|
6 | * This program is free software; you can redistribute it and/or
|
||
7 | * modify it under the terms of the GNU General Public License
|
||
8 | 40559 | jjdelcerro | * as published by the Free Software Foundation; either version 3
|
9 | 40435 | jjdelcerro | * of the License, or (at your option) any later version.
|
10 | *
|
||
11 | * This program is distributed in the hope that it will be useful,
|
||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
14 | * GNU General Public License for more details.
|
||
15 | *
|
||
16 | * You should have received a copy of the GNU General Public License
|
||
17 | * along with this program; if not, write to the Free Software
|
||
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||
19 | * MA 02110-1301, USA.
|
||
20 | *
|
||
21 | 40559 | jjdelcerro | * For any additional information, do not hesitate to contact us
|
22 | * at info AT gvsig.com, or visit our website www.gvsig.com.
|
||
23 | 40435 | jjdelcerro | */
|
24 | package org.gvsig.fmap.dal.feature.impl; |
||
25 | |||
26 | import java.util.ArrayList; |
||
27 | 46970 | jjdelcerro | import java.util.Arrays; |
28 | import java.util.Collection; |
||
29 | 40435 | jjdelcerro | import java.util.HashMap; |
30 | 46540 | fdiaz | import java.util.Iterator; |
31 | 40435 | jjdelcerro | import java.util.List; |
32 | import java.util.Map; |
||
33 | 46970 | jjdelcerro | import javax.json.JsonObject; |
34 | 43358 | jjdelcerro | import org.apache.commons.lang3.ArrayUtils; |
35 | 43913 | jjdelcerro | import org.apache.commons.lang3.StringUtils; |
36 | 44023 | jjdelcerro | import org.gvsig.expressionevaluator.Expression; |
37 | 44712 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionUtils; |
38 | 44829 | omartinez | import org.gvsig.fmap.dal.DALLocator; |
39 | import org.gvsig.fmap.dal.DataManager; |
||
40 | 43358 | jjdelcerro | import org.gvsig.fmap.dal.DataTypes; |
41 | import org.gvsig.fmap.dal.exception.DataException; |
||
42 | 44829 | omartinez | import org.gvsig.fmap.dal.exception.InitializeException; |
43 | 45366 | omartinez | import org.gvsig.expressionevaluator.ExpressionEvaluator; |
44 | 46010 | jjdelcerro | import org.gvsig.expressionevaluator.MutableSymbolTable; |
45 | 43358 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
46 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureQuery; |
47 | import org.gvsig.fmap.dal.feature.FeatureQueryOrder; |
||
48 | 43358 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureStore; |
49 | 40435 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureType; |
50 | 45366 | omartinez | import org.gvsig.fmap.dal.impl.expressionevaluator.DefaultFeatureExpressionEvaluator; |
51 | 40435 | jjdelcerro | import org.gvsig.tools.ToolsLocator; |
52 | import org.gvsig.tools.dynobject.DynStruct; |
||
53 | import org.gvsig.tools.evaluator.AndEvaluator; |
||
54 | import org.gvsig.tools.evaluator.Evaluator; |
||
55 | import org.gvsig.tools.evaluator.EvaluatorFieldsInfo; |
||
56 | import org.gvsig.tools.persistence.PersistentState; |
||
57 | import org.gvsig.tools.persistence.exception.PersistenceException; |
||
58 | 44829 | omartinez | import org.slf4j.Logger; |
59 | import org.slf4j.LoggerFactory; |
||
60 | import org.gvsig.fmap.dal.feature.FeatureExtraColumns; |
||
61 | 46970 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureRuleExpression; |
62 | import org.gvsig.json.Json; |
||
63 | import org.gvsig.json.JsonArrayBuilder; |
||
64 | import org.gvsig.json.JsonObjectBuilder; |
||
65 | import org.gvsig.json.SupportJson; |
||
66 | import org.gvsig.json.SupportToJson; |
||
67 | 46907 | fdiaz | import org.gvsig.tools.packageutils.Version; |
68 | import org.gvsig.tools.packageutils.impl.DefaultVersion; |
||
69 | 40435 | jjdelcerro | |
70 | /**
|
||
71 | * Defines the properties of a collection of Features, as a result of a query
|
||
72 | * through a FeatureStore.
|
||
73 | * <p>
|
||
74 | * A FeatureQuery is always defined by a FeatureType, or by the list of
|
||
75 | * attribute names of the FeatureStore to return.
|
||
76 | * </p>
|
||
77 | * <p>
|
||
78 | * The filter allows to select Features whose properties have values with the
|
||
79 | * characteristics defined by the filter.
|
||
80 | * </p>
|
||
81 | * <p>
|
||
82 | * The order is used to set the order of the result FeatureCollection, based on
|
||
83 | * the values of the properties of the Features.
|
||
84 | * </p>
|
||
85 | * <p>
|
||
86 | * The scale parameter can be used by the FeatureStore as a hint about the
|
||
87 | * quality or resolution of the data needed to view or operate with the data
|
||
88 | * returned. As an example, the FeatureStore may use the scale to return only a
|
||
89 | * representative subset of the data, or maybe to return Features with less
|
||
90 | * detail, like a point or a line instead of a polygon.
|
||
91 | * </p>
|
||
92 | * <p>
|
||
93 | * If an implementation of FeatureStore is able to get other parameters to
|
||
94 | * customize the behavior of the getDataCollection methods, there is an option
|
||
95 | * to set more parameters through the setAttribute method.
|
||
96 | * </p>
|
||
97 | 42975 | jjdelcerro | *
|
98 | 40435 | jjdelcerro | * @author 2009- <a href="cordinyana@gvsig.org">C?sar Ordi?ana</a> - gvSIG team
|
99 | */
|
||
100 | public class DefaultFeatureQuery implements FeatureQuery { |
||
101 | 44829 | omartinez | |
102 | private static final Logger LOGGER = LoggerFactory.getLogger(DefaultFeatureQuery.class); |
||
103 | 40435 | jjdelcerro | |
104 | public static final String SCALE_PARAM_NAME = "Scale"; |
||
105 | 46907 | fdiaz | |
106 | private static final Version VERSION_2_6_0 = ToolsLocator.getPackageManager().createVersion("2.6.0"); |
||
107 | 40435 | jjdelcerro | |
108 | 44712 | jjdelcerro | private Map<String,Object> queryParameters = new HashMap(); |
109 | 40435 | jjdelcerro | |
110 | private String featureTypeId = null; |
||
111 | |||
112 | 44712 | jjdelcerro | private List<String> attributeNames = new ArrayList(); |
113 | 40435 | jjdelcerro | |
114 | 44712 | jjdelcerro | private List<String> constantsAttributeNames = new ArrayList(); |
115 | 41212 | jjdelcerro | |
116 | 40435 | jjdelcerro | private Evaluator filter;
|
117 | |||
118 | 45308 | fdiaz | private FeatureQueryOrder order = new DefaultFeatureQueryOrder(); |
119 | 40435 | jjdelcerro | |
120 | private long limit; |
||
121 | |||
122 | private long pageSize; |
||
123 | |||
124 | 44712 | jjdelcerro | private List<String> groupByColumns; |
125 | |||
126 | private Map<String,String> aggregateFunctions; |
||
127 | |||
128 | 46501 | jjdelcerro | private FeatureExtraColumns extraColumns = new DefaultFeatureExtraColumns(); |
129 | 44754 | omartinez | |
130 | 46010 | jjdelcerro | private MutableSymbolTable symbolTable;
|
131 | |||
132 | 46163 | jjdelcerro | private String storeName; |
133 | |||
134 | private boolean useSubquery; |
||
135 | |||
136 | 40435 | jjdelcerro | /**
|
137 | * Creates a FeatureQuery which will load all available Features of a type.
|
||
138 | 42975 | jjdelcerro | *
|
139 | 40435 | jjdelcerro | */
|
140 | public DefaultFeatureQuery() {
|
||
141 | 46163 | jjdelcerro | super();
|
142 | this.useSubquery = true; // true for backwards compatibility. |
||
143 | 46456 | jjdelcerro | this.limit = NO_LIMIT;
|
144 | 46748 | jjdelcerro | this.pageSize = 0; |
145 | 46163 | jjdelcerro | } |
146 | 46078 | omartinez | |
147 | public DefaultFeatureQuery(String storeName) { |
||
148 | this();
|
||
149 | 46163 | jjdelcerro | this.storeName = storeName;
|
150 | 46078 | omartinez | |
151 | 40435 | jjdelcerro | } |
152 | |||
153 | /**
|
||
154 | * Creates a FeatureQuery which will load all available Features of a type.
|
||
155 | 42975 | jjdelcerro | *
|
156 | 40435 | jjdelcerro | * @param featureType
|
157 | * the type of Features of the query
|
||
158 | */
|
||
159 | public DefaultFeatureQuery(FeatureType featureType) {
|
||
160 | 46163 | jjdelcerro | this();
|
161 | 40435 | jjdelcerro | this.setFeatureType(featureType);
|
162 | } |
||
163 | |||
164 | /**
|
||
165 | * Creates a FeatureQuery with the type of features, a filter and the order
|
||
166 | * for the FeatureCollection.
|
||
167 | 42975 | jjdelcerro | *
|
168 | 40435 | jjdelcerro | * @param featureType
|
169 | * the type of Features of the query
|
||
170 | * @param filter
|
||
171 | * based on the properties of the Features
|
||
172 | */
|
||
173 | public DefaultFeatureQuery(FeatureType featureType, Evaluator filter) {
|
||
174 | 46163 | jjdelcerro | this();
|
175 | 40435 | jjdelcerro | this.setFeatureType(featureType);
|
176 | this.filter = filter;
|
||
177 | } |
||
178 | |||
179 | /**
|
||
180 | * Creates a FeatureQuery with the type of features, a filter, the order for
|
||
181 | * the FeatureCollection and the view scale.
|
||
182 | 42975 | jjdelcerro | *
|
183 | 40435 | jjdelcerro | * @param featureType
|
184 | * the type of Features of the query
|
||
185 | * @param filter
|
||
186 | * based on the properties of the Features
|
||
187 | * @param scale
|
||
188 | * to view the Features.
|
||
189 | */
|
||
190 | public DefaultFeatureQuery(FeatureType featureType, Evaluator filter,
|
||
191 | double scale) {
|
||
192 | 46163 | jjdelcerro | this();
|
193 | 40435 | jjdelcerro | this.setFeatureType(featureType);
|
194 | this.filter = filter;
|
||
195 | this.setScale(scale);
|
||
196 | } |
||
197 | |||
198 | /**
|
||
199 | * Creates a FeatureQuery which will load a list of attribute names of all
|
||
200 | * available Features.
|
||
201 | 42975 | jjdelcerro | *
|
202 | 40435 | jjdelcerro | * @param attributeNames
|
203 | * the list of attribute names to load
|
||
204 | */
|
||
205 | public DefaultFeatureQuery(String[] attributeNames) { |
||
206 | 46163 | jjdelcerro | this();
|
207 | 40435 | jjdelcerro | setAttributeNames(attributeNames); |
208 | } |
||
209 | |||
210 | /**
|
||
211 | * Creates a FeatureQuery with the list of attribute names of feature, a
|
||
212 | * filter and the order for the FeatureCollection.
|
||
213 | 42975 | jjdelcerro | *
|
214 | 40435 | jjdelcerro | * @param attributeNames
|
215 | * the list of attribute names to load
|
||
216 | * @param filter
|
||
217 | * based on the properties of the Features
|
||
218 | */
|
||
219 | public DefaultFeatureQuery(String[] attributeNames, Evaluator filter) { |
||
220 | 46163 | jjdelcerro | this();
|
221 | 40435 | jjdelcerro | setAttributeNames(attributeNames); |
222 | this.filter = filter;
|
||
223 | } |
||
224 | |||
225 | /**
|
||
226 | * Creates a FeatureQuery with the list of attribute names of feature, a
|
||
227 | * filter, the order for the FeatureCollection and the view scale.
|
||
228 | 42975 | jjdelcerro | *
|
229 | 40435 | jjdelcerro | * @param attributeNames
|
230 | * the list of attribute names to load
|
||
231 | * @param filter
|
||
232 | * based on the properties of the Features
|
||
233 | * @param scale
|
||
234 | * to view the Features.
|
||
235 | */
|
||
236 | public DefaultFeatureQuery(String[] attributeNames, Evaluator filter, |
||
237 | double scale) {
|
||
238 | 46163 | jjdelcerro | this();
|
239 | 40435 | jjdelcerro | setAttributeNames(attributeNames); |
240 | this.filter = filter;
|
||
241 | this.setScale(scale);
|
||
242 | } |
||
243 | |||
244 | 43358 | jjdelcerro | @Override
|
245 | 40435 | jjdelcerro | public double getScale() { |
246 | Double scale = (Double) this.getQueryParameter(SCALE_PARAM_NAME); |
||
247 | if (scale == null) { |
||
248 | return 0; |
||
249 | } |
||
250 | 43358 | jjdelcerro | return scale;
|
251 | 40435 | jjdelcerro | } |
252 | |||
253 | 43358 | jjdelcerro | @Override
|
254 | 46970 | jjdelcerro | public final void setScale(double scale) { |
255 | 43358 | jjdelcerro | this.setQueryParameter(SCALE_PARAM_NAME, scale);
|
256 | 40435 | jjdelcerro | } |
257 | |||
258 | 43358 | jjdelcerro | @Override
|
259 | 40435 | jjdelcerro | public Object getQueryParameter(String name) { |
260 | return queryParameters.get(name);
|
||
261 | } |
||
262 | |||
263 | 43358 | jjdelcerro | @Override
|
264 | 40435 | jjdelcerro | public void setQueryParameter(String name, Object value) { |
265 | queryParameters.put(name, value); |
||
266 | } |
||
267 | |||
268 | 43358 | jjdelcerro | @Override
|
269 | 46970 | jjdelcerro | public final void setFeatureType(FeatureType featureType) { |
270 | 40435 | jjdelcerro | this.featureTypeId = featureType.getId();
|
271 | } |
||
272 | |||
273 | 43358 | jjdelcerro | @Override
|
274 | 40435 | jjdelcerro | public String[] getAttributeNames() { |
275 | 45271 | omartinez | if (this.hasExtraColumnDeclaredAsGroupByField()) { |
276 | this.retrievesAllAttributes();
|
||
277 | } |
||
278 | 40435 | jjdelcerro | return (String[])attributeNames.toArray(new String[attributeNames.size()]); |
279 | } |
||
280 | 45271 | omartinez | |
281 | private boolean hasExtraColumnDeclaredAsGroupByField() { |
||
282 | // indica si un campo de agrupaciones es una columna calculada
|
||
283 | if (this.hasGroupByColumns()) { |
||
284 | for (String groupByColumn : groupByColumns) { |
||
285 | 46501 | jjdelcerro | if (this.extraColumns.get(groupByColumn)!=null) { |
286 | 45271 | omartinez | return true; |
287 | } |
||
288 | } |
||
289 | } |
||
290 | return false; |
||
291 | } |
||
292 | 40435 | jjdelcerro | |
293 | 43358 | jjdelcerro | @Override
|
294 | 46970 | jjdelcerro | public final void setAttributeNames(String[] attributeNames) { |
295 | 40435 | jjdelcerro | this.attributeNames.clear();
|
296 | if (attributeNames != null){ |
||
297 | 46970 | jjdelcerro | this.attributeNames.addAll(Arrays.asList(attributeNames)); |
298 | 40435 | jjdelcerro | } |
299 | } |
||
300 | 42975 | jjdelcerro | |
301 | 43358 | jjdelcerro | @Override
|
302 | 43558 | jjdelcerro | public void retrievesAllAttributes() { |
303 | this.attributeNames.clear();
|
||
304 | } |
||
305 | |||
306 | @Override
|
||
307 | 40435 | jjdelcerro | public void addAttributeName(String attributeName){ |
308 | //If the attribute exists finish the method
|
||
309 | for (int i=0 ; i<attributeNames.size() ; i++){ |
||
310 | if (attributeNames.get(i).equals(attributeName)){
|
||
311 | return;
|
||
312 | 42975 | jjdelcerro | } |
313 | } |
||
314 | 40435 | jjdelcerro | this.attributeNames.add(attributeName);
|
315 | } |
||
316 | |||
317 | 43358 | jjdelcerro | @Override
|
318 | public void addEssentialAttributeNames(FeatureStore store) { |
||
319 | FeatureType storeType; |
||
320 | try {
|
||
321 | storeType = store.getDefaultFeatureType(); |
||
322 | } catch (DataException ex) {
|
||
323 | throw new RuntimeException("Can't access to the default feature type of tghe store", ex); |
||
324 | } |
||
325 | FeatureAttributeDescriptor[] pks = storeType.getPrimaryKey();
|
||
326 | if( storeType.hasOID() || ArrayUtils.isEmpty(pks) ) {
|
||
327 | FeatureAttributeDescriptor attrInt = null;
|
||
328 | FeatureAttributeDescriptor attrStr = null;
|
||
329 | FeatureAttributeDescriptor attrNotGeom = null;
|
||
330 | for (FeatureAttributeDescriptor attr : storeType) {
|
||
331 | if( attrInt == null && (attr.getType()==DataTypes.INT || attr.getType()==DataTypes.LONG) ) { |
||
332 | attrInt = attr; |
||
333 | } else if( attrStr == null && attr.getType()==DataTypes.STRING ) { |
||
334 | attrStr = attr; |
||
335 | } else if( attrNotGeom == null && attr.getType()!=DataTypes.GEOMETRY ) { |
||
336 | attrNotGeom = attr; |
||
337 | } |
||
338 | } |
||
339 | if( attrInt != null ) { |
||
340 | this.addAttributeName(attrInt.getName());
|
||
341 | } else if( attrStr != null ) { |
||
342 | this.addAttributeName(attrStr.getName());
|
||
343 | } else if( attrNotGeom != null ) { |
||
344 | this.addAttributeName(attrNotGeom.getName());
|
||
345 | } else {
|
||
346 | this.addAttributeName(storeType.getAttributeDescriptor(0).getName()); |
||
347 | } |
||
348 | } else {
|
||
349 | for(FeatureAttributeDescriptor attr : pks ) {
|
||
350 | this.addAttributeName(attr.getName());
|
||
351 | } |
||
352 | } |
||
353 | } |
||
354 | |||
355 | @Override
|
||
356 | public void addPrimaryKeyAttributeNames(FeatureStore store) { |
||
357 | FeatureType storeType; |
||
358 | try {
|
||
359 | storeType = store.getDefaultFeatureType(); |
||
360 | } catch (DataException ex) {
|
||
361 | throw new RuntimeException("Can't access to the default feature type of tghe store", ex); |
||
362 | } |
||
363 | for(FeatureAttributeDescriptor attr : storeType.getPrimaryKey() ) {
|
||
364 | this.addAttributeName(attr.getName());
|
||
365 | } |
||
366 | } |
||
367 | |||
368 | @Override
|
||
369 | 41212 | jjdelcerro | public boolean hasAttributeNames() { |
370 | 45271 | omartinez | if (hasExtraColumnDeclaredAsGroupByField()) {
|
371 | return true; |
||
372 | } |
||
373 | 41212 | jjdelcerro | return !this.attributeNames.isEmpty(); |
374 | } |
||
375 | |||
376 | 43358 | jjdelcerro | @Override
|
377 | 41212 | jjdelcerro | public void clearAttributeNames() { |
378 | this.attributeNames = new ArrayList(); |
||
379 | } |
||
380 | |||
381 | 43358 | jjdelcerro | @Override
|
382 | 40435 | jjdelcerro | public Evaluator getFilter() {
|
383 | 46010 | jjdelcerro | if( this.filter instanceof ExpressionEvaluator ) { |
384 | 46748 | jjdelcerro | ExpressionEvaluator eefilter = (ExpressionEvaluator) this.filter;
|
385 | if( symbolTable != null ) { |
||
386 | eefilter.addSymbolTable(symbolTable); |
||
387 | } |
||
388 | 46010 | jjdelcerro | } |
389 | return filter;
|
||
390 | 40435 | jjdelcerro | } |
391 | 42975 | jjdelcerro | |
392 | 42971 | jjdelcerro | @Override
|
393 | 44712 | jjdelcerro | public Expression getExpressionFilter() { |
394 | if( this.filter instanceof ExpressionEvaluator ) { |
||
395 | 46748 | jjdelcerro | ExpressionEvaluator eefilter = (ExpressionEvaluator) this.filter;
|
396 | if( symbolTable != null ) { |
||
397 | eefilter.addSymbolTable(symbolTable); |
||
398 | } |
||
399 | return eefilter.toExpression();
|
||
400 | 44712 | jjdelcerro | } |
401 | return null; |
||
402 | } |
||
403 | |||
404 | @Override
|
||
405 | 44023 | jjdelcerro | public void setFilter(Expression filter) { |
406 | 44259 | jjdelcerro | if( filter == null ) { |
407 | this.clearFilter();
|
||
408 | return;
|
||
409 | } |
||
410 | 46078 | omartinez | Evaluator x = new DefaultFeatureExpressionEvaluator(storeName, filter);
|
411 | 44023 | jjdelcerro | this.setFilter(x);
|
412 | } |
||
413 | |||
414 | @Override
|
||
415 | 42971 | jjdelcerro | public void setFilter(String filter) { |
416 | 43913 | jjdelcerro | if( StringUtils.isEmpty(filter) ) {
|
417 | this.clearFilter();
|
||
418 | return;
|
||
419 | } |
||
420 | 42971 | jjdelcerro | try {
|
421 | 44712 | jjdelcerro | this.setFilter(ExpressionUtils.createExpression(filter));
|
422 | 42971 | jjdelcerro | } catch (Exception ex) { |
423 | throw new RuntimeException("Can't create filter from '"+filter+"'",ex); |
||
424 | } |
||
425 | } |
||
426 | 40435 | jjdelcerro | |
427 | 43358 | jjdelcerro | @Override
|
428 | 40435 | jjdelcerro | public void setFilter(Evaluator filter) { |
429 | 43913 | jjdelcerro | if( filter == null ) { |
430 | this.clearFilter();
|
||
431 | return;
|
||
432 | } |
||
433 | 40435 | jjdelcerro | this.filter = filter;
|
434 | addFilterAttributes(filter); |
||
435 | } |
||
436 | |||
437 | 42795 | jjdelcerro | @Override
|
438 | 42971 | jjdelcerro | public void addFilter(String filter) { |
439 | 43913 | jjdelcerro | if( StringUtils.isEmpty(filter) ) {
|
440 | return;
|
||
441 | } |
||
442 | 44712 | jjdelcerro | this.addFilter(ExpressionUtils.createExpression(filter));
|
443 | 42971 | jjdelcerro | } |
444 | 42975 | jjdelcerro | |
445 | 42971 | jjdelcerro | @Override
|
446 | 44023 | jjdelcerro | public void addFilter(Expression filter) { |
447 | 45366 | omartinez | Evaluator x = new DefaultFeatureExpressionEvaluator(filter);
|
448 | 44023 | jjdelcerro | this.addFilter(x);
|
449 | } |
||
450 | |||
451 | @Override
|
||
452 | 40435 | jjdelcerro | public void addFilter(Evaluator evaluator) { |
453 | 43913 | jjdelcerro | if (evaluator == null) { |
454 | 42795 | jjdelcerro | return;
|
455 | } |
||
456 | 43913 | jjdelcerro | if (this.filter == null) { |
457 | this.filter = evaluator;
|
||
458 | } else {
|
||
459 | if (this.filter instanceof AndEvaluator) { |
||
460 | ((AndEvaluator) this.filter).addEvaluator(evaluator);
|
||
461 | } else {
|
||
462 | this.filter = new AndEvaluator(this.filter); |
||
463 | ((AndEvaluator) this.filter).addEvaluator(evaluator);
|
||
464 | 40435 | jjdelcerro | } |
465 | 43913 | jjdelcerro | } |
466 | 40435 | jjdelcerro | addFilterAttributes(evaluator); |
467 | } |
||
468 | 42975 | jjdelcerro | |
469 | 43358 | jjdelcerro | @Override
|
470 | 42975 | jjdelcerro | public void clearFilter() { |
471 | this.filter = null; |
||
472 | } |
||
473 | |||
474 | 40435 | jjdelcerro | private void addFilterAttributes(Evaluator evaluator){ |
475 | if (evaluator != null){ |
||
476 | EvaluatorFieldsInfo fieldsInfo = evaluator.getFieldsInfo(); |
||
477 | if (fieldsInfo == null){ |
||
478 | // FieldsInfo is not available in this evaluator
|
||
479 | return;
|
||
480 | } |
||
481 | String[] fieldNames = fieldsInfo.getFieldNames(); |
||
482 | if (fieldNames== null){ |
||
483 | // fieldNames is not available in this evaluator
|
||
484 | return;
|
||
485 | } |
||
486 | 42975 | jjdelcerro | |
487 | 46970 | jjdelcerro | for (String fieldName : fieldNames) { |
488 | addAttributeName(fieldName); |
||
489 | 40435 | jjdelcerro | } |
490 | } |
||
491 | } |
||
492 | |||
493 | 43358 | jjdelcerro | @Override
|
494 | 40435 | jjdelcerro | public FeatureQueryOrder getOrder() {
|
495 | return order;
|
||
496 | } |
||
497 | |||
498 | 43358 | jjdelcerro | @Override
|
499 | 40435 | jjdelcerro | public void setOrder(FeatureQueryOrder order) { |
500 | 45308 | fdiaz | if(order == null){ |
501 | this.order = new DefaultFeatureQueryOrder(); |
||
502 | } else {
|
||
503 | this.order = order;
|
||
504 | } |
||
505 | 40435 | jjdelcerro | } |
506 | |||
507 | 43358 | jjdelcerro | @Override
|
508 | 40435 | jjdelcerro | public boolean hasFilter() { |
509 | return this.filter != null; |
||
510 | } |
||
511 | |||
512 | 43358 | jjdelcerro | @Override
|
513 | 46277 | jjdelcerro | public boolean hasLimit() { |
514 | 46456 | jjdelcerro | return this.limit != NO_LIMIT; |
515 | 46277 | jjdelcerro | } |
516 | |||
517 | @Override
|
||
518 | 40435 | jjdelcerro | public boolean hasOrder() { |
519 | return this.order != null && this.order.size() > 0; |
||
520 | } |
||
521 | |||
522 | 43358 | jjdelcerro | @Override
|
523 | 40435 | jjdelcerro | public Object clone() throws CloneNotSupportedException { |
524 | DefaultFeatureQuery clone = (DefaultFeatureQuery) super.clone();
|
||
525 | |||
526 | // Clone attribute names array
|
||
527 | if (attributeNames != null) { |
||
528 | clone.attributeNames = new ArrayList(); |
||
529 | for (int i=0 ; i<attributeNames.size() ; i++){ |
||
530 | clone.attributeNames.add(attributeNames.get(i)); |
||
531 | 42975 | jjdelcerro | } |
532 | 40435 | jjdelcerro | } |
533 | |||
534 | // Clone order
|
||
535 | if (order != null) { |
||
536 | clone.order = (FeatureQueryOrder) order.clone(); |
||
537 | } |
||
538 | 44801 | omartinez | |
539 | 46501 | jjdelcerro | clone.extraColumns = extraColumns.getCopy(); |
540 | 44829 | omartinez | |
541 | if( this.filter instanceof ExpressionEvaluator ) { |
||
542 | 45366 | omartinez | Expression exp = ((ExpressionEvaluator)this.filter).toExpression(); |
543 | clone.filter = new DefaultFeatureExpressionEvaluator(exp);
|
||
544 | 44829 | omartinez | } |
545 | 45269 | omartinez | |
546 | if (groupByColumns!=null) { |
||
547 | 46970 | jjdelcerro | clone.groupByColumns = new ArrayList<>(); |
548 | 45269 | omartinez | for (String value : groupByColumns) { |
549 | clone.groupByColumns.add(value); |
||
550 | } |
||
551 | } else {
|
||
552 | clone.groupByColumns = null;
|
||
553 | } |
||
554 | |||
555 | |||
556 | if (aggregateFunctions!=null) { |
||
557 | 46970 | jjdelcerro | clone.aggregateFunctions = new HashMap<>(); |
558 | 45269 | omartinez | for (String key : aggregateFunctions.keySet()) { |
559 | clone.aggregateFunctions.put(key, aggregateFunctions.get(key)); |
||
560 | } |
||
561 | } else {
|
||
562 | clone.aggregateFunctions = null;
|
||
563 | } |
||
564 | 46010 | jjdelcerro | if( this.symbolTable!=null ) { |
565 | clone.symbolTable = this.symbolTable.clone();
|
||
566 | } |
||
567 | 45269 | omartinez | |
568 | 40435 | jjdelcerro | return clone;
|
569 | } |
||
570 | |||
571 | 43358 | jjdelcerro | @Override
|
572 | 40435 | jjdelcerro | public FeatureQuery getCopy() {
|
573 | try {
|
||
574 | return (FeatureQuery) clone();
|
||
575 | } catch (CloneNotSupportedException e) { |
||
576 | 46010 | jjdelcerro | LOGGER.debug("Can't clone feature query",e);
|
577 | 40435 | jjdelcerro | return null; |
578 | } |
||
579 | // DefaultFeatureQuery aCopy = new DefaultFeatureQuery();
|
||
580 | //
|
||
581 | // aCopy.featureTypeId = this.featureTypeId;
|
||
582 | //
|
||
583 | // if (this.attributeNames != null) {
|
||
584 | // aCopy.attributeNames = (String[]) Arrays
|
||
585 | // .asList(this.attributeNames).toArray(new String[0]);
|
||
586 | // }
|
||
587 | //
|
||
588 | // aCopy.filter = this.filter;
|
||
589 | //
|
||
590 | // if (this.order != null) {
|
||
591 | // aCopy.order = this.order.getCopy();
|
||
592 | // }
|
||
593 | //
|
||
594 | // return aCopy;
|
||
595 | } |
||
596 | |||
597 | 43358 | jjdelcerro | @Override
|
598 | 40435 | jjdelcerro | public String getFeatureTypeId() { |
599 | return featureTypeId;
|
||
600 | } |
||
601 | |||
602 | 43358 | jjdelcerro | @Override
|
603 | 40435 | jjdelcerro | public void setFeatureTypeId(String featureTypeId) { |
604 | this.featureTypeId = featureTypeId;
|
||
605 | } |
||
606 | |||
607 | 43358 | jjdelcerro | @Override
|
608 | 40435 | jjdelcerro | public void saveToState(PersistentState state) throws PersistenceException { |
609 | // FIXME: falta por terminar de implementar
|
||
610 | 46907 | fdiaz | state.set("version", VERSION_2_6_0);
|
611 | 40435 | jjdelcerro | state.set("queryParameters", this.queryParameters); |
612 | state.set("featureTypeId", this.featureTypeId); |
||
613 | state.set("attributeNames", this.attributeNames); |
||
614 | 44829 | omartinez | |
615 | ArrayList<Expression> filterList = new ArrayList<>(); |
||
616 | 45366 | omartinez | if (this.filter instanceof DefaultFeatureExpressionEvaluator) { |
617 | DefaultFeatureExpressionEvaluator filterExpression = (DefaultFeatureExpressionEvaluator) this.filter;
|
||
618 | filterList.add(filterExpression.toExpression()); |
||
619 | 44829 | omartinez | } else if (this.filter instanceof AndEvaluator) { |
620 | AndEvaluator filterAnd = (AndEvaluator) this.filter;
|
||
621 | List<Evaluator> evaluators = filterAnd.getEvaluators();
|
||
622 | for (Evaluator evaluator : evaluators) {
|
||
623 | 45366 | omartinez | if (evaluator instanceof DefaultFeatureExpressionEvaluator) { |
624 | DefaultFeatureExpressionEvaluator expressionEvaluator = (DefaultFeatureExpressionEvaluator) evaluator; |
||
625 | filterList.add(expressionEvaluator.toExpression()); |
||
626 | 44829 | omartinez | } else {
|
627 | filterList.clear(); |
||
628 | LOGGER.warn(StringUtils.join("Filters in this FeatureQuery will not persist:", this.toString())); |
||
629 | break;
|
||
630 | } |
||
631 | } |
||
632 | } else {
|
||
633 | filterList.clear(); |
||
634 | 46262 | jjdelcerro | if( this.filter!=null ) { |
635 | LOGGER.warn(StringUtils.join("Filters in this FeatureQuery will not persist:", this.toString())); |
||
636 | } |
||
637 | 44829 | omartinez | } |
638 | |||
639 | state.set("filter", filterList);
|
||
640 | 40435 | jjdelcerro | state.set("limit", this.limit); |
641 | state.set("pageSize", this.pageSize); |
||
642 | 46163 | jjdelcerro | state.set("useSubquery", this.useSubquery); |
643 | 44829 | omartinez | |
644 | state.set("order", this.order); |
||
645 | state.set("groupByColumns", this.groupByColumns); |
||
646 | state.set("aggregateFunctions", this.aggregateFunctions); |
||
647 | 46501 | jjdelcerro | state.set("extraColumn", this.extraColumns); |
648 | 46262 | jjdelcerro | state.set("storeName", this.storeName); |
649 | 44829 | omartinez | |
650 | 40435 | jjdelcerro | |
651 | } |
||
652 | 44829 | omartinez | |
653 | 40435 | jjdelcerro | |
654 | 43358 | jjdelcerro | @Override
|
655 | 40435 | jjdelcerro | public void loadFromState(PersistentState state) throws PersistenceException { |
656 | // FIXME: falta por terminar de implementar
|
||
657 | 46907 | fdiaz | Version version = (Version) state.get("version");
|
658 | 40435 | jjdelcerro | this.queryParameters = (Map) state.get("queryParameters"); |
659 | this.featureTypeId = state.getString("featureTypeId"); |
||
660 | this.attributeNames = state.getList("attributeNames"); |
||
661 | 44829 | omartinez | List<Expression> filterList = state.getList("filter"); |
662 | String stateFilter = ""; |
||
663 | DataManager dataManager = DALLocator.getDataManager(); |
||
664 | 46970 | jjdelcerro | if (filterList.isEmpty()) {
|
665 | 44829 | omartinez | this.filter = null; |
666 | } else if (filterList.size() == 1) { |
||
667 | Expression expression = filterList.get(0); |
||
668 | Evaluator evaluator; |
||
669 | try {
|
||
670 | evaluator = dataManager.createFilter(expression); |
||
671 | } catch (InitializeException ex) {
|
||
672 | LOGGER.warn("Can't create evaluator", ex);
|
||
673 | evaluator = null;
|
||
674 | } |
||
675 | this.filter = evaluator;
|
||
676 | } else {
|
||
677 | AndEvaluator andEvaluator = null;
|
||
678 | for (Expression expression : filterList) { |
||
679 | Evaluator evaluator; |
||
680 | try {
|
||
681 | evaluator = dataManager.createFilter(expression); |
||
682 | |||
683 | if (andEvaluator == null) { |
||
684 | andEvaluator = new AndEvaluator(evaluator);
|
||
685 | } else {
|
||
686 | andEvaluator.addEvaluator(evaluator); |
||
687 | } |
||
688 | } catch (InitializeException ex) {
|
||
689 | LOGGER.warn("Can't create AndEvaluator", ex);//TODO evaluator a null |
||
690 | break;
|
||
691 | } |
||
692 | this.filter = evaluator;
|
||
693 | |||
694 | } |
||
695 | } |
||
696 | 40435 | jjdelcerro | this.limit = state.getLong("limit"); |
697 | 46907 | fdiaz | if(version == null || version.compareTo(VERSION_2_6_0)<0){ |
698 | if(this.limit == 0) { |
||
699 | this.clearLimit();
|
||
700 | } |
||
701 | } |
||
702 | 40435 | jjdelcerro | this.pageSize = state.getLong("pageSize"); |
703 | 46163 | jjdelcerro | this.useSubquery = state.getBoolean("useSubquery",true); |
704 | this.storeName = state.getString("storeName"); |
||
705 | 44829 | omartinez | |
706 | |||
707 | this.order = (FeatureQueryOrder) state.get("order"); |
||
708 | 45257 | omartinez | List asListGroupByColumns = (List) state.getList("groupByColumns"); |
709 | if (asListGroupByColumns!=null) { |
||
710 | this.groupByColumns = new ArrayList<>(asListGroupByColumns); |
||
711 | } else {
|
||
712 | this.groupByColumns = null; |
||
713 | } |
||
714 | Map asMapAggregateFunctions = (Map) state.getMap("aggregateFunctions"); |
||
715 | if (asMapAggregateFunctions!=null) { |
||
716 | this.aggregateFunctions = new HashMap<>(asMapAggregateFunctions); |
||
717 | } else {
|
||
718 | this.aggregateFunctions = null; |
||
719 | } |
||
720 | 46501 | jjdelcerro | this.extraColumns = (FeatureExtraColumns) state.get("extraColumn"); |
721 | 40435 | jjdelcerro | |
722 | 44829 | omartinez | |
723 | 40435 | jjdelcerro | } |
724 | |||
725 | 46970 | jjdelcerro | public static void selfRegister() { |
726 | registerPersistent(); |
||
727 | Json.registerSerializer(DefaultFeatureQuery.class); |
||
728 | } |
||
729 | |||
730 | 40435 | jjdelcerro | /**
|
731 | * Register the class on PersistenceManager
|
||
732 | 42975 | jjdelcerro | *
|
733 | 40435 | jjdelcerro | */
|
734 | 46970 | jjdelcerro | private static void registerPersistent() { |
735 | 40435 | jjdelcerro | DynStruct definition = |
736 | ToolsLocator.getPersistenceManager() |
||
737 | .addDefinition(DefaultFeatureQuery.class, |
||
738 | "DefaultFeatureQuery",
|
||
739 | "DefaultFeatureQuery Persistent definition",
|
||
740 | null,
|
||
741 | null);
|
||
742 | |||
743 | 46907 | fdiaz | |
744 | definition.addDynFieldObject("version")
|
||
745 | .setClassOfValue(DefaultVersion.class) |
||
746 | .setMandatory(false);
|
||
747 | |||
748 | 40435 | jjdelcerro | definition.addDynFieldMap("queryParameters")
|
749 | 44829 | omartinez | .setClassOfItems(Object.class)
|
750 | .setMandatory(true);
|
||
751 | 40435 | jjdelcerro | |
752 | definition.addDynFieldString("featureTypeId").setMandatory(false); |
||
753 | |||
754 | definition.addDynFieldList("attributeNames")
|
||
755 | 44829 | omartinez | .setClassOfItems(String.class)
|
756 | .setMandatory(false);
|
||
757 | 40435 | jjdelcerro | |
758 | 44829 | omartinez | definition.addDynFieldList("filter")
|
759 | .setClassOfItems(Expression.class)
|
||
760 | .setMandatory(false);
|
||
761 | 40435 | jjdelcerro | |
762 | definition.addDynFieldObject("order")
|
||
763 | 44829 | omartinez | .setClassOfValue(FeatureQueryOrder.class) |
764 | .setMandatory(false);
|
||
765 | 40435 | jjdelcerro | |
766 | definition.addDynFieldLong("limit").setMandatory(false); |
||
767 | |||
768 | definition.addDynFieldLong("pageSize").setMandatory(false); |
||
769 | 44829 | omartinez | |
770 | 46163 | jjdelcerro | definition.addDynFieldBoolean("useSubquery").setMandatory(false); |
771 | 44829 | omartinez | |
772 | definition.addDynFieldList("groupByColumns")
|
||
773 | .setClassOfItems(String.class);
|
||
774 | 40435 | jjdelcerro | |
775 | 44829 | omartinez | definition.addDynFieldMap("aggregateFunctions")
|
776 | .setClassOfItems(String.class)
|
||
777 | .setClassOfValue(String.class);
|
||
778 | |||
779 | definition.addDynFieldObject("extraColumn")
|
||
780 | .setClassOfValue(DefaultFeatureExtraColumns.class); |
||
781 | |||
782 | 46078 | omartinez | definition.addDynFieldString("storeName").setMandatory(false); |
783 | 44829 | omartinez | |
784 | 40435 | jjdelcerro | } |
785 | |||
786 | 43358 | jjdelcerro | @Override
|
787 | 40435 | jjdelcerro | public long getLimit() { |
788 | return limit;
|
||
789 | } |
||
790 | |||
791 | 43358 | jjdelcerro | @Override
|
792 | 40435 | jjdelcerro | public long getPageSize() { |
793 | return pageSize;
|
||
794 | } |
||
795 | |||
796 | 43358 | jjdelcerro | @Override
|
797 | 40435 | jjdelcerro | public void setLimit(long limit) { |
798 | this.limit = limit;
|
||
799 | } |
||
800 | |||
801 | 43358 | jjdelcerro | @Override
|
802 | 46456 | jjdelcerro | public void clearLimit() { |
803 | this.limit = NO_LIMIT;
|
||
804 | } |
||
805 | |||
806 | @Override
|
||
807 | 40435 | jjdelcerro | public void setPageSize(long pageSize) { |
808 | this.pageSize = pageSize;
|
||
809 | } |
||
810 | |||
811 | 43358 | jjdelcerro | @Override
|
812 | 41212 | jjdelcerro | public String[] getConstantsAttributeNames() { |
813 | return (String[])constantsAttributeNames.toArray(new String[constantsAttributeNames.size()]); |
||
814 | } |
||
815 | |||
816 | 43358 | jjdelcerro | @Override
|
817 | 41212 | jjdelcerro | public void setConstantsAttributeNames(String[] constantsAttributeNames) { |
818 | this.constantsAttributeNames.clear();
|
||
819 | if (constantsAttributeNames != null){ |
||
820 | 46970 | jjdelcerro | this.constantsAttributeNames.addAll(Arrays.asList(constantsAttributeNames)); |
821 | 41212 | jjdelcerro | } |
822 | } |
||
823 | 42975 | jjdelcerro | |
824 | 43358 | jjdelcerro | @Override
|
825 | 41212 | jjdelcerro | public void addConstantAttributeName(String attributeName) { |
826 | //If the attribute exists finish the method
|
||
827 | for (int i=0 ; i<constantsAttributeNames.size() ; i++){ |
||
828 | if (constantsAttributeNames.get(i).equals(attributeName)){
|
||
829 | return;
|
||
830 | 42975 | jjdelcerro | } |
831 | } |
||
832 | 41212 | jjdelcerro | this.constantsAttributeNames.add(attributeName);
|
833 | } |
||
834 | |||
835 | 43358 | jjdelcerro | @Override
|
836 | 41212 | jjdelcerro | public boolean hasConstantsAttributeNames() { |
837 | return !this.constantsAttributeNames.isEmpty(); |
||
838 | } |
||
839 | |||
840 | 43358 | jjdelcerro | @Override
|
841 | 41212 | jjdelcerro | public void clearConstantsAttributeNames() { |
842 | this.constantsAttributeNames = new ArrayList(); |
||
843 | } |
||
844 | |||
845 | 44712 | jjdelcerro | @Override
|
846 | 44727 | jjdelcerro | public boolean isAGroupByColumn(String name) { |
847 | 46248 | jjdelcerro | if( groupByColumns==null ) { |
848 | return false; |
||
849 | } |
||
850 | 44727 | jjdelcerro | for (String columnName : groupByColumns) { |
851 | if( StringUtils.equalsIgnoreCase(name, columnName) ) {
|
||
852 | return true; |
||
853 | } |
||
854 | } |
||
855 | return false; |
||
856 | } |
||
857 | |||
858 | @Override
|
||
859 | 44712 | jjdelcerro | public List<String> getGroupByColumns() { |
860 | if( this.groupByColumns == null ) { |
||
861 | this.groupByColumns = new ArrayList<>(); |
||
862 | 44374 | jjdelcerro | } |
863 | 44712 | jjdelcerro | return this.groupByColumns; |
864 | } |
||
865 | 44374 | jjdelcerro | |
866 | 44712 | jjdelcerro | @Override
|
867 | 46251 | jjdelcerro | public void removeGroupByColumn(String colname) { |
868 | if( this.groupByColumns == null ) { |
||
869 | return;
|
||
870 | } |
||
871 | this.groupByColumns.remove(colname);
|
||
872 | } |
||
873 | |||
874 | @Override
|
||
875 | 45425 | jjdelcerro | public void addAggregate(String funcName, String columnName) { |
876 | Map<String, String> aggregateds = this.getAggregateFunctions(); |
||
877 | aggregateds.put(columnName, funcName); |
||
878 | } |
||
879 | |||
880 | @Override
|
||
881 | 44712 | jjdelcerro | public Map<String, String> getAggregateFunctions() { |
882 | if( this.aggregateFunctions == null ) { |
||
883 | this.aggregateFunctions = new HashMap<>(); |
||
884 | 44374 | jjdelcerro | } |
885 | 44712 | jjdelcerro | return this.aggregateFunctions; |
886 | } |
||
887 | 44374 | jjdelcerro | |
888 | 44712 | jjdelcerro | @Override
|
889 | 46250 | jjdelcerro | public void removeAggregateFunction(String colname) { |
890 | if( this.aggregateFunctions == null ) { |
||
891 | return;
|
||
892 | } |
||
893 | 46540 | fdiaz | for (Iterator<Map.Entry<String, String>> iterator = this.getAggregateFunctions().entrySet().iterator(); iterator.hasNext();) { |
894 | Map.Entry<String, String> entry = iterator.next(); |
||
895 | String attrName = entry.getKey();
|
||
896 | String function = entry.getValue();
|
||
897 | if(StringUtils.equalsIgnoreCase(colname, attrName)){
|
||
898 | iterator.remove(); |
||
899 | return;
|
||
900 | } |
||
901 | } |
||
902 | 46250 | jjdelcerro | } |
903 | |||
904 | @Override
|
||
905 | 46540 | fdiaz | public String getAggregateFunction(String name){ |
906 | for (Map.Entry<String, String> entry : this.getAggregateFunctions().entrySet()) { |
||
907 | String attrName = entry.getKey();
|
||
908 | String function = entry.getValue();
|
||
909 | if(StringUtils.equalsIgnoreCase(name, attrName)){
|
||
910 | return function;
|
||
911 | } |
||
912 | } |
||
913 | return null; |
||
914 | } |
||
915 | |||
916 | @Override
|
||
917 | 44727 | jjdelcerro | public String getAggregate(String name) { |
918 | 46540 | fdiaz | String fn = this.getAggregateFunction(name); |
919 | 44727 | jjdelcerro | if( StringUtils.isAlphanumeric(fn) ) {
|
920 | return fn + "(\""+ name + "\")"; |
||
921 | } |
||
922 | return fn;
|
||
923 | } |
||
924 | |||
925 | @Override
|
||
926 | 45162 | omartinez | public String getAggregate(String tableName, String name) { |
927 | 46540 | fdiaz | String fn = this.getAggregateFunction(name); |
928 | 45162 | omartinez | if (!tableName.startsWith("\"")) { |
929 | tableName = "\""+tableName+"\""; |
||
930 | } |
||
931 | if( StringUtils.isAlphanumeric(fn) ) {
|
||
932 | return fn + "("+tableName+".\""+ name + "\")"; |
||
933 | } |
||
934 | return fn;
|
||
935 | } |
||
936 | 46505 | fdiaz | |
937 | @Override
|
||
938 | public boolean isAggregate(String name) { |
||
939 | 46540 | fdiaz | return this.getAggregateFunction(name) != null; |
940 | 46505 | fdiaz | } |
941 | |||
942 | 45162 | omartinez | @Override
|
943 | 44712 | jjdelcerro | public boolean hasAggregateFunctions() { |
944 | 45252 | jjdelcerro | return this.aggregateFunctions != null && !this.aggregateFunctions.isEmpty(); |
945 | 44712 | jjdelcerro | } |
946 | |||
947 | @Override
|
||
948 | public boolean hasGroupByColumns() { |
||
949 | return this.groupByColumns != null && !this.groupByColumns.isEmpty(); |
||
950 | } |
||
951 | |||
952 | 46748 | jjdelcerro | private void clear() { |
953 | this.queryParameters = new HashMap(); |
||
954 | |||
955 | // this.featureTypeId = other.featureTypeId;
|
||
956 | // this.storeName = other.storeName;
|
||
957 | |||
958 | this.clearConstantsAttributeNames();
|
||
959 | this.clearAttributeNames();
|
||
960 | this.clearFilter();
|
||
961 | this.clearLimit();
|
||
962 | this.setOrder(null); |
||
963 | this.useSubquery = true; // true for backwards compatibility. |
||
964 | this.limit = NO_LIMIT;
|
||
965 | this.pageSize = 0; |
||
966 | this.groupByColumns = null; |
||
967 | this.aggregateFunctions=null; |
||
968 | this.extraColumns = new DefaultFeatureExtraColumns(); |
||
969 | this.symbolTable = null; |
||
970 | |||
971 | } |
||
972 | |||
973 | 44712 | jjdelcerro | @Override
|
974 | public void copyFrom(FeatureQuery query) { |
||
975 | 46748 | jjdelcerro | if( query == null ) { |
976 | this.clear();
|
||
977 | return;
|
||
978 | } |
||
979 | 44712 | jjdelcerro | DefaultFeatureQuery other = (DefaultFeatureQuery) query; |
980 | 44829 | omartinez | this.queryParameters = new HashMap(); |
981 | 44712 | jjdelcerro | this.queryParameters.putAll(other.queryParameters);
|
982 | |||
983 | this.featureTypeId = other.featureTypeId;
|
||
984 | |||
985 | this.attributeNames.clear();
|
||
986 | this.attributeNames.addAll(other.attributeNames);
|
||
987 | |||
988 | this.constantsAttributeNames.clear();
|
||
989 | this.constantsAttributeNames.addAll(other.constantsAttributeNames);
|
||
990 | |||
991 | this.filter = other.filter;
|
||
992 | |||
993 | this.order.copyFrom(other.order);
|
||
994 | |||
995 | this.limit = other.limit;
|
||
996 | |||
997 | this.pageSize = other.pageSize;
|
||
998 | 46163 | jjdelcerro | this.useSubquery = other.useSubquery;
|
999 | 44712 | jjdelcerro | |
1000 | if( this.groupByColumns!=null && other.groupByColumns!=null ) { |
||
1001 | this.groupByColumns.clear();
|
||
1002 | this.groupByColumns.addAll(other.groupByColumns);
|
||
1003 | } else if( other.groupByColumns!=null ) { |
||
1004 | this.groupByColumns = new ArrayList<>(); |
||
1005 | this.groupByColumns.addAll(other.groupByColumns);
|
||
1006 | } else if( this.groupByColumns!=null ) { |
||
1007 | this.groupByColumns = null; |
||
1008 | } |
||
1009 | |||
1010 | 44765 | omartinez | if( this.aggregateFunctions!=null && other.aggregateFunctions!=null ) { |
1011 | 44712 | jjdelcerro | this.aggregateFunctions.clear();
|
1012 | this.aggregateFunctions.putAll(other.aggregateFunctions);
|
||
1013 | 44765 | omartinez | } else if( other.aggregateFunctions!=null ) { |
1014 | 45252 | jjdelcerro | this.aggregateFunctions = new HashMap<>(other.aggregateFunctions); |
1015 | 44765 | omartinez | } else if( this.aggregateFunctions!=null ) { |
1016 | this.aggregateFunctions=null; |
||
1017 | 44712 | jjdelcerro | } |
1018 | 46501 | jjdelcerro | this.extraColumns.copyFrom(other.extraColumns);
|
1019 | 46010 | jjdelcerro | if( other.symbolTable!=null ) { |
1020 | try {
|
||
1021 | this.symbolTable = other.symbolTable.clone();
|
||
1022 | } catch (CloneNotSupportedException ex) { |
||
1023 | LOGGER.debug("Can't clone symbol table",ex);
|
||
1024 | } |
||
1025 | } |
||
1026 | 46078 | omartinez | this.storeName = other.storeName;
|
1027 | 44712 | jjdelcerro | } |
1028 | |||
1029 | 46010 | jjdelcerro | @Override
|
1030 | 46501 | jjdelcerro | public FeatureExtraColumns getExtraColumns() {
|
1031 | return this.extraColumns; |
||
1032 | } |
||
1033 | |||
1034 | @Override
|
||
1035 | @Deprecated
|
||
1036 | 46010 | jjdelcerro | public FeatureExtraColumns getExtraColumn() {
|
1037 | 46501 | jjdelcerro | return this.extraColumns; |
1038 | 46010 | jjdelcerro | } |
1039 | |||
1040 | @Override
|
||
1041 | public MutableSymbolTable getSymbolTable() {
|
||
1042 | return symbolTable;
|
||
1043 | } |
||
1044 | |||
1045 | @Override
|
||
1046 | public void setSymbolTable(MutableSymbolTable symbolTable) { |
||
1047 | this.symbolTable = symbolTable;
|
||
1048 | } |
||
1049 | |||
1050 | @Override
|
||
1051 | public void setVar(String name, Object value) { |
||
1052 | if( this.symbolTable==null ) { |
||
1053 | this.symbolTable = ExpressionUtils.createSymbolTable();
|
||
1054 | } |
||
1055 | this.symbolTable.setVar(name, value);
|
||
1056 | } |
||
1057 | |||
1058 | 46163 | jjdelcerro | @Override
|
1059 | public boolean isUseSubquery() { |
||
1060 | return useSubquery;
|
||
1061 | } |
||
1062 | |||
1063 | @Override
|
||
1064 | public void setUseSubquery(boolean useSubquery) { |
||
1065 | this.useSubquery = useSubquery;
|
||
1066 | } |
||
1067 | 46970 | jjdelcerro | |
1068 | @Override
|
||
1069 | public void fromJson(JsonObject json) { |
||
1070 | DataManager dataManager = DALLocator.getDataManager(); |
||
1071 | |||
1072 | String s = json.getString("version",null); |
||
1073 | Version version = s==null?null:Version.valueOf(s); |
||
1074 | |||
1075 | this.queryParameters = Json.toMap(json, "queryParameters"); |
||
1076 | this.featureTypeId = json.getString("featureTypeId", null); |
||
1077 | |||
1078 | this.attributeNames = new ArrayList<>(); |
||
1079 | Collection theAttributeNames = Json.toCollection(json,"attributeNames"); |
||
1080 | if( theAttributeNames!=null ) { |
||
1081 | this.attributeNames.addAll(theAttributeNames);
|
||
1082 | } |
||
1083 | |||
1084 | List<Expression> filterList = null; |
||
1085 | Collection theFilter = Json.toCollection(json, "filter"); |
||
1086 | if( theFilter!=null ) { |
||
1087 | filterList = new ArrayList<>(theFilter); |
||
1088 | } |
||
1089 | if (filterList==null || filterList.isEmpty()) { |
||
1090 | this.filter = null; |
||
1091 | } else if (filterList.size() == 1) { |
||
1092 | Expression expression = filterList.get(0); |
||
1093 | Evaluator evaluator; |
||
1094 | try {
|
||
1095 | evaluator = dataManager.createFilter(expression); |
||
1096 | } catch (InitializeException ex) {
|
||
1097 | LOGGER.warn("Can't create evaluator", ex);
|
||
1098 | evaluator = null;
|
||
1099 | } |
||
1100 | this.filter = evaluator;
|
||
1101 | } else {
|
||
1102 | AndEvaluator andEvaluator = null;
|
||
1103 | for (Expression expression : filterList) { |
||
1104 | Evaluator evaluator; |
||
1105 | try {
|
||
1106 | evaluator = dataManager.createFilter(expression); |
||
1107 | |||
1108 | if (andEvaluator == null) { |
||
1109 | andEvaluator = new AndEvaluator(evaluator);
|
||
1110 | } else {
|
||
1111 | andEvaluator.addEvaluator(evaluator); |
||
1112 | } |
||
1113 | } catch (InitializeException ex) {
|
||
1114 | LOGGER.warn("Can't create AndEvaluator", ex);//TODO evaluator a null |
||
1115 | break;
|
||
1116 | } |
||
1117 | this.filter = evaluator;
|
||
1118 | |||
1119 | } |
||
1120 | } |
||
1121 | this.limit = json.getInt("limit"); |
||
1122 | if(version == null || version.compareTo(VERSION_2_6_0)<0){ |
||
1123 | if(this.limit == 0) { |
||
1124 | this.clearLimit();
|
||
1125 | } |
||
1126 | } |
||
1127 | this.pageSize = json.getInt("pageSize"); |
||
1128 | this.useSubquery = json.getBoolean("useSubquery",true); |
||
1129 | this.storeName = json.getString("storeName"); |
||
1130 | |||
1131 | |||
1132 | this.order = (FeatureQueryOrder) Json.toObject(json, "order"); |
||
1133 | |||
1134 | Collection<String> theGroupByColumns = Json.toCollection(json.getJsonArray("groupByColumns")); |
||
1135 | if (theGroupByColumns!=null) { |
||
1136 | this.groupByColumns = new ArrayList<>(theGroupByColumns); |
||
1137 | } else {
|
||
1138 | this.groupByColumns = null; |
||
1139 | } |
||
1140 | |||
1141 | |||
1142 | Map asMapAggregateFunctions = Json.toMap(json,"aggregateFunctions"); |
||
1143 | if (asMapAggregateFunctions!=null) { |
||
1144 | this.aggregateFunctions = new HashMap<>(asMapAggregateFunctions); |
||
1145 | } else {
|
||
1146 | this.aggregateFunctions = null; |
||
1147 | } |
||
1148 | this.extraColumns = (FeatureExtraColumns) Json.toObject(json,"extraColumn"); |
||
1149 | } |
||
1150 | |||
1151 | @Override
|
||
1152 | public JsonObjectBuilder toJsonBuilder() {
|
||
1153 | JsonObjectBuilder state = Json.createObjectBuilder(); |
||
1154 | state.add("version", VERSION_2_6_0.toString());
|
||
1155 | state.add("queryParameters", this.queryParameters); |
||
1156 | state.add("featureTypeId", this.featureTypeId); |
||
1157 | state.add("attributeNames", this.attributeNames); |
||
1158 | |||
1159 | JsonArrayBuilder filterList = Json.createArrayBuilder(); |
||
1160 | if (this.filter instanceof DefaultFeatureExpressionEvaluator) { |
||
1161 | DefaultFeatureExpressionEvaluator filterExpression = (DefaultFeatureExpressionEvaluator) this.filter;
|
||
1162 | filterList.add(filterExpression.toExpression()); |
||
1163 | } else if (this.filter instanceof AndEvaluator) { |
||
1164 | AndEvaluator filterAnd = (AndEvaluator) this.filter;
|
||
1165 | List<Evaluator> evaluators = filterAnd.getEvaluators();
|
||
1166 | for (Evaluator evaluator : evaluators) {
|
||
1167 | if (evaluator instanceof DefaultFeatureExpressionEvaluator) { |
||
1168 | DefaultFeatureExpressionEvaluator expressionEvaluator = (DefaultFeatureExpressionEvaluator) evaluator; |
||
1169 | filterList.add(expressionEvaluator.toExpression()); |
||
1170 | } else {
|
||
1171 | filterList = Json.createArrayBuilder(); |
||
1172 | LOGGER.warn(StringUtils.join("Filters in this FeatureQuery will not persist:", this.toString())); |
||
1173 | break;
|
||
1174 | } |
||
1175 | } |
||
1176 | } else {
|
||
1177 | filterList = Json.createArrayBuilder(); |
||
1178 | if( this.filter!=null ) { |
||
1179 | LOGGER.warn(StringUtils.join("Filters in this FeatureQuery will not persist:", this.toString())); |
||
1180 | } |
||
1181 | } |
||
1182 | |||
1183 | state.add("filter", filterList);
|
||
1184 | state.add("limit", this.limit); |
||
1185 | state.add("pageSize", this.pageSize); |
||
1186 | state.add("useSubquery", this.useSubquery); |
||
1187 | |||
1188 | state.add("order", (SupportJson) this.order); |
||
1189 | state.add("groupByColumns", this.groupByColumns); |
||
1190 | state.add("aggregateFunctions", this.aggregateFunctions); |
||
1191 | state.add("extraColumn", (SupportToJson) this.extraColumns); |
||
1192 | state.add("storeName", this.storeName); |
||
1193 | |||
1194 | return state;
|
||
1195 | } |
||
1196 | 46010 | jjdelcerro | |
1197 | 40435 | jjdelcerro | } |