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 @ 45192

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

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

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

    
545
        swingManager.createTableColumnAdjuster(tblResults);
546

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

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

    
552
        this.historyController.setFilter(null);
553

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

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

    
580
            }
581
        };
582
        this.historyController.addActionListener(bookmarksAndHistoryListener);
583
        this.bookmarksController.addActionListener(bookmarksAndHistoryListener);
584
        this.addComponentListener(new ComponentAdapter() {
585
            @Override
586
            public void componentHidden(ComponentEvent e) {
587
                dispose();
588
            }
589
        });
590
        this.tblResults.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
591
        this.tblResults.addKeyListener(new KeyAdapter() {
592
            @Override
593
            public void keyPressed(KeyEvent e) {
594
                if( e.getKeyCode()==KeyEvent.VK_F2 ) {
595
                    doShowCellInDialog();
596
                }
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
            FeatureQuery myQuery;
688
            SearchParameters searchParams;
689
            try {
690
                searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
691
                Date date = Calendar.getInstance().getTime();
692
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
693
                String strDate = dateFormat.format(date);
694
                searchParams.setName("Params: " + strDate);
695
            } catch (Exception ex) {
696
                LOGGER.warn("Not able to create search parameters.", ex);
697
                return;
698
            }
699
            
700
            final MutableLong rowCount=new MutableLong();
701
            try {
702
                final List<Feature> features;
703

    
704
                myQuery = this.getQuery().getCopy();
705
                features = store.getFeatures(myQuery, 20);
706
                FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
707
                FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
708
                    // al modelo le pasamos el ftype de esas features
709
                    SimpleFeaturesTableModel tableModel = new SimpleFeaturesTableModel(
710
                            ftype,
711
                            searchParams.getResultColumnNames(),
712
                            features
713
                    );
714
                model.setValue(tableModel);
715
                rowCount.setValue(tableModel.getRowCount());
716
            } catch (Exception ex) {
717
                LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
718
            } finally {
719
                SwingUtilities.invokeLater(() -> {
720
                    I18nManager i18n = ToolsLocator.getI18nManager();
721
                    TableModel oldmodel = tblResults.getModel();
722
                    SimpleFeaturesTableModel m = (SimpleFeaturesTableModel) model.getValue();
723
                    tblResults.setModel(m);
724
                    SimpleFeaturesTableModel.setCellRenderers(tblResults);
725
                    if( oldmodel instanceof SimpleFeaturesTableModel )  {
726
                        ((SimpleFeaturesTableModel)oldmodel).dispose();
727
                    }
728
                    if( m.hasErrors() ) {
729
                      lblMsg.setText("_Errors_occurred_during_search");
730
                    } else {
731
                      lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), rowCount.getValue()));
732
                    }
733
                    setEnabled(true);
734
                });
735
                if (this.parameters != null && this.parameters.getQuery() != null) {
736
                    this.history.add(searchParams);
737
                }
738
            }
739
        });
740
        th.start();
741
    }
742

    
743
    public void setResultColumnNames(List<String> names) {
744
        this.parameters.getResultColumnNames().clear();
745
        this.parameters.getResultColumnNames().addAll(names);
746
        if (this.conditionPanels == null) {
747
            return;
748
        }
749
        SimpleFeaturesTableModel model;
750
//        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
751
        List<Feature> features = store.getFeatures(this.parameters.getQuery());
752
        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
753
        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
754
        model = new SimpleFeaturesTableModel(
755
                ftype,
756
                this.parameters.getResultColumnNames(),
757
                features
758
        );
759
        tblResults.setModel(model);
760
    }
761

    
762
    @Override
763
    public boolean setFilter(Expression filter) {
764
        try {
765
            if (this.conditionPanels == null) {
766
                this.initComponents();
767
            }
768
            if (ExpressionUtils.isPhraseEmpty(filter)) {
769
                this.clear();
770
                return true;
771
            }
772
            int panel = 0;
773
            int selected = PANEL_ADVANCED;
774
            for (SearchConditionPanel conditionPanel : conditionPanels) {
775
                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
776
                    selected = panel;
777
                }
778
                panel++;
779
            }
780
            this.tabSearchMode.setSelectedIndex(selected);
781

    
782
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
783
//            tblResults.setModel(model);
784
//            lblMsg.setText("");
785
            return true;
786
        } catch (Exception ex) {
787
            LOGGER.warn("Can't set current search", ex);
788
            return false;
789
        }
790
    }
791

    
792
    @Override
793
    public List<SearchConditionPanel> getConditionPanels() {
794
        return Collections.unmodifiableList(this.conditionPanels);
795
    }
796

    
797
    @Override
798
    public SearchConditionPanel getConditionPanel(String name) {
799
        for (SearchConditionPanel panel : conditionPanels) {
800
            if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
801
                return panel;
802
            }
803
        }
804
        return null;
805
    }
806

    
807
    @Override
808
    public Expression getFilterForSelectedFeature() {
809
        if (this.conditionPanels == null) {
810
            return null;
811
        }
812
        int selectedRow = this.tblResults.getSelectedRow();
813
        if (selectedRow < 0) {
814
            return null;
815
        }
816
        try {
817
            List<Feature> features = ((SimpleFeaturesTableModel) this.tblResults.getModel()).getFeatures();
818
            Feature feature = features.get(selectedRow);
819

    
820
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
821
            FeatureType ftype = this.store.getDefaultFeatureType();
822
            for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
823
                builder.and(
824
                        builder.eq(
825
                                builder.column(attrdesc.getName()),
826
                                builder.constant(feature.get(attrdesc.getName()))
827
                        )
828
                );
829
            }
830
            Expression filter = ExpressionUtils.createExpression(builder.toString());
831
            return filter;
832
        } catch (Exception ex) {
833
            LOGGER.warn("Can't build search for the selected feature.", ex);
834
            return null;
835
        }
836
    }
837

    
838
    @Override
839
    public FeatureStore getStore() {
840
        return store;
841
    }
842

    
843
    private void doOrderBy() {
844
        I18nManager i18n = ToolsLocator.getI18nManager();
845
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
846
        FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
847
        orderPanel.setStore(store);
848
        orderPanel.put(parameters.getQuery());
849
        Dialog dialog = windowManager.createDialog(
850
                orderPanel.asJComponent(),
851
                i18n.getTranslation("_Select_order"),
852
                null,
853
                WindowManager_v2.BUTTONS_OK_CANCEL
854
        );
855
        dialog.addActionListener((ActionEvent e) -> {
856
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
857
                orderPanel.fetch(this.parameters.getQuery());
858
                search();
859
            }
860
        });
861
        dialog.show(WindowManager.MODE.DIALOG);
862

    
863
    }
864

    
865
    @Override
866
    public ImageIcon loadImage(String imageName) {
867
        String name = FilenameUtils.getBaseName(imageName);
868
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
869
        if (theme.exists(name)) {
870
            return theme.get(name);
871
        }
872
        URL url = this.getClass().getResource(name + ".png");
873
        if (url == null) {
874
            return null;
875
        }
876
        return new ImageIcon(url);
877
    }
878

    
879
    @Override
880
    public int getSelectedFeatureCount() {
881
        if (this.conditionPanels == null) {
882
            return 0;
883
        }
884
        return this.tblResults.getSelectedRowCount();
885
    }
886

    
887
    @Override
888
    public JComponent getActionButton(String name) {
889
        ActionButtons actionButton = this.actions.get(name);
890
        if (actionButton == null) {
891
            return null;
892
        }
893
        return actionButton.button;
894
    }
895

    
896
    @Override
897
    public void setShowActions(boolean showActions) {
898
        this.showActions = showActions;
899
    }
900

    
901
    @Override
902
    public boolean isShowActions() {
903
        return this.showActions;
904
    }
905

    
906
    public static String getAttributeDescriptorLabel(FeatureAttributeDescriptor attrdesc, String tableName) {
907
        String theLabel;
908
        int theUseLabels;
909
        if (useLabels == null) {
910
            Tags tags = attrdesc.getTags();
911
            if (tags.has(DAL_USE_LABELS)) {
912
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
913
            } else {
914
                tags = attrdesc.getFeatureType().getTags();
915
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
916
            }
917
        } else {
918
            theUseLabels = useLabels;
919
        }
920
        switch (theUseLabels) {
921
            case USE_LABELS_YES:
922
                if (StringUtils.isBlank(tableName)) {
923
                    theLabel = attrdesc.getLocalizedLabel();
924
                } else {
925
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), tableName);
926
                }
927
                break;
928
            default:
929
            case USE_LABELS_NO:
930
                if (StringUtils.isBlank(tableName)) {
931
                    theLabel = attrdesc.getName();
932
                } else {
933
                    theLabel = String.format("%s [%s]", attrdesc.getName(), tableName);
934
                }
935
                break;
936
            case USE_LABELS_BOTH:
937
                if (StringUtils.isBlank(tableName)) {
938
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), attrdesc.getName());
939
                } else {
940
                    theLabel = String.format("%s [%s/%s]", attrdesc.getLocalizedLabel(), attrdesc.getName(), tableName);
941
                }
942
                break;
943
        }
944
        return theLabel;
945
    }
946

    
947
    private void doCalculatedColumns() {
948
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
949
        I18nManager i18n = ToolsLocator.getI18nManager();
950
        final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
951
        panel.setStore(this.store);
952
        panel.put(this.parameters.getQuery());
953
        final Dialog dialog = winmanager.createDialog(
954
                panel.asJComponent(),
955
                i18n.getTranslation("_Calculated_columns"),
956
                null,
957
                WindowManager_v2.BUTTONS_OK_CANCEL
958
        );
959
        dialog.addActionListener((ActionEvent e) -> {
960
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
961
                panel.fetch(this.parameters.getQuery());
962
                search();
963
            }
964
        });
965
        dialog.show(WindowManager.MODE.DIALOG);
966
    }
967

    
968
    private void doGroupBy() {
969
        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
970
        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
971
        if (allowGroupBy != DataType.YES) {
972
          // FIXME: mensaje al usaurio.
973
          I18nManager i18n = ToolsLocator.getI18nManager();
974
          ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
975
          dialogs.messageDialog(
976
                    i18n.getTranslation("_The_group_function_is_not_available_for_this_table"), 
977
                    i18n.getTranslation("_Information"), 
978
                    JOptionPane.INFORMATION_MESSAGE
979
          );
980
          return;
981
        }
982

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

    
1003
    private void doSelectResultColumnNames() {
1004
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1005
        I18nManager i18n = ToolsLocator.getI18nManager();
1006
        final FeatureAttributesSelectionPanel panel = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
1007
        panel.allowCalculatedAttributes(false);
1008
        FeatureType ftype = this.getFeatureType();
1009
        try {
1010
          Feature f = store.findFirst(this.parameters.getQuery());
1011
          if( f!=null ) {
1012
            ftype = f.getType();
1013
          }
1014
        } catch (Throwable ex) {
1015
            LOGGER.warn("Can't retrieve the feature type from the first feature.",ex);
1016
        }
1017
        panel.setFeatureType(ftype);
1018
        panel.setSelectedNames(this.parameters.getResultColumnNames());
1019
        final Dialog dialog = winmanager.createDialog(
1020
                panel.asJComponent(),
1021
                i18n.getTranslation("_Select_the_columns_to_display"),
1022
                null,
1023
                WindowManager_v2.BUTTONS_OK_CANCEL
1024
        );
1025
        dialog.addActionListener((ActionEvent e) -> {
1026
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1027
                this.setResultColumnNames(panel.getSelectedNames());
1028
            }
1029
        });
1030
        dialog.show(WindowManager.MODE.DIALOG);
1031
    }
1032

    
1033
    @Override
1034
    public void put(SearchParameters inParams) {
1035
        for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1036
            try {
1037
                conditionPanel.put(inParams);
1038
            } catch (Exception ex) {
1039
                LOGGER.warn("Can't open panel", ex);
1040
            }
1041
        }
1042
        this.parameters = (DefaultSearchParameters) inParams;
1043

    
1044
    }
1045

    
1046
    private FeatureQuery getQuery() {
1047
        FeatureQuery query;
1048
        try {
1049
            int searchMode = this.tabSearchMode.getSelectedIndex();
1050
            SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1051
            Expression filter = panel.get();
1052
            if (searchMode != PANEL_ADVANCED) {
1053
                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1054
            }
1055
            query = (FeatureQuery) this.parameters.getQuery().clone();
1056
            query.retrievesAllAttributes();
1057
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1058
                return query;
1059
            }
1060
            query.setFilter(filter);
1061
            query.retrievesAllAttributes();
1062
            return query;
1063
        } catch (Exception ex) {
1064
            LOGGER.warn("Can't build query.", ex);
1065
            return null;
1066
        }
1067
    }
1068

    
1069
    @Override
1070
    public SearchParameters fetch(SearchParameters outParams) {
1071
        // Actualiza el fquery del parameters con los paneles
1072
        for (SearchConditionPanel conditionPanel : conditionPanels) {
1073
            try {
1074
                conditionPanel.fetch(this.parameters);
1075
            } catch (Exception ex) {
1076
                LOGGER.warn("Panel not able to fetch values", ex);
1077
            }
1078
        }
1079

    
1080
        // Actualiza el filtro con el panel activo
1081
        int searchMode = this.tabSearchMode.getSelectedIndex();
1082
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1083
        Expression filter = panel.get();
1084
        if (searchMode != PANEL_ADVANCED) {
1085
            this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1086
        }
1087
        FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1088
        this.lastQuery = query.getCopy();
1089
        query.retrievesAllAttributes();
1090
        query.clearFilter();
1091
        if (!ExpressionUtils.isPhraseEmpty(filter)) {
1092
            query.setFilter(filter);
1093
            query.retrievesAllAttributes();
1094
        }
1095

    
1096
        if (outParams == null) {
1097
            return this.parameters.getCopy();
1098
        }
1099
        outParams.copyFrom(this.parameters.getCopy());
1100
        return outParams;
1101
    }
1102

    
1103
    public static void selfRegister() {
1104
        String[][] iconNames = new String[][]{
1105
            new String[]{"dalswing", "featurestore-column"},
1106
            new String[]{"dalswing", "featurestore-foreing-key"},
1107
            new String[]{"dalswing", "featurestore-table"},
1108
            new String[]{"dalswing", "search-action-showform"},
1109
            new String[]{"dalswing", "search-action-select"},
1110
            new String[]{"dalswing", "search-action-select-add"},
1111
            new String[]{"dalswing", "search-action-select-filter"}
1112
        };
1113
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1114
        for (String[] icon : iconNames) {
1115
            URL url = DefaultSearchPanel.class.getResource(icon[1] + ".png");
1116
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1117
        }
1118

    
1119
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1120
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1121
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1122
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1123
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1124
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1125
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1126
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1127
    }
1128
}