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 / SearchFieldController.java @ 44263

History | View | Annotate | Download (18.2 KB)

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

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

    
56
/**
57
 *
58
 * @author jjdelcerro
59
 */
60
@SuppressWarnings("UseSpecificCatch")
61
public class SearchFieldController {
62

    
63
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchFieldController.class);
64
    
65
    private static class FeatureAttribute extends LabeledValueImpl<String> {
66

    
67
        FeatureAttributeDescriptor attrdesc;
68
        private final FeatureStore store;
69

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

    
74
        public FeatureAttribute(
75
                FeatureStore store,
76
                FeatureAttributeDescriptor attrdesc, 
77
                String label, 
78
                String value
79
            ) {
80
            super(
81
                    ObjectUtils.defaultIfNull(label, attrdesc.getLabel()),
82
                    ObjectUtils.defaultIfNull(value, attrdesc.getName())
83
            );
84
            this.store = store;
85
            this.attrdesc = attrdesc;
86
        }
87

    
88
        public FeatureAttributeDescriptor getDescriptor() {
89
            return this.attrdesc;
90
        }
91

    
92
        public FeatureStore getFeatureStore() {
93
            return this.store;
94
        }
95
        
96
        public boolean isExpression() {
97
            FeatureType type = this.attrdesc.getFeatureType();
98
            if (type == null) {
99
                return false;
100
            }
101
            Object x = type.get(this.getValue());
102
            return x == null;
103
        }
104

    
105
    }
106

    
107
    private FeatureStore store;
108
    private final JLabel lblFields;
109
    private final JLabel lblExtraFields;
110
    private final JLabel lblLogicalOperators;
111
    private final JLabel lblRelationalOperators;
112
    private final JComboBox cboValue;
113

    
114
    private DropDown ddnFields;
115
    private DropDown ddnLogicalOperators;
116
    private DropDown ddnRelationalOperators;
117

    
118
    private final LabeledValue[] relationalOperators = {
119
        new LabeledValueImpl("Equals to", ExpressionBuilder.OPERATOR_EQ),
120
        new LabeledValueImpl("Like to", ExpressionBuilder.OPERATOR_ILIKE),
121
        new LabeledValueImpl("Not equals to", ExpressionBuilder.OPERATOR_NE),
122
        new LabeledValueImpl("Greater than", ExpressionBuilder.OPERATOR_GT),
123
        new LabeledValueImpl("Greater or equal to", ExpressionBuilder.OPERATOR_GE),
124
        new LabeledValueImpl("Less than", ExpressionBuilder.OPERATOR_LT),
125
        new LabeledValueImpl("Less or equal to", ExpressionBuilder.OPERATOR_LE)
126
    };
127
    private final LabeledValue[] logicalOperators = {
128
        new LabeledValueImpl("Or", ExpressionBuilder.OPERATOR_OR),
129
        new LabeledValueImpl("And", ExpressionBuilder.OPERATOR_AND)
130
    };
131

    
132
    public SearchFieldController(
133
            FeatureStore store,
134
            JLabel lblFields,
135
            JLabel lblExtraFields,
136
            JLabel lblRelationalOperators,
137
            JComboBox cboValue,
138
            JLabel lblLogicalOperators
139
    ) {
140
        this.store = store;
141
        this.lblFields = lblFields;
142
        this.lblExtraFields = lblExtraFields;
143
        this.lblRelationalOperators = lblRelationalOperators;
144
        this.cboValue = cboValue;
145
        this.lblLogicalOperators = lblLogicalOperators;
146
        this.initComponents();
147
    }
148

    
149
    private void initComponents() {
150
        try {
151
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
152
            this.lblExtraFields.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
153

    
154
            this.ddnFields = toolsSwingManager.createDropDown(lblFields);
155
            this.ddnRelationalOperators = toolsSwingManager.createDropDown(lblRelationalOperators);
156
            if (lblLogicalOperators != null) {
157
                this.ddnLogicalOperators = toolsSwingManager.createDropDown(lblLogicalOperators);
158
            }
159

    
160
            DefaultComboBoxModel modelRelationalOperators = new DefaultComboBoxModel();
161
            for (LabeledValue op : relationalOperators) {
162
                modelRelationalOperators.addElement(op);
163
            }
164
            this.ddnRelationalOperators.setModel(modelRelationalOperators);
165

    
166
            if (this.ddnLogicalOperators != null) {
167
                DefaultComboBoxModel modelLogicalOperators = new DefaultComboBoxModel();
168
                for (LabeledValue op : logicalOperators) {
169
                    modelLogicalOperators.addElement(op);
170
                }
171
                this.ddnLogicalOperators.setModel(modelLogicalOperators);
172
            }
173
            FeatureType featureType = store.getDefaultFeatureType();
174
            Search search = (Search) ToolsLocator.getComplementsManager().get(
175
                    Search.COMPLEMENT_MANE, featureType
176
            );
177
            List<FeatureAttributeDescriptor> orderedAttributes = search.getOrderedAttributes(
178
                    Search.BASIC_TYPES_FILTER,
179
                    Search.STR_INT_LONG_LABEL_ORDER,
180
                    20
181
            );
182
            List<ImageIcon>icons = new ArrayList<>();
183
            DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
184
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
185
            DefaultComboBoxModel model = new DefaultComboBoxModel();
186
            for (FeatureAttributeDescriptor attrdesc : orderedAttributes) {
187
                model.addElement(new FeatureAttribute(this.store, attrdesc));
188
                String iconName = attrdesc.getDataType().getIconName();
189
                if( iconTheme.exists(iconName) ) {
190
                    icons.add(iconTheme.get(iconName));
191
                } else {
192
                    icons.add(null);
193
                }
194
            }
195
            this.ddnFields.setIcons(icons);
196
            this.ddnFields.setModel(model);
197
            this.ddnFields.addItemListener(new ItemListener() {
198
                @Override
199
                public void itemStateChanged(ItemEvent e) {
200
                    if (e.getStateChange() == ItemEvent.SELECTED) {
201
                        doUpdateValuesList();
202
                    }
203

    
204
                }
205
            });
206

    
207
            this.lblExtraFields.addMouseListener(new MouseAdapter() {
208
                @Override
209
                public void mouseClicked(MouseEvent e) {
210
                    doSelectExtraField();
211
                }
212
            });
213
            clear();
214
        } catch (Exception ex) {
215
            throw new RuntimeException(ex);
216
        }
217
    }
218

    
219
    private FeatureType getFeatureType() {
220
        try {
221
            return this.store.getDefaultFeatureType();
222
        } catch (DataException ex) {
223
            return null;
224
        }
225
    }
226

    
227
    private void doSelectExtraField() {
228
        FeatureType featureType = this.getFeatureType();
229
        AdvancedAttributeSelectionTreeModel treeModel = new AdvancedAttributeSelectionTreeModel(
230
                this.store,
231
                Search.BASIC_TYPES_FILTER
232
        );
233
        final JTree tree = new JTree();
234
        tree.setCellRenderer(new AdvancedAttributeSelectionTreeCellRenderer());
235
        tree.setModel(treeModel);
236
        JScrollPane scrollpane = new JScrollPane(tree);
237
        scrollpane.setPreferredSize(new Dimension(400, 300));
238
        scrollpane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
239
        scrollpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
240

    
241
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
242
        final Dialog dialog = winManager.createDialog(
243
                scrollpane,
244
                "Select attribute",
245
                null,
246
                WindowManager_v2.BUTTONS_OK_CANCEL
247
        );
248
        dialog.addActionListener(new ActionListener() {
249
            @Override
250
            public void actionPerformed(ActionEvent e) {
251
                if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
252
                    TreePath path = tree.getSelectionPath();
253
                    doAddAndSelect(path.getPath());
254
                }
255
            }
256
        });
257
        dialog.show(WindowManager.MODE.DIALOG);
258

    
259
    }
260

    
261
    private void doAddAndSelect(Object[] nodes) {
262
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
263
        ExpressionBuilder.Function list = builder.list();
264
        for (int i = 1; i < nodes.length; i++) {
265
            Node node = (Node) nodes[i];
266
            FeatureAttributeDescriptor attrdesc = node.getValue();
267
            list.parameter(builder.constant(attrdesc.getName()));
268
        }
269
        Node node = (Node) nodes[nodes.length - 1];
270
        FeatureStore theStore = node.getFeatureStore();
271
        FeatureAttributeDescriptor attrdesc = node.getValue();
272
        String storeFullName = theStore.getFullName();
273
        DefaultComboBoxModel<FeatureAttribute> model = (DefaultComboBoxModel) this.ddnFields.getModel();
274
        for (int i = 0; i < model.getSize(); i++) {
275
            FeatureAttribute attr = model.getElementAt(i);
276
            FeatureAttributeDescriptor attrdescN = attr.getDescriptor();
277
            if (StringUtils.equalsIgnoreCase(storeFullName, attrdescN.getStore().getFullName())
278
                    && StringUtils.equalsIgnoreCase(attrdesc.getName(), attrdescN.getName())) {
279
                this.setAttribute(i);
280
                return;
281
            }
282
        }
283
        String formula = builder.function(DataManager.FUNCTION_FOREING_VALUE, list).toString();
284
        String label = attrdesc.getLabel() + " [" + theStore.getName() + "]";
285
        if (StringUtils.equalsIgnoreCase(storeFullName, this.store.getFullName())) {
286
            label = attrdesc.getLabel();
287
            formula = attrdesc.getName();
288
        }
289
        FeatureAttribute attribute = new FeatureAttribute(theStore, attrdesc, label, formula);
290
        model.addElement(attribute);
291
        IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
292
        this.ddnFields.getIcons().add(iconTheme.get(attrdesc.getDataType().getIconName()));
293
        this.setAttribute(model.getSize() - 1);
294
    }
295

    
296
    public void clear() {
297
        this.ddnRelationalOperators.setSelectedIndex(0);
298
        if (this.ddnLogicalOperators != null) {
299
            this.ddnLogicalOperators.setSelectedIndex(0);
300
        }
301
        this.cboValue.setSelectedIndex(-1);
302
    }
303

    
304
    private void doUpdateValuesList() {
305
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
306
        if (attribute == null) {
307
            return;
308
        }
309

    
310
        final List<Object> values = new ArrayList<>();
311
        final int limit = 60;
312
        final long timeLimit = System.currentTimeMillis() + limit * 1000;
313
        final DefaultComboBoxModel model = new DefaultComboBoxModel();
314
        this.setEnabled(false);
315
        Thread th = new Thread(new Runnable() {
316
            @Override
317
            public void run() {
318
                try {
319
                    FeatureSet set = attribute.getFeatureStore().getFeatureSet();
320
                    set.accept(new Visitor() {
321
                        @Override
322
                        public void visit(Object o) throws VisitCanceledException, BaseException {
323
                            Object value = ((Feature) o).get(attribute.getDescriptor().getName());
324
                            if (!values.contains(value)) {
325
                                values.add(value);
326
                            }
327
                            if (System.currentTimeMillis() > timeLimit) {
328
                                throw new VisitCanceledException();
329
                            }
330
                            if (values.size() > 1000) {
331
                                throw new VisitCanceledException();
332
                            }
333
                        }
334
                    });
335
                } catch (VisitCanceledException ex) {
336

    
337
                } catch (Exception ex) {
338
                    LOGGER.warn("Can't update list of values of '"+attribute.getLabel()+"'.", ex);
339
                }
340
                List<LabeledValue> elements = new ArrayList<>();
341
                if (!values.isEmpty()) {
342
                    LabeledValue[] availableValues = attribute.getDescriptor().getAvailableValues();
343
                    Map<String, String> availableValuesMap = new HashMap<>();
344
                    if (availableValues != null) {
345
                        for (LabeledValue availableValue : availableValues) {
346
                            availableValuesMap.put(
347
                                    Objects.toString(availableValue.getValue()),
348
                                    availableValue.getLabel()
349
                            );
350
                        }
351
                    }
352
                    elements.add(new LabeledValueImpl("", null));
353
                    for (Object value : values) {
354
                        String key = Objects.toString(value);
355
                        String label = availableValuesMap.getOrDefault(key, key);
356
                        elements.add(new LabeledValueImpl(label, value));
357
                    }
358
                    elements.sort(null);
359
                    
360
                }
361
                for (LabeledValue element : elements) {
362
                    model.addElement(element);
363
                }
364
                SwingUtilities.invokeLater(new Runnable() {
365
                    @Override
366
                    public void run() {
367
                        cboValue.setModel(model);
368
                        setEnabled(true);
369
                    }
370
                });
371
            }
372
        });
373
        th.start();
374
    }
375

    
376
    public void setEnabled(boolean enabled) {
377
        this.ddnFields.setEnabled(enabled);
378
        if( this.ddnLogicalOperators!=null ) {
379
            this.ddnLogicalOperators.setEnabled(enabled);
380
        }
381
        this.ddnRelationalOperators.setEnabled(enabled);
382
        this.lblExtraFields.setEnabled(enabled);
383
    }
384
    
385
    public String getRelationalOperator() {
386
        LabeledValue<String> op = (LabeledValue) this.ddnRelationalOperators.getSelectedItem();
387
        if (op == null) {
388
            return null;
389
        }
390
        return op.getValue();
391
    }
392

    
393
    public String getLogicalOperator() {
394
        if (this.ddnLogicalOperators == null) {
395
            return null;
396
        }
397
        LabeledValue<String> rel = (LabeledValue) this.ddnLogicalOperators.getSelectedItem();
398
        if (rel == null) {
399
            return null;
400
        }
401
        return rel.getValue();
402
    }
403

    
404
    public Object getValue() {
405
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
406
        if (attribute == null) {
407
            return null;
408
        }
409
        Object v = this.cboValue.getSelectedItem();
410
        if (v == null) {
411
            return null;
412
        }
413
        if (v instanceof LabeledValue) {
414
            v = ((LabeledValue) v).getValue();
415
            if (v == null) {
416
                return null;
417
            }
418
        }
419
        if (v instanceof CharSequence) {
420
            if (StringUtils.isBlank((CharSequence) v)) {
421
                return null;
422
            }
423
        }
424
        DataTypesManager.Coercion coercion = attribute.getDescriptor().getDataType().getCoercion();
425
        try {
426
            return coercion.coerce(v);
427
        } catch (CoercionException ex) {
428
            return null;
429
        }
430
    }
431

    
432
    public boolean isAttributeAnExpression() {
433
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
434
        if (attribute == null) {
435
            return false;
436
        }
437
        return attribute.isExpression();
438
    }
439

    
440
    public String getAttribute() {
441
        final FeatureAttribute attribute = (FeatureAttribute) this.ddnFields.getSelectedItem();
442
        if (attribute == null) {
443
            return null;
444
        }
445
        if( this.getValue()!=null ) {
446
            attribute.getDescriptor().recentUsed();
447
        }
448
        return attribute.getValue();
449
    }
450

    
451
    public void setAttribute(String name) {
452
        ComboBoxModel<FeatureAttribute> model = this.ddnFields.getModel();
453
        for (int i = 0; i < model.getSize(); i++) {
454
            FeatureAttribute x = model.getElementAt(i);
455
            if (StringUtils.equalsIgnoreCase(name, x.getLabel())) {
456
                this.setAttribute(i);
457
                return;
458
            }
459
        }
460
        this.setAttribute(-1);
461
    }
462

    
463
    public void setAttribute(int index) {
464
        try {
465
            this.ddnFields.setSelectedIndex(index);
466
        } catch (Exception ex) {
467
            this.ddnFields.setSelectedIndex(-1);
468
        }
469
        doUpdateValuesList();
470
    }
471

    
472
};