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

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

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

    
107
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSearchPanel.class);
108

    
109
    static /* friend */ Integer useLabels = null;
110
    private BookmarksController bookmarksController;
111
    private HistoryController historyController;
112
    private FeatureQuery lastQuery;
113

    
114
    public static class UseLabelsYesAction extends AbstractAction {
115

    
116
        @SuppressWarnings("OverridableMethodCallInConstructor")
117
        public UseLabelsYesAction() {
118
            I18nManager i18n = ToolsLocator.getI18nManager();
119

    
120
            this.putValue(NAME, i18n.getTranslation("_Use_labels"));
121
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsYes");
122
        }
123

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

    
134
        @Override
135
        public void actionPerformed(ActionEvent ae) {
136
            DefaultSearchPanel.useLabels = USE_LABELS_YES;
137
        }
138
    }
139

    
140
    public static class UseLabelsNoAction extends AbstractAction {
141

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

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

    
159
        @Override
160
        public void actionPerformed(ActionEvent ae) {
161
            DefaultSearchPanel.useLabels = USE_LABELS_NO;
162
        }
163
    }
164

    
165
    public static class UseLabelsBothAction extends AbstractAction {
166

    
167
        @SuppressWarnings("OverridableMethodCallInConstructor")
168
        public UseLabelsBothAction() {
169
            I18nManager i18n = ToolsLocator.getI18nManager();
170

    
171
            this.putValue(NAME, i18n.getTranslation("_Use_labels_and_names"));
172
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsBoth");
173
        }
174

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

    
185
        @Override
186
        public void actionPerformed(ActionEvent ae) {
187
            DefaultSearchPanel.useLabels = USE_LABELS_BOTH;
188
        }
189
    }
190

    
191
    public static class SelectColumnsAction extends AbstractAction {
192

    
193
        @SuppressWarnings("OverridableMethodCallInConstructor")
194
        public SelectColumnsAction() {
195
            I18nManager i18n = ToolsLocator.getI18nManager();
196

    
197
            this.putValue(NAME, i18n.getTranslation("_Select_columns_to_display"));
198
            this.putValue(ACTION_COMMAND_KEY, "SelectColumns");
199
        }
200

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

    
211
        @Override
212
        public void actionPerformed(ActionEvent ae) {
213
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
214
            panel.doSelectResultColumnNames();
215
        }
216
    }
217

    
218
    public static class CalculatedColumnsAction extends AbstractAction {
219

    
220
        @SuppressWarnings("OverridableMethodCallInConstructor")
221
        public CalculatedColumnsAction() {
222
            I18nManager i18n = ToolsLocator.getI18nManager();
223

    
224
            this.putValue(NAME, i18n.getTranslation("_Calculated_columns"));
225
            this.putValue(ACTION_COMMAND_KEY, "CalculatedColumns");
226
        }
227

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

    
238
        @Override
239
        public void actionPerformed(ActionEvent ae) {
240
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
241
            panel.doCalculatedColumns();
242
        }
243
    }
244

    
245
    public static class GroupByAction extends AbstractAction {
246

    
247
        @SuppressWarnings("OverridableMethodCallInConstructor")
248
        public GroupByAction() {
249
            I18nManager i18n = ToolsLocator.getI18nManager();
250

    
251
            this.putValue(NAME, i18n.getTranslation("_Group_by"));
252
            this.putValue(ACTION_COMMAND_KEY, "GroupBy");
253
        }
254

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

    
265
        @Override
266
        public void actionPerformed(ActionEvent ae) {
267
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
268
            panel.doGroupBy();
269
        }
270
    }
271

    
272
    public static class OrderByAction extends AbstractAction {
273

    
274
        @SuppressWarnings("OverridableMethodCallInConstructor")
275
        public OrderByAction() {
276
            I18nManager i18n = ToolsLocator.getI18nManager();
277

    
278
            this.putValue(NAME, i18n.getTranslation("_Order_by"));
279
            this.putValue(ACTION_COMMAND_KEY, "SelectOrderBy");
280
        }
281

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

    
292
        @Override
293
        public void actionPerformed(ActionEvent ae) {
294
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
295
            panel.doOrderBy();
296
        }
297
    }
298

    
299
    private class ActionButtons {
300

    
301
        private final DALActionFactory factory;
302
        private final Action action;
303
        private final JButton button;
304

    
305
        public ActionButtons(DALActionFactory factory, Action action, JButton button) {
306
            this.factory = factory;
307
            this.action = action;
308
            this.button = button;
309
        }
310
    }
311

    
312
    public static class SearchActionContext extends AbstractDALActionContext {
313

    
314
        private final DefaultSearchPanel panel;
315

    
316
        public SearchActionContext(DefaultSearchPanel panel) {
317
            super(FeatureStoreSearchPanel.ACTION_CONTEXT_NAME);
318
            this.panel = panel;
319
        }
320

    
321
        @Override
322
        public DataStore getStore() {
323
            return this.panel.getStore();
324
        }
325

    
326
        @Override
327
        public JComponent getActionButton(String actionName) {
328
            return this.panel.getActionButton(actionName);
329
        }
330

    
331
        @Override
332
        public int getSelectedsCount() {
333
            return this.panel.getSelectedFeatureCount();
334
        }
335

    
336
        @Override
337
        public Expression getFilterForSelecteds() {
338
            return this.panel.getFilterForSelectedFeature();
339
        }
340

    
341
        @Override
342
        public FeatureQuery getQuery() {
343
            return this.panel.getQuery();
344
        }
345
    }
346

    
347
    private FeatureStore store;
348
    private final ActionListenerSupport acctionListeners;
349
    private final Map<String, ActionButtons> actions;
350
    private boolean showActions = true;
351
    private DefaultSearchParameters parameters;
352

    
353
    private List<SearchConditionPanel> conditionPanels;
354

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

    
361
    public DefaultSearchPanel(FeatureStore store) {
362
        this.store = store;
363
        this.acctionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
364
        this.actions = new HashMap<>();
365
        this.parameters = new DefaultSearchParameters();
366
        FeatureQuery featureQuery = this.store.createFeatureQuery();
367
        featureQuery.retrievesAllAttributes();
368
        this.parameters.setQuery(featureQuery);
369

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

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

    
396
    @Override
397
    public JComponent asJComponent() {
398
        if (this.conditionPanels == null) {
399
            this.initComponents();
400
        }
401
        return this;
402
    }
403

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

    
427
    @Override
428
    public void addActionListener(ActionListener listener) {
429
        this.acctionListeners.addActionListener(listener);
430
    }
431

    
432
    @Override
433
    public ActionListener[] getActionListeners() {
434
        return this.acctionListeners.getActionListeners();
435
    }
436

    
437
    @Override
438
    public void removeActionListener(ActionListener listener) {
439
        this.acctionListeners.removeActionListener(listener);
440
    }
441

    
442
    @Override
443
    public void removeAllActionListener() {
444
        this.acctionListeners.removeAllActionListener();
445
    }
446

    
447
    @Override
448
    public void fireActionEvent(ActionEvent event) {
449
        this.acctionListeners.fireActionEvent(event);
450
    }
451

    
452
    @Override
453
    public boolean hasActionListeners() {
454
        return this.acctionListeners.hasActionListeners();
455
    }
456

    
457
    private void initComponents() {
458
        this.conditionPanels = new ArrayList<>();
459

    
460
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
461
        swingManager.translate(this.tabSearchMode);
462
        swingManager.translate(this.btnSearch);
463
        swingManager.translate(this.btnClear);
464
        swingManager.translate(this.lblExpressionDeBusqueda);
465
        swingManager.translate(this.btnAddAccumulatedFilter);
466
        swingManager.translate(this.btnRemoveAccumulatedFilter);
467
        swingManager.translate(this.btnViewAccumulatedFilter);
468

    
469
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
470
        JComponent c = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
471
        this.pnlCfgActions.setLayout(new BorderLayout(0, 0));
472
        this.pnlCfgActions.add(c, BorderLayout.CENTER);
473

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

    
525
        this.btnSearch.addActionListener((ActionEvent e) -> {
526
            search();
527
        });
528

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

    
541
        swingManager.createTableColumnAdjuster(tblResults);
542

    
543
        this.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
544

    
545
        this.bookmarksController = ToolsSwingLocator.getToolsSwingManager().createBookmarksController(this.bookmarks, btnBookmarks);
546
        this.historyController = ToolsSwingLocator.getToolsSwingManager().createHistoryController(this.history, btnHistory);
547

    
548
        this.historyController.setFilter(null);
549

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

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

    
576
            }
577
        };
578
        this.historyController.addActionListener(bookmarksAndHistoryListener);
579
        this.bookmarksController.addActionListener(bookmarksAndHistoryListener);
580
        this.addComponentListener(new ComponentAdapter() {
581
            @Override
582
            public void componentHidden(ComponentEvent e) {
583
                dispose();
584
            }
585
        });
586
        search();
587
    }
588

    
589
    private FeatureType getFeatureType() {
590
        try {
591
            return store.getDefaultFeatureType();
592
        } catch (Exception ex) {
593
            throw new RuntimeException("Can't retrieve the feature type.", ex);
594
        }
595
    }
596

    
597
    @Override
598
    public void setEnabled(boolean enabled) {
599
        if (this.conditionPanels == null) {
600
            this.initComponents();
601
        }
602
        for (SearchConditionPanel conditionPanel : conditionPanels) {
603
            conditionPanel.setEnabled(enabled);
604
        }
605

    
606
        this.btnClear.setEnabled(enabled);
607
        this.btnSearch.setEnabled(enabled);
608
        for (ActionButtons actionButton : actions.values()) {
609
            actionButton.action.setEnabled(enabled);
610
        }
611
    }
612

    
613
    @Override
614
    public void clear() {
615
        if (this.conditionPanels == null) {
616
            return;
617
        }
618
        for (SearchConditionPanel conditionPanel : conditionPanels) {
619
            conditionPanel.clear();
620
        }
621
    }
622

    
623
    @Override
624
    public FeatureQuery getLastQuery() {
625
        return this.lastQuery;
626
    }
627

    
628
    public boolean isValid(StringBuilder message) {
629
        int searchMode = this.tabSearchMode.getSelectedIndex();
630
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
631
        boolean valid = panel.isValid(message);
632
        return valid;
633
    }
634

    
635
    @Override
636
    public void search() {
637
        final MutableObject model = new MutableObject(null);
638

    
639
        StringBuilder message = new StringBuilder();
640
        if (!this.isValid(message)) {
641
            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
642
            dialogManager.messageDialog(
643
                    "_The_specified_search_condition_is_not_valid",
644
                    "_Search",
645
                    JOptionPane.WARNING_MESSAGE
646
            );
647
            return;
648
        }
649
        lblMsg.setText("Searching...");
650
        setEnabled(false);
651
        Thread th = new Thread(() -> {
652
                FeatureQuery myQuery = null;
653
                SearchParameters searchParams;
654
            try {
655
                searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
656
                Date date = Calendar.getInstance().getTime();
657
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
658
                String strDate = dateFormat.format(date);
659
                searchParams.setName("Params: " + strDate);
660
            } catch (Exception ex) {
661
                LOGGER.warn("Not able to create search parameters.", ex);
662
                return;
663
            }
664

    
665
            try {
666
                final List<Feature> features;
667

    
668
                myQuery = this.getQuery().getCopy();
669
                features = store.getFeatures(myQuery, 20);
670
                FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
671
                FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
672
                // al modelo le pasamos el ftype de esas features
673
                model.setValue(new SimpleFeaturesTableModel(
674
                        ftype,
675
                        searchParams.getResultColumnNames(),
676
                        features
677
                )
678
                );
679
            } catch (Exception ex) {
680
                LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
681
            } finally {
682
                SwingUtilities.invokeLater(() -> {
683
                    I18nManager i18n = ToolsLocator.getI18nManager();
684
                    TableModel oldmodel = tblResults.getModel();
685
                    SimpleFeaturesTableModel m = (SimpleFeaturesTableModel) model.getValue();
686
                    tblResults.setModel(m);
687
                    if( oldmodel instanceof SimpleFeaturesTableModel )  {
688
                        ((SimpleFeaturesTableModel)oldmodel).dispose();
689
                    }
690
                    if( m.hasErrors() ) {
691
                      lblMsg.setText("_Errors_occurred_during_search");
692
                    } else {
693
                      lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), m.getRowCount()));
694
                    }
695
                    setEnabled(true);
696
                });
697
                if (this.parameters != null && this.parameters.getQuery() != null) {
698
                    this.history.add(searchParams);
699
                }
700
            }
701
        });
702
        th.start();
703
    }
704

    
705
    public void setResultColumnNames(List<String> names) {
706
        this.parameters.getResultColumnNames().clear();
707
        this.parameters.getResultColumnNames().addAll(names);
708
        if (this.conditionPanels == null) {
709
            return;
710
        }
711
        SimpleFeaturesTableModel model;
712
        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
713
        List<Feature> features = store.getFeatures(this.parameters.getQuery());
714
        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
715
        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
716
        model = new SimpleFeaturesTableModel(
717
                ftype,
718
                this.parameters.getResultColumnNames(),
719
                features
720
        );
721
        tblResults.setModel(model);
722
    }
723

    
724
    @Override
725
    public boolean setFilter(Expression filter) {
726
        try {
727
            if (this.conditionPanels == null) {
728
                this.initComponents();
729
            }
730
            if (ExpressionUtils.isPhraseEmpty(filter)) {
731
                this.clear();
732
                return true;
733
            }
734
            int panel = 0;
735
            int selected = PANEL_ADVANCED;
736
            for (SearchConditionPanel conditionPanel : conditionPanels) {
737
                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
738
                    selected = panel;
739
                }
740
                panel++;
741
            }
742
            this.tabSearchMode.setSelectedIndex(selected);
743

    
744
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
745
//            tblResults.setModel(model);
746
//            lblMsg.setText("");
747
            return true;
748
        } catch (Exception ex) {
749
            LOGGER.warn("Can't set current search", ex);
750
            return false;
751
        }
752
    }
753

    
754
    @Override
755
    public List<SearchConditionPanel> getConditionPanels() {
756
        return Collections.unmodifiableList(this.conditionPanels);
757
    }
758

    
759
    @Override
760
    public SearchConditionPanel getConditionPanel(String name) {
761
        for (SearchConditionPanel panel : conditionPanels) {
762
            if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
763
                return panel;
764
            }
765
        }
766
        return null;
767
    }
768

    
769
    @Override
770
    public Expression getFilterForSelectedFeature() {
771
        if (this.conditionPanels == null) {
772
            return null;
773
        }
774
        int selectedRow = this.tblResults.getSelectedRow();
775
        if (selectedRow < 0) {
776
            return null;
777
        }
778
        try {
779
            List<Feature> features = ((SimpleFeaturesTableModel) this.tblResults.getModel()).getFeatures();
780
            Feature feature = features.get(selectedRow);
781

    
782
            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
783
            FeatureType ftype = this.store.getDefaultFeatureType();
784
            for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
785
                builder.and(
786
                        builder.eq(
787
                                builder.column(attrdesc.getName()),
788
                                builder.constant(feature.get(attrdesc.getName()))
789
                        )
790
                );
791
            }
792
            Expression filter = ExpressionUtils.createExpression(builder.toString());
793
            return filter;
794
        } catch (Exception ex) {
795
            LOGGER.warn("Can't build search for the selected feature.", ex);
796
            return null;
797
        }
798
    }
799

    
800
    @Override
801
    public FeatureStore getStore() {
802
        return store;
803
    }
804

    
805
    private void doOrderBy() {
806
        I18nManager i18n = ToolsLocator.getI18nManager();
807
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
808
        FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
809
        orderPanel.setStore(store);
810
        orderPanel.put(parameters.getQuery());
811
        Dialog dialog = windowManager.createDialog(
812
                orderPanel.asJComponent(),
813
                i18n.getTranslation("_Select_order"),
814
                null,
815
                WindowManager_v2.BUTTONS_OK_CANCEL
816
        );
817
        dialog.addActionListener((ActionEvent e) -> {
818
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
819
                orderPanel.fetch(this.parameters.getQuery());
820
                search();
821
            }
822
        });
823
        dialog.show(WindowManager.MODE.DIALOG);
824

    
825
    }
826

    
827
    @Override
828
    public ImageIcon loadImage(String imageName) {
829
        String name = FilenameUtils.getBaseName(imageName);
830
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
831
        if (theme.exists(name)) {
832
            return theme.get(name);
833
        }
834
        URL url = this.getClass().getResource(name + ".png");
835
        if (url == null) {
836
            return null;
837
        }
838
        return new ImageIcon(url);
839
    }
840

    
841
    @Override
842
    public int getSelectedFeatureCount() {
843
        if (this.conditionPanels == null) {
844
            return 0;
845
        }
846
        return this.tblResults.getSelectedRowCount();
847
    }
848

    
849
    @Override
850
    public JComponent getActionButton(String name) {
851
        ActionButtons actionButton = this.actions.get(name);
852
        if (actionButton == null) {
853
            return null;
854
        }
855
        return actionButton.button;
856
    }
857

    
858
    @Override
859
    public void setShowActions(boolean showActions) {
860
        this.showActions = showActions;
861
    }
862

    
863
    @Override
864
    public boolean isShowActions() {
865
        return this.showActions;
866
    }
867

    
868
    public static String getAttributeDescriptorLabel(FeatureAttributeDescriptor attrdesc, String tableName) {
869
        String theLabel;
870
        int theUseLabels;
871
        if (useLabels == null) {
872
            Tags tags = attrdesc.getTags();
873
            if (tags.has(DAL_USE_LABELS)) {
874
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
875
            } else {
876
                tags = attrdesc.getFeatureType().getTags();
877
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
878
            }
879
        } else {
880
            theUseLabels = useLabels;
881
        }
882
        switch (theUseLabels) {
883
            case USE_LABELS_YES:
884
                if (StringUtils.isBlank(tableName)) {
885
                    theLabel = attrdesc.getLocalizedLabel();
886
                } else {
887
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), tableName);
888
                }
889
                break;
890
            default:
891
            case USE_LABELS_NO:
892
                if (StringUtils.isBlank(tableName)) {
893
                    theLabel = attrdesc.getName();
894
                } else {
895
                    theLabel = String.format("%s [%s]", attrdesc.getName(), tableName);
896
                }
897
                break;
898
            case USE_LABELS_BOTH:
899
                if (StringUtils.isBlank(tableName)) {
900
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), attrdesc.getName());
901
                } else {
902
                    theLabel = String.format("%s [%s/%s]", attrdesc.getLocalizedLabel(), attrdesc.getName(), tableName);
903
                }
904
                break;
905
        }
906
        return theLabel;
907
    }
908

    
909
    private void doCalculatedColumns() {
910
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
911
        I18nManager i18n = ToolsLocator.getI18nManager();
912
        final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
913
        panel.setStore(this.store);
914
        panel.put(this.parameters.getQuery());
915
        final Dialog dialog = winmanager.createDialog(
916
                panel.asJComponent(),
917
                i18n.getTranslation("_Calculated_columns"),
918
                null,
919
                WindowManager_v2.BUTTONS_OK_CANCEL
920
        );
921
        dialog.addActionListener((ActionEvent e) -> {
922
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
923
                panel.fetch(this.parameters.getQuery());
924
                search();
925
            }
926
        });
927
        dialog.show(WindowManager.MODE.DIALOG);
928
    }
929

    
930
    private void doGroupBy() {
931
        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
932
        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
933
        if (allowGroupBy != DataType.YES) {
934
          // FIXME: mensaje al usaurio.
935
          I18nManager i18n = ToolsLocator.getI18nManager();
936
          ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
937
          dialogs.messageDialog(
938
                    i18n.getTranslation("_The_group_function_is_not_available_for_this_table"), 
939
                    i18n.getTranslation("_Information"), 
940
                    JOptionPane.INFORMATION_MESSAGE
941
          );
942
          return;
943
        }
944

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

    
965
    private void doSelectResultColumnNames() {
966
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
967
        I18nManager i18n = ToolsLocator.getI18nManager();
968
        final FeatureAttributesSelectionPanel panel = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
969
        FeatureType ftype = this.getFeatureType();
970
        try {
971
          Feature f = store.findFirst(this.parameters.getQuery());
972
          if( f!=null ) {
973
            ftype = f.getType();
974
          }
975
        } catch (Throwable ex) {
976
            LOGGER.warn("Can't retrieve the feature type from the first feature.",ex);
977
        }
978
        panel.setFeatureType(ftype);
979
        panel.setSelectedNames(this.parameters.getResultColumnNames());
980
        final Dialog dialog = winmanager.createDialog(
981
                panel.asJComponent(),
982
                i18n.getTranslation("_Select_the_columns_to_display"),
983
                null,
984
                WindowManager_v2.BUTTONS_OK_CANCEL
985
        );
986
        dialog.addActionListener((ActionEvent e) -> {
987
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
988
                this.setResultColumnNames(panel.getSelectedNames());
989
            }
990
        });
991
        dialog.show(WindowManager.MODE.DIALOG);
992
    }
993

    
994
    @Override
995
    public void put(SearchParameters inParams) {
996
        for (SearchConditionPanel conditionPanel : this.conditionPanels) {
997
            try {
998
                conditionPanel.put(inParams);
999
            } catch (Exception ex) {
1000
                LOGGER.warn("Can't open panel", ex);
1001
            }
1002
        }
1003
        this.parameters = (DefaultSearchParameters) inParams;
1004

    
1005
    }
1006

    
1007
    private FeatureQuery getQuery() {
1008
        FeatureQuery query;
1009
        try {
1010
            int searchMode = this.tabSearchMode.getSelectedIndex();
1011
            SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1012
            Expression filter = panel.get();
1013
            if (searchMode != PANEL_ADVANCED) {
1014
                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1015
            }
1016
            query = (FeatureQuery) this.parameters.getQuery().clone();
1017
            query.retrievesAllAttributes();
1018
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1019
                return query;
1020
            }
1021
            query.setFilter(filter);
1022
            query.retrievesAllAttributes();
1023
            return query;
1024
        } catch (Exception ex) {
1025
            LOGGER.warn("Can't build query.", ex);
1026
            return null;
1027
        }
1028
    }
1029

    
1030
    @Override
1031
    public SearchParameters fetch(SearchParameters outParams) {
1032
        // Actualiza el fquery del parameters con los paneles
1033
        for (SearchConditionPanel conditionPanel : conditionPanels) {
1034
            try {
1035
                conditionPanel.fetch(this.parameters);
1036
            } catch (Exception ex) {
1037
                LOGGER.warn("Panel not able to fetch values", ex);
1038
            }
1039
        }
1040

    
1041
        // Actualiza el filtro con el panel activo
1042
        int searchMode = this.tabSearchMode.getSelectedIndex();
1043
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1044
        Expression filter = panel.get();
1045
        if (searchMode != PANEL_ADVANCED) {
1046
            this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1047
        }
1048
        FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1049
        this.lastQuery = query.getCopy();
1050
        query.retrievesAllAttributes();
1051
        query.clearFilter();
1052
        if (!ExpressionUtils.isPhraseEmpty(filter)) {
1053
            query.setFilter(filter);
1054
            query.retrievesAllAttributes();
1055
        }
1056

    
1057
        if (outParams == null) {
1058
            return this.parameters.getCopy();
1059
        }
1060
        outParams.copyFrom(this.parameters.getCopy());
1061
        return outParams;
1062
    }
1063

    
1064
    public static void selfRegister() {
1065
        String[][] iconNames = new String[][]{
1066
            new String[]{"dalswing", "featurestore-column"},
1067
            new String[]{"dalswing", "featurestore-foreing-key"},
1068
            new String[]{"dalswing", "featurestore-table"},
1069
            new String[]{"dalswing", "search-action-showform"},
1070
            new String[]{"dalswing", "search-action-select"},
1071
            new String[]{"dalswing", "search-action-select-add"},
1072
            new String[]{"dalswing", "search-action-select-filter"}
1073
        };
1074
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1075
        for (String[] icon : iconNames) {
1076
            URL url = DefaultSearchPanel.class.getResource(icon[1] + ".png");
1077
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1078
        }
1079

    
1080
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1081
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1082
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1083
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1084
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1085
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1086
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1087
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1088
    }
1089
}