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

History | View | Annotate | Download (44.7 KB)

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

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

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

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

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

    
117
    public static class UseLabelsYesAction extends AbstractAction {
118

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

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

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

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

    
143
    public static class UseLabelsNoAction extends AbstractAction {
144

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

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

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

    
168
    public static class UseLabelsBothAction extends AbstractAction {
169

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

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

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

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

    
194
    public static class SelectColumnsAction extends AbstractAction {
195

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

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

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

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

    
221
    public static class CalculatedColumnsAction extends AbstractAction {
222

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

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

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

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

    
248
    public static class GroupByAction extends AbstractAction {
249

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

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

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

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

    
275
    public static class OrderByAction extends AbstractAction {
276

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

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

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

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

    
302
    private class ActionButtons {
303

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

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

    
315
    public static class SearchActionContext extends AbstractDALActionContext {
316

    
317
        private final DefaultSearchPanel panel;
318

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

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

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

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

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

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

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

    
356
    private List<SearchConditionPanel> conditionPanels;
357

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
546
        swingManager.createTableColumnAdjuster(tblResults);
547

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

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

    
553
        this.historyController.setFilter(null);
554

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

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

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

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

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

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

    
648
    @Override
649
    public void clear() {
650
        if (this.conditionPanels == null) {
651
            return;
652
        }
653
        for (SearchConditionPanel conditionPanel : conditionPanels) {
654
            conditionPanel.clear();
655
        }
656
        FeatureQuery emptyQuery = this.store.createFeatureQuery();
657
        emptyQuery.retrievesAllAttributes();
658
        this.parameters.setQuery(emptyQuery);
659
        resetTable();
660
    }
661

    
662
    @Override
663
    public FeatureQuery getLastQuery() {
664
        return this.lastQuery;
665
    }
666

    
667
    public boolean isValid(StringBuilder message) {
668
        int searchMode = this.tabSearchMode.getSelectedIndex();
669
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
670
        boolean valid = panel.isValid(message);
671
        return valid;
672
    }
673

    
674
    @Override
675
    public void search() {
676
        final MutableObject model = new MutableObject(null);
677

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

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

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

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

    
822
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
823
//            tblResults.setModel(model);
824
//            lblMsg.setText("");
825
            return true;
826
        } catch (Exception ex) {
827
            LOGGER.warn("Can't set current search", ex);
828
            return false;
829
        }
830
    }
831

    
832
    @Override
833
    public List<SearchConditionPanel> getConditionPanels() {
834
        return Collections.unmodifiableList(this.conditionPanels);
835
    }
836

    
837
    @Override
838
    public SearchConditionPanel getConditionPanel(String name) {
839
        for (SearchConditionPanel panel : conditionPanels) {
840
            if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
841
                return panel;
842
            }
843
        }
844
        return null;
845
    }
846

    
847
    @Override
848
    public Expression getFilterForSelectedFeature() {
849
        if (this.conditionPanels == null) {
850
            return null;
851
        }
852
        int selectedRow = this.tblResults.getSelectedRow();
853
        if (selectedRow < 0) {
854
            return null;
855
        }
856
        try {
857
            List<Feature> features = ((SimpleFeaturesTableModel) this.tblResults.getModel()).getFeatures();
858
            Feature feature = features.get(selectedRow);
859

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

    
878
    @Override
879
    public FeatureStore getStore() {
880
        return store;
881
    }
882

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

    
903
    }
904

    
905
    @Override
906
    public ImageIcon loadImage(String imageName) {
907
        String name = FilenameUtils.getBaseName(imageName);
908
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
909
        if (theme.exists(name)) {
910
            return theme.get(name);
911
        }
912
        URL url = this.getClass().getResource(name + ".png");
913
        if (url == null) {
914
            return null;
915
        }
916
        return new ImageIcon(url);
917
    }
918

    
919
    @Override
920
    public int getSelectedFeatureCount() {
921
        if (this.conditionPanels == null) {
922
            return 0;
923
        }
924
        return this.tblResults.getSelectedRowCount();
925
    }
926

    
927
    @Override
928
    public JComponent getActionButton(String name) {
929
        ActionButtons actionButton = this.actions.get(name);
930
        if (actionButton == null) {
931
            return null;
932
        }
933
        return actionButton.button;
934
    }
935

    
936
    @Override
937
    public void setShowActions(boolean showActions) {
938
        this.showActions = showActions;
939
    }
940

    
941
    @Override
942
    public boolean isShowActions() {
943
        return this.showActions;
944
    }
945

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

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

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

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

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

    
1077
    @Override
1078
    public void put(SearchParameters inParams) {
1079
        for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1080
            try {
1081
                conditionPanel.put(inParams);
1082
            } catch (Exception ex) {
1083
                LOGGER.warn("Can't open panel", ex);
1084
            }
1085
        }
1086
        this.parameters = (DefaultSearchParameters) inParams;
1087

    
1088
    }
1089

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

    
1113
    @Override
1114
    public SearchParameters fetch(SearchParameters outParams) {
1115
        // Actualiza el fquery del parameters con los paneles
1116
        for (SearchConditionPanel conditionPanel : conditionPanels) {
1117
            try {
1118
                conditionPanel.fetch(this.parameters);
1119
            } catch (Exception ex) {
1120
                LOGGER.warn("Panel not able to fetch values", ex);
1121
            }
1122
        }
1123

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

    
1140
        if (outParams == null) {
1141
            return this.parameters.getCopy();
1142
        }
1143
        outParams.copyFrom(this.parameters.getCopy());
1144
        return outParams;
1145
    }
1146

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

    
1163
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1164
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1165
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1166
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1167
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1168
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1169
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1170
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1171
    }
1172
}