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

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