Revision 46955
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