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 / SearchConditionFieldController.java @ 44713

History | View | Annotate | Download (20.5 KB)

1
package org.gvsig.fmap.dal.swing.impl.searchpanel;
2

    
3
import java.awt.Cursor;
4
import java.awt.event.ActionEvent;
5
import java.awt.event.ItemEvent;
6
import java.awt.event.ItemListener;
7
import java.awt.event.MouseAdapter;
8
import java.awt.event.MouseEvent;
9
import java.util.ArrayList;
10
import java.util.HashMap;
11
import java.util.List;
12
import java.util.Map;
13
import java.util.Objects;
14
import javax.swing.ComboBoxModel;
15
import javax.swing.DefaultComboBoxModel;
16
import javax.swing.ImageIcon;
17
import javax.swing.JComboBox;
18
import javax.swing.JLabel;
19
import javax.swing.SwingUtilities;
20
import org.apache.commons.lang3.ObjectUtils;
21
import org.apache.commons.lang3.StringUtils;
22
import org.gvsig.expressionevaluator.ExpressionBuilder;
23
import org.gvsig.expressionevaluator.ExpressionUtils;
24
import org.gvsig.fmap.dal.DataManager;
25
import org.gvsig.fmap.dal.complements.Search;
26
import org.gvsig.fmap.dal.exception.DataException;
27
import org.gvsig.fmap.dal.feature.Feature;
28
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
29
import org.gvsig.fmap.dal.feature.FeatureQuery;
30
import org.gvsig.fmap.dal.feature.FeatureSet;
31
import org.gvsig.fmap.dal.feature.FeatureStore;
32
import org.gvsig.fmap.dal.feature.FeatureType;
33
import org.gvsig.fmap.dal.swing.impl.featuretype.DefaultFeatureAttributeSelectionPanel;
34
import static org.gvsig.fmap.dal.swing.impl.searchpanel.DefaultSearchPanel.getAttributeDescriptorLabel;
35
import org.gvsig.tools.ToolsLocator;
36
import org.gvsig.tools.dataTypes.Coercion;
37
import org.gvsig.tools.dataTypes.CoercionException;
38
import org.gvsig.tools.exception.BaseException;
39
import org.gvsig.tools.i18n.I18nManager;
40
import org.gvsig.tools.swing.api.DropDown;
41
import org.gvsig.tools.swing.api.ToolsSwingLocator;
42
import org.gvsig.tools.swing.api.ToolsSwingManager;
43
import org.gvsig.tools.swing.api.windowmanager.Dialog;
44
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
45
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
46
import org.gvsig.tools.swing.icontheme.IconTheme;
47
import org.gvsig.tools.util.LabeledValue;
48
import org.gvsig.tools.util.LabeledValueImpl;
49
import org.gvsig.tools.visitor.VisitCanceledException;
50
import org.gvsig.tools.visitor.Visitor;
51
import org.slf4j.Logger;
52
import org.slf4j.LoggerFactory;
53

    
54
/**
55
 *
56
 * @author jjdelcerro
57
 */
58
@SuppressWarnings("UseSpecificCatch")
59
public class SearchConditionFieldController {
60

    
61
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchConditionFieldController.class);
62
    
63
    private static class FeatureAttribute extends LabeledValueImpl<String> {
64

    
65
        FeatureAttributeDescriptor attrdesc;
66
        private final FeatureStore store;
67
        private final int type;
68
        private final boolean showStoreName;
69

    
70
        public FeatureAttribute(FeatureStore store, FeatureAttributeDescriptor attrdesc, int type) {
71
            this(store, attrdesc, null, type, false);
72
        }
73

    
74
        public FeatureAttribute(
75
                FeatureStore store,
76
                FeatureAttributeDescriptor attrdesc, 
77
                String value,
78
                int type,
79
                boolean showStoreName
80
            ) {
81
            super(
82
                    getAttributeDescriptorLabel(attrdesc, store.getName()),
83
                    ObjectUtils.defaultIfNull(value, attrdesc.getName())
84
            );
85
            this.store = store;
86
            this.attrdesc = attrdesc;
87
            this.type = type;
88
            this.showStoreName = showStoreName;
89
        }
90

    
91
        @Override
92
        public String getLabel() {
93
            String theLabel = getAttributeDescriptorLabel(attrdesc, showStoreName? store.getName():null);
94
            switch(this.type) {
95
                case Search.OrderedAttribute.TYPE_REGURAL:
96
                    break;
97
                case Search.OrderedAttribute.TYPE_FAVORITE:
98
                    theLabel = "<html><b>"+theLabel+"</b></html>";
99
                    break;
100
                case Search.OrderedAttribute.TYPE_RECENT:
101
                    theLabel = "<html><i><b>"+theLabel+"</b></i></html>";
102
                    break;
103
            }
104
            return theLabel;
105
        }
106
        
107
        public FeatureAttributeDescriptor getDescriptor() {
108
            return this.attrdesc;
109
        }
110

    
111
        public FeatureStore getFeatureStore() {
112
            return this.store;
113
        }
114
        
115
        public boolean isExpression() {
116
            FeatureType type = this.attrdesc.getFeatureType();
117
            if (type == null) {
118
                return false;
119
            }
120
            Object x = type.get(this.getValue());
121
            return x == null;
122
        }
123

    
124
    }
125

    
126
    private FeatureStore store;
127
    private final JLabel lblFields;
128
    private final JLabel lblExtraFields;
129
    private final JLabel lblLogicalOperators;
130
    private final JLabel lblRelationalOperators;
131
    private final JComboBox cboValue;
132
    private Object valueAssigned = null;
133

    
134
    private DropDown ddnFields;
135
    private DropDown ddnLogicalOperators;
136
    private DropDown ddnRelationalOperators;
137

    
138
    private LabeledValue[] relationalOperators;
139
    private LabeledValue[] logicalOperators;
140

    
141
    public SearchConditionFieldController(
142
            FeatureStore store,
143
            JLabel lblFields,
144
            JLabel lblExtraFields,
145
            JLabel lblRelationalOperators,
146
            JComboBox cboValue,
147
            JLabel lblLogicalOperators
148
    ) {
149
        this.store = store;
150
        this.lblFields = lblFields;
151
        this.lblExtraFields = lblExtraFields;
152
        this.lblRelationalOperators = lblRelationalOperators;
153
        this.cboValue = cboValue;
154
        this.lblLogicalOperators = lblLogicalOperators;
155
        this.initComponents();
156
    }
157

    
158
    public boolean isAValidRelationOperator(String name) {
159
        for (LabeledValue relationalOperator : relationalOperators) {
160
            if( StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
161
                return true;
162
            }
163
        }
164
        return false;
165
    }
166
    
167
    private void initComponents() {
168
        try {
169
            I18nManager i18n = ToolsLocator.getI18nManager();
170
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
171
            
172
            relationalOperators = new LabeledValue[] {
173
                new LabeledValueImpl(i18n.getTranslation("_Equals_to"), ExpressionBuilder.OPERATOR_EQ),
174
                new LabeledValueImpl(i18n.getTranslation("_Like_to"), ExpressionBuilder.OPERATOR_ILIKE),
175
                new LabeledValueImpl(i18n.getTranslation("_Not_equals_to"), ExpressionBuilder.OPERATOR_NE),
176
                new LabeledValueImpl(i18n.getTranslation("_Greater_than"), ExpressionBuilder.OPERATOR_GT),
177
                new LabeledValueImpl(i18n.getTranslation("_Greater_or_equal_to"), ExpressionBuilder.OPERATOR_GE),
178
                new LabeledValueImpl(i18n.getTranslation("_Less_than"), ExpressionBuilder.OPERATOR_LT),
179
                new LabeledValueImpl(i18n.getTranslation("_Less_or_equal_to"), ExpressionBuilder.OPERATOR_LE)
180
            };
181

    
182
            logicalOperators = new LabeledValue[] {
183
                new LabeledValueImpl(i18n.getTranslation("_Or"), ExpressionBuilder.OPERATOR_OR),
184
                new LabeledValueImpl(i18n.getTranslation("_And"), ExpressionBuilder.OPERATOR_AND)
185
            };
186
            
187
            this.lblExtraFields.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
188

    
189
            this.ddnFields = toolsSwingManager.createDropDown(lblFields);
190
            this.ddnFields.setVisibleDropdownArrow(false);
191
            this.ddnRelationalOperators = toolsSwingManager.createDropDown(lblRelationalOperators);
192
            this.ddnRelationalOperators.setVisibleDropdownArrow(false);
193
            if (lblLogicalOperators != null) {
194
                this.ddnLogicalOperators = toolsSwingManager.createDropDown(lblLogicalOperators);
195
                this.ddnLogicalOperators.setVisibleDropdownArrow(false);
196
            }
197

    
198
            DefaultComboBoxModel modelRelationalOperators = new DefaultComboBoxModel();
199
            for (LabeledValue op : relationalOperators) {
200
                modelRelationalOperators.addElement(op);
201
            }
202
            this.ddnRelationalOperators.setModel(modelRelationalOperators);
203

    
204
            if (this.ddnLogicalOperators != null) {
205
                DefaultComboBoxModel modelLogicalOperators = new DefaultComboBoxModel();
206
                for (LabeledValue op : logicalOperators) {
207
                    modelLogicalOperators.addElement(op);
208
                }
209
                this.ddnLogicalOperators.setModel(modelLogicalOperators);
210
            }
211
            FeatureType featureType = store.getDefaultFeatureType();
212
            Search search = (Search) ToolsLocator.getComplementsManager().get(
213
                    Search.COMPLEMENT_MANE, featureType
214
            );
215
            List<Search.OrderedAttribute> orderedAttributes = search.getOrderedAttributes(
216
                    Search.BASIC_TYPES_FILTER,
217
                    Search.STR_INT_LONG_LABEL_ORDER,
218
                    20
219
            );
220
            List<ImageIcon>icons = new ArrayList<>();
221
//            DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
222
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
223
            DefaultComboBoxModel model = new DefaultComboBoxModel();
224
            for (Search.OrderedAttribute attr : orderedAttributes) {
225
                FeatureAttributeDescriptor attrdesc = attr.getDescriptor();
226
                model.addElement(new FeatureAttribute(this.store, attrdesc, attr.getType()));
227
                String iconName = attrdesc.getDataType().getIconName();
228
                if( iconTheme.exists(iconName) ) {
229
                    icons.add(iconTheme.get(iconName));
230
                } else {
231
                    icons.add(null);
232
                }
233
            }
234
            this.ddnFields.setIcons(icons);
235
            this.ddnFields.setModel(model);
236
            this.ddnFields.addItemListener(new ItemListener() {
237
                @Override
238
                public void itemStateChanged(ItemEvent e) {
239
                    if (e.getStateChange() == ItemEvent.SELECTED) {
240
                        doUpdateValuesList();
241
                    }
242

    
243
                }
244
            });
245

    
246
            this.lblExtraFields.addMouseListener(new MouseAdapter() {
247
                @Override
248
                public void mouseClicked(MouseEvent e) {
249
                    doSelectExtraField();
250
                }
251
            });
252
            clear();
253
        } catch (Exception ex) {
254
            throw new RuntimeException(ex);
255
        }
256
    }
257

    
258
    private FeatureType getFeatureType() {
259
        try {
260
            return this.store.getDefaultFeatureType();
261
        } catch (DataException ex) {
262
            return null;
263
        }
264
    }
265

    
266
    private void doSelectExtraField() {
267
        DefaultFeatureAttributeSelectionPanel panel = new DefaultFeatureAttributeSelectionPanel(store);
268
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
269
        final Dialog dialog = winManager.createDialog(
270
                panel,
271
                "Select attribute",
272
                null,
273
                WindowManager_v2.BUTTONS_OK_CANCEL
274
        );
275
        dialog.addActionListener((ActionEvent e) -> {
276
          if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
277
            doAddAndSelect(
278
                    panel.getSelectedStore(),
279
                    panel.getSelectedAttributeDescriptor(),
280
                    panel.getSelectedPath()
281
            );
282
          }
283
        });
284
        dialog.show(WindowManager.MODE.DIALOG);
285

    
286
    }
287

    
288
    private void doAddAndSelect(FeatureStore theStore, FeatureAttributeDescriptor attrdesc, FeatureAttributeDescriptor[] attributes) {
289
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
290
        List<String> list = new ArrayList<>();
291
        for (FeatureAttributeDescriptor attribute : attributes) {
292
            list.add(attribute.getName());
293
        }
294
        String storeFullName = theStore.getFullName();
295
        DefaultComboBoxModel<FeatureAttribute> model = (DefaultComboBoxModel) this.ddnFields.getModel();
296
        for (int i = 0; i < model.getSize(); i++) {
297
            FeatureAttribute attr = model.getElementAt(i);
298
            FeatureAttributeDescriptor attrdescN = attr.getDescriptor();
299
            if (StringUtils.equalsIgnoreCase(storeFullName, attrdescN.getStore().getFullName())
300
                    && StringUtils.equalsIgnoreCase(attrdesc.getName(), attrdescN.getName())) {
301
                this.setAttribute(i);
302
                return;
303
            }
304
        }
305
        String formula;
306
        boolean showStoreName;
307
        if (StringUtils.equalsIgnoreCase(storeFullName, this.store.getFullName())) {
308
            formula = attrdesc.getName();
309
            showStoreName = false;
310
        } else {
311
            formula = builder.function(
312
                    DataManager.FUNCTION_FOREING_VALUE, 
313
                    builder.constant(StringUtils.join(list,"."))
314
            ).toString();
315
            showStoreName = true;
316
        }
317
        FeatureAttribute attribute = new FeatureAttribute(theStore, attrdesc, formula, Search.OrderedAttribute.TYPE_REGURAL, showStoreName);
318
        model.addElement(attribute);
319
        IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
320
        this.ddnFields.getIcons().add(iconTheme.get(attrdesc.getDataType().getIconName()));
321
        this.setAttribute(model.getSize() - 1);
322
    }
323

    
324
    public void clear() {
325
        this.ddnRelationalOperators.setSelectedIndex(0);
326
        if (this.ddnLogicalOperators != null) {
327
            this.ddnLogicalOperators.setSelectedIndex(0);
328
        }
329
        this.cboValue.setSelectedIndex(-1);
330
    }
331

    
332
    private void doUpdateValuesList() {
333
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
334
        if (attribute == null) {
335
            return;
336
        }
337

    
338
        final List<Object> values = new ArrayList<>();
339
        final int limit = 60;
340
        final long timeLimit = System.currentTimeMillis() + limit * 1000;
341
        final DefaultComboBoxModel model = new DefaultComboBoxModel();
342
        this.setEnabled(false);
343
        final FeatureStore theStore = attribute.getFeatureStore();
344
        final FeatureQuery query = theStore.createFeatureQuery();
345
        query.addAttributeName(attribute.getDescriptor().getName());
346
        query.setLimit(1000);
347
        Thread th = new Thread(new Runnable() {
348
            @Override
349
            public void run() {
350
                try {
351
                    FeatureSet set = theStore.getFeatureSet(query);
352
                    set.accept(new Visitor() {
353
                        @Override
354
                        public void visit(Object o) throws VisitCanceledException, BaseException {
355
                            Object value = ((Feature) o).get(attribute.getDescriptor().getName());
356
                            if (!values.contains(value)) {
357
                                values.add(value);
358
                            }
359
                            if (System.currentTimeMillis() > timeLimit) {
360
                                throw new VisitCanceledException();
361
                            }
362
                            if (values.size() > 1000) {
363
                                throw new VisitCanceledException();
364
                            }
365
                        }
366
                    });
367
                } catch (VisitCanceledException ex) {
368

    
369
                } catch (Exception ex) {
370
                    LOGGER.warn("Can't update list of values of '"+attribute.getLabel()+"'.", ex);
371
                }
372
                List<LabeledValue> elements = new ArrayList<>();
373
                if (!values.isEmpty()) {
374
                    LabeledValue[] availableValues = attribute.getDescriptor().getAvailableValues();
375
                    Map<String, String> availableValuesMap = new HashMap<>();
376
                    if (availableValues != null) {
377
                        for (LabeledValue availableValue : availableValues) {
378
                            availableValuesMap.put(
379
                                    Objects.toString(availableValue.getValue()),
380
                                    availableValue.getLabel()
381
                            );
382
                        }
383
                    }
384
                    elements.add(new LabeledValueImpl("", null));
385
                    for (Object value : values) {
386
                        String key = Objects.toString(value);
387
                        String label = availableValuesMap.getOrDefault(key, key);
388
                        elements.add(new LabeledValueImpl(label, value));
389
                    }
390
                    elements.sort(null);
391
                    
392
                }
393
                for (LabeledValue element : elements) {
394
                    model.addElement(element);
395
                }
396
                SwingUtilities.invokeLater(new Runnable() {
397
                    @Override
398
                    public void run() {
399
                        cboValue.setModel(model);
400
                        if( valueAssigned!=null ) {
401
                            cboValue.setSelectedItem(valueAssigned);
402
                            valueAssigned = null;
403
                        }
404
                        setEnabled(true);
405
                    }
406
                });
407
            }
408
        });
409
        th.start();
410
    }
411

    
412
    public void setEnabled(boolean enabled) {
413
        this.ddnFields.setEnabled(enabled);
414
        if( this.ddnLogicalOperators!=null ) {
415
            this.ddnLogicalOperators.setEnabled(enabled);
416
        }
417
        this.ddnRelationalOperators.setEnabled(enabled);
418
        this.lblExtraFields.setEnabled(enabled);
419
    }
420
    
421
    public String getRelationalOperator() {
422
        LabeledValue<String> op = (LabeledValue) this.ddnRelationalOperators.getSelectedItem();
423
        if (op == null) {
424
            return null;
425
        }
426
        return op.getValue();
427
    }
428

    
429
    public int setRelationalOperator(String name) {
430
        int n = 0;
431
        for (LabeledValue relationalOperator : relationalOperators) {
432
            if( StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
433
                break;
434
            }
435
            n++;
436
        }
437
        if( this.relationalOperators.length<=n ) {
438
            return -1;
439
        }
440
        this.ddnRelationalOperators.setSelectedIndex(n);
441
        return n;
442
    }
443
    
444
    public String getLogicalOperator() {
445
        if (this.ddnLogicalOperators == null) {
446
            return null;
447
        }
448
        LabeledValue<String> rel = (LabeledValue) this.ddnLogicalOperators.getSelectedItem();
449
        if (rel == null) {
450
            return null;
451
        }
452
        return rel.getValue();
453
    }
454

    
455
    public Object getValue() {
456
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
457
        if (attribute == null) {
458
            return null;
459
        }
460
        Object v = this.cboValue.getSelectedItem();
461
        if (v == null) {
462
            return null;
463
        }
464
        if (v instanceof LabeledValue) {
465
            v = ((LabeledValue) v).getValue();
466
            if (v == null) {
467
                return null;
468
            }
469
        }
470
        if (v instanceof CharSequence) {
471
            if (StringUtils.isBlank((CharSequence) v)) {
472
                return null;
473
            }
474
        }
475
        Coercion coercion = attribute.getDescriptor().getDataType().getCoercion();
476
        try {
477
            return coercion.coerce(v);
478
        } catch (CoercionException ex) {
479
            return null;
480
        }
481
    }
482
    
483
    public void setValue(Object value) {
484
        this.cboValue.setSelectedItem(value);
485
        this.valueAssigned = value;
486
    }
487
    
488
    public boolean isAttributeAnExpression() {
489
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
490
        if (attribute == null) {
491
            return false;
492
        }
493
        return attribute.isExpression();
494
    }
495

    
496
    public String getAttribute() {
497
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
498
        if (attribute == null) {
499
            return null;
500
        }
501
        if( this.getValue()!=null ) {
502
            attribute.getDescriptor().recentUsed();
503
        }
504
        return attribute.getValue();
505
    }
506

    
507
    public int setAttribute(String name) {
508
        ComboBoxModel<FeatureAttribute> model = this.ddnFields.getModel();
509
        for (int i = 0; i < model.getSize(); i++) {
510
            FeatureAttribute x = model.getElementAt(i);
511
            if (StringUtils.equalsIgnoreCase(name, x.getValue())) {
512
                this.setAttribute(i);
513
                return i;
514
            }
515
        }
516
        this.setAttribute(-1);
517
        return -1;
518
    }
519

    
520
    public void setAttribute(int index) {
521
        try {
522
            this.ddnFields.setSelectedIndex(index);
523
        } catch (Exception ex) {
524
            this.ddnFields.setSelectedIndex(-1);
525
        }
526
        doUpdateValuesList();
527
    }
528

    
529
}