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 / fmap / dal / feature / impl / DefaultFeatureQuery.java @ 47248

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