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

History | View | Annotate | Download (44.5 KB)

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

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

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

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

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

    
117
    public static class UseLabelsYesAction extends AbstractAction {
118

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

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

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

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

    
143
    public static class UseLabelsNoAction extends AbstractAction {
144

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

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

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

    
168
    public static class UseLabelsBothAction extends AbstractAction {
169

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

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

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

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

    
194
    public static class SelectColumnsAction extends AbstractAction {
195

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

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

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

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

    
221
    public static class CalculatedColumnsAction extends AbstractAction {
222

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

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

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

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

    
248
    public static class GroupByAction extends AbstractAction {
249

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

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

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

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

    
275
    public static class OrderByAction extends AbstractAction {
276

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

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

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

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

    
302
    private class ActionButtons {
303

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

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

    
315
    public static class SearchActionContext extends AbstractDALActionContext {
316

    
317
        private final DefaultSearchPanel panel;
318

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

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

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

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

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

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

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

    
356
    private List<SearchConditionPanel> conditionPanels;
357

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
546
        swingManager.createTableColumnAdjuster(tblResults);
547

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

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

    
553
        this.historyController.setFilter(null);
554

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
874
    @Override
875
    public FeatureStore getStore() {
876
        return store;
877
    }
878

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

    
899
    }
900

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

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

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

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

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

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

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

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

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

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

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

    
1084
    }
1085

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

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

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

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

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

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