Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.swing / org.gvsig.fmap.dal.swing.impl / src / main / java / org / gvsig / fmap / dal / swing / impl / searchpanel / DefaultSearchParameters.java @ 46505

History | View | Annotate | Download (21.7 KB)

1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.fmap.dal.swing.impl.searchpanel;
7

    
8
import java.io.ByteArrayInputStream;
9
import java.io.InputStream;
10
import java.util.ArrayList;
11
import java.util.HashMap;
12
import java.util.List;
13
import java.util.Map;
14
import javax.json.Json;
15
import javax.json.JsonObject;
16
import javax.json.JsonReader;
17
import org.apache.commons.lang3.StringUtils;
18
import org.gvsig.expressionevaluator.Code;
19
import org.gvsig.expressionevaluator.Expression;
20
import org.gvsig.expressionevaluator.ExpressionUtils;
21
import org.gvsig.fmap.dal.exception.DataException;
22
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
23
import org.gvsig.fmap.dal.feature.EditableFeatureAttributeDescriptor;
24
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
25
import org.gvsig.fmap.dal.feature.FeatureQuery;
26
import org.gvsig.fmap.dal.feature.FeatureQueryOrder;
27
import org.gvsig.fmap.dal.feature.FeatureSet;
28
import org.gvsig.fmap.dal.feature.FeatureStore;
29
import org.gvsig.fmap.dal.feature.FeatureType;
30
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dispose.DisposeUtils;
33
import org.gvsig.tools.dynobject.DynStruct;
34
import org.gvsig.tools.persistence.PersistenceManager;
35
import org.gvsig.tools.persistence.PersistentState;
36
import org.gvsig.tools.persistence.exception.PersistenceException;
37
import org.gvsig.tools.visitor.FilteredVisitable;
38

    
39
/**
40
 *
41
 * @author jjdelcerro
42
 */
43
public class DefaultSearchParameters implements SearchParameters, Cloneable {
44

    
45
    private List<String> resultColumnNames;
46
    private FeatureQuery query;
47
    private String name;
48
    private Map<String, JsonObject> values;
49
    private int searchMode;
50

    
51
    public DefaultSearchParameters() {
52
        this.resultColumnNames = new ArrayList<>();
53
        this.query = null;
54
        this.values = new HashMap<>();
55
        this.searchMode = DefaultSearchPanel.PANEL_SIMPLIFIED;
56
    }
57

    
58
    @Override
59
    public List<String> getResultColumnNames() {
60
        return this.resultColumnNames;
61
    }
62

    
63
    public List<String> getGroupByColumns() {
64
        return this.query.getGroupByColumns();
65
    }
66

    
67
    public Map<String, String> getAggregateFunctions() {
68
        return this.query.getAggregateFunctions();
69
    }
70

    
71
    public void setQuery(FeatureQuery query) {
72
        this.query = query;
73
    }
74

    
75
    public void setFilter(Expression exp) {
76
        this.query.setFilter(exp);
77
    }
78

    
79
    public FeatureQuery getQuery() {
80
        return this.query;
81
    }
82

    
83
    void setResultColumnNames(List<String> selectedNames) {
84
        throw new UnsupportedOperationException("Not supported yet.");
85
    }
86

    
87
    @Override
88
    public Map<String, JsonObject> getValues() {
89
        return this.values;
90
    }
91

    
92
    public static void registerPersistence() {
93
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
94
        if (manager.getDefinition("SearchParameters") == null) {
95
            DynStruct definition = manager.addDefinition(DefaultSearchParameters.class,
96
                    "DefaultSearchParameters", "DefaultSearchParameters persistence definition", null, null);
97
            definition.addDynFieldList("resultColumnNames").setClassOfItems(String.class);
98
            definition.addDynFieldMap("values").setClassOfItems(String.class);
99
            definition.addDynFieldObject("query").setClassOfValue(FeatureQuery.class).setMandatory(false);
100
            definition.addDynFieldString("name").setClassOfValue(String.class);
101
            definition.addDynFieldInt("searchMode").setClassOfValue(Integer.class);
102
        }
103
    }
104

    
105
    @Override
106
    public void saveToState(PersistentState state) throws PersistenceException {
107
        state.set("resultColumnNames", this.resultColumnNames);
108
        HashMap<String, String> valuesMap = new HashMap<>();
109
        for (String key : this.values.keySet()) {
110
            JsonObject value = this.values.get(key);
111
            valuesMap.put(key, value.toString());
112
        }
113
        state.set("values", valuesMap);
114
        state.set("query", this.query);
115
        state.set("name", this.name);
116
        state.set("searchMode", this.searchMode);
117
    }
118

    
119
    @Override
120
    public void loadFromState(PersistentState state) throws PersistenceException {
121
        this.resultColumnNames = new ArrayList<>(state.getList("resultColumnNames"));
122
        Map<String, String> valuesState = state.getMap("values");
123
        HashMap<String, JsonObject> valuesMap = new HashMap<>();
124

    
125
        for (String key : valuesState.keySet()) {
126
            String value = valuesState.get(key);
127
            InputStream targetStream = new ByteArrayInputStream(value.getBytes());
128
            JsonReader reader = Json.createReader(targetStream);
129
            JsonObject jsonObject = reader.readObject();
130
            valuesMap.put(key, jsonObject);
131
        }
132

    
133
        this.values = valuesMap;
134
        this.query = (FeatureQuery) state.get("query");
135
        this.name = state.getString("name");
136
        try {
137
            this.searchMode = state.getInt("searchMode");
138
        } catch(Exception ex) {
139
            this.searchMode = DefaultSearchPanel.PANEL_SIMPLIFIED;
140
        }
141
    }
142
    
143
    private boolean isColumn(String name, FeatureType type) {
144
        if(type != null) {
145
            FeatureAttributeDescriptor attr = type.getAttributeDescriptorFromAll(name);
146
            if(attr != null){
147
                return true;
148
            }
149
        }
150
        if( this.query!=null ) {
151
            EditableFeatureAttributeDescriptor x = this.query.getExtraColumn().get(name);
152
            return x!=null;
153
        }
154
        return false;
155
    }
156

    
157
    @Override
158
    public String toString() {
159
        StringBuilder builder = new StringBuilder();
160
        builder.append("NAME: ");
161
        builder.append(this.getName());
162
        builder.append("\n");
163
        builder.append("SEARCH MODE: ");
164
        builder.append(this.getSearchMode());
165
        builder.append("\n");
166
        
167
        boolean first = true;
168
        for (String attributeName : this.getResultColumnNames()) {
169
            if (first) {
170
                builder.append("COLUMNS:\n  ");
171
                first=false;
172
            } else {
173
                builder.append(", ");
174
            }
175
            builder.append("\"");
176
            builder.append(attributeName);
177
            builder.append("\"");
178
        }                
179
        if( !first ) {
180
            builder.append("\n");
181
        }
182
        
183
        if (this.query != null) { 
184
            try {
185
                first = true;
186
                for (Map.Entry<String, String> aggregate : this.getAggregateFunctions().entrySet()) {
187
                    String exp = aggregate.getKey();
188
                    String function = aggregate.getValue();
189
                    if (first) {
190
                        builder.append("AGGREGATES:\n");
191
                        first=false;
192
                    }
193
                    builder.append("- ");
194
                    builder.append(function);
195
                    builder.append("(");
196
                    if( this.isColumn(exp, null) ) {
197
                        builder.append("\"");
198
                        builder.append(exp);
199
                        builder.append("\"");
200
                    } else {
201
                        builder.append(exp);
202
                    }
203
                    builder.append(")\n");
204
                }
205
            } catch(Exception ex) {
206
                builder.append("ERROR: ");
207
                builder.append(ex.getMessage());
208
                builder.append("\n");
209
            }
210

    
211
            try {
212
                if (this.query.getExpressionFilter() != null) {
213
                    builder.append("WHERE:\n  ");
214
                    builder.append(this.query.getExpressionFilter().getPhrase().replace("\n", " "));
215
                    builder.append("\n");
216
                }
217
            } catch(Exception ex) {
218
                builder.append("ERROR: ");
219
                builder.append(ex.getMessage());
220
                builder.append("\n");
221
            }
222

    
223
            try {
224
                first = true;
225
                for (String groupByColumn : this.query.getGroupByColumns()) {
226
                    if (first) {
227
                        builder.append("GROUP BY:\n");
228
                        first=false;
229
                    } else {
230
                        builder.append(", ");
231
                    }
232
                    if( isColumn(groupByColumn, null) ) {
233
                        builder.append("\"");
234
                        builder.append(groupByColumn);
235
                        builder.append("\"");
236
                    } else {
237
                        builder.append(groupByColumn);
238
                    }
239
                }
240
                if( !first ) {
241
                    builder.append("\n");
242
                }
243
            } catch(Exception ex) {
244
                builder.append("ERROR: ");
245
                builder.append(ex.getMessage());
246
                builder.append("\n");
247
            }
248

    
249
            try {
250
                first = true;
251
                for (FeatureQueryOrder.FeatureQueryOrderMember member : this.query.getOrder().members()) {
252
                    if (first) {
253
                        builder.append("ORDER BY: ");
254
                        first=false;
255
                    } else {
256
                        builder.append(", ");
257
                    }
258
                    builder.append("\"");
259
                    builder.append(member.getAttributeName());
260
                    builder.append("\"");
261
                    if(member.getAscending()) {
262
                        builder.append(" ASC");
263
                    } else {
264
                        builder.append(" DESC");
265
                    }
266
                }
267
                if( !first ) {
268
                    builder.append("\n");
269
                }
270
            } catch(Exception ex) {
271
                builder.append("ERROR: ");
272
                builder.append(ex.getMessage());
273
                builder.append("\n");
274
            }
275

    
276
            try {
277
                first = true;
278
                for (EditableFeatureAttributeDescriptor col : this.query.getExtraColumn().getColumns()) {
279
                    if (first) {
280
                        builder.append("USER COLUMNS:\n");
281
                        first=false;
282
                    }
283
                    builder.append("- \"");
284
                    builder.append(col.getName());
285
                    builder.append("\" ");
286
                    builder.append(col.getDataTypeName());
287
                    if( col.getFeatureAttributeEmulator() instanceof FeatureAttributeEmulatorExpression ) {
288
                        Expression exp = ((FeatureAttributeEmulatorExpression)col.getFeatureAttributeEmulator()).getExpression();
289
                        if( exp != null ) {
290
                            builder.append(" AS ");
291
                            builder.append(exp.getPhrase().replace("\n", " "));
292
                        }
293
                    }
294
                    builder.append("\n");
295
                }
296
            } catch(Exception ex) {
297
                builder.append("ERROR: ");
298
                builder.append(ex.getMessage());
299
                builder.append("\n");
300
            }
301
        }
302
        try {
303
            first = true;
304
            for (Map.Entry<String, JsonObject> value : this.getValues().entrySet()) {
305
                String key = value.getKey();
306
                JsonObject data = value.getValue();
307
                if (first) {
308
                    builder.append("VALUES:\n");
309
                    first=false;
310
                }
311
                builder.append("- ");
312
                builder.append(key);
313
                if( data != null ) {
314
                    builder.append(", ");
315
                    builder.append(data.toString().replace("\n"," "));
316
                }
317
                builder.append("\n");
318
            }
319
        } catch(Exception ex) {
320
            builder.append("ERROR: ");
321
            builder.append(ex.getMessage());
322
            builder.append("\n");
323
        }
324
        return builder.toString();
325
    }
326

    
327
    @Override
328
    public Object clone() throws CloneNotSupportedException {
329
        DefaultSearchParameters clone = (DefaultSearchParameters) super.clone();
330
        clone.query = this.query.getCopy();
331
        clone.resultColumnNames = new ArrayList(this.resultColumnNames);
332
        HashMap<String, JsonObject> cloneValues = new HashMap<>(this.values);
333
        clone.values = cloneValues;
334
        return clone;
335
    }
336

    
337
    public DefaultSearchParameters getCopy() {
338
        try {
339
            return (DefaultSearchParameters) this.clone();
340
        } catch (CloneNotSupportedException ex) {
341
            return null;
342
        }
343
    }
344

    
345
    @Override
346
    public void copyFrom(SearchParameters params) {
347
        this.resultColumnNames = params.getResultColumnNames();
348
        this.query = params.getQuery().getCopy();
349
        this.name = params.getName();
350
        this.values = params.getValues();
351
    }
352

    
353
    @Override
354
    public String getName() {
355
        return this.name;
356
    }
357

    
358
    @Override
359
    public void setName(String name) {
360
        this.name = name;
361
    }
362

    
363
    @Override
364
    public FeatureType getFeatureType(FeatureStore store) {
365
        FeatureSet fset = null;
366
        try {
367
            fset = store.getFeatureSet(this.query);
368
            FeatureType ft = fset.getDefaultFeatureType();
369
            return ft;
370
        } catch (DataException ex) {
371
            return store.getDefaultFeatureTypeQuietly();
372
        } finally {
373
            DisposeUtils.disposeQuietly(fset);
374
        }
375
    }
376
    
377
    public int getSearchMode()  {
378
        return this.searchMode;
379
    }
380
    
381
    public void setSearchMode(int searchMode) {
382
        this.searchMode = searchMode;
383
    }
384

    
385
    void fix(FeatureType featureType) {
386
        fix(featureType, false);
387
    }
388
    
389
    void fix(FeatureType featureType, boolean onlyEssentials) {
390
        if(!onlyEssentials){
391
            List<String> toRemoveAggregateColumns = new ArrayList<>();
392
            Map<String, String> aggregateFunctions = this.query.getAggregateFunctions();
393
            for (Map.Entry<String, String> aggregate : aggregateFunctions.entrySet()) {
394
                String colname = aggregate.getKey();
395
                String funcname = aggregate.getValue();
396
                if( this.query.getExtraColumn().get(colname)==null && featureType.get(colname)==null ) {
397
                    toRemoveAggregateColumns.add(colname);
398
                }
399
            }
400
            for (String toRemoveAggregateColumn : toRemoveAggregateColumns) {
401
                this.query.removeAggregateFunction(toRemoveAggregateColumn);
402
            }
403
        }
404
        if( this.query.getLimit()==0 ) {
405
            // Esto es por compatibilidad con querys guardados con antelacion
406
            // al cambio para hacer valido el limit 0.
407
            this.query.clearLimit();
408
        }
409
    }
410
    
411
    public boolean isValid(FeatureType type, StringBuilder errMessage){
412
        StringBuilder message;
413
        if(errMessage == null){
414
            message = new StringBuilder();
415
        } else {
416
            message = errMessage;
417
        }
418
        for (String attributeName : this.getResultColumnNames()) {
419
            if(!isColumn(attributeName, type)){
420
                message.append("Column \"");
421
                message.append(attributeName);
422
                message.append("\" not defined.\n");
423
            }
424
        }                
425
        
426
        if (this.query != null) { 
427
            try {
428
                for (Map.Entry<String, String> aggregate : this.getAggregateFunctions().entrySet()) {
429
                    String exp = aggregate.getKey();
430
                    String function = aggregate.getValue();
431
                    if(!isColumn(exp, type)){
432
                        Code code = null;
433
                        try {
434
                            code = ExpressionUtils.compile(exp);
435
                        } catch(Throwable t){
436
                            //TODO
437
                        }
438
                        if(code == null) {
439
                            message.append("Invalid expression in aggregate function ");
440
                            message.append(function);
441
                            message.append("(");
442
                            message.append(exp);
443
                            message.append(")\n");
444
                        }
445
                    }
446
                }
447
            } catch(Exception ex) {
448
                message.append("ERROR: ");
449
                message.append(ex.getMessage());
450
                message.append("\n");
451
            }
452

    
453
            try {
454
                Expression exp = this.query.getExpressionFilter();
455
                if (exp != null) {
456
                    Code code = null;
457
                    try {
458
                        code = exp.getCode();
459
                        code.accept((Object obj) -> {
460
                            String name1 = ((Code.Identifier)obj).name();
461
                            if (!isColumn(name1, type)) {
462
                                    message.append("Column \"");
463
                                    message.append(name1);
464
                                    message.append("\" not defined in filter.\n");
465
                            }
466
                        }, (FilteredVisitable t) -> (t instanceof Code.Identifier));
467
                    } catch (Throwable t) {
468
                        //TODO
469
                    }
470
                    if (code == null) {
471
                        message.append("Incorrect filter ");
472
                        message.append(exp.getPhrase());
473
                        message.append("\n");
474
                    }
475
                }
476
            } catch(Exception ex) {
477
                message.append("ERROR: ");
478
                message.append(ex.getMessage());
479
                message.append("\n");
480
            }
481

    
482
            try {
483
                for (String groupByColumn : this.query.getGroupByColumns()) {
484
                    if(!isColumn(groupByColumn, type)){
485
                        Code code = null;
486
                        try {
487
                            code = ExpressionUtils.compile(groupByColumn);
488
                        } catch(Throwable t){
489
                            //TODO
490
                        }
491
                        if(code == null) {
492
                            message.append("Group expression ");
493
                            message.append(groupByColumn);
494
                            message.append(" not valid \n");
495
                        }
496
                    }
497
                    
498
                }
499
            } catch(Exception ex) {
500
                message.append("ERROR: ");
501
                message.append(ex.getMessage());
502
                message.append("\n");
503
            }
504

    
505
            try {
506
                for (FeatureQueryOrder.FeatureQueryOrderMember member : this.query.getOrder().members()) {
507
                    if(!isColumn(member.getAttributeName(), type)){
508
                        Code code = null;
509
                        try {
510
                            code = ExpressionUtils.compile(member.getAttributeName());
511
                        } catch(Throwable t){
512
                            //Do nothing
513
                        }
514
                        if(code == null) {
515
                            message.append("Order expression ");
516
                            message.append(member.getAttributeName());
517
                            message.append(" not valid \n");
518
                        }
519
                    }
520

    
521
                }
522
            } catch(Exception ex) {
523
                message.append("ERROR: ");
524
                message.append(ex.getMessage());
525
                message.append("\n");
526
            }
527

    
528
            try {
529
                for (EditableFeatureAttributeDescriptor col : this.query.getExtraColumn().getColumns()) {
530
                    if( col.getFeatureAttributeEmulator() instanceof FeatureAttributeEmulatorExpression ) {
531
                        Expression exp = ((FeatureAttributeEmulatorExpression)col.getFeatureAttributeEmulator()).getExpression();
532
                        if( exp == null) {
533
                        } else {
534
                            Code code = null;
535
                            try {
536
                                code = exp.getCode();
537
                                code.accept((Object obj) -> {
538
                                    String name1 = ((Code.Identifier) obj).name();
539
                                    if (!isColumn(name1, type)) {
540
                                        message.append("\"");
541
                                        message.append(col.getName());
542
                                        message.append("\" refers to the nonexistent column \"");
543
                                        message.append(name1);
544
                                        message.append("\"");
545
                                    }
546
                                }, (FilteredVisitable t) -> (t instanceof Code.Identifier));
547
                            } catch (Throwable t) {
548
                                //Do nothing
549
                            }
550
                            if (code == null) {
551
                                message.append("Incorrect calculate column \"");
552
                                message.append(col.getName());
553
                                message.append("\"\n");
554
                            }
555
                        }
556
                    }
557
                }
558
            } catch(Exception ex) {
559
                message.append("ERROR: ");
560
                message.append(ex.getMessage());
561
                message.append("\n");
562
            }
563
        }
564
        if(StringUtils.isNotBlank(message)){
565
            return false;
566
        }
567
        
568
//        try {
569
//            for (Map.Entry<String, JsonObject> value : this.getValues().entrySet()) {
570
//                String key = value.getKey();
571
//                JsonObject data = value.getValue();
572
//            }
573
//        } catch(Exception ex) {
574
//                errMessage.append("ERROR: ");
575
//                errMessage.append(ex.getMessage());
576
//                errMessage.append("\n");
577
//        }
578
        return true;
579

    
580
    }
581
}
582