Revision 46955

View differences:

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/SearchConditionFieldController.java
30 30
import javax.swing.SwingUtilities;
31 31
import javax.swing.text.JTextComponent;
32 32
import org.apache.commons.lang3.StringUtils;
33
import org.apache.commons.lang3.mutable.MutableBoolean;
33 34
import org.gvsig.expressionevaluator.ExpressionBuilder;
34 35
import org.gvsig.fmap.dal.DALLocator;
35 36
import org.gvsig.fmap.dal.DataManager;
......
59 60
import org.gvsig.tools.dataTypes.DataTypes;
60 61
import org.gvsig.tools.dispose.DisposeUtils;
61 62
import org.gvsig.tools.dynobject.DynField;
62
import org.gvsig.tools.exception.BaseException;
63 63
import org.gvsig.tools.i18n.I18nManager;
64 64
import org.gvsig.tools.swing.api.DropDown;
65 65
import org.gvsig.tools.swing.api.ToolsSwingLocator;
......
70 70
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
71 71
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
72 72
import org.gvsig.tools.swing.icontheme.IconTheme;
73
import org.gvsig.tools.task.CancellableTask;
73 74
import org.gvsig.tools.util.CompareUtils;
74 75
import org.gvsig.tools.util.LabeledValue;
75 76
import org.gvsig.tools.util.LabeledValueImpl;
76 77
import org.gvsig.tools.visitor.VisitCanceledException;
77
import org.gvsig.tools.visitor.Visitor;
78 78
import org.slf4j.Logger;
79 79
import org.slf4j.LoggerFactory;
80 80

  
......
91 91
    private static final int MAXLEN_IN_COMBOS = 70;
92 92
    
93 93
    private static final String OPERATOR_CONTAINS = "CONTAINS";
94
    private UpdateValueList updateValueListTask;
94 95
    
96
    private class UpdateValueList implements Runnable, CancellableTask {
97

  
98
        private final Field field;
99
        private boolean cancelled;
100

  
101
        public UpdateValueList(Field field) {
102
            this.field = field;
103
        }
104
        
105
        @Override
106
        public void run() {
107
            if (isCancellationRequested()) {
108
                return;
109
            }
110
            final FeatureStore theStore = field.getFeatureStore();
111
            final FeatureQuery query;
112
            query = theStore.createFeatureQuery();
113
            query.addAttributeName(field.getDescriptor().getName());
114
            query.setFilter("");
115
    //        query.getExtraColumns().copyFrom(this.parameters.getQuery().getExtraColumns());
116
            query.setLimit(updateValuesFeaturesLimit);
117
            query.getGroupByColumns().clear();
118
            query.getAggregateFunctions().clear();     
119
            
120
            FeatureSet set = null;
121
            final List<Object> values = new ArrayList<>();
122
            final DefaultComboBoxModel model = new DefaultComboBoxModel();
123
            MutableBoolean canHasMoreElements = new MutableBoolean();
124
            
125
            try {
126
                canHasMoreElements.setFalse();
127
                if (isCancellationRequested()) {
128
                    return;
129
                }
130
                set = theStore.getFeatureSet(query);
131
                if (set.size() >= updateValuesFeaturesLimit) {
132
                    canHasMoreElements.setTrue();
133
                }
134
                final long timeLimit = System.currentTimeMillis() + updateValuesTimeLimit * 1000;
135
                set.accept((Object o) -> {
136
                    if (isCancellationRequested()) {
137
                        throw new VisitCanceledException();
138
                    }
139
                    Object value = ((Feature) o).get(field.getDescriptor().getName());
140
                    if (value != null && !values.contains(value)) {
141
                        values.add(value);
142
                    }
143
                    if (System.currentTimeMillis() > timeLimit) {
144
                        canHasMoreElements.setTrue();
145
                        throw new VisitCanceledException();
146
                    }
147
                    if (values.size() > updateValuesFeaturesLimit) {
148
                        canHasMoreElements.setTrue();
149
                        throw new VisitCanceledException();
150
                    }
151
                });
152
            } catch (VisitCanceledException ex) {
153
                canHasMoreElements.setTrue();
154
            } catch (Exception ex) {
155
                canHasMoreElements.setFalse();
156
                LOGGER.warn("Can't update list of values of '" + field.getLabel() + "'.", ex);
157
            } finally {
158
                DisposeUtils.disposeQuietly(set);
159
            }
160
            if (isCancellationRequested()) {
161
                return;
162
            }
163
            List<LabeledValue> elements = new ArrayList<>();
164
            if (!values.isEmpty()) {
165
                LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
166
                Map<String, String> availableValuesMap = new HashMap<>();
167
                if (availableValues != null) {
168
                    for (LabeledValue availableValue : availableValues) {
169
                        availableValuesMap.put(
170
                                Objects.toString(availableValue.getValue()),
171
                                availableValue.getLabel()
172
                        );
173
                    }
174
                }
175
                elements.add(new LabeledValueImpl("", null, MAXLEN_IN_COMBOS));
176
                for (Object value : values) {
177
                    String key;
178
                    key = DataTypeUtils.toString(value);
179
                    String label = availableValuesMap.getOrDefault(key, key);
180
                    elements.add(new LabeledValueImpl(label, value, MAXLEN_IN_COMBOS));
181
                }
182
                Comparator comparator = null;
183
                if (availableValues == null) {
184
                    switch (field.getDescriptor().getType()) {
185
                        case DataTypes.DATE:
186
                        case DataTypes.TIME:
187
                        case DataTypes.TIMESTAMP:
188
                            comparator = new CompareUtils.NullSafeComparator() {
189
                                @Override
190
                                public int safeCompare(Object o1, Object o2) {
191
                                    Comparable v1 = (Comparable) ((LabeledValue) o1).getValue();
192
                                    Comparable v2 = (Comparable) ((LabeledValue) o2).getValue();
193
                                    if (v1 == v2) {
194
                                        return 0;
195
                                    }
196
                                    if (v1 == null) {
197
                                        return -1;
198
                                    }
199
                                    if (v2 == null) {
200
                                        return 1;
201
                                    }
202
                                    return v1.compareTo(v2);
203
                                }
204
                            };
205
                    }
206
                }
207
                elements.sort(comparator);
208

  
209
            }
210
            for (LabeledValue element : elements) {
211
                model.addElement(element);
212
            }
213
            if (canHasMoreElements.isTrue()) {
214
                model.addElement(new LabeledValueImpl("...", LOAD_MORE_ELEMENTS));
215
            }
216
            if (isCancellationRequested()) {
217
                return;
218
            }
219
            SwingUtilities.invokeLater(new Runnable() {
220
                @Override
221
                public void run() {
222
                    if (isCancellationRequested()) {
223
                        return;
224
                    }
225
                    setEnabled(false);
226
                    cboValue.setModel(model);
227
                    if (valueAssigned != null) {
228
                        cboValue.setSelectedItem(valueAssigned);
229
                        valueAssigned = null;
230
                    }
231
                    setEnabled(true);
232
                }
233
            });
234
        }
235

  
236
        @Override
237
        public boolean isCancellationRequested() {
238
            return this.cancelled;
239
        }
240

  
241
        @Override
242
        public void cancelRequest() {
243
            this.cancelled = true;
244
        }
245
        
246
    }
247
    
95 248
    private static class Field extends LabeledValueImpl<String> {
96 249

  
97 250
        FeatureAttributeDescriptor attrdesc;
......
185 338

  
186 339
    private int updateValuesTimeLimit;
187 340
    private int updateValuesFeaturesLimit;
188
    private boolean canHasMoreElements;
189 341

  
190 342
    public SearchConditionFieldController(
191 343
            SearchParameters parameters,
......
207 359
        this.lblLogicalOperators = lblLogicalOperators;
208 360
        this.updateValuesTimeLimit = 60;
209 361
        this.updateValuesFeaturesLimit = 1000;
210
        this.canHasMoreElements = false;
211 362
        this.initComponents();
212 363
    }
213 364

  
......
525 676
            }
526 677
        }
527 678

  
528
        final List<Object> values = new ArrayList<>();
529
        final DefaultComboBoxModel model = new DefaultComboBoxModel();
530
        final FeatureStore theStore = field.getFeatureStore();
531
        final FeatureQuery query;
532
        query = theStore.createFeatureQuery();
533
        query.addAttributeName(field.getDescriptor().getName());
534
        query.setFilter("");
535
//        query.getExtraColumns().copyFrom(this.parameters.getQuery().getExtraColumns());
536
        query.setLimit(updateValuesFeaturesLimit);
537
        query.getGroupByColumns().clear();
538
        query.getAggregateFunctions().clear();
539
        Thread th = new Thread(new Runnable() {
540
            @Override
541
            public void run() {
542
                FeatureSet set = null;
543
                try {
544
                    canHasMoreElements = false;
545
                    set = theStore.getFeatureSet(query);
546
                    if (set.size() >= updateValuesFeaturesLimit) {
547
                        canHasMoreElements = true;
548
                    }
549
                    final long timeLimit = System.currentTimeMillis() + updateValuesTimeLimit * 1000;
550
                    set.accept(new Visitor() {
551
                        @Override
552
                        public void visit(Object o) throws VisitCanceledException, BaseException {
553
                            Object value = ((Feature) o).get(field.getDescriptor().getName());
554
                            if (value!=null && !values.contains(value)) {
555
                                values.add(value);
556
                            }
557
                            if (System.currentTimeMillis() > timeLimit) {
558
                                canHasMoreElements = true;
559
                                throw new VisitCanceledException();
560
                            }
561
                            if (values.size() > updateValuesFeaturesLimit) {
562
                                canHasMoreElements = true;
563
                                throw new VisitCanceledException();
564
                            }
565
                        }
566
                    });
567
                } catch (VisitCanceledException ex) {
568
                    canHasMoreElements = true;
569
                } catch (Exception ex) {
570
                    canHasMoreElements = false;
571
                    LOGGER.warn("Can't update list of values of '" + field.getLabel() + "'.", ex);
572
                } finally {
573
                    DisposeUtils.disposeQuietly(set);
574
                }
575
                List<LabeledValue> elements = new ArrayList<>();
576
                if (!values.isEmpty()) {
577
                    LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
578
                    Map<String, String> availableValuesMap = new HashMap<>();
579
                    if (availableValues != null) {
580
                        for (LabeledValue availableValue : availableValues) {
581
                            availableValuesMap.put(
582
                                    Objects.toString(availableValue.getValue()),
583
                                    availableValue.getLabel()
584
                            );
585
                        }
586
                    }
587
                    elements.add(new LabeledValueImpl("", null, MAXLEN_IN_COMBOS));
588
                    for (Object value : values) {
589
                        String key;
590
                        key = DataTypeUtils.toString(value);
591
                        String label = availableValuesMap.getOrDefault(key, key);
592
                        elements.add(new LabeledValueImpl(label, value, MAXLEN_IN_COMBOS));
593
                    }
594
                    Comparator comparator = null;
595
                    if (availableValues == null) {
596
                        switch (field.getDescriptor().getType()) {
597
                            case DataTypes.DATE:
598
                            case DataTypes.TIME:
599
                            case DataTypes.TIMESTAMP:
600
                                comparator = new CompareUtils.NullSafeComparator() {
601
                                    @Override
602
                                    public int safeCompare(Object o1, Object o2) {
603
                                        Comparable v1 = (Comparable)((LabeledValue)o1).getValue();
604
                                        Comparable v2 = (Comparable)((LabeledValue)o2).getValue();
605
                                        if (v1 == v2) {
606
                                            return 0;
607
                                        }
608
                                        if (v1 == null) {
609
                                            return -1;
610
                                        }
611
                                        if (v2 == null) {
612
                                            return 1;
613
                                        }
614
                                        return v1.compareTo(v2);
615
                                    }
616
                                };
617
                        }
618
                    }
619
                    elements.sort(comparator);
620

  
621
                }
622
                for (LabeledValue element : elements) {
623
                    model.addElement(element);
624
                }
625
                if (canHasMoreElements) {
626
                    model.addElement(new LabeledValueImpl("...", LOAD_MORE_ELEMENTS));
627
                }
628
                SwingUtilities.invokeLater(new Runnable() {
629
                    @Override
630
                    public void run() {
631
                        setEnabled(false);
632
                        cboValue.setModel(model);
633
                        if (valueAssigned != null) {
634
                            cboValue.setSelectedItem(valueAssigned);
635
                            valueAssigned = null;
636
                        }
637
                        setEnabled(true);
638
                    }
639
                });
640
            }
641
        });
679
        if(this.updateValueListTask != null){
680
            this.updateValueListTask.cancelRequest();
681
        }
682
        this.updateValueListTask = new UpdateValueList(field);
683
        Thread th = new Thread(updateValueListTask);
642 684
        th.start();
643 685
    }
644 686

  

Also available in: Unified diff