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

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_F4 ) {
595
                    doShowCellInDialog();
596
                }
597
            }
598
        });
599
        search();
600
    }
601
    
602
    private void doShowCellInDialog() {
603
        int row = this.tblResults.getSelectedRow();
604
        if( row < 0 ) {
605
            return;
606
        }
607
        int col = this.tblResults.getSelectedColumn();
608
        if( col < 0 ) {
609
            return;
610
        }
611
        String s = Objects.toString(this.tblResults.getValueAt(row, col),null);
612
        if( StringUtils.isBlank(s) ) {
613
            return;
614
        }
615
        ToolsSwingLocator.getToolsSwingManager().showZoomDialog(
616
            this, 
617
            this.tblResults.getColumnName(col), 
618
            s,
619
            false
620
        );
621
    }
622

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
862
    }
863

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

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

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

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

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

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

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

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

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

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

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

    
1043
    }
1044

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

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

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

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

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

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