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 / DefaultSearchPanel.java @ 45229

History | View | Annotate | Download (44.2 KB)

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

    
3
import java.awt.BorderLayout;
4
import java.awt.Cursor;
5
import java.awt.Dimension;
6
import java.awt.FlowLayout;
7
import java.awt.event.ActionEvent;
8
import java.awt.event.ActionListener;
9
import java.awt.event.ComponentAdapter;
10
import java.awt.event.ComponentEvent;
11
import java.awt.event.KeyAdapter;
12
import java.awt.event.KeyEvent;
13
import java.net.URL;
14
import java.text.DateFormat;
15
import java.text.SimpleDateFormat;
16
import java.util.ArrayList;
17
import java.util.Calendar;
18
import java.util.Collection;
19
import java.util.Collections;
20
import java.util.Date;
21
import java.util.HashMap;
22
import java.util.List;
23
import java.util.Map;
24
import java.util.Objects;
25
import javax.swing.AbstractAction;
26
import javax.swing.Action;
27
import static javax.swing.Action.ACTION_COMMAND_KEY;
28
import static javax.swing.Action.NAME;
29
import javax.swing.BorderFactory;
30
import javax.swing.ImageIcon;
31
import javax.swing.JButton;
32
import javax.swing.JComponent;
33
import javax.swing.JOptionPane;
34
import javax.swing.ListSelectionModel;
35
import javax.swing.SwingUtilities;
36
import javax.swing.event.ListSelectionEvent;
37
import javax.swing.event.ListSelectionListener;
38
import javax.swing.table.DefaultTableModel;
39
import javax.swing.table.TableModel;
40
import org.apache.commons.io.FilenameUtils;
41
import org.apache.commons.lang.mutable.MutableObject;
42
import org.apache.commons.lang3.StringUtils;
43
import org.apache.commons.lang3.mutable.MutableLong;
44
import org.gvsig.configurableactions.ConfigurableActionsMamager;
45
import org.gvsig.expressionevaluator.Expression;
46
import org.gvsig.expressionevaluator.ExpressionBuilder;
47
import org.gvsig.expressionevaluator.ExpressionUtils;
48
import static org.gvsig.fmap.dal.DataManager.DAL_USE_LABELS;
49
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_BOTH;
50
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_NO;
51
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_YES;
52
import org.gvsig.fmap.dal.DataStore;
53
import org.gvsig.fmap.dal.DataStoreProviderFactory;
54
import org.gvsig.fmap.dal.complements.Search;
55
import org.gvsig.fmap.dal.feature.Feature;
56
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
57
import org.gvsig.fmap.dal.feature.FeatureQuery;
58
import org.gvsig.fmap.dal.feature.FeatureStore;
59
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
60
import org.gvsig.fmap.dal.feature.FeatureType;
61
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
62
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
63
import org.gvsig.fmap.dal.swing.DALActionFactory;
64
import org.gvsig.fmap.dal.swing.DALSwingLocator;
65
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
66
import org.gvsig.fmap.dal.swing.impl.featuretable.SimpleFeaturesTableModel;
67
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryGroupByPanel;
68
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
69
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel;
70
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel.SearchConditionPanelFactory;
71
import org.gvsig.tools.ToolsLocator;
72
import org.gvsig.tools.dataTypes.DataType;
73
import org.gvsig.tools.dynobject.Tags;
74
import org.gvsig.tools.i18n.I18nManager;
75
import org.gvsig.tools.swing.api.ActionListenerSupport;
76
import org.gvsig.tools.swing.api.ToolsSwingLocator;
77
import org.gvsig.tools.swing.api.ToolsSwingManager;
78
import org.gvsig.tools.swing.api.windowmanager.Dialog;
79
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
80
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
81
import org.gvsig.tools.swing.icontheme.IconTheme;
82
import org.gvsig.tools.util.ToolsUtilLocator;
83
import org.slf4j.Logger;
84
import org.slf4j.LoggerFactory;
85
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryGroupByPanel;
86
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryOrderPanel;
87
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryCalculatedColumnsPanel;
88
import org.gvsig.fmap.dal.swing.featuretype.FeatureAttributesSelectionPanel;
89
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
90
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
91
import org.gvsig.tools.bookmarksandhistory.History;
92
import org.gvsig.tools.dispose.Disposable;
93
import org.gvsig.tools.dispose.DisposeUtils;
94
import org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue;
95
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_GETVALUE;
96
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETVALUE;
97
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController;
98
import org.gvsig.tools.swing.api.bookmarkshistory.HistoryController;
99
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
100

    
101
/**
102
 *
103
 * @author jjdelcerro
104
 */
105
@SuppressWarnings({"UseSpecificCatch"})
106
public class DefaultSearchPanel
107
        extends DefaultSearchPanelView
108
        implements FeatureStoreSearchPanel {
109

    
110
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSearchPanel.class);
111

    
112
    static /* friend */ Integer useLabels = null;
113
    private BookmarksController bookmarksController;
114
    private HistoryController historyController;
115
    private FeatureQuery lastQuery;
116

    
117
    public static class UseLabelsYesAction extends AbstractAction {
118

    
119
        @SuppressWarnings("OverridableMethodCallInConstructor")
120
        public UseLabelsYesAction() {
121
            I18nManager i18n = ToolsLocator.getI18nManager();
122

    
123
            this.putValue(NAME, i18n.getTranslation("_Use_labels"));
124
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsYes");
125
        }
126

    
127
        @Override
128
        public Object getValue(String key) {
129
            if (NAME.equals(key)) {
130
                // Cuando se registra la accion aun no se han cargado las traducciones
131
                I18nManager i18n = ToolsLocator.getI18nManager();
132
                return i18n.getTranslation("_Use_labels");
133
            }
134
            return super.getValue(key);
135
        }
136

    
137
        @Override
138
        public void actionPerformed(ActionEvent ae) {
139
            DefaultSearchPanel.useLabels = USE_LABELS_YES;
140
        }
141
    }
142

    
143
    public static class UseLabelsNoAction extends AbstractAction {
144

    
145
        @SuppressWarnings("OverridableMethodCallInConstructor")
146
        public UseLabelsNoAction() {
147
            I18nManager i18n = ToolsLocator.getI18nManager();
148
            this.putValue(NAME, i18n.getTranslation("_Use_names"));
149
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsNo");
150
        }
151

    
152
        @Override
153
        public Object getValue(String key) {
154
            if (NAME.equals(key)) {
155
                // Cuando se registra la accion aun no se han cargado las traducciones
156
                I18nManager i18n = ToolsLocator.getI18nManager();
157
                return i18n.getTranslation("_Use_names");
158
            }
159
            return super.getValue(key);
160
        }
161

    
162
        @Override
163
        public void actionPerformed(ActionEvent ae) {
164
            DefaultSearchPanel.useLabels = USE_LABELS_NO;
165
        }
166
    }
167

    
168
    public static class UseLabelsBothAction extends AbstractAction {
169

    
170
        @SuppressWarnings("OverridableMethodCallInConstructor")
171
        public UseLabelsBothAction() {
172
            I18nManager i18n = ToolsLocator.getI18nManager();
173

    
174
            this.putValue(NAME, i18n.getTranslation("_Use_labels_and_names"));
175
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsBoth");
176
        }
177

    
178
        @Override
179
        public Object getValue(String key) {
180
            if (NAME.equals(key)) {
181
                // Cuando se registra la accion aun no se han cargado las traducciones
182
                I18nManager i18n = ToolsLocator.getI18nManager();
183
                return i18n.getTranslation("_Use_labels_and_names");
184
            }
185
            return super.getValue(key);
186
        }
187

    
188
        @Override
189
        public void actionPerformed(ActionEvent ae) {
190
            DefaultSearchPanel.useLabels = USE_LABELS_BOTH;
191
        }
192
    }
193

    
194
    public static class SelectColumnsAction extends AbstractAction {
195

    
196
        @SuppressWarnings("OverridableMethodCallInConstructor")
197
        public SelectColumnsAction() {
198
            I18nManager i18n = ToolsLocator.getI18nManager();
199

    
200
            this.putValue(NAME, i18n.getTranslation("_Select_columns_to_display"));
201
            this.putValue(ACTION_COMMAND_KEY, "SelectColumns");
202
        }
203

    
204
        @Override
205
        public Object getValue(String key) {
206
            if (NAME.equals(key)) {
207
                // Cuando se registra la accion aun no se han cargado las traducciones
208
                I18nManager i18n = ToolsLocator.getI18nManager();
209
                return i18n.getTranslation("_Select_columns_to_display");
210
            }
211
            return super.getValue(key);
212
        }
213

    
214
        @Override
215
        public void actionPerformed(ActionEvent ae) {
216
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
217
            panel.doSelectResultColumnNames();
218
        }
219
    }
220

    
221
    public static class CalculatedColumnsAction extends AbstractAction {
222

    
223
        @SuppressWarnings("OverridableMethodCallInConstructor")
224
        public CalculatedColumnsAction() {
225
            I18nManager i18n = ToolsLocator.getI18nManager();
226

    
227
            this.putValue(NAME, i18n.getTranslation("_Calculated_columns"));
228
            this.putValue(ACTION_COMMAND_KEY, "CalculatedColumns");
229
        }
230

    
231
        @Override
232
        public Object getValue(String key) {
233
            if (NAME.equals(key)) {
234
                // Cuando se registra la accion aun no se han cargado las traducciones
235
                I18nManager i18n = ToolsLocator.getI18nManager();
236
                return i18n.getTranslation("_Calculated_columns");
237
            }
238
            return super.getValue(key);
239
        }
240

    
241
        @Override
242
        public void actionPerformed(ActionEvent ae) {
243
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
244
            panel.doCalculatedColumns();
245
        }
246
    }
247

    
248
    public static class GroupByAction extends AbstractAction {
249

    
250
        @SuppressWarnings("OverridableMethodCallInConstructor")
251
        public GroupByAction() {
252
            I18nManager i18n = ToolsLocator.getI18nManager();
253

    
254
            this.putValue(NAME, i18n.getTranslation("_Group_by"));
255
            this.putValue(ACTION_COMMAND_KEY, "GroupBy");
256
        }
257

    
258
        @Override
259
        public Object getValue(String key) {
260
            if (NAME.equals(key)) {
261
                // Cuando se registra la accion aun no se han cargado las traducciones
262
                I18nManager i18n = ToolsLocator.getI18nManager();
263
                return i18n.getTranslation("_Group_by");
264
            }
265
            return super.getValue(key);
266
        }
267

    
268
        @Override
269
        public void actionPerformed(ActionEvent ae) {
270
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
271
            panel.doGroupBy();
272
        }
273
    }
274

    
275
    public static class OrderByAction extends AbstractAction {
276

    
277
        @SuppressWarnings("OverridableMethodCallInConstructor")
278
        public OrderByAction() {
279
            I18nManager i18n = ToolsLocator.getI18nManager();
280

    
281
            this.putValue(NAME, i18n.getTranslation("_Order_by"));
282
            this.putValue(ACTION_COMMAND_KEY, "SelectOrderBy");
283
        }
284

    
285
        @Override
286
        public Object getValue(String key) {
287
            if (NAME.equals(key)) {
288
                // Cuando se registra la accion aun no se han cargado las traducciones
289
                I18nManager i18n = ToolsLocator.getI18nManager();
290
                return i18n.getTranslation("_Order_by");
291
            }
292
            return super.getValue(key);
293
        }
294

    
295
        @Override
296
        public void actionPerformed(ActionEvent ae) {
297
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
298
            panel.doOrderBy();
299
        }
300
    }
301

    
302
    private class ActionButtons {
303

    
304
        private final DALActionFactory factory;
305
        private final Action action;
306
        private final JButton button;
307

    
308
        public ActionButtons(DALActionFactory factory, Action action, JButton button) {
309
            this.factory = factory;
310
            this.action = action;
311
            this.button = button;
312
        }
313
    }
314

    
315
    public static class SearchActionContext extends AbstractDALActionContext {
316

    
317
        private final DefaultSearchPanel panel;
318

    
319
        public SearchActionContext(DefaultSearchPanel panel) {
320
            super(FeatureStoreSearchPanel.ACTION_CONTEXT_NAME);
321
            this.panel = panel;
322
        }
323

    
324
        @Override
325
        public DataStore getStore() {
326
            return this.panel.getStore();
327
        }
328

    
329
        @Override
330
        public JComponent getActionButton(String actionName) {
331
            return this.panel.getActionButton(actionName);
332
        }
333

    
334
        @Override
335
        public int getSelectedsCount() {
336
            return this.panel.getSelectedFeatureCount();
337
        }
338

    
339
        @Override
340
        public Expression getFilterForSelecteds() {
341
            return this.panel.getFilterForSelectedFeature();
342
        }
343

    
344
        @Override
345
        public FeatureQuery getQuery() {
346
            return this.panel.getQuery();
347
        }
348
    }
349

    
350
    private FeatureStore store;
351
    private final ActionListenerSupport acctionListeners;
352
    private final Map<String, ActionButtons> actions;
353
    private boolean showActions = true;
354
    private DefaultSearchParameters parameters;
355

    
356
    private List<SearchConditionPanel> conditionPanels;
357

    
358
    private static final int PANEL_SIMPLIFIED = 0;
359
    private static final int PANEL_ADVANCED = 1;
360
    private static final String BOOKMARKSANDHISTORY_NAME = "SearchPanel";
361
    private final Bookmarks<Object> bookmarks;
362
    private final History<Object> history;
363

    
364
    public DefaultSearchPanel(FeatureStore store) {
365
        this.store = store;
366
        DisposeUtils.bind(store);
367
        this.acctionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
368
        this.actions = new HashMap<>();
369
        this.parameters = new DefaultSearchParameters();
370
        FeatureQuery featureQuery = this.store.createFeatureQuery();
371
        featureQuery.retrievesAllAttributes();
372
        this.parameters.setQuery(featureQuery);
373

    
374
        Search search = (Search) ToolsLocator.getComplementsManager().get(
375
                Search.COMPLEMENT_MANE, getFeatureType()
376
        );
377
        List<Search.OrderedAttribute> attributos = search.getOrderedAttributes(
378
                Search.BASIC_TYPES_FILTER,
379
                Search.STR_INT_LONG_LABEL_ORDER,
380
                12
381
        );
382
        for (Search.OrderedAttribute attrdesc : attributos) {
383
            this.parameters.getResultColumnNames().add(attrdesc.getDescriptor().getName());
384
        }
385
        this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
386
        this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
387
    }
388

    
389
    @Override
390
    public void dispose() {
391
        DisposeUtils.disposeQuietly(store);
392
        TableModel m = this.tblResults.getModel();
393
        if( m instanceof Disposable ) {
394
            DisposeUtils.disposeQuietly((Disposable) m);
395
        }
396
        this.store = null;
397
        this.tblResults.setModel(new DefaultTableModel());
398
    }
399

    
400
    @Override
401
    public JComponent asJComponent() {
402
        if (this.conditionPanels == null) {
403
            this.initComponents();
404
        }
405
        return this;
406
    }
407

    
408
    private void addActions() {
409
        if (!this.showActions) {
410
            return;
411
        }
412
        this.pnlActions.removeAll();
413
        this.pnlActions.setLayout(new FlowLayout(FlowLayout.TRAILING, 8, 4));
414
        SearchActionContext actionContext = new SearchActionContext(this);
415
        Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getStoreActions();
416
        for (DALActionFactory factory : factories) {
417
            Action action = factory.createAction(actionContext);
418
            JButton button = new JButton(action);
419
            this.actions.put(factory.getName(), new ActionButtons(factory, action, button));
420
            button.setBorder(BorderFactory.createEmptyBorder());
421
            button.setBorderPainted(false);
422
            button.setFocusPainted(false);
423
            button.setContentAreaFilled(false);
424
            button.setCursor(new Cursor(Cursor.HAND_CURSOR));
425
            this.pnlActions.add(button);
426
        }
427
        this.pnlActions.revalidate();
428
        this.pnlActions.repaint();
429
    }
430

    
431
    @Override
432
    public void addActionListener(ActionListener listener) {
433
        this.acctionListeners.addActionListener(listener);
434
    }
435

    
436
    @Override
437
    public ActionListener[] getActionListeners() {
438
        return this.acctionListeners.getActionListeners();
439
    }
440

    
441
    @Override
442
    public void removeActionListener(ActionListener listener) {
443
        this.acctionListeners.removeActionListener(listener);
444
    }
445

    
446
    @Override
447
    public void removeAllActionListener() {
448
        this.acctionListeners.removeAllActionListener();
449
    }
450

    
451
    @Override
452
    public void fireActionEvent(ActionEvent event) {
453
        this.acctionListeners.fireActionEvent(event);
454
    }
455

    
456
    @Override
457
    public boolean hasActionListeners() {
458
        return this.acctionListeners.hasActionListeners();
459
    }
460

    
461
    private void initComponents() {
462
        this.conditionPanels = new ArrayList<>();
463

    
464
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
465
        swingManager.translate(this.tabSearchMode);
466
        swingManager.translate(this.btnSearch);
467
        swingManager.translate(this.btnClear);
468
        swingManager.translate(this.lblExpressionDeBusqueda);
469
        swingManager.translate(this.btnAddAccumulatedFilter);
470
        swingManager.translate(this.btnRemoveAccumulatedFilter);
471
        swingManager.translate(this.btnViewAccumulatedFilter);
472

    
473
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
474
        JComponent c = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
475
        this.pnlCfgActions.setLayout(new BorderLayout(0, 0));
476
        this.pnlCfgActions.add(c, BorderLayout.CENTER);
477

    
478
        this.conditionPanels.add(
479
                new SearchConditionPanelSimplified(
480
                        parameters,
481
                        store,
482
                        btnAddAccumulatedFilter,
483
                        btnRemoveAccumulatedFilter,
484
                        btnViewAccumulatedFilter,
485
                        lblField1,
486
                        lblExtraFields1,
487
                        lblRelationalOperator1,
488
                        cboValue1,
489
                        lblLogicalOperators1,
490
                        lblField2,
491
                        lblExtraFields2,
492
                        lblRelationalOperator2,
493
                        cboValue2,
494
                        lblLogicalOperators2,
495
                        lblField3,
496
                        lblExtraFields3,
497
                        lblRelationalOperator3,
498
                        cboValue3,
499
                        lblLogicalOperators3,
500
                        lblField4,
501
                        lblExtraFields4,
502
                        lblRelationalOperator4,
503
                        cboValue4,
504
                        null
505
                )
506
        );
507
        this.conditionPanels.add(
508
                new SearchConditionPanelAdvanced(
509
                        this.store,
510
                        txtAdvancedExpression,
511
                        btnAdvancedExpression,
512
                        btnAdvancedExpressionHistory,
513
                        btnAdvancedExpressionBookmarks
514
                )
515
        );
516
        for (SearchConditionPanelFactory factory : DALSwingLocator.getManager().getSearchConditionPanels()) {
517
            String factoryName = "unknown";
518
            try {
519
                factoryName = factory.getName();
520
                if (factory.isApplicable(store)) {
521
                    SearchConditionPanel panel = factory.create(this);
522
                    this.conditionPanels.add(panel);
523
                    this.tabSearchMode.add(factory.getName(), panel.asJComponent());
524
                }
525
            } catch (Throwable th) {
526
                LOGGER.warn("Can't create search panel '" + factoryName + "'.");
527
            }
528
        }
529

    
530
        this.btnSearch.addActionListener((ActionEvent e) -> {
531
            search();
532
        });
533

    
534
        this.tblResults.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
535
            for (ActionButtons actionButton : actions.values()) {
536
                if (actionButton.action instanceof ListSelectionListener) {
537
                    ((ListSelectionListener) actionButton.action).valueChanged(e);
538
                }
539
            }
540
        });
541
        this.btnClear.addActionListener((ActionEvent e) -> {
542
            clear();
543
        });
544
        addActions();
545

    
546
        swingManager.createTableColumnAdjuster(tblResults);
547

    
548
        this.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
549

    
550
        this.bookmarksController = ToolsSwingLocator.getToolsSwingManager().createBookmarksController(this.bookmarks, btnBookmarks);
551
        this.historyController = ToolsSwingLocator.getToolsSwingManager().createHistoryController(this.history, btnHistory);
552

    
553
        this.historyController.setFilter(null);
554

    
555
        ActionListener bookmarksAndHistoryListener = new ActionListener() {
556
            @Override
557
            public void actionPerformed(ActionEvent e) {
558
                ActionEventWithCurrentValue<DefaultSearchParameters> b = (ActionEventWithCurrentValue<DefaultSearchParameters>) e;
559
                switch (b.getID()) {
560
                    case ID_GETVALUE:
561
                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
562
                        b.setCurrentValue(actualParams);
563
                        break;
564

    
565
                    case ID_SETVALUE:
566
                        if (b.getCurrentValue() == null) {
567
                            return;
568
                        }
569
                        DefaultSearchParameters searchParams;
570
                        try {
571
                            searchParams = b.getCurrentValue().getCopy();
572
                        } catch (Exception ex) {
573
                            LOGGER.warn("Not been able to clone export parameters", ex);
574
                            return;
575
                        }
576
                        clear();
577
                        put(searchParams);
578
                        break;
579
                }
580

    
581
            }
582
        };
583
        this.historyController.addActionListener(bookmarksAndHistoryListener);
584
        this.bookmarksController.addActionListener(bookmarksAndHistoryListener);
585
        this.addComponentListener(new ComponentAdapter() {
586
            @Override
587
            public void componentHidden(ComponentEvent e) {
588
                dispose();
589
            }
590
        });
591
        this.tblResults.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
592
        this.tblResults.addKeyListener(new KeyAdapter() {
593
            @Override
594
            public void keyPressed(KeyEvent e) {
595
                if( e.getKeyCode()==KeyEvent.VK_F4 ) {
596
                    doShowCellInDialog();
597
                }
598
            }
599
        });
600
        search();
601
    }
602
    
603
    private void doShowCellInDialog() {
604
        int row = this.tblResults.getSelectedRow();
605
        if( row < 0 ) {
606
            return;
607
        }
608
        int col = this.tblResults.getSelectedColumn();
609
        if( col < 0 ) {
610
            return;
611
        }
612
        String s = Objects.toString(this.tblResults.getValueAt(row, col),null);
613
        if( StringUtils.isBlank(s) ) {
614
            return;
615
        }
616
        ToolsSwingLocator.getToolsSwingManager().showZoomDialog(
617
            this, 
618
            this.tblResults.getColumnName(col), 
619
            s,
620
            false
621
        );
622
    }
623

    
624
    private FeatureType getFeatureType() {
625
        try {
626
            return store.getDefaultFeatureType();
627
        } catch (Exception ex) {
628
            throw new RuntimeException("Can't retrieve the feature type.", ex);
629
        }
630
    }
631

    
632
    @Override
633
    public void setEnabled(boolean enabled) {
634
        if (this.conditionPanels == null) {
635
            this.initComponents();
636
        }
637
        for (SearchConditionPanel conditionPanel : conditionPanels) {
638
            conditionPanel.setEnabled(enabled);
639
        }
640

    
641
        this.btnClear.setEnabled(enabled);
642
        this.btnSearch.setEnabled(enabled);
643
        for (ActionButtons actionButton : actions.values()) {
644
            actionButton.action.setEnabled(enabled);
645
        }
646
    }
647

    
648
    @Override
649
    public void clear() {
650
        if (this.conditionPanels == null) {
651
            return;
652
        }
653
        for (SearchConditionPanel conditionPanel : conditionPanels) {
654
            conditionPanel.clear();
655
        }
656
    }
657

    
658
    @Override
659
    public FeatureQuery getLastQuery() {
660
        return this.lastQuery;
661
    }
662

    
663
    public boolean isValid(StringBuilder message) {
664
        int searchMode = this.tabSearchMode.getSelectedIndex();
665
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
666
        boolean valid = panel.isValid(message);
667
        return valid;
668
    }
669

    
670
    @Override
671
    public void search() {
672
        final MutableObject model = new MutableObject(null);
673

    
674
        StringBuilder message = new StringBuilder();
675
        if (!this.isValid(message)) {
676
            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
677
            dialogManager.messageDialog(
678
                    "_The_specified_search_condition_is_not_valid",
679
                    "_Search",
680
                    JOptionPane.WARNING_MESSAGE
681
            );
682
            return;
683
        }
684
        lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Searching")+"...");
685
        setEnabled(false);
686
        Thread th = new Thread(() -> {
687
            try {
688
            FeatureQuery myQuery;
689
            SearchParameters searchParams;
690
            List<String> resultColumnNames;
691
            try {
692
                searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
693
                resultColumnNames = searchParams.getResultColumnNames();
694
                Date date = Calendar.getInstance().getTime();
695
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
696
                String strDate = dateFormat.format(date);
697
                searchParams.setName("Params: " + strDate);
698
            } catch (Exception ex) {
699
                LOGGER.warn("Not able to create search parameters.", ex);
700
                resetTable();
701
                return;
702
            }
703
            
704
            final MutableLong rowCount=new MutableLong();
705
            try {
706
                final List<Feature> features;
707

    
708
                myQuery = this.getQuery().getCopy();
709
                features = store.getFeatures(myQuery, 20);
710
                FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
711
                FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
712
                    // al modelo le pasamos el ftype de esas features
713
                    SimpleFeaturesTableModel tableModel = new SimpleFeaturesTableModel(
714
                            ftype,
715
                            resultColumnNames,
716
                            features
717
                    );
718
                model.setValue(tableModel);
719
                rowCount.setValue(tableModel.getRowCount());
720
            } catch (Exception ex) {
721
                LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
722
                resetTable();
723
            } finally {
724
                SwingUtilities.invokeLater(() -> {
725
                    I18nManager i18n = ToolsLocator.getI18nManager();
726
                    TableModel oldmodel = tblResults.getModel();
727
                    SimpleFeaturesTableModel m = (SimpleFeaturesTableModel) model.getValue();
728
                    tblResults.setModel(m);
729
                    SimpleFeaturesTableModel.setCellRenderers(tblResults);
730
                    if( oldmodel instanceof SimpleFeaturesTableModel )  {
731
                        ((SimpleFeaturesTableModel)oldmodel).dispose();
732
                    }
733
                    if( m.hasErrors() ) {
734
                      lblMsg.setText(i18n.getTranslation("_Errors_occurred_during_search"));
735
                    } else {
736
                      lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), rowCount.getValue()));
737
                    }
738
                    setEnabled(true);
739
                });
740
                if (this.parameters != null && this.parameters.getQuery() != null) {
741
                    this.history.add(searchParams);                   
742
                }
743
            }
744
            } catch (Exception ex) {
745
                LOGGER.warn("Search panel has errors during the search", ex);
746
                resetTable();
747
            } finally {
748
                SwingUtilities.invokeLater(() -> {
749
                    setEnabled(true);
750
                });
751
            }
752
        });
753
        th.start();
754
    }
755
    
756
    private void resetTable() {
757
        if(!SwingUtilities.isEventDispatchThread()) {
758
            SwingUtilities.invokeLater(this::resetTable);
759
            return;
760
        }
761
        List<String> resultColumnNames = null;
762
        try {
763
            resultColumnNames = this.parameters.getResultColumnNames();
764
        } catch(Exception ex) {
765
            
766
        }
767
        FeatureType ftype = this.store.getDefaultFeatureTypeQuietly();
768
        SimpleFeaturesTableModel emptyTableModel = new SimpleFeaturesTableModel(
769
                ftype,
770
                resultColumnNames,
771
                null
772
        );
773
        this.tblResults.setModel(emptyTableModel);
774
        
775
    }
776

    
777
    public void setResultColumnNames(List<String> names) {
778
        this.parameters.getResultColumnNames().clear();
779
        this.parameters.getResultColumnNames().addAll(names);
780
        if (this.conditionPanels == null) {
781
            return;
782
        }
783
        SimpleFeaturesTableModel model;
784
//        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
785
        List<Feature> features = store.getFeatures(this.parameters.getQuery());
786
        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
787
        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
788
        model = new SimpleFeaturesTableModel(
789
                ftype,
790
                this.parameters.getResultColumnNames(),
791
                features
792
        );
793
        tblResults.setModel(model);
794
    }
795

    
796
    @Override
797
    public boolean setFilter(Expression filter) {
798
        try {
799
            if (this.conditionPanels == null) {
800
                this.initComponents();
801
            }
802
            if (ExpressionUtils.isPhraseEmpty(filter)) {
803
                this.clear();
804
                return true;
805
            }
806
            int panel = 0;
807
            int selected = PANEL_ADVANCED;
808
            for (SearchConditionPanel conditionPanel : conditionPanels) {
809
                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
810
                    selected = panel;
811
                }
812
                panel++;
813
            }
814
            this.tabSearchMode.setSelectedIndex(selected);
815

    
816
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
817
//            tblResults.setModel(model);
818
//            lblMsg.setText("");
819
            return true;
820
        } catch (Exception ex) {
821
            LOGGER.warn("Can't set current search", ex);
822
            return false;
823
        }
824
    }
825

    
826
    @Override
827
    public List<SearchConditionPanel> getConditionPanels() {
828
        return Collections.unmodifiableList(this.conditionPanels);
829
    }
830

    
831
    @Override
832
    public SearchConditionPanel getConditionPanel(String name) {
833
        for (SearchConditionPanel panel : conditionPanels) {
834
            if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
835
                return panel;
836
            }
837
        }
838
        return null;
839
    }
840

    
841
    @Override
842
    public Expression getFilterForSelectedFeature() {
843
        if (this.conditionPanels == null) {
844
            return null;
845
        }
846
        int selectedRow = this.tblResults.getSelectedRow();
847
        if (selectedRow < 0) {
848
            return null;
849
        }
850
        try {
851
            List<Feature> features = ((SimpleFeaturesTableModel) this.tblResults.getModel()).getFeatures();
852
            Feature feature = features.get(selectedRow);
853

    
854
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
855
            FeatureType ftype = this.store.getDefaultFeatureType();
856
            for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
857
                builder.and(
858
                        builder.eq(
859
                                builder.column(attrdesc.getName()),
860
                                builder.constant(feature.get(attrdesc.getName()))
861
                        )
862
                );
863
            }
864
            Expression filter = ExpressionUtils.createExpression(builder.toString());
865
            return filter;
866
        } catch (Exception ex) {
867
            LOGGER.warn("Can't build search for the selected feature.", ex);
868
            return null;
869
        }
870
    }
871

    
872
    @Override
873
    public FeatureStore getStore() {
874
        return store;
875
    }
876

    
877
    private void doOrderBy() {
878
        I18nManager i18n = ToolsLocator.getI18nManager();
879
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
880
        FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
881
        orderPanel.setStore(store);
882
        orderPanel.put(parameters.getQuery());
883
        Dialog dialog = windowManager.createDialog(
884
                orderPanel.asJComponent(),
885
                i18n.getTranslation("_Select_order"),
886
                null,
887
                WindowManager_v2.BUTTONS_OK_CANCEL
888
        );
889
        dialog.addActionListener((ActionEvent e) -> {
890
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
891
                orderPanel.fetch(this.parameters.getQuery());
892
                search();
893
            }
894
        });
895
        dialog.show(WindowManager.MODE.DIALOG);
896

    
897
    }
898

    
899
    @Override
900
    public ImageIcon loadImage(String imageName) {
901
        String name = FilenameUtils.getBaseName(imageName);
902
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
903
        if (theme.exists(name)) {
904
            return theme.get(name);
905
        }
906
        URL url = this.getClass().getResource(name + ".png");
907
        if (url == null) {
908
            return null;
909
        }
910
        return new ImageIcon(url);
911
    }
912

    
913
    @Override
914
    public int getSelectedFeatureCount() {
915
        if (this.conditionPanels == null) {
916
            return 0;
917
        }
918
        return this.tblResults.getSelectedRowCount();
919
    }
920

    
921
    @Override
922
    public JComponent getActionButton(String name) {
923
        ActionButtons actionButton = this.actions.get(name);
924
        if (actionButton == null) {
925
            return null;
926
        }
927
        return actionButton.button;
928
    }
929

    
930
    @Override
931
    public void setShowActions(boolean showActions) {
932
        this.showActions = showActions;
933
    }
934

    
935
    @Override
936
    public boolean isShowActions() {
937
        return this.showActions;
938
    }
939

    
940
    public static String getAttributeDescriptorLabel(FeatureAttributeDescriptor attrdesc, String tableName) {
941
        String theLabel;
942
        int theUseLabels;
943
        if (useLabels == null) {
944
            Tags tags = attrdesc.getTags();
945
            if (tags.has(DAL_USE_LABELS)) {
946
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
947
            } else {
948
                if (attrdesc.getFeatureType()!=null) {
949
                    tags = attrdesc.getFeatureType().getTags();
950
                    theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
951
                } else {
952
                    theUseLabels = USE_LABELS_NO;
953
                }
954
            }
955
        } else {
956
            theUseLabels = useLabels;
957
        }
958
        switch (theUseLabels) {
959
            case USE_LABELS_YES:
960
                if (StringUtils.isBlank(tableName)) {
961
                    theLabel = attrdesc.getLocalizedLabel();
962
                } else {
963
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), tableName);
964
                }
965
                break;
966
            default:
967
            case USE_LABELS_NO:
968
                if (StringUtils.isBlank(tableName)) {
969
                    theLabel = attrdesc.getName();
970
                } else {
971
                    theLabel = String.format("%s [%s]", attrdesc.getName(), tableName);
972
                }
973
                break;
974
            case USE_LABELS_BOTH:
975
                if (StringUtils.isBlank(tableName)) {
976
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), attrdesc.getName());
977
                } else {
978
                    theLabel = String.format("%s [%s/%s]", attrdesc.getLocalizedLabel(), attrdesc.getName(), tableName);
979
                }
980
                break;
981
        }
982
        return theLabel;
983
    }
984

    
985
    private void doCalculatedColumns() {
986
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
987
        I18nManager i18n = ToolsLocator.getI18nManager();
988
        final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
989
        panel.setStore(this.store);
990
        panel.put(this.parameters.getQuery());
991
        final Dialog dialog = winmanager.createDialog(
992
                panel.asJComponent(),
993
                i18n.getTranslation("_Calculated_columns"),
994
                null,
995
                WindowManager_v2.BUTTONS_OK_CANCEL
996
        );
997
        dialog.addActionListener((ActionEvent e) -> {
998
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
999
                panel.fetch(this.parameters.getQuery());
1000
                search();
1001
            }
1002
        });
1003
        dialog.show(WindowManager.MODE.DIALOG);
1004
    }
1005

    
1006
    private void doGroupBy() {
1007
        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1008
        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1009
        if (allowGroupBy != DataType.YES) {
1010
          // FIXME: mensaje al usaurio.
1011
          I18nManager i18n = ToolsLocator.getI18nManager();
1012
          ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1013
          dialogs.messageDialog(
1014
                    i18n.getTranslation("_The_group_function_is_not_available_for_this_table"), 
1015
                    i18n.getTranslation("_Information"), 
1016
                    JOptionPane.INFORMATION_MESSAGE
1017
          );
1018
          return;
1019
        }
1020

    
1021
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1022
        I18nManager i18n = ToolsLocator.getI18nManager();
1023
        final FeatureQueryGroupByPanel panel = new DefaultFeatureQueryGroupByPanel();
1024
        panel.setStore(this.store);
1025
        panel.put(this.parameters.getQuery());
1026
        final Dialog dialog = winmanager.createDialog(
1027
                panel.asJComponent(),
1028
                i18n.getTranslation("_Select_group_columns_and_aggregate_functions"),
1029
                null,
1030
                WindowManager_v2.BUTTONS_OK_CANCEL
1031
        );
1032
        dialog.addActionListener((ActionEvent e) -> {
1033
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1034
                panel.fetch(this.parameters.getQuery());
1035
                search();
1036
            }
1037
        });
1038
        dialog.show(WindowManager.MODE.DIALOG);
1039
    }
1040

    
1041
    private void doSelectResultColumnNames() {
1042
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1043
        I18nManager i18n = ToolsLocator.getI18nManager();
1044
        final FeatureAttributesSelectionPanel panel = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
1045
        panel.allowCalculatedAttributes(false);
1046
        FeatureType ftype = this.getFeatureType();
1047
        try {
1048
          Feature f = store.findFirst(this.parameters.getQuery());
1049
          if( f!=null ) {
1050
            ftype = f.getType();
1051
          }
1052
        } catch (Throwable ex) {
1053
            LOGGER.warn("Can't retrieve the feature type from the first feature.",ex);
1054
        }
1055
        panel.setFeatureType(ftype);
1056
        panel.setSelectedNames(this.parameters.getResultColumnNames());
1057
        final Dialog dialog = winmanager.createDialog(
1058
                panel.asJComponent(),
1059
                i18n.getTranslation("_Select_the_columns_to_display"),
1060
                null,
1061
                WindowManager_v2.BUTTONS_OK_CANCEL
1062
        );
1063
        dialog.addActionListener((ActionEvent e) -> {
1064
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1065
                this.setResultColumnNames(panel.getSelectedNames());
1066
            }
1067
        });
1068
        dialog.show(WindowManager.MODE.DIALOG);
1069
    }
1070

    
1071
    @Override
1072
    public void put(SearchParameters inParams) {
1073
        for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1074
            try {
1075
                conditionPanel.put(inParams);
1076
            } catch (Exception ex) {
1077
                LOGGER.warn("Can't open panel", ex);
1078
            }
1079
        }
1080
        this.parameters = (DefaultSearchParameters) inParams;
1081

    
1082
    }
1083

    
1084
    private FeatureQuery getQuery() {
1085
        FeatureQuery query;
1086
        try {
1087
            int searchMode = this.tabSearchMode.getSelectedIndex();
1088
            SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1089
            Expression filter = panel.get();
1090
            if (searchMode != PANEL_ADVANCED) {
1091
                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1092
            }
1093
            query = (FeatureQuery) this.parameters.getQuery().clone();
1094
            query.retrievesAllAttributes();
1095
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1096
                return query;
1097
            }
1098
            query.setFilter(filter);
1099
            query.retrievesAllAttributes();
1100
            return query;
1101
        } catch (Exception ex) {
1102
            LOGGER.warn("Can't build query.", ex);
1103
            return null;
1104
        }
1105
    }
1106

    
1107
    @Override
1108
    public SearchParameters fetch(SearchParameters outParams) {
1109
        // Actualiza el fquery del parameters con los paneles
1110
        for (SearchConditionPanel conditionPanel : conditionPanels) {
1111
            try {
1112
                conditionPanel.fetch(this.parameters);
1113
            } catch (Exception ex) {
1114
                LOGGER.warn("Panel not able to fetch values", ex);
1115
            }
1116
        }
1117

    
1118
        // Actualiza el filtro con el panel activo
1119
        int searchMode = this.tabSearchMode.getSelectedIndex();
1120
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1121
        Expression filter = panel.get();
1122
        if (searchMode != PANEL_ADVANCED) {
1123
            this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1124
        }
1125
        FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1126
        this.lastQuery = query.getCopy();
1127
        query.retrievesAllAttributes();
1128
        query.clearFilter();
1129
        if (!ExpressionUtils.isPhraseEmpty(filter)) {
1130
            query.setFilter(filter);
1131
            query.retrievesAllAttributes();
1132
        }
1133

    
1134
        if (outParams == null) {
1135
            return this.parameters.getCopy();
1136
        }
1137
        outParams.copyFrom(this.parameters.getCopy());
1138
        return outParams;
1139
    }
1140

    
1141
    public static void selfRegister() {
1142
        String[][] iconNames = new String[][]{
1143
            new String[]{"dalswing", "featurestore-column"},
1144
            new String[]{"dalswing", "featurestore-foreing-key"},
1145
            new String[]{"dalswing", "featurestore-table"},
1146
            new String[]{"dalswing", "search-action-showform"},
1147
            new String[]{"dalswing", "search-action-select"},
1148
            new String[]{"dalswing", "search-action-select-add"},
1149
            new String[]{"dalswing", "search-action-select-filter"}
1150
        };
1151
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1152
        for (String[] icon : iconNames) {
1153
            URL url = DefaultSearchPanel.class.getResource(icon[1] + ".png");
1154
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1155
        }
1156

    
1157
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1158
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1159
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1160
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1161
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1162
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1163
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1164
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1165
    }
1166
}