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

History | View | Annotate | Download (67.8 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.Toolkit;
8
import java.awt.datatransfer.Clipboard;
9
import java.awt.datatransfer.StringSelection;
10
import java.awt.datatransfer.Transferable;
11
import java.awt.event.ActionEvent;
12
import java.awt.event.ActionListener;
13
import java.awt.event.ComponentAdapter;
14
import java.awt.event.ComponentEvent;
15
import java.awt.event.KeyAdapter;
16
import java.awt.event.KeyEvent;
17
import java.net.URL;
18
import java.text.DateFormat;
19
import java.text.SimpleDateFormat;
20
import java.util.ArrayList;
21
import java.util.Calendar;
22
import java.util.Collection;
23
import java.util.Collections;
24
import java.util.Date;
25
import java.util.HashMap;
26
import java.util.List;
27
import java.util.Map;
28
import java.util.Objects;
29
import javax.swing.AbstractAction;
30
import javax.swing.Action;
31
import static javax.swing.Action.ACTION_COMMAND_KEY;
32
import static javax.swing.Action.NAME;
33
import javax.swing.BorderFactory;
34
import javax.swing.ImageIcon;
35
import javax.swing.JButton;
36
import javax.swing.JComponent;
37
import javax.swing.JMenuItem;
38
import javax.swing.JOptionPane;
39
import javax.swing.JPopupMenu;
40
import javax.swing.JTable;
41
import javax.swing.ListSelectionModel;
42
import javax.swing.SwingUtilities;
43
import javax.swing.TransferHandler;
44
import javax.swing.event.ChangeEvent;
45
import javax.swing.event.ChangeListener;
46
import javax.swing.event.ListSelectionEvent;
47
import javax.swing.event.ListSelectionListener;
48
import javax.swing.table.DefaultTableModel;
49
import javax.swing.table.TableModel;
50
import org.apache.commons.io.FilenameUtils;
51
import org.apache.commons.lang.mutable.MutableObject;
52
import org.apache.commons.lang3.StringUtils;
53
import org.apache.commons.lang3.mutable.MutableLong;
54
import org.gvsig.configurableactions.ConfigurableActionsMamager;
55
import org.gvsig.expressionevaluator.Expression;
56
import org.gvsig.expressionevaluator.ExpressionBuilder;
57
import org.gvsig.expressionevaluator.ExpressionUtils;
58
import static org.gvsig.fmap.dal.DataManager.DAL_USE_LABELS;
59
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_BOTH;
60
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_NO;
61
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_YES;
62
import org.gvsig.fmap.dal.DataStore;
63
import org.gvsig.fmap.dal.DataStoreProviderFactory;
64
import org.gvsig.fmap.dal.complements.Search;
65
import org.gvsig.fmap.dal.exception.DataException;
66
import org.gvsig.fmap.dal.feature.Feature;
67
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
68
import org.gvsig.fmap.dal.feature.FeatureQuery;
69
import org.gvsig.fmap.dal.feature.FeatureStore;
70
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
71
import org.gvsig.fmap.dal.feature.FeatureType;
72
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
73
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
74
import org.gvsig.fmap.dal.swing.DALActionFactory;
75
import org.gvsig.fmap.dal.swing.DALSwingLocator;
76
import org.gvsig.fmap.dal.swing.DataSwingManager;
77
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
78
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryGroupByPanel;
79
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
80
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel;
81
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel.SearchConditionPanelFactory;
82
import org.gvsig.tools.ToolsLocator;
83
import org.gvsig.tools.dataTypes.DataType;
84
import org.gvsig.tools.dynobject.Tags;
85
import org.gvsig.tools.i18n.I18nManager;
86
import org.gvsig.tools.swing.api.ActionListenerSupport;
87
import org.gvsig.tools.swing.api.ToolsSwingLocator;
88
import org.gvsig.tools.swing.api.ToolsSwingManager;
89
import org.gvsig.tools.swing.api.windowmanager.Dialog;
90
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
91
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
92
import org.gvsig.tools.swing.icontheme.IconTheme;
93
import org.gvsig.tools.util.ToolsUtilLocator;
94
import org.slf4j.Logger;
95
import org.slf4j.LoggerFactory;
96
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryGroupByPanel;
97
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryOrderPanel;
98
import org.gvsig.fmap.dal.swing.featuretable.SimpleFeaturesTableModel;
99
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryCalculatedColumnsPanel;
100
import org.gvsig.fmap.dal.swing.featuretype.FeatureAttributesSelectionPanel;
101
import org.gvsig.fmap.dal.swing.impl.featuretable.SimpleFeaturesTableModelImpl;
102
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcess;
103
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcessFactory;
104
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
105
import org.gvsig.tools.bookmarksandhistory.Bookmark;
106
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
107
import org.gvsig.tools.bookmarksandhistory.History;
108
import org.gvsig.tools.dispose.Disposable;
109
import org.gvsig.tools.dispose.DisposeUtils;
110
import org.gvsig.tools.dynform.DynFormLocator;
111
import org.gvsig.tools.dynform.JDynForm;
112
import org.gvsig.tools.dynobject.DynObject;
113
import org.gvsig.tools.swing.api.SupportIsEnable;
114
import org.gvsig.tools.swing.api.SupportIsVisible;
115
import org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue;
116
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_GETVALUE;
117
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETVALUE;
118
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController;
119
import org.gvsig.tools.swing.api.bookmarkshistory.HistoryController;
120
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
121

    
122
/**
123
 *
124
 * @author jjdelcerro
125
 */
126
@SuppressWarnings({"UseSpecificCatch"})
127
public class DefaultSearchPanel
128
        extends DefaultSearchPanelView2
129
        implements FeatureStoreSearchPanel, SupportIsEnable, SupportIsVisible {
130

    
131
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSearchPanel.class);
132

    
133
    static /* friend */ Integer useLabels = null;
134
    private BookmarksController bookmarksController;
135
    private HistoryController historyController;
136
    private FeatureQuery lastQuery;
137

    
138
    public static class UseLabelsYesAction extends AbstractAction {
139

    
140
        @SuppressWarnings("OverridableMethodCallInConstructor")
141
        public UseLabelsYesAction() {
142
            I18nManager i18n = ToolsLocator.getI18nManager();
143

    
144
            this.putValue(NAME, i18n.getTranslation("_Use_labels"));
145
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsYes");
146
        }
147

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

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

    
164
    public static class UseLabelsNoAction extends AbstractAction {
165

    
166
        @SuppressWarnings("OverridableMethodCallInConstructor")
167
        public UseLabelsNoAction() {
168
            I18nManager i18n = ToolsLocator.getI18nManager();
169
            this.putValue(NAME, i18n.getTranslation("_Use_names"));
170
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsNo");
171
        }
172

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

    
183
        @Override
184
        public void actionPerformed(ActionEvent ae) {
185
            DefaultSearchPanel.useLabels = USE_LABELS_NO;
186
        }
187
    }
188

    
189
    public static class UseLabelsBothAction extends AbstractAction {
190

    
191
        @SuppressWarnings("OverridableMethodCallInConstructor")
192
        public UseLabelsBothAction() {
193
            I18nManager i18n = ToolsLocator.getI18nManager();
194

    
195
            this.putValue(NAME, i18n.getTranslation("_Use_labels_and_names"));
196
            this.putValue(ACTION_COMMAND_KEY, "UseLabelsBoth");
197
        }
198

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

    
209
        @Override
210
        public void actionPerformed(ActionEvent ae) {
211
            DefaultSearchPanel.useLabels = USE_LABELS_BOTH;
212
        }
213
    }
214

    
215
    public static class SelectColumnsAction extends AbstractAction {
216

    
217
        @SuppressWarnings("OverridableMethodCallInConstructor")
218
        public SelectColumnsAction() {
219
            I18nManager i18n = ToolsLocator.getI18nManager();
220

    
221
            this.putValue(NAME, i18n.getTranslation("_Select_columns_to_display"));
222
            this.putValue(ACTION_COMMAND_KEY, "SelectColumns");
223
        }
224

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

    
235
        @Override
236
        public void actionPerformed(ActionEvent ae) {
237
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
238
            panel.doSelectResultColumnNames();
239
        }
240
    }
241

    
242
    public static class CalculatedColumnsAction extends AbstractAction {
243

    
244
        @SuppressWarnings("OverridableMethodCallInConstructor")
245
        public CalculatedColumnsAction() {
246
            I18nManager i18n = ToolsLocator.getI18nManager();
247

    
248
            this.putValue(NAME, i18n.getTranslation("_Calculated_columns"));
249
            this.putValue(ACTION_COMMAND_KEY, "CalculatedColumns");
250
        }
251

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

    
262
        @Override
263
        public void actionPerformed(ActionEvent ae) {
264
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
265
            panel.doCalculatedColumns();
266
        }
267
    }
268

    
269
    public static class GroupByAction extends AbstractAction {
270

    
271
        @SuppressWarnings("OverridableMethodCallInConstructor")
272
        public GroupByAction() {
273
            I18nManager i18n = ToolsLocator.getI18nManager();
274

    
275
            this.putValue(NAME, i18n.getTranslation("_Group_by"));
276
            this.putValue(ACTION_COMMAND_KEY, "GroupBy");
277
        }
278

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

    
289
        @Override
290
        public void actionPerformed(ActionEvent ae) {
291
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
292
            panel.doGroupBy();
293
        }
294
    }
295

    
296
    public static class OrderByAction extends AbstractAction {
297

    
298
        @SuppressWarnings("OverridableMethodCallInConstructor")
299
        public OrderByAction() {
300
            I18nManager i18n = ToolsLocator.getI18nManager();
301

    
302
            this.putValue(NAME, i18n.getTranslation("_Order_by"));
303
            this.putValue(ACTION_COMMAND_KEY, "SelectOrderBy");
304
        }
305

    
306
        @Override
307
        public Object getValue(String key) {
308
            if (NAME.equals(key)) {
309
                // Cuando se registra la accion aun no se han cargado las traducciones
310
                I18nManager i18n = ToolsLocator.getI18nManager();
311
                return i18n.getTranslation("_Order_by");
312
            }
313
            return super.getValue(key);
314
        }
315

    
316
        @Override
317
        public void actionPerformed(ActionEvent ae) {
318
            DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
319
            panel.doOrderBy();
320
        }
321
    }
322
    
323
    private class TablePopupMenu extends JPopupMenu {
324
            public final JTable table;
325
            public TablePopupMenu(JTable inputTable) {
326
                this.table = inputTable;
327
                JMenuItem copyRowsActionMenu = new JMenuItem("_Copy_rows");
328
                copyRowsActionMenu.addActionListener(new ActionListener() {
329

    
330
                    @Override
331
                    public void actionPerformed(ActionEvent e) {
332
                        doCopyRows(table);
333
                    }
334
                });
335
                this.add(copyRowsActionMenu);
336
            }
337
        }
338
            
339
    private class ActionButtons {
340

    
341
        private final DALActionFactory factory;
342
        private final Action action;
343
        private final JButton button;
344

    
345
        public ActionButtons(DALActionFactory factory, Action action, JButton button) {
346
            this.factory = factory;
347
            this.action = action;
348
            this.button = button;
349
        }
350
    }
351

    
352
    public static class SearchActionContext extends AbstractDALActionContext {
353

    
354
        private final DefaultSearchPanel panel;
355

    
356
        public SearchActionContext(DefaultSearchPanel panel) {
357
            super(FeatureStoreSearchPanel.ACTION_CONTEXT_NAME);
358
            this.panel = panel;
359
        }
360

    
361
        @Override
362
        public DataStore getStore() {
363
            if (this.panel.currentPostProcess == null || this.panel.tabResults.getSelectedIndex() == 0) {
364
                return this.panel.getStore();
365
            } else {
366
                return this.panel.postProcessStore;
367
//                DataSwingManager manager = DALSwingLocator.getDataSwingManager();
368
//                SearchPostProcessFactory factory= manager.getSearchPostProcess(this.panel.currentPostProcess);
369
//                SearchParameters searchParams = this.panel.parameters.getCopy();
370
//                if (factory.hasProcessParameters()){
371
//                    SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, this.panel.postProcessParams, searchParams);
372
//                    return searchPostProcessResult.getStore();
373
//                }
374
//                SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, null, searchParams);
375
//                return searchPostProcessResult.getStore();
376
            }
377
        }
378

    
379
        @Override
380
        public JComponent getActionButton(String actionName) {
381
            return this.panel.getActionButton(actionName);
382
        }
383

    
384
        @Override
385
        public int getSelectedsCount() {
386
            return this.panel.getSelectedFeatureCount();
387
        }
388

    
389
        @Override
390
        public Expression getFilterForSelecteds() {
391
            return this.panel.getFilterForSelectedFeature();
392
        }
393

    
394
        @Override
395
        public FeatureQuery getQuery() {
396
            if (this.panel.currentPostProcess == null || this.panel.tabResults.getSelectedIndex() == 0) {
397
                return this.panel.parameters.getQuery();
398
            } else {
399
                return this.panel.postProcessQuery;
400
//                DataSwingManager manager = DALSwingLocator.getDataSwingManager();
401
//                SearchPostProcessFactory factory= manager.getSearchPostProcess(this.panel.currentPostProcess);
402
//                SearchParameters searchParams =this.panel.parameters.getCopy();
403
//                if (factory.hasProcessParameters()){
404
//                    SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, this.panel.postProcessParams, searchParams);
405
//                    return searchPostProcessResult.getQuery();
406
//                }
407
//                SearchPostProcess.SearchPostProcessResult searchPostProcessResult = this.panel.doExecuteSearchPostProcess(this.panel.store, this.panel.parameters.getQuery(), factory, null, searchParams);
408
//                return searchPostProcessResult.getQuery();
409
            }
410
        }
411
    }
412

    
413
//    private class SearchPostProcessListener implements ActionListener {
414
//
415
//        private final FeatureStore input;
416
//        private final SearchPostProcessFactory factory;
417
//        private final FeatureQuery query;
418
//
419
//        public SearchPostProcessListener(
420
//                FeatureStore input,
421
//                FeatureQuery query,
422
//                SearchPostProcessFactory factory
423
//        ) {
424
//            this.input = input;
425
//            this.query = query;
426
//            this.factory = factory;
427
//        }
428
//
429
//        @Override
430
//        public void actionPerformed(ActionEvent e) {
431
//            // habilita la pesta�a del tab con los resultados del post procesado
432
//            if (this.factory.hasProcessParameters()) {
433
//                DynObject parameters = this.factory.createProcessParameters(this.input);
434
//                JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(parameters);
435
//                form.asJComponent().setPreferredSize(new Dimension(350, 250));
436
//
437
//                I18nManager i18n = ToolsLocator.getI18nManager();
438
//                WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
439
//
440
//                Dialog dialog = windowManager.createDialog(
441
//                        form.asJComponent(),
442
//                        i18n.getTranslation("_create_parameters"),
443
//                        i18n.getTranslation("_parameters_list"),
444
//                        WindowManager_v2.BUTTONS_OK_CANCEL);
445
//
446
//                dialog.addActionListener((ActionEvent e2) -> {
447
//                    if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
448
//                        form.getValues(parameters); // actualiza el valor de lo los parametros con los valores introducidos por el usuario
449
//                        doExecuteSearchPostProcess(this.input, this.query, this.factory, parameters);
450
//                        postProcessParams = parameters;
451
//                    }
452
//                });
453
//
454
//                dialog.show(WindowManager.MODE.DIALOG);
455
//
456
//            } else {
457
//                doExecuteSearchPostProcess(this.input, this.query, this.factory, null);
458
//            }
459
//        }
460
//    }
461

    
462
    private FeatureStore store;
463
    private final ActionListenerSupport acctionListeners;
464
    private final Map<String, ActionButtons> actions;
465
    private boolean showActions = true;
466
    private DefaultSearchParameters parameters;
467

    
468
    private List<SearchConditionPanel> conditionPanels;
469

    
470
    public static final int PANEL_SIMPLIFIED = 0;
471
    public static final int PANEL_ADVANCED = 1;
472
    private static final String BOOKMARKSANDHISTORY_NAME = "SearchPanel";
473
    private final Bookmarks<Object> bookmarks;
474
    private final History<Object> history;
475
    private boolean filterOnlyMode;
476

    
477
    private String currentPostProcess;
478

    
479
    private DynObject postProcessParams;
480
    private FeatureStore postProcessStore;
481
    private FeatureQuery postProcessQuery;
482
    private SimpleFeaturesTableModel resultModel;
483
    private SimpleFeaturesTableModel resultPostProcessModel;
484

    
485
    private boolean processing;
486

    
487
    private JComponent configurableActions;
488

    
489
    public DefaultSearchPanel(FeatureStore store) {
490
        this.store = store;
491
        this.filterOnlyMode = false;
492
        DisposeUtils.bind(store);
493
        this.acctionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
494
        this.actions = new HashMap<>();
495
        this.parameters = new DefaultSearchParameters();
496
        FeatureQuery featureQuery = this.store.createFeatureQuery();
497
        featureQuery.retrievesAllAttributes();
498
        this.parameters.setQuery(featureQuery);
499
        this.currentPostProcess = null;
500
        this.postProcessParams = null;
501
        this.postProcessStore = null;
502
        this.postProcessQuery = null;
503
        this.processing = false;
504
        this.configurableActions = null;
505
        this.resultModel = null;
506
        this.resultPostProcessModel = null;
507

    
508
        Search search = (Search) ToolsLocator.getComplementsManager().get(
509
                Search.COMPLEMENT_MANE, getFeatureType()
510
        );
511
        List<Search.OrderedAttribute> attributos = search.getOrderedAttributes(
512
                Search.BASIC_TYPES_FILTER,
513
                Search.STR_INT_LONG_LABEL_ORDER,
514
                12
515
        );
516
        for (Search.OrderedAttribute attrdesc : attributos) {
517
            this.parameters.getResultColumnNames().add(attrdesc.getDescriptor().getName());
518
        }
519
        this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
520
        this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
521
    }
522

    
523
    @Override
524
    public void dispose() {
525
        DisposeUtils.disposeQuietly(store);
526
        TableModel m = this.tblResults.getModel();
527
        if (m instanceof Disposable) {
528
            DisposeUtils.disposeQuietly((Disposable) m);
529
        }
530
        this.store = null;
531
        this.tblResults.setModel(new DefaultTableModel());
532
    }
533

    
534
    @Override
535
    public JComponent asJComponent() {
536
        if (this.conditionPanels == null) {
537
            this.initComponents();
538
        }
539
        return this;
540
    }
541

    
542
    private void addActions() {
543
        if (!this.showActions) {
544
            return;
545
        }
546
        this.pnlActions.removeAll();
547
        this.pnlActions.setLayout(new FlowLayout(FlowLayout.TRAILING, 8, 4));
548
        SearchActionContext actionContext = new SearchActionContext(this);
549
        Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getStoreActions();
550
        for (DALActionFactory factory : factories) {
551
            Action action = factory.createAction(actionContext);
552
            JButton button = new JButton(action);
553
            this.actions.put(factory.getName(), new ActionButtons(factory, action, button));
554
            button.setBorder(BorderFactory.createEmptyBorder());
555
            button.setBorderPainted(false);
556
            button.setFocusPainted(false);
557
            button.setContentAreaFilled(false);
558
            button.setCursor(new Cursor(Cursor.HAND_CURSOR));
559
            this.pnlActions.add(button);
560
        }
561
        this.pnlActions.revalidate();
562
        this.pnlActions.repaint();
563
    }
564

    
565
    @Override
566
    public void addActionListener(ActionListener listener) {
567
        this.acctionListeners.addActionListener(listener);
568
    }
569

    
570
    @Override
571
    public ActionListener[] getActionListeners() {
572
        return this.acctionListeners.getActionListeners();
573
    }
574

    
575
    @Override
576
    public void removeActionListener(ActionListener listener) {
577
        this.acctionListeners.removeActionListener(listener);
578
    }
579

    
580
    @Override
581
    public void removeAllActionListener() {
582
        this.acctionListeners.removeAllActionListener();
583
    }
584

    
585
    @Override
586
    public void fireActionEvent(ActionEvent event) {
587
        this.acctionListeners.fireActionEvent(event);
588
    }
589

    
590
    @Override
591
    public boolean hasActionListeners() {
592
        return this.acctionListeners.hasActionListeners();
593
    }
594

    
595
    private void initComponents() {
596
        this.conditionPanels = new ArrayList<>();
597

    
598
        ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
599
        swingManager.translate(this.tabSearchMode);
600
        swingManager.translate(this.tabResults);
601
        swingManager.translate(this.btnSearch);
602
        swingManager.translate(this.btnClear);
603
        swingManager.translate(this.btnSearchPostProcess);
604
        swingManager.translate(this.lblExpressionDeBusqueda);
605
        swingManager.translate(this.btnAddAccumulatedFilter);
606
        swingManager.translate(this.btnRemoveAccumulatedFilter);
607
        swingManager.translate(this.btnViewAccumulatedFilter);
608

    
609
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
610
        this.configurableActions = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
611
        this.pnlCfgActions.setLayout(new BorderLayout(0, 0));
612
        this.pnlCfgActions.add(configurableActions, BorderLayout.CENTER);
613

    
614
        this.conditionPanels.add(
615
                new SearchConditionPanelSimplified(
616
                        parameters,
617
                        store,
618
                        btnAddAccumulatedFilter,
619
                        btnRemoveAccumulatedFilter,
620
                        btnViewAccumulatedFilter,
621
                        lblField1,
622
                        lblExtraFields1,
623
                        lblRelationalOperator1,
624
                        cboValue1,
625
                        lblNull1,
626
                        lblLogicalOperators1,
627
                        lblField2,
628
                        lblExtraFields2,
629
                        lblRelationalOperator2,
630
                        cboValue2,
631
                        lblNull2,
632
                        lblLogicalOperators2,
633
                        lblField3,
634
                        lblExtraFields3,
635
                        lblRelationalOperator3,
636
                        cboValue3,
637
                        lblNull3,
638
                        lblLogicalOperators3,
639
                        lblField4,
640
                        lblExtraFields4,
641
                        lblRelationalOperator4,
642
                        cboValue4,
643
                        lblNull4,
644
                        null
645
                )
646
        );
647
        this.conditionPanels.add(
648
                new SearchConditionPanelAdvanced(
649
                        this.store,
650
                        txtAdvancedExpression,
651
                        btnAdvancedExpression,
652
                        btnAdvancedExpressionHistory,
653
                        btnAdvancedExpressionBookmarks
654
                )
655
        );
656
        for (SearchConditionPanelFactory factory : DALSwingLocator.getManager().getSearchConditionPanels()) {
657
            String factoryName = "unknown";
658
            try {
659
                factoryName = factory.getName();
660
                if (factory.isApplicable(store)) {
661
                    SearchConditionPanel panel = factory.create(this);
662
                    this.conditionPanels.add(panel);
663
                    this.tabSearchMode.add(factory.getName(), panel.asJComponent());
664
                }
665
            } catch (Throwable th) {
666
                LOGGER.warn("Can't create search panel '" + factoryName + "'.");
667
            }
668
        }
669

    
670
        this.btnSearch.addActionListener((ActionEvent e) -> {
671
            this.tabResults.setEnabledAt(1, false);
672
            search();
673
        });
674

    
675
        this.tblResults.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
676
            for (ActionButtons actionButton : actions.values()) {
677
                if (actionButton.action instanceof ListSelectionListener) {
678
                    ((ListSelectionListener) actionButton.action).valueChanged(e);
679
                }
680
            }
681
        });
682
        this.btnClear.addActionListener((ActionEvent e) -> {
683
            clear();
684
        });
685
        addActions();
686

    
687
        swingManager.createTableColumnAdjuster(tblResults);
688
        swingManager.createTableColumnAdjuster(tblSearchPostProcessResults);
689

    
690
        this.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
691

    
692
        this.bookmarksController = ToolsSwingLocator.getToolsSwingManager().createBookmarksController(this.bookmarks, btnBookmarks);
693
        this.historyController = ToolsSwingLocator.getToolsSwingManager().createHistoryController(this.history, btnHistory);
694

    
695
        this.historyController.setFilter(null);
696

    
697
        ActionListener bookmarksAndHistoryListener = new ActionListener() {
698
            @Override
699
            public void actionPerformed(ActionEvent e) {
700
                ActionEventWithCurrentValue<DefaultSearchParameters> b = (ActionEventWithCurrentValue<DefaultSearchParameters>) e;
701
                switch (b.getID()) {
702
                    case ID_GETVALUE:
703
                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
704
                        b.setCurrentValue(actualParams);
705
                        break;
706

    
707
                    case ID_SETVALUE:
708
                        if (b.getCurrentValue() == null) {
709
                            return;
710
                        }
711
                        DefaultSearchParameters searchParams;
712
                        try {
713
                            searchParams = b.getCurrentValue().getCopy();
714
                        } catch (Exception ex) {
715
                            LOGGER.warn("Not been able to clone export parameters", ex);
716
                            return;
717
                        }
718
                        clear();
719
                        put(searchParams);
720
                        Thread th = new Thread(() -> {
721
                            doSearch(searchParams);
722
                        });
723
                        th.start();
724
                        break;
725
                }
726

    
727
            }
728
        };
729
        this.historyController.addActionListener(bookmarksAndHistoryListener);
730
        this.bookmarksController.addActionListener(bookmarksAndHistoryListener);
731
        this.addComponentListener(new ComponentAdapter() {
732
            @Override
733
            public void componentHidden(ComponentEvent e) {
734
                dispose();
735
            }
736
        });
737

    
738
        this.btnSearchPostProcess.addActionListener(new ActionListener() {
739
            @Override
740
            public void actionPerformed(ActionEvent e) {
741
                try {
742
                    doSelectSearchPostprocess();
743
                } catch (DataException ex) {
744
                    LOGGER.warn("Can't select a Search Post Process", ex);
745
                }
746
            }
747
        });
748

    
749
        this.tabResults.setEnabledAt(1, false);
750

    
751
        this.tblResults.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
752
        this.tblResults.addKeyListener(new KeyAdapter() {
753
            @Override
754
            public void keyPressed(KeyEvent e) {
755
                if( e.getKeyCode()==KeyEvent.VK_F4 ) {
756
                    doShowCellInDialog();
757
                }
758
            }
759
        });        
760
        
761
        this.tblResults.setComponentPopupMenu(new TablePopupMenu(this.tblResults));
762
        this.tblSearchPostProcessResults.setComponentPopupMenu(new TablePopupMenu(this.tblSearchPostProcessResults));
763
                
764
        //this.tblResults.add
765
        if (this.bookmarks.hasBookmark(this.store.getName())) {
766
            Bookmark<DefaultSearchParameters> initBookmark = this.bookmarks.get(this.store.getName());
767
            DefaultSearchParameters initSearchParams = initBookmark.getValue().getCopy();
768
            put(initSearchParams);
769
            Thread th = new Thread(() -> {
770
                doSearch(initSearchParams);
771
            });
772
            th.start();
773
            return;
774
        }
775
        
776
        this.tabResults.addChangeListener(new ChangeListener() {
777
            public void stateChanged(ChangeEvent evt) {
778
                SwingUtilities.invokeLater(() -> {
779
                    if(tabResults.getSelectedIndex()==0){
780
                        updateNumberElementsMsg(resultModel);
781
                    }else{
782
                        updateNumberElementsMsg(resultPostProcessModel);
783
                    }
784
                });
785
            }
786
        });
787
        
788
        search();
789
    }
790
    
791
    private void doShowCellInDialog() {
792
        int row = this.tblResults.getSelectedRow();
793
        if( row < 0 ) {
794
            return;
795
        }
796
        int col = this.tblResults.getSelectedColumn();
797
        if( col < 0 ) {
798
            return;
799
        }
800
        String s = Objects.toString(this.tblResults.getValueAt(row, col),null);
801
        if( StringUtils.isBlank(s) ) {
802
            return;
803
        }
804
        ToolsSwingLocator.getToolsSwingManager().showZoomDialog(
805
            this, 
806
            this.tblResults.getColumnName(col), 
807
            s,
808
            false
809
        );
810
    }
811

    
812
    private FeatureType getFeatureType() {
813
        try {
814
            return store.getDefaultFeatureType();
815
        } catch (Exception ex) {
816
            throw new RuntimeException("Can't retrieve the feature type.", ex);
817
        }
818
    }
819

    
820
    @Override
821
    public void setEnabled(boolean enabled) {
822
        if (this.conditionPanels == null) {
823
            this.initComponents();
824
        }
825
        for (SearchConditionPanel conditionPanel : conditionPanels) {
826
            conditionPanel.setEnabled(enabled);
827
        }
828

    
829
        this.btnClear.setEnabled(enabled);
830
        this.btnSearch.setEnabled(enabled);
831
        for (ActionButtons actionButton : actions.values()) {
832
            actionButton.action.setEnabled(enabled);
833
        }
834
        this.btnSearchPostProcess.setEnabled(enabled);
835
        //bookmarkController,historyController,configurableActions
836
    }
837

    
838
    @Override
839
    public void clear() {
840
        this.lblMsg.setText("");
841
        if (this.conditionPanels == null) {
842
            return;
843
        }
844
        for (SearchConditionPanel conditionPanel : conditionPanels) {
845
            conditionPanel.clear();
846
        }
847
        FeatureQuery emptyQuery = this.store.createFeatureQuery();
848
        emptyQuery.retrievesAllAttributes();
849
        this.parameters.setQuery(emptyQuery);
850
        // Mantener las columnas visualizadas
851
        // Elimina las que no existen en el store como campos calculados que
852
        // pudieran existir en el fquery
853
        List<String> resultColumnNames = this.parameters.getResultColumnNames();
854
        ArrayList<String> toDeleteAlreadyDontExist = new ArrayList<>();
855
        for (String resultColumnName : resultColumnNames) {
856
            try {
857
                FeatureAttributeDescriptor attr = this.store.getDefaultFeatureType().getAttributeDescriptor(resultColumnName);
858
                if (attr == null) {
859
                    toDeleteAlreadyDontExist.add(resultColumnName);
860
                }
861
            } catch (DataException ex) {
862

    
863
            }
864
        }
865
        resultColumnNames.removeAll(toDeleteAlreadyDontExist);
866
        resetTable();
867
    }
868

    
869
    @Override
870
    public FeatureQuery getLastQuery() {
871
        return this.lastQuery;
872
    }
873

    
874
    public boolean isValid(StringBuilder message) {
875
        int searchMode = this.tabSearchMode.getSelectedIndex();
876
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
877
        boolean valid = panel.isValid(message);
878
        return valid;
879
    }
880
    
881
    public void search() {
882
        StringBuilder message = new StringBuilder();
883
        if (!this.isValid(message)) {
884
            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
885
            dialogManager.messageDialog(
886
                    "_The_specified_search_condition_is_not_valid",
887
                    "_Search",
888
                    JOptionPane.WARNING_MESSAGE
889
            );
890
            return;
891
        }
892
        lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Searching")+"...");
893
        setEnabled(false);
894
        Thread th = new Thread(() -> {
895
            try {
896
            SearchParameters searchParams;
897
            try {
898
                searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
899

    
900
                Date date = Calendar.getInstance().getTime();
901
                DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
902
                String strDate = dateFormat.format(date);
903
                searchParams.setName("Params: " + strDate);
904
            } catch (Exception ex) {
905
                LOGGER.warn("Not able to create search parameters.", ex);
906
                lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Errors_fetching_new_query")+"...");
907
                resetTable();
908
                return;
909
            }
910
            doSearch(searchParams);
911
                        } catch (Exception ex) {
912
                LOGGER.warn("Search panel has errors during the search", ex);
913
                resetTable();
914
            } finally {
915
                SwingUtilities.invokeLater(() -> {
916
                    setEnabled(true);
917
                });
918
            }
919
        });
920
        th.start();
921
    }
922
    
923
     private void doSearch(SearchParameters searchParams)  {
924
            final MutableObject model = new MutableObject(null);       
925
            final MutableLong rowCount=new MutableLong();
926
            try {
927
                final List<Feature> features;
928
                 FeatureQuery myQuery;
929
//                myQuery = this.getQuery().getCopy();
930
                this.tabResults.setSelectedIndex(0);
931
                List<String> resultColumnNames = searchParams.getResultColumnNames();
932
                myQuery = searchParams.getQuery().getCopy();
933
                features = store.getFeatures(myQuery, 50);
934
                FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
935
                FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
936
                // al modelo le pasamos el ftype de esas features
937
                SimpleFeaturesTableModel tableModel = new SimpleFeaturesTableModelImpl(
938
                        ftype,
939
                        resultColumnNames,
940
                        features
941
                );
942
                model.setValue(tableModel);
943
                rowCount.setValue(tableModel.getRowCount());
944
            } catch (Exception ex) {
945
                LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
946
                lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Errors_getting_new_feature_set") + "...");
947
                resetTable();
948
            } finally {
949
                SwingUtilities.invokeLater(() -> {
950
                    I18nManager i18n = ToolsLocator.getI18nManager();
951
                    try {
952
                        TableModel oldmodel = tblResults.getModel();
953
                        resultModel = (SimpleFeaturesTableModel) model.getValue();
954
                        tblResults.setModel(resultModel);
955
                        resultModel.setCellRenderers(tblResults);
956
                        if (oldmodel instanceof SimpleFeaturesTableModelImpl) {
957
                            ((SimpleFeaturesTableModelImpl) oldmodel).dispose();
958
                        }
959
                        updateNumberElementsMsg(resultModel);
960
//                        if (resultModel.hasErrors()) {
961
//                            lblMsg.setText(i18n.getTranslation("_Errors_occurred_during_search"));
962
//                        } else {
963
//                            lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), rowCount.getValue()));
964
//                        }
965
                        if (this.parameters != null && this.parameters.getQuery() != null) {
966
                            this.history.add(searchParams);                   
967
                        }
968
                    } catch (Exception ex) {
969
                        LOGGER.warn(" Errors occurred during search getting old model", ex);
970
                        lblMsg.setText(i18n.getTranslation("_Errors_occurred_during_search"));
971
                    } finally {
972
                        setEnabled(true);
973
                    }
974
                });
975
            }
976
     }
977

    
978
    private void resetTable() {
979
        if(!SwingUtilities.isEventDispatchThread()) {
980
            SwingUtilities.invokeLater(this::resetTable);
981
            return;
982
        }
983
        List<String> resultColumnNames = null;
984
        try {
985
            resultColumnNames = this.parameters.getResultColumnNames();
986
        } catch(Exception ex) {
987
            
988
        }
989
        FeatureType ftype = this.store.getDefaultFeatureTypeQuietly();
990
        SimpleFeaturesTableModelImpl emptyTableModel = new SimpleFeaturesTableModelImpl(
991
                ftype,
992
                resultColumnNames,
993
                null
994
        );
995
        this.tblResults.setModel(emptyTableModel);
996
        
997
    }
998

    
999
    public void setResultColumnNames(List<String> names) {
1000
        this.parameters.getResultColumnNames().clear();
1001
        this.parameters.getResultColumnNames().addAll(names);
1002
        if (this.conditionPanels == null) {
1003
            return;
1004
        }
1005
        SimpleFeaturesTableModelImpl model;
1006
//        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
1007
        List<Feature> features = store.getFeatures(this.parameters.getQuery());
1008
        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
1009
        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1010
        model = new SimpleFeaturesTableModelImpl(
1011
                ftype,
1012
                this.parameters.getResultColumnNames(),
1013
                features
1014
        );
1015
        tblResults.setModel(model);
1016
    }
1017

    
1018
    @Override
1019
    public boolean setFilter(Expression filter) {
1020
        try {
1021
            if (this.conditionPanels == null) {
1022
                this.initComponents();
1023
            }
1024
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1025
                this.clear();
1026
                return true;
1027
            }
1028
            int panel = 0;
1029
            int selected = PANEL_ADVANCED;
1030
            for (SearchConditionPanel conditionPanel : conditionPanels) {
1031
                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
1032
                    selected = panel;
1033
                }
1034
                panel++;
1035
            }
1036
            this.tabSearchMode.setSelectedIndex(selected);
1037

    
1038
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
1039
//            tblResults.setModel(model);
1040
//            lblMsg.setText("");
1041
            return true;
1042
        } catch (Exception ex) {
1043
            LOGGER.warn("Can't set current search", ex);
1044
            return false;
1045
        }
1046
    }
1047

    
1048
    @Override
1049
    public List<SearchConditionPanel> getConditionPanels() {
1050
        return Collections.unmodifiableList(this.conditionPanels);
1051
    }
1052

    
1053
    @Override
1054
    public SearchConditionPanel getConditionPanel(String name) {
1055
        for (SearchConditionPanel panel : conditionPanels) {
1056
            if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
1057
                return panel;
1058
            }
1059
        }
1060
        return null;
1061
    }
1062

    
1063

    
1064
 @Override
1065
    public Expression getFilterForSelectedFeature() {
1066
        if (this.conditionPanels == null) {
1067
            return null;
1068
        }
1069
        if (this.tabResults.getSelectedIndex() == 0) {
1070
            int selectedRow = this.tblResults.getSelectedRow();
1071
            if (selectedRow < 0) {
1072
                return null;
1073
            }
1074
            try {
1075
                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1076
                Feature feature = features.get(selectedRow);
1077

    
1078
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1079
                FeatureType ftype = this.store.getDefaultFeatureType();
1080
                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1081
                    builder.and(
1082
                            builder.eq(
1083
                                    builder.column(attrdesc.getName()),
1084
                                    builder.constant(feature.get(attrdesc.getName()))
1085
                            )
1086
                    );
1087
                }
1088
                Expression filter = ExpressionUtils.createExpression(builder.toString());
1089
                return filter;
1090
            } catch (Exception ex) {
1091
                LOGGER.warn("Can't build search for the selected feature.", ex);
1092
                return null;
1093
            }
1094
        } else {
1095
            if (this.currentPostProcess == null) {
1096
                return null;
1097
            }
1098
            int selectedRow = this.tblSearchPostProcessResults.getSelectedRow();
1099
            if (selectedRow < 0) {
1100
                return null;
1101
            }
1102
            try {
1103
                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1104
                Feature feature = features.get(selectedRow);
1105

    
1106
                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1107
                FeatureType ftype = this.postProcessStore.getDefaultFeatureType();
1108
                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1109
                    builder.and(
1110
                            builder.eq(
1111
                                    builder.column(attrdesc.getName()),
1112
                                    builder.constant(feature.get(attrdesc.getName()))
1113
                            )
1114
                    );
1115
                }
1116
                Expression filter = ExpressionUtils.createExpression(builder.toString());
1117
                return filter;
1118
            } catch (Exception ex) {
1119
                LOGGER.warn("Can't build search for the selected feature.", ex);
1120
                return null;
1121
            }
1122
        }
1123

    
1124
    }
1125
    
1126
    @Override
1127
    public FeatureStore getStore() {
1128
        return store;
1129
    }
1130

    
1131
    private void doOrderBy() {
1132
        I18nManager i18n = ToolsLocator.getI18nManager();
1133
        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1134
        FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
1135
        orderPanel.setStore(store);
1136
        orderPanel.put(parameters.getQuery());
1137
        Dialog dialog = windowManager.createDialog(
1138
                orderPanel.asJComponent(),
1139
                i18n.getTranslation("_Select_order"),
1140
                null,
1141
                WindowManager_v2.BUTTONS_OK_CANCEL
1142
        );
1143
        dialog.addActionListener((ActionEvent e) -> {
1144
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1145
                orderPanel.fetch(this.parameters.getQuery());
1146
                search();
1147
            }
1148
        });
1149
        dialog.show(WindowManager.MODE.DIALOG);
1150
    }
1151
       
1152
    private void doCopyRows(JTable table) {
1153
        
1154
        SimpleFeaturesTableModel model = null;
1155
        if (table.getModel() instanceof SimpleFeaturesTableModel) {
1156
            model = (SimpleFeaturesTableModel) table.getModel();
1157
        }
1158

    
1159
        String LINE_BREAK = System.lineSeparator();
1160
        String CELL_BREAK = "\t";
1161
        char DELIMITER = '"';
1162
        
1163
        Clipboard CLIPBOARD = Toolkit.getDefaultToolkit().getSystemClipboard();
1164
        
1165
        int[] selection = table.getSelectedRows();
1166
        for (int i = 0; i < selection.length; i++) {
1167
          selection[i] = table.convertRowIndexToModel(selection[i]);
1168
        }
1169
   
1170
        int numCols = table.getColumnCount();
1171
        StringBuilder excelStr = new StringBuilder();
1172
        boolean valueIsNumeric;
1173

    
1174
        for (int j = 0; j < numCols; j++) {
1175

    
1176
            excelStr.append(DELIMITER);
1177
            excelStr.append(escape(table.getColumnName(j), LINE_BREAK, CELL_BREAK));
1178
            excelStr.append(DELIMITER);
1179

    
1180
            if (j < numCols - 1) {
1181
                excelStr.append(CELL_BREAK);
1182
            }
1183
        }
1184
        excelStr.append(LINE_BREAK);
1185
        for (int i : selection) {
1186
            for (int j = 0; j < numCols; j++) {
1187
                valueIsNumeric = false;
1188
                if (model != null) {
1189
                    FeatureAttributeDescriptor descriptor = model.getFeatureDescriptor(j);
1190
                    if (descriptor.getDataType().isNumeric()) {
1191
                        if (!descriptor.hasAvailableValues()) {
1192
                            valueIsNumeric = true;
1193
                        }
1194
                    }
1195
                }
1196
                if (!valueIsNumeric) {
1197
                    excelStr.append(DELIMITER);
1198
                }
1199

    
1200
                excelStr.append(escape(table.getValueAt(i, j), LINE_BREAK, CELL_BREAK));
1201

    
1202
                if (!valueIsNumeric) {
1203
                    excelStr.append(DELIMITER);
1204
                }
1205
                if (j < numCols - 1) {
1206
                    excelStr.append(CELL_BREAK);
1207
                }
1208
            }
1209
            excelStr.append(LINE_BREAK);
1210
        }
1211

    
1212
        StringSelection sel = new StringSelection(excelStr.toString());
1213
        CLIPBOARD.setContents(sel, sel);
1214
    }
1215

    
1216
    private String escape(Object cell,String LINE_BREAK, String CELL_BREAK) {
1217
        return (cell == null ? "" : cell.toString()
1218
                .replace(CELL_BREAK, " ")
1219
                );
1220
    }
1221
       
1222
    @Override
1223
    public ImageIcon loadImage(String imageName) {
1224
        String name = FilenameUtils.getBaseName(imageName);
1225
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getDefault();
1226
        if (theme.exists(name)) {
1227
            return theme.get(name);
1228
        }
1229
        URL url = this.getClass().getResource(name + ".png");
1230
        if (url == null) {
1231
            return null;
1232
        }
1233
        return new ImageIcon(url);
1234
    }
1235

    
1236
    @Override
1237
    public int getSelectedFeatureCount() {
1238
        if (this.conditionPanels == null) {
1239
            return 0;
1240
        }
1241
        if (this.currentPostProcess == null || this.tabResults.getSelectedIndex() == 0) {
1242
            return this.tblResults.getSelectedRowCount();
1243
        }
1244
        return this.tblSearchPostProcessResults.getSelectedRowCount();
1245
    }
1246

    
1247
    @Override
1248
    public JComponent getActionButton(String name) {
1249
        ActionButtons actionButton = this.actions.get(name);
1250
        if (actionButton == null) {
1251
            return null;
1252
        }
1253
        return actionButton.button;
1254
    }
1255

    
1256
    @Override
1257
    public void setShowActions(boolean showActions) {
1258
        this.showActions = showActions;
1259
    }
1260

    
1261
    @Override
1262
    public boolean isShowActions() {
1263
        return this.showActions;
1264
    }
1265

    
1266
    public static String getAttributeDescriptorLabel(FeatureAttributeDescriptor attrdesc, String tableName) {
1267
        String theLabel;
1268
        int theUseLabels;
1269
        if (useLabels == null) {
1270
            Tags tags = attrdesc.getTags();
1271
            if (tags.has(DAL_USE_LABELS)) {
1272
                theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
1273
            } else {
1274
                if (attrdesc.getFeatureType()!=null) {
1275
                    tags = attrdesc.getFeatureType().getTags();
1276
                    theUseLabels = tags.getInt(DAL_USE_LABELS, USE_LABELS_NO);
1277
                } else {
1278
                    theUseLabels = USE_LABELS_NO;
1279
                }
1280
            }
1281
        } else {
1282
            theUseLabels = useLabels;
1283
        }
1284
        switch (theUseLabels) {
1285
            case USE_LABELS_YES:
1286
                if (StringUtils.isBlank(tableName)) {
1287
                    theLabel = attrdesc.getLocalizedLabel();
1288
                } else {
1289
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), tableName);
1290
                }
1291
                break;
1292
            default:
1293
            case USE_LABELS_NO:
1294
                if (StringUtils.isBlank(tableName)) {
1295
                    theLabel = attrdesc.getName();
1296
                } else {
1297
                    theLabel = String.format("%s [%s]", attrdesc.getName(), tableName);
1298
                }
1299
                break;
1300
            case USE_LABELS_BOTH:
1301
                if (StringUtils.isBlank(tableName)) {
1302
                    theLabel = String.format("%s [%s]", attrdesc.getLocalizedLabel(), attrdesc.getName());
1303
                } else {
1304
                    theLabel = String.format("%s [%s/%s]", attrdesc.getLocalizedLabel(), attrdesc.getName(), tableName);
1305
                }
1306
                break;
1307
        }
1308
        return theLabel;
1309
    }
1310

    
1311
    private void doCalculatedColumns() {
1312
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1313
        I18nManager i18n = ToolsLocator.getI18nManager();
1314
        final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
1315
        panel.setStore(this.store);
1316
        panel.put(this.parameters.getQuery());
1317
        final Dialog dialog = winmanager.createDialog(
1318
                panel.asJComponent(),
1319
                i18n.getTranslation("_Calculated_columns"),
1320
                null,
1321
                WindowManager_v2.BUTTONS_OK_CANCEL
1322
        );
1323
        dialog.addActionListener((ActionEvent e) -> {
1324
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1325
                panel.fetch(this.parameters.getQuery());
1326
                search();
1327
            }
1328
        });
1329
        dialog.show(WindowManager.MODE.DIALOG);
1330
    }
1331

    
1332
    private void doGroupBy() {
1333
        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1334
        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1335
        if (allowGroupBy != DataType.YES) {
1336
            // FIXME: mensaje al usaurio.
1337
            I18nManager i18n = ToolsLocator.getI18nManager();
1338
            ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1339
            dialogs.messageDialog(
1340
                    i18n.getTranslation("_The_group_function_is_not_available_for_this_table"),
1341
                    i18n.getTranslation("_Information"),
1342
                    JOptionPane.INFORMATION_MESSAGE
1343
            );
1344
            return;
1345
        }
1346

    
1347
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1348
        I18nManager i18n = ToolsLocator.getI18nManager();
1349
        final FeatureQueryGroupByPanel panelGroupBy = new DefaultFeatureQueryGroupByPanel();
1350
        panelGroupBy.setStore(this.store);
1351
        panelGroupBy.put(this.parameters.getQuery());
1352
        final Dialog dialog = winmanager.createDialog(
1353
                panelGroupBy.asJComponent(),
1354
                i18n.getTranslation("_Select_group_columns_and_aggregate_functions"),
1355
                null,
1356
                WindowManager_v2.BUTTONS_OK_CANCEL
1357
        );
1358
        dialog.addActionListener((ActionEvent e) -> {
1359
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1360
                panelGroupBy.fetch(this.parameters.getQuery());
1361
                search();
1362
            }
1363
        });
1364
        dialog.show(WindowManager.MODE.DIALOG);
1365
    }
1366

    
1367
    private void doSelectResultColumnNames() {
1368
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1369
        I18nManager i18n = ToolsLocator.getI18nManager();
1370
        final FeatureAttributesSelectionPanel panelSelectColumns = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
1371
        panelSelectColumns.allowCalculatedAttributes(false);
1372
        FeatureType ftype = this.getFeatureType();
1373
        try {
1374
            Feature f = store.findFirst(this.parameters.getQuery());
1375
            if (f != null) {
1376
                ftype = f.getType();
1377
            }
1378
        } catch (Throwable ex) {
1379
            LOGGER.warn("Can't retrieve the feature type from the first feature.", ex);
1380
        }
1381
        panelSelectColumns.setFeatureType(ftype);
1382
        panelSelectColumns.setSelectedNames(this.parameters.getResultColumnNames());
1383
        final Dialog dialog = winmanager.createDialog(
1384
                panelSelectColumns.asJComponent(),
1385
                i18n.getTranslation("_Select_the_columns_to_display"),
1386
                null,
1387
                WindowManager_v2.BUTTONS_OK_CANCEL
1388
        );
1389
        dialog.addActionListener((ActionEvent e) -> {
1390
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1391
                this.setResultColumnNames(panelSelectColumns.getSelectedNames());
1392
            }
1393
        });
1394
        dialog.show(WindowManager.MODE.DIALOG);
1395
    }
1396

    
1397
    @Override
1398
    public void put(SearchParameters inParams) {
1399
        this.parameters = (DefaultSearchParameters) inParams;
1400
        for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1401
            try {
1402
                conditionPanel.put(inParams);
1403
            } catch (Exception ex) {
1404
                LOGGER.warn("Can't open panel", ex);
1405
            }
1406
        }
1407
        this.tabSearchMode.setSelectedIndex(inParams.getSearchMode());
1408
//        this.resetTable();
1409

    
1410
    }
1411

    
1412
    private FeatureQuery getQuery() {
1413
        FeatureQuery query;
1414
        try {
1415
            int searchMode = this.tabSearchMode.getSelectedIndex();
1416
            SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1417
            Expression filter = panel.get();
1418
            if (searchMode != PANEL_ADVANCED) {
1419
                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1420
            }
1421
            query = (FeatureQuery) this.parameters.getQuery().clone();
1422
            query.retrievesAllAttributes();
1423
            if (ExpressionUtils.isPhraseEmpty(filter)) {
1424
                return query;
1425
            }
1426
            query.setFilter(filter);
1427
            query.retrievesAllAttributes();
1428
            return query;
1429
        } catch (Exception ex) {
1430
            LOGGER.warn("Can't build query.", ex);
1431
            return null;
1432
        }
1433
    }
1434

    
1435
    @Override
1436
    public SearchParameters fetch(SearchParameters outParams) {
1437
        // Actualiza el fquery del parameters con los paneles
1438
        for (SearchConditionPanel conditionPanel : conditionPanels) {
1439
            try {
1440
                conditionPanel.fetch(this.parameters);
1441
            } catch (Exception ex) {
1442
                LOGGER.warn("Panel not able to fetch values", ex);
1443
            }
1444
        }
1445

    
1446
        // Actualiza el filtro con el panel activo
1447
        int searchMode = this.tabSearchMode.getSelectedIndex();
1448
        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1449
        Expression filter = panel.get();
1450
        if (searchMode != PANEL_ADVANCED) {
1451
            this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1452
        }
1453
        this.parameters.setSearchMode(searchMode);
1454
        FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1455
        this.lastQuery = query.getCopy();
1456
        query.retrievesAllAttributes();
1457
        query.clearFilter();
1458
        if (!ExpressionUtils.isPhraseEmpty(filter)) {
1459
            query.setFilter(filter);
1460
            query.retrievesAllAttributes();
1461
        }
1462

    
1463
        if (outParams == null) {
1464
            return this.parameters.getCopy();
1465
        }
1466
        outParams.copyFrom(this.parameters.getCopy());
1467
        return outParams;
1468
    }
1469

    
1470
    public static void selfRegister() {
1471
        String[][] iconNames = new String[][]{
1472
            new String[]{"dalswing", "featurestore-column"},
1473
            new String[]{"dalswing", "featurestore-foreing-key"},
1474
            new String[]{"dalswing", "featurestore-table"},
1475
            new String[]{"Common", "common-showform"},
1476
            new String[]{"dalswing", "search-action-select"},
1477
            new String[]{"dalswing", "search-action-select-add"},
1478
            new String[]{"dalswing", "search-action-select-filter"},        
1479
            new String[]{"dalswing", "search-nullbehavior-null"},
1480
            new String[]{"dalswing", "search-nullbehavior-true"},
1481
            new String[]{"dalswing", "search-nullbehavior-false2"}
1482
       
1483
        };
1484
        IconTheme theme = ToolsSwingLocator.getIconThemeManager().getCurrent();
1485
        for (String[] icon : iconNames) {
1486
            URL url = DefaultSearchPanel.class.getResource(icon[1] + ".png");
1487
            theme.registerDefault("DALSwing", icon[0], icon[1], null, url);
1488
        }
1489

    
1490
        ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1491
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1492
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1493
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1494
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1495
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1496
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1497
        cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1498
    }
1499
    
1500
    private void doSelectSearchPostprocess() throws DataException {
1501
        DataSwingManager manager = DALSwingLocator.getDataSwingManager();
1502
        Map<String, SearchPostProcessFactory> searchPostProcessFactoryMap = manager.getSearchPostProcess();
1503

    
1504
        JPopupMenu menu = new JPopupMenu();
1505
        for (String factory : searchPostProcessFactoryMap.keySet()) {
1506
            JMenuItem item;
1507
            item = new JMenuItem(factory);
1508
            SearchParameters searchParams = this.fetch(this.parameters.getCopy());
1509
            FeatureQuery myQuery = searchParams.getQuery().getCopy();
1510
//            item.addActionListener(new SearchPostProcessListener(this.store, myQuery, manager.getSearchPostProcess(factory)));
1511
            item.addActionListener((ActionEvent e) -> {
1512
                doSearchPostProcess(store, myQuery, manager.getSearchPostProcess(factory));
1513
            });
1514
            menu.add(item);
1515
        }
1516
        menu.show(this.btnSearchPostProcess, 0, this.btnSearchPostProcess.getHeight());
1517
    }
1518

    
1519
    private void doExecuteSearchPostProcess(
1520
            FeatureStore input,
1521
            FeatureQuery query,
1522
            SearchPostProcessFactory factory,
1523
            DynObject parameters
1524
            ) {
1525
        Thread task = new Thread(() -> {
1526
            try {
1527
                this.processing = true;
1528
                this.updateComponentState();
1529
                SearchPostProcess process = factory.createProcess(factory, input, query, parameters);
1530

    
1531
                if (parameters != null) {
1532
                    process.setParameters(parameters);
1533
                }
1534
                //Ejecutar el execute en thread para no bloquear el software
1535
                SearchPostProcess.SearchPostProcessResult output = process.execute(input, query, parameters);
1536
                this.postProcessStore = output.getStore();
1537
                this.postProcessQuery = output.getQuery();
1538
                this.currentPostProcess = factory.getName();
1539
                SwingUtilities.invokeLater(() -> { // Añade a la cola de eventos un evento a ejecutar de código
1540
                    doLoadSearchPostProccessResults(this.postProcessStore);
1541
                });
1542
            }catch (Exception ex){
1543
                LOGGER.warn("SearchPostProcess not able to be executed.", ex);
1544
                resetPostProcessTable();
1545
                
1546
            } finally {
1547
                this.processing = false;
1548
                this.updateComponentState();
1549
            }
1550
        }, "ExecuteSearchPostProcess");
1551

    
1552
        task.start();
1553

    
1554
    }
1555

    
1556
    private void doLoadSearchPostProccessResults(FeatureStore input) {
1557

    
1558
        final List<Feature> featuresSearchPostProccessResults;
1559
        final FeatureQuery finalQuery;
1560
        finalQuery = null;
1561
        try {
1562
            this.tabResults.setEnabledAt(1, true);
1563
            this.tabResults.setSelectedIndex(1);
1564
            featuresSearchPostProccessResults = input.getFeatures(finalQuery, 20);
1565
            FacadeOfAFeaturePagingHelper facadeSearchPostProccessResults = (FacadeOfAFeaturePagingHelper) featuresSearchPostProccessResults;
1566
            FeatureType ftypeSearchPostProccessResults = facadeSearchPostProccessResults.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1567
            // al modelo le pasamos el ftype de esas features
1568
            resultPostProcessModel = new SimpleFeaturesTableModelImpl(
1569
                    ftypeSearchPostProccessResults,
1570
                    null,
1571
                    featuresSearchPostProccessResults
1572
            );
1573

    
1574
            I18nManager i18n = ToolsLocator.getI18nManager();
1575
            TableModel oldmodel = tblSearchPostProcessResults.getModel();
1576
            tblSearchPostProcessResults.setModel(resultPostProcessModel);
1577
            if (oldmodel instanceof SimpleFeaturesTableModel) {
1578
                ((SimpleFeaturesTableModel) oldmodel).dispose();
1579
            }
1580
            updateNumberElementsMsg(resultPostProcessModel);
1581
//            if (resultPostProcessModel.hasErrors()) {
1582
//                lblMsg.setText("_Errors_occurred_load_search_post_process");
1583
//            } else {
1584
//                lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), resultPostProcessModel.getRowCount()));
1585
//            }
1586
        } catch (Exception ex) {
1587
            resetPostProcessTable();
1588
            LOGGER.warn("SearchPostProcess not able to be executed. Can't get features or create table model", ex);
1589
        }
1590
    }
1591

    
1592
    private void updateComponentState() {
1593
        if (!SwingUtilities.isEventDispatchThread()) {
1594
            SwingUtilities.invokeLater(this::updateComponentState);
1595
            return;
1596
        }
1597
        this.setEnabled(!processing);
1598
    }
1599
    
1600
    private void resetPostProcessTable() {
1601
        if(!SwingUtilities.isEventDispatchThread()) {
1602
            SwingUtilities.invokeLater(this::resetPostProcessTable);
1603
            return;
1604
        }
1605
       
1606
        this.tblSearchPostProcessResults.setModel(new DefaultTableModel());
1607
    }
1608
    
1609
    private void doSearchPostProcess(FeatureStore store, FeatureQuery query, SearchPostProcessFactory factory){
1610
        if (factory.hasProcessParameters()) {
1611
                DynObject parametersPostProcess = factory.createProcessParameters(store);
1612
                JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(parametersPostProcess);
1613
                form.setLayoutMode(JDynForm.USE_SEPARATORS);
1614

    
1615
                I18nManager i18n = ToolsLocator.getI18nManager();
1616
                WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1617

    
1618
                Dialog dialog = windowManager.createDialog(
1619
                        form.asJComponent(),
1620
                        i18n.getTranslation("_Postprocess_parameters"),
1621
                        i18n.getTranslation(
1622
                                "_Parameters_for_XpostprocessNameX_postprocess_on_XtableNameX",
1623
                                new String[] {
1624
                                    factory.getName(),
1625
                                    this.store.getName()
1626
                                }
1627
                        ),
1628
                        WindowManager_v2.BUTTONS_OK_CANCEL);
1629

    
1630
                dialog.addActionListener((ActionEvent e2) -> {
1631
                    if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1632
                        form.getValues(parametersPostProcess); // actualiza el valor de lo los parametros con los valores introducidos por el usuario
1633
                        doExecuteSearchPostProcess(store, query, factory, parametersPostProcess);
1634
                        this.postProcessParams = parametersPostProcess;
1635
                    }
1636
                });
1637

    
1638
                dialog.show(WindowManager.MODE.DIALOG);
1639

    
1640
            } else {
1641
                doExecuteSearchPostProcess(store, query, factory, null);
1642
            }
1643
    }
1644
    
1645
    private void updateNumberElementsMsg( SimpleFeaturesTableModel model){
1646
        I18nManager i18n = ToolsLocator.getI18nManager();
1647
        
1648
        if (model.hasErrors()) {
1649
            lblMsg.setText(i18n.getTranslation("_Errors_occurred_load_search_post_process"));
1650
        } else {
1651
            lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), model.getRowCount()));
1652
        }
1653
    }
1654
    
1655
    @Override
1656
    public boolean isVisible(Object component) {
1657
       if( this.filterOnlyMode ) {
1658
            if( component instanceof GroupByAction ) {
1659
                return false;
1660
            }
1661
            if( component instanceof OrderByAction ) {
1662
                return false;
1663
            }
1664
            if( component instanceof CalculatedColumnsAction ) {
1665
                return false;
1666
            }
1667
        }
1668
        return true;
1669
    }
1670

    
1671
    @Override
1672
    public boolean isEnabled(Object component) {
1673
        if( component instanceof GroupByAction ) {
1674
            DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1675
            int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1676
            if (allowGroupBy != DataType.YES) {
1677
                return false;
1678
            }
1679
        }
1680
        return true;
1681
    }
1682

    
1683
    @Override
1684
    public void setFilterOnlyMode(boolean filterOnlyMode) {
1685
        if( this.conditionPanels!=null ) {
1686
            throw new IllegalStateException("Cannot change filter-only-mode after invoking asJComponent.");
1687
        }
1688
        this.filterOnlyMode = filterOnlyMode;
1689
        this.showActions = false;
1690
    }
1691

    
1692
    @Override
1693
    public boolean isFilterOnlyMode() {
1694
        return this.filterOnlyMode;
1695
    }
1696

    
1697
}
1698