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

History | View | Annotate | Download (86.6 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.FlowLayout;
6
import java.awt.event.ActionEvent;
7
import java.awt.event.ActionListener;
8
import java.awt.event.ComponentAdapter;
9
import java.awt.event.ComponentEvent;
10
import java.awt.event.KeyAdapter;
11
import java.awt.event.KeyEvent;
12
import java.io.ByteArrayOutputStream;
13
import java.io.File;
14
import java.nio.charset.Charset;
15
import java.sql.SQLException;
16
import java.text.DateFormat;
17
import java.text.SimpleDateFormat;
18
import java.util.ArrayList;
19
import java.util.Calendar;
20
import java.util.Collection;
21
import java.util.Collections;
22
import java.util.Date;
23
import java.util.HashMap;
24
import java.util.Iterator;
25
import java.util.List;
26
import java.util.Map;
27
import java.util.Objects;
28
import javax.swing.AbstractAction;
29
import javax.swing.Action;
30
import static javax.swing.Action.ACTION_COMMAND_KEY;
31
import static javax.swing.Action.NAME;
32
import javax.swing.BorderFactory;
33
import javax.swing.ImageIcon;
34
import javax.swing.JButton;
35
import javax.swing.JComponent;
36
import static javax.swing.JFileChooser.FILES_ONLY;
37
import javax.swing.JMenuItem;
38
import javax.swing.JOptionPane;
39
import static javax.swing.JOptionPane.YES_OPTION;
40
import javax.swing.JPopupMenu;
41
import javax.swing.JTable;
42
import javax.swing.ListSelectionModel;
43
import javax.swing.SwingUtilities;
44
import javax.swing.event.ChangeEvent;
45
import javax.swing.event.ListSelectionEvent;
46
import javax.swing.event.ListSelectionListener;
47
import javax.swing.filechooser.FileFilter;
48
import javax.swing.table.DefaultTableModel;
49
import javax.swing.table.TableCellRenderer;
50
import javax.swing.table.TableModel;
51
import org.apache.commons.io.FilenameUtils;
52
import org.apache.commons.lang.mutable.MutableObject;
53
import org.apache.commons.lang3.ArrayUtils;
54
import org.apache.commons.lang3.StringUtils;
55
import org.apache.commons.lang3.mutable.MutableLong;
56
import org.apache.commons.lang3.tuple.ImmutablePair;
57
import org.apache.commons.lang3.tuple.Pair;
58
import org.gvsig.configurableactions.ConfigurableActionsMamager;
59
import org.gvsig.expressionevaluator.Expression;
60
import org.gvsig.expressionevaluator.ExpressionBuilder;
61
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
62
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
63
import org.gvsig.expressionevaluator.ExpressionUtils;
64
import static org.gvsig.filedialogchooser.FileDialogChooser.SAVE_DIALOG;
65
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_BOTH;
66
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_NO;
67
import static org.gvsig.fmap.dal.DataManager.USE_LABELS_YES;
68
import org.gvsig.fmap.dal.DataStore;
69
import org.gvsig.fmap.dal.DataStoreProviderFactory;
70
import org.gvsig.fmap.dal.complements.Search;
71
import org.gvsig.fmap.dal.exception.DataException;
72
import org.gvsig.fmap.dal.feature.Feature;
73
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
74
import org.gvsig.fmap.dal.feature.FeatureQuery;
75
import org.gvsig.fmap.dal.feature.FeatureSelection;
76
import org.gvsig.fmap.dal.feature.FeatureSet;
77
import org.gvsig.fmap.dal.feature.FeatureStore;
78
import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory;
79
import org.gvsig.fmap.dal.feature.FeatureType;
80
import org.gvsig.fmap.dal.feature.paging.FacadeOfAFeaturePagingHelper;
81
import org.gvsig.fmap.dal.swing.AbstractDALActionFactory.AbstractDALActionContext;
82
import org.gvsig.fmap.dal.swing.DALActionFactory;
83
import org.gvsig.fmap.dal.swing.DALSwingLocator;
84
import org.gvsig.fmap.dal.swing.DataSwingManager;
85
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryCalculatedColumnsPanel;
86
import org.gvsig.fmap.dal.swing.featurequery.FeatureQueryOrderPanel;
87
import org.gvsig.fmap.dal.swing.featuretable.SimpleFeaturesTableModel;
88
import org.gvsig.fmap.dal.swing.featuretype.FeatureAttributesSelectionPanel;
89
import org.gvsig.fmap.dal.swing.impl.DefaultDALSwingLibrary;
90
import static org.gvsig.fmap.dal.swing.impl.DefaultDALSwingLibrary.LIBRARY_NAME;
91
import org.gvsig.fmap.dal.swing.impl.featurequery.DefaultFeatureQueryCalculatedColumnsPanel;
92
import org.gvsig.fmap.dal.swing.impl.featuretable.SimpleFeaturesTableModelImpl;
93
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcess;
94
import org.gvsig.fmap.dal.swing.searchPostProcess.SearchPostProcessFactory;
95
import org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel;
96
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel;
97
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel.SearchConditionPanelFactory;
98
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
99
import org.gvsig.tools.ToolsLocator;
100
import org.gvsig.tools.bookmarksandhistory.Bookmark;
101
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
102
import org.gvsig.tools.bookmarksandhistory.History;
103
import org.gvsig.tools.dataTypes.DataType;
104
import org.gvsig.tools.dispose.Disposable;
105
import org.gvsig.tools.dispose.DisposeUtils;
106
import org.gvsig.tools.dynform.DynFormLocator;
107
import org.gvsig.tools.dynform.JDynForm;
108
import org.gvsig.tools.dynobject.DynObject;
109
import org.gvsig.tools.folders.FoldersManager;
110
import org.gvsig.tools.i18n.I18nManager;
111
import org.gvsig.tools.swing.api.ActionListenerSupport;
112
import org.gvsig.tools.swing.api.Component;
113
import org.gvsig.tools.swing.api.SupportIsEnable;
114
import org.gvsig.tools.swing.api.SupportIsVisible;
115
import org.gvsig.tools.swing.api.ToolsSwingLocator;
116
import org.gvsig.tools.swing.api.ToolsSwingManager;
117
import org.gvsig.tools.swing.api.ToolsSwingUtils;
118
import org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue;
119
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_GETVALUE;
120
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETNAME;
121
import static org.gvsig.tools.swing.api.bookmarkshistory.ActionEventWithCurrentValue.ID_SETVALUE;
122
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController;
123
import org.gvsig.tools.swing.api.bookmarkshistory.BookmarksController.BookmarkEvent;
124
import org.gvsig.tools.swing.api.bookmarkshistory.HistoryController;
125
import org.gvsig.tools.swing.api.task.TaskStatusController;
126
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
127
import org.gvsig.tools.swing.api.windowmanager.Dialog;
128
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
129
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
130
import org.gvsig.tools.task.SimpleTaskStatus;
131
import org.gvsig.tools.util.ListBuilder;
132
import org.gvsig.tools.util.PropertiesSupportHelper;
133
import org.gvsig.tools.util.ToolsUtilLocator;
134
import org.slf4j.Logger;
135
import org.slf4j.LoggerFactory;
136

    
137
/**
138
 *
139
 * @author jjdelcerro
140
 */
141
@SuppressWarnings({"UseSpecificCatch"})
142
public class DefaultSearchPanel
143
        extends DefaultSearchPanelView2
144
        implements FeatureStoreSearchPanel, SupportIsEnable, SupportIsVisible {
145

    
146
        private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSearchPanel.class);
147
        
148
        private static final String EXPORT_TO_TSV_TITLE="_Export_to_TSV";
149
        private static final String EXPORT_TO_TSV_LASTPATHID="exporttotsv.lastpath";
150
        private static final String TSV_EXTENSION="tsv";
151

    
152
        private BookmarksController bookmarksController;
153
        private HistoryController historyController;
154
        private FeatureQuery lastQuery;
155
        private Feature lastSelectedFeature;
156
        private final PropertiesSupportHelper propertiesHelper;
157
        private TaskStatusController taskStatusController;
158
        private boolean automaticallySearch;
159
        private String lastErrorMessage;
160
        private boolean initialized;
161
        private boolean postProcessEnabled;
162
        private boolean groupByEnabled;
163
        
164
        private Map<String,AdditionalResultsPanel> additionalResultsPanels;
165
        
166
        private static class AdditionalResultsPanel implements Component {
167
            
168
            private final String name;
169
            private final String title;
170
            private int index;
171
            private final Component component;
172
            
173
            public AdditionalResultsPanel(String name, String title, Component component, int index) {
174
                this.name = name;
175
                this.title = title;
176
                this.component = component;
177
                this.index = index;
178
            }
179
            
180
            public AdditionalResultsPanel(String name, String title, Component component) {
181
                this(name, title, component,-1);
182
            }
183
            
184
            public String getName() {
185
                return this.name;
186
            }
187

    
188
            public String getTitle() {
189
                return title;
190
            }
191
        
192
            public int getIndex() {
193
                return this.index;
194
            }
195

    
196
            @Override
197
            public JComponent asJComponent() {
198
                return this.component.asJComponent();
199
            }
200
            
201
            public void setIndex(int index) {
202
                this.index = index;
203
            }
204
            
205
            public void fireActionEvent(ActionEvent e) {                
206
                if( this.component instanceof ActionListenerSupport ) {
207
                    ((ActionListenerSupport)this.component).fireActionEvent(e);
208
                }
209
            }
210
            
211
            public void doDispose() {
212
                DisposeUtils.dispose(this.component);
213
            }
214
        }
215

    
216
        public static class UseLabelsYesAction extends AbstractAction {
217

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

    
222
                        this.putValue(NAME, i18n.getTranslation("_Use_labels"));
223
                        this.putValue(ACTION_COMMAND_KEY, "UseLabelsYes");
224
                }
225

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

    
236
                @Override
237
                public void actionPerformed(ActionEvent ae) {
238
                    DALSwingLocator.getDataSwingManager().setUseLabels(USE_LABELS_YES);
239
                }
240
        }
241

    
242
        public static class UseLabelsNoAction extends AbstractAction {
243

    
244
                @SuppressWarnings("OverridableMethodCallInConstructor")
245
                public UseLabelsNoAction() {
246
                        I18nManager i18n = ToolsLocator.getI18nManager();
247
                        this.putValue(NAME, i18n.getTranslation("_Use_names"));
248
                        this.putValue(ACTION_COMMAND_KEY, "UseLabelsNo");
249
                }
250

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

    
261
                @Override
262
                public void actionPerformed(ActionEvent ae) {
263
                    DALSwingLocator.getDataSwingManager().setUseLabels(USE_LABELS_NO);
264
                }
265
        }
266

    
267
        public static class UseLabelsBothAction extends AbstractAction {
268

    
269
                @SuppressWarnings("OverridableMethodCallInConstructor")
270
                public UseLabelsBothAction() {
271
                        I18nManager i18n = ToolsLocator.getI18nManager();
272

    
273
                        this.putValue(NAME, i18n.getTranslation("_Use_labels_and_names"));
274
                        this.putValue(ACTION_COMMAND_KEY, "UseLabelsBoth");
275
                }
276

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

    
287
                @Override
288
                public void actionPerformed(ActionEvent ae) {
289
                    DALSwingLocator.getDataSwingManager().setUseLabels(USE_LABELS_BOTH);
290
                }
291
        }
292

    
293
        public static class SelectColumnsAction extends AbstractAction {
294

    
295
                @SuppressWarnings("OverridableMethodCallInConstructor")
296
                public SelectColumnsAction() {
297
                        I18nManager i18n = ToolsLocator.getI18nManager();
298

    
299
                        this.putValue(NAME, i18n.getTranslation("_Select_columns_to_display"));
300
                        this.putValue(ACTION_COMMAND_KEY, "SelectColumns");
301
                }
302

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

    
313
                @Override
314
                public void actionPerformed(ActionEvent ae) {
315
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
316
                        panel.doSelectResultColumnNames();
317
                }
318
        }
319

    
320
        public static class CalculatedColumnsAction extends AbstractAction {
321

    
322
                @SuppressWarnings("OverridableMethodCallInConstructor")
323
                public CalculatedColumnsAction() {
324
                        I18nManager i18n = ToolsLocator.getI18nManager();
325

    
326
                        this.putValue(NAME, i18n.getTranslation("_Calculated_columns"));
327
                        this.putValue(ACTION_COMMAND_KEY, "CalculatedColumns");
328
                }
329

    
330
                @Override
331
                public Object getValue(String key) {
332
                        if (NAME.equals(key)) {
333
                                // Cuando se registra la accion aun no se han cargado las traducciones
334
                                I18nManager i18n = ToolsLocator.getI18nManager();
335
                                return i18n.getTranslation("_Calculated_columns");
336
                        }
337
                        return super.getValue(key);
338
                }
339

    
340
                @Override
341
                public void actionPerformed(ActionEvent ae) {
342
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
343
                        panel.doCalculatedColumns();
344
                }
345
        }
346

    
347
        public static class GroupByAction extends AbstractAction {
348

    
349
                @SuppressWarnings("OverridableMethodCallInConstructor")
350
                public GroupByAction() {
351
                        I18nManager i18n = ToolsLocator.getI18nManager();
352

    
353
                        this.putValue(NAME, i18n.getTranslation("_Group_by"));
354
                        this.putValue(ACTION_COMMAND_KEY, "GroupBy");
355
                }
356

    
357
                @Override
358
                public Object getValue(String key) {
359
                        if (NAME.equals(key)) {
360
                                // Cuando se registra la accion aun no se han cargado las traducciones
361
                                I18nManager i18n = ToolsLocator.getI18nManager();
362
                                return i18n.getTranslation("_Group_by");
363
                        }
364
                        return super.getValue(key);
365
                }
366

    
367
                @Override
368
                public void actionPerformed(ActionEvent ae) {
369
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
370
                        panel.doGroupBy();
371
                }
372
        }
373

    
374
        public static class OrderByAction extends AbstractAction {
375

    
376
                @SuppressWarnings("OverridableMethodCallInConstructor")
377
                public OrderByAction() {
378
                        I18nManager i18n = ToolsLocator.getI18nManager();
379

    
380
                        this.putValue(NAME, i18n.getTranslation("_Order_by"));
381
                        this.putValue(ACTION_COMMAND_KEY, "SelectOrderBy");
382
                }
383

    
384
                @Override
385
                public Object getValue(String key) {
386
                        if (NAME.equals(key)) {
387
                                // Cuando se registra la accion aun no se han cargado las traducciones
388
                                I18nManager i18n = ToolsLocator.getI18nManager();
389
                                return i18n.getTranslation("_Order_by");
390
                        }
391
                        return super.getValue(key);
392
                }
393

    
394
                @Override
395
                public void actionPerformed(ActionEvent ae) {
396
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
397
                        panel.doOrderBy();
398
                }
399
        }
400

    
401
        public static class PropertiesAction extends AbstractAction {
402

    
403
                @SuppressWarnings("OverridableMethodCallInConstructor")
404
                public PropertiesAction() {
405
                        I18nManager i18n = ToolsLocator.getI18nManager();
406

    
407
                        this.putValue(NAME, i18n.getTranslation("_Properties"));
408
                        this.putValue(ACTION_COMMAND_KEY, "Properties");
409
                }
410

    
411
                @Override
412
                public Object getValue(String key) {
413
                        if (NAME.equals(key)) {
414
                                // Cuando se registra la accion aun no se han cargado las traducciones
415
                                I18nManager i18n = ToolsLocator.getI18nManager();
416
                                return i18n.getTranslation("_Properties");
417
                        }
418
                        return super.getValue(key);
419
                }
420

    
421
                @Override
422
                public void actionPerformed(ActionEvent ae) {
423
                        DefaultSearchPanel panel = (DefaultSearchPanel) ae.getSource();
424
                        panel.doShowProperties();
425
                }
426
        }
427

    
428
        private class TablePopupMenu extends JPopupMenu {
429

    
430
                public final JTable table;
431

    
432
                @SuppressWarnings("OverridableMethodCallInConstructor")
433
                public TablePopupMenu(JTable inputTable) {
434
                        this.table = inputTable;
435
                        I18nManager i18n = ToolsLocator.getI18nManager();
436
                        JMenuItem copyRowsActionMenu = new JMenuItem(i18n.getTranslation("_Copy_rows"));
437
                        copyRowsActionMenu.addActionListener((ActionEvent e) -> {
438
                                doCopyRows(table);
439
                        });
440
                        this.add(copyRowsActionMenu);
441
                        JMenuItem exportTSVActionMenu = new JMenuItem(i18n.getTranslation(EXPORT_TO_TSV_TITLE));
442
                        exportTSVActionMenu.addActionListener((ActionEvent e) -> {
443
                                doExportTSV(table);
444
                        });
445
                        this.add(exportTSVActionMenu);
446
                }
447
        }
448

    
449
        private class ActionButtons {
450

    
451
                private final DALActionFactory factory;
452
                private final Action action;
453
                private final JButton button;
454

    
455
                public ActionButtons(DALActionFactory factory, Action action, JButton button) {
456
                        this.factory = factory;
457
                        this.action = action;
458
                        this.button = button;
459
                }
460
        }
461

    
462
        public static class SearchActionContext extends AbstractDALActionContext {
463

    
464
                private final DefaultSearchPanel panel;
465

    
466
                public SearchActionContext(DefaultSearchPanel panel) {
467
                        super(FeatureStoreSearchPanel.ACTION_CONTEXT_NAME);
468
                        this.panel = panel;
469
                }
470

    
471
                @Override
472
                public DataStore getStore() {
473
                        if (this.panel.currentPostProcess != null && this.panel.tabResults.getSelectedIndex() == 1) {
474
                                return this.panel.postProcessStore;
475
                        } else {
476
                                return this.panel.getStore();
477
                        }
478
                }
479

    
480
                @Override
481
                public JComponent getActionButton(String actionName) {
482
                        return this.panel.getActionButton(actionName);
483
                }
484

    
485
                @Override
486
                public int getSelectedsCount() {
487
                        return this.panel.getSelectedFeatureCount();
488
                }
489

    
490
                @Override
491
                public Expression getFilterForSelecteds() {
492
                        return this.panel.getFilterForSelectedFeatures();
493
                }
494

    
495
                @Override
496
                public FeatureSelection getSelecteds() {
497
                        return this.panel.getSelectedFeatures();
498
                }
499

    
500
                @Override
501
                public FeatureQuery getQuery() {
502
                        if (this.panel.currentPostProcess != null && this.panel.tabResults.getSelectedIndex() == 1) {
503
                            return this.panel.postProcessQuery;
504
                        } else {
505
                            SearchParameters searchParams = this.panel.parameters;                            
506
                            FeatureQuery query = searchParams.getQueryToApply();
507
                            if( panel.useSelection() ) {
508
                                query = panel.addSelection(panel.store, query);
509
                            }
510
                            return query;
511
                        }
512
                }
513
        }
514

    
515
        private FeatureStore store;
516
        private final ActionListenerSupport acctionListeners;
517
        private final Map<String, ActionButtons> actions;
518
        private boolean showActions = true;
519
        private DefaultSearchParameters parameters;
520

    
521
        private List<SearchConditionPanel> conditionPanels;
522

    
523
        public static final int PANEL_SIMPLIFIED = 0;
524
        public static final int PANEL_ADVANCED = 1;
525
        private static final String BOOKMARKSANDHISTORY_NAME = "SearchPanel";
526
        private final Bookmarks<Object> bookmarks;
527
        private final History<Object> history;
528
        private boolean filterOnlyMode;
529

    
530
        private String currentPostProcess;
531

    
532
        private DynObject postProcessParams;
533
        private FeatureStore postProcessStore;
534
        private FeatureQuery postProcessQuery;
535
        private SimpleFeaturesTableModel resultModel;
536
        private SimpleFeaturesTableModel resultPostProcessModel;
537

    
538
        private boolean processing;
539
        private JComponent configurableActions;
540

    
541
        @SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"})
542
        public DefaultSearchPanel(FeatureStore store) {
543
                this.store = store;
544
                this.filterOnlyMode = false;
545
                DisposeUtils.bind(store);
546
                this.acctionListeners = ToolsSwingLocator.getToolsSwingManager().createActionListenerSupport();
547
                this.actions = new HashMap<>();
548
                this.parameters = new DefaultSearchParameters();
549
                this.additionalResultsPanels = new HashMap<>();
550
                FeatureQuery featureQuery = this.store.createFeatureQuery();
551
                featureQuery.retrievesAllAttributes();
552
                this.parameters.setQuery(featureQuery);
553
                this.currentPostProcess = null;
554
                this.postProcessParams = null;
555
                this.postProcessStore = null;
556
                this.postProcessQuery = null;
557
                this.processing = false;
558
                this.configurableActions = null;
559
                this.resultModel = null;
560
                this.resultPostProcessModel = null;
561
                this.propertiesHelper = new PropertiesSupportHelper();
562
                this.propertiesHelper.setProperty("SearchPanel", this);
563
                this.automaticallySearch = true;
564
                this.postProcessEnabled = true;
565
                this.groupByEnabled = true;
566

    
567
                Search search = (Search) ToolsLocator.getComplementsManager().get(
568
                        Search.COMPLEMENT_MANE, getFeatureType()
569
                );
570
                List<Search.OrderedAttribute> attributos = search.getOrderedAttributes(
571
                        Search.BASIC_TYPES_FILTER,
572
                        Search.STR_INT_LONG_LABEL_ORDER,
573
                        12
574
                );
575
                for (Search.OrderedAttribute attrdesc : attributos) {
576
                        this.parameters.getResultColumnNames().add(attrdesc.getDescriptor().getName());
577
                }
578
                this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
579
                this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
580
                this.initComponents0();
581
                this.initialized = false;
582
        }
583

    
584
        @Override
585
        public void dispose() {
586
                DisposeUtils.disposeQuietly(store);
587
                TableModel m = this.tblResults.getModel();
588
                if (m instanceof Disposable) {
589
                        DisposeUtils.disposeQuietly((Disposable) m);
590
                }
591
                this.store = null;
592
                this.tblResults.setModel(new DefaultTableModel());
593
                for (AdditionalResultsPanel additionalResultsPanel : this.additionalResultsPanels.values()) {
594
                    additionalResultsPanel.doDispose();
595
                }                
596
        }
597

    
598
        @Override
599
        public JComponent asJComponent() {
600
                if (!this.initialized) { //this.conditionPanels == null) {
601
                        this.initComponents1();
602
                }
603
                return this;
604
        }
605

    
606
        private void addActions() {
607
                if (!this.showActions) {
608
                        return;
609
                }
610
                this.pnlActions.removeAll();
611
                this.pnlActions.setLayout(new FlowLayout(FlowLayout.TRAILING, 8, 4));
612
                SearchActionContext actionContext = new SearchActionContext(this);
613
                actionContext.set("searchpanel", this);
614
                Collection<DALActionFactory> factories = DALSwingLocator.getSwingManager().getApplicableStoreActions(actionContext);
615
                for (DALActionFactory factory : factories) {
616
                    Action action = factory.createAction(actionContext);
617
                    JButton button = new JButton(action);
618
                    this.actions.put(factory.getName(), new ActionButtons(factory, action, button));
619
                    button.setBorder(BorderFactory.createEmptyBorder());
620
                    button.setBorderPainted(false);
621
                    button.setFocusPainted(false);
622
                    button.setContentAreaFilled(false);
623
                    button.setCursor(new Cursor(Cursor.HAND_CURSOR));
624
                    this.pnlActions.add(button);
625
                }
626
                this.pnlActions.revalidate();
627
                this.pnlActions.repaint();
628
        }
629

    
630
        @Override
631
        public void addActionListener(ActionListener listener) {
632
                this.acctionListeners.addActionListener(listener);
633
        }
634

    
635
        @Override
636
        public ActionListener[] getActionListeners() {
637
                return this.acctionListeners.getActionListeners();
638
        }
639

    
640
        @Override
641
        public void removeActionListener(ActionListener listener) {
642
                this.acctionListeners.removeActionListener(listener);
643
        }
644

    
645
        @Override
646
        public void removeAllActionListener() {
647
                this.acctionListeners.removeAllActionListener();
648
        }
649

    
650
        @Override
651
        public void fireActionEvent(ActionEvent event) {
652
                this.acctionListeners.fireActionEvent(event);
653
        }
654

    
655
        @Override
656
        public boolean hasActionListeners() {
657
                return this.acctionListeners.hasActionListeners();
658
        }
659

    
660
        private void initComponents0() {
661
                this.conditionPanels = new ArrayList<>();
662
                this.taskStatusController = ToolsSwingLocator.getTaskStatusSwingManager().createTaskStatusController(
663
                        this.lblStatusTitle,
664
                        this.lblMsg,
665
                        this.pgbStatus);
666
        }
667

    
668
        private void initComponents1() {
669

    
670
                ToolsSwingManager swingManager = ToolsSwingLocator.getToolsSwingManager();
671
                swingManager.translate(this.tabSearchMode);
672
                swingManager.translate(this.tabResults);
673
                swingManager.translate(this.btnSearch);
674
                swingManager.translate(this.btnClear);
675
                swingManager.translate(this.btnSearchPostProcess);
676
                swingManager.translate(this.lblExpressionDeBusqueda);
677
                swingManager.translate(this.btnAddAccumulatedFilter);
678
                swingManager.translate(this.btnRemoveAccumulatedFilter);
679
                swingManager.translate(this.btnViewAccumulatedFilter);
680
                swingManager.translate(this.chkUseSelection);
681

    
682
                ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
683
                this.configurableActions = cfgActionsManager.getConfigurableActionsComponent(CONFIGURABLE_PANEL_ID, this);
684
                this.pnlCfgActions.setLayout(new BorderLayout(0, 0));
685
                this.pnlCfgActions.add(configurableActions, BorderLayout.CENTER);
686

    
687
                this.pgbStatus.setVisible(false);
688

    
689
                this.conditionPanels.add(
690
                        new SearchConditionPanelSimplified(
691
                                parameters,
692
                                store,
693
                                this.pnlConditionField,
694
                                btnAddAccumulatedFilter,
695
                                btnRemoveAccumulatedFilter,
696
                                btnViewAccumulatedFilter
697
                        )
698
                );
699

    
700
                SearchConditionPanelAdvanced advancedPanel = new SearchConditionPanelAdvanced(
701
                        this.store,
702
                        txtAdvancedExpression,
703
                        btnAdvancedExpression,
704
                        btnAdvancedExpressionHistory,
705
                        btnAdvancedExpressionBookmarks
706
                );
707
                this.conditionPanels.add(advancedPanel);
708

    
709
                for (SearchConditionPanelFactory factory : DALSwingLocator.getManager().getSearchConditionPanels()) {
710
                        String factoryName = "unknown";
711
                        try {
712
                                factoryName = factory.getName();
713
                                if (factory.isApplicable(store)) {
714
                                        SearchConditionPanel panel = factory.create(this);
715
                                        this.conditionPanels.add(panel);
716
                                        this.tabSearchMode.add(factory.getName(), panel.asJComponent());
717
                                }
718
                        } catch (Throwable th) {
719
                                LOGGER.warn("Can't create search panel '" + factoryName + "'.", th);
720
                        }
721
                }
722

    
723
                this.btnSearch.addActionListener((ActionEvent e) -> {
724
                        this.tabResults.setEnabledAt(1, false);
725
                        search();
726
                });
727

    
728
                this.tblResults.getSelectionModel().addListSelectionListener((ListSelectionEvent e) -> {
729
                        try {
730
                                lastSelectedFeature = resultModel.getFeatureAt(tblResults.getSelectedRow());
731
                        } catch (Throwable th) {
732
                                LOGGER.debug("Can't retrieve last selected feature.", th);
733
                        }
734
                        for (ActionButtons actionButton : actions.values()) {
735
                                if (actionButton.action instanceof ListSelectionListener) {
736
                                        ((ListSelectionListener) actionButton.action).valueChanged(e);
737
                                }
738
                        }
739
                });
740
                this.btnClear.addActionListener((ActionEvent e) -> {
741
                        clear();
742
                });
743
                addActions();
744

    
745
                //swingManager.createTableColumnAdjuster(tblResults);
746
                //swingManager.createTableColumnAdjuster(tblSearchPostProcessResults);
747
//        this.setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
748
                ToolsSwingUtils.ensureRowsCols(this, 20, 100, 30, 120);
749

    
750
                this.bookmarksController = ToolsSwingLocator.getToolsSwingManager().createBookmarksController(this.bookmarks, btnBookmarks);
751
                this.historyController = ToolsSwingLocator.getToolsSwingManager().createHistoryController(this.history, btnHistory);
752

    
753
                this.historyController.setFilter(null);
754

    
755
                this.historyController.addActionListener((ActionEvent e) -> {
756
                        ActionEventWithCurrentValue<DefaultSearchParameters> b = (ActionEventWithCurrentValue<DefaultSearchParameters>) e;
757
                        switch (b.getID()) {
758
                                case ID_GETVALUE:
759
                                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
760
                                        b.setCurrentValue(actualParams);
761
                                        break;
762

    
763
                                case ID_SETVALUE:
764
                                        if (b.getCurrentValue() == null) {
765
                                                return;
766
                                        }
767
                                        putParametersAndSearch(b.getCurrentValue());
768
                                        break;
769
                        }
770
                });
771
                this.bookmarksController.addActionListener((ActionEvent e) -> {
772
                        BookmarkEvent<DefaultSearchParameters> b = (BookmarkEvent<DefaultSearchParameters>) e;
773
                        switch (b.getID()) {
774
                                case ID_GETVALUE:
775
                                    LOGGER.info("Save bookmark");
776
                                        DefaultSearchParameters actualParams = (DefaultSearchParameters) fetch(null);
777
                                        b.setCurrentValue(actualParams);
778
                                        break;
779

    
780
                                case ID_SETVALUE:
781
                                    LOGGER.info("Restore bookmark");
782
                                        if (b.getCurrentValue() == null) {
783
                                                return;
784
                                        }
785
                                        b.getBookmark().used();
786
                                        b.getCurrentValue().setName(b.getBookmark().getName());
787
                                        putParametersAndSearch(b.getCurrentValue());
788
                                        break;
789
                                case ID_SETNAME:
790
                                    LOGGER.info("Rename bookmark");
791
                                        if (b.getCurrentValue() == null) {
792
                                                return;
793
                                        }
794
                                        b.getCurrentValue().setName(b.getBookmark().getName());
795
                                        break;
796
                        }
797
                });
798
                this.addComponentListener(new ComponentAdapter() {
799
                        @Override
800
                        public void componentHidden(ComponentEvent e) {
801
                                dispose();
802
                        }
803
                });
804

    
805
                this.btnSearchPostProcess.addActionListener((ActionEvent e) -> {
806
                        try {
807
                                doSelectSearchPostprocess();
808
                        } catch (DataException ex) {
809
                                LOGGER.warn("Can't select a Search Post Process", ex);
810
                        }
811
                });
812

    
813
                this.tabResults.setEnabledAt(1, false);
814
                this.tblResults.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
815
                this.tblResults.addKeyListener(new KeyAdapter() {
816
                        @Override
817
                        public void keyPressed(KeyEvent e) {
818
                                if (e.getKeyCode() == KeyEvent.VK_F4) {
819
                                        doShowCellInDialog();
820
                                }
821
                        }
822
                });
823
                this.tblResults.setComponentPopupMenu(new TablePopupMenu(this.tblResults));
824
                this.tabResults.addChangeListener((ChangeEvent evt) -> {
825
                        SwingUtilities.invokeLater(() -> {
826
                                switch(tabResults.getSelectedIndex()) {
827
                                    case 1:
828
                                        updateNumberElementsMsg(resultPostProcessModel);
829
                                        break;
830
                                    case 0:
831
                                    default:
832
                                        updateNumberElementsMsg(resultModel);
833
                                }
834
                        });
835
                });
836
                this.tblResults.getTableHeader().setReorderingAllowed(false);
837
                
838
                this.tblSearchPostProcessResults.setComponentPopupMenu(new TablePopupMenu(this.tblSearchPostProcessResults));
839
                this.tblSearchPostProcessResults.getTableHeader().setReorderingAllowed(false);
840

    
841
                if (this.filterOnlyMode || !this.postProcessEnabled) {
842
                        this.btnSearchPostProcess.setVisible(false);
843
                }
844
                
845
                for (SearchResultsPanelFactory factory : DALSwingLocator.getManager().getSearchResultsPanels()) {
846
                        String factoryName = "unknown";
847
                        try {
848
                            factoryName = factory.getName();
849
                            this.addResultPanel(
850
                                    factory.getName(),
851
                                    factory.getTitle(),
852
                                    factory.create(this)
853
                                );
854
                        } catch (Throwable th) {
855
                                LOGGER.warn("Can't create results panel '" + factoryName + "'.",th);
856
                        }
857
                }
858
                for (AdditionalResultsPanel panel : this.additionalResultsPanels.values()) {
859
                    panel.setIndex(this.tabResults.getTabCount());
860
                    this.tabResults.addTab(panel.getTitle(), panel.asJComponent());
861
                }
862

    
863
                this.initialized = true;
864
                
865
                if (this.automaticallySearch){
866
                    if (this.bookmarks.hasBookmark(this.store.getName())) {
867
                            Bookmark<DefaultSearchParameters> initBookmark = this.bookmarks.get(this.store.getName());
868
                            initBookmark.used();
869
                            putParametersAndSearch(initBookmark.getValue());
870
                    } else {
871
                        clear();
872
                        search();
873
                    }
874
                } else {
875
                    clear();
876
                    
877
                }
878
        }
879
        
880
    private void putParametersAndSearch(DefaultSearchParameters searchParams) {
881
        DefaultSearchParameters params;
882
        try {
883
            params = searchParams.getCopy();
884
            FeatureType featType = this.getFeatureType();
885
            StringBuilder errMessage = new StringBuilder();
886
            boolean onlyEssentials = false;
887
            boolean isValid = params.isValid(featType, errMessage);
888
            if(!isValid){
889
                ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
890
                I18nManager i18n = ToolsLocator.getI18nManager();
891
                int n = dialogs.confirmDialog(
892
                        i18n.getTranslation("_The_validation_of_the_search_parameters_has_returned_the_following_errors")+":\n\n"+errMessage.toString()+"\n"+i18n.getTranslation("_You_want_the_application_to_try_to_resolve_them_before_launching_the_query"),
893
                        i18n.getTranslation("_Validation_of_search_parameters"),
894
                        JOptionPane.YES_NO_OPTION,
895
                        JOptionPane.WARNING_MESSAGE,
896
                        "_Fix_search_parameters"
897
                );
898
                if( n != JOptionPane.YES_OPTION ) {
899
                    onlyEssentials = true;
900
                } else {
901
                    LOGGER.info("It has been decided do not resolve errors in parameters of search");
902
                }
903
                
904
            }
905
            params.fix(featType, onlyEssentials);
906
        } catch (Exception ex) {
907
            LOGGER.warn("Not been able to clone export parameters", ex);
908
            return;
909
        }
910
        clear();
911
        put(params);
912
        Thread th = new Thread(() -> {
913
            doSearch(params);
914
        });
915
        th.start();
916

    
917
    }
918

    
919
        private void doShowCellInDialog() {
920
                int row = this.tblResults.getSelectedRow();
921
                if (row < 0) {
922
                        return;
923
                }
924
                int col = this.tblResults.getSelectedColumn();
925
                if (col < 0) {
926
                        return;
927
                }
928
                String s = Objects.toString(this.tblResults.getValueAt(row, col), null);
929
                if (StringUtils.isBlank(s)) {
930
                        return;
931
                }
932
                ToolsSwingLocator.getToolsSwingManager().showZoomDialog(
933
                        this,
934
                        this.tblResults.getColumnName(col),
935
                        s,
936
                        false
937
                );
938
        }
939

    
940
        @Override
941
        public FeatureType getFeatureType() {
942
                try {
943
                        return store.getDefaultFeatureType();
944
                } catch (Exception ex) {
945
                        throw new RuntimeException("Can't retrieve the feature type.", ex);
946
                }
947
        }
948

    
949
        @Override
950
        public void setEnabled(boolean enabled) {
951
                if (!SwingUtilities.isEventDispatchThread()) {
952
                        SwingUtilities.invokeLater(() -> {
953
                                setEnabled(enabled);
954
                        });
955
                        return;
956
                }
957

    
958
                if (!this.initialized) { //this.conditionPanels == null) {
959
                        this.initComponents1();
960
                }
961
                for (SearchConditionPanel conditionPanel : conditionPanels) {
962
                        conditionPanel.setEnabled(enabled);
963
                }
964

    
965
                this.btnClear.setEnabled(enabled);
966
                this.btnSearch.setEnabled(enabled);
967
                for (ActionButtons actionButton : actions.values()) {
968
                        actionButton.action.setEnabled(enabled);
969
                }
970
                this.btnSearchPostProcess.setEnabled(enabled);
971
                //bookmarkController,historyController,configurableActions
972
        }
973

    
974
        @Override
975
        public void clear() {
976
                this.taskStatusController.setTitle("");
977
                if (!this.initialized) { //this.conditionPanels == null) {
978
                        return;
979
                }
980
                for (SearchConditionPanel conditionPanel : conditionPanels) {
981
                        conditionPanel.clear();
982
                }
983
                FeatureQuery emptyQuery = this.store.createFeatureQuery();
984
                emptyQuery.retrievesAllAttributes();
985
                this.parameters.setQuery(emptyQuery);
986
                // Mantener las columnas visualizadas
987
                // Elimina las que no existen en el store como campos calculados que
988
                // pudieran existir en el fquery
989
                List<String> resultColumnNames = this.parameters.getResultColumnNames();
990
                ArrayList<String> toDeleteAlreadyDontExist = new ArrayList<>();
991
                for (String resultColumnName : resultColumnNames) {
992
                        try {
993
                                FeatureAttributeDescriptor attr = this.store.getDefaultFeatureType().getAttributeDescriptor(resultColumnName);
994
                                if (attr == null) {
995
                                        toDeleteAlreadyDontExist.add(resultColumnName);
996
                                }
997
                        } catch (DataException ex) {
998

    
999
                        }
1000
                }
1001
                resultColumnNames.removeAll(toDeleteAlreadyDontExist);
1002
                resetTable();
1003
        }
1004

    
1005
        @Override
1006
        public FeatureQuery getLastQuery() {
1007
                return this.lastQuery;
1008
        }
1009

    
1010
        public boolean isValid(StringBuilder message) {
1011
                int searchMode = this.tabSearchMode.getSelectedIndex();
1012
                SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1013
                boolean valid = panel.isValid(message);
1014
                return valid;
1015
        }
1016

    
1017
        public String getWarnings() {
1018
                int searchMode = this.tabSearchMode.getSelectedIndex();
1019
                SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1020
                String s = panel.getWarnings();
1021
                if( StringUtils.isBlank(s) ) {
1022
                    return null;
1023
                }
1024
                return s;
1025
        }
1026
        
1027
        @Override
1028
        public int search() {
1029
                StringBuilder message = new StringBuilder();
1030
                if (!this.isValid(message)) {
1031
                        ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1032
                        dialogManager.messageDialog(
1033
                                "_The_specified_search_condition_is_not_valid",
1034
                                "_Search",
1035
                                JOptionPane.WARNING_MESSAGE
1036
                        );
1037
                        return STATUS_NOT_VALID;
1038
                }
1039
                String warnings = this.getWarnings();
1040
                if( StringUtils.isNotBlank(warnings) ) {
1041
                        ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1042
                        int n = dialogManager.confirmDialog(
1043
                                "The indicated search can cause problems." + 
1044
                                        "\n" + warnings + "\n" +
1045
                                        "Do you want to run it anyway?",
1046
                                "_Search",
1047
                                JOptionPane.YES_NO_OPTION,
1048
                                JOptionPane.WARNING_MESSAGE
1049
                        );
1050
                        if( n == JOptionPane.NO_OPTION ) {
1051
                            return STATUS_OK;
1052
                        }
1053
                }
1054
                lblMsg.setText(ToolsLocator.getI18nManager().getTranslation("_Searching") + "...");
1055
                setEnabled(false);
1056
                Thread th = new Thread(() -> {
1057
                        try {
1058
                                SearchParameters searchParams;
1059
                                try {
1060
                                        searchParams = this.fetch(this.parameters.getCopy()); // esto lo actualiza a la ultima // decidir si se devuelve clonado
1061

    
1062
                                        Date date = Calendar.getInstance().getTime();
1063
                                        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
1064
                                        String strDate = dateFormat.format(date);
1065
                                        searchParams.setName("Params: " + strDate);
1066
                                } catch (Exception ex) {
1067
                                        LOGGER.warn("Not able to create search parameters.", ex);
1068
                                        this.taskStatusController.setTitle(ToolsLocator.getI18nManager().getTranslation("_Errors_fetching_new_query") + "...");
1069
                                        resetTable();
1070
                                        return;
1071
                                }
1072
                                doSearch(searchParams);
1073
                        } catch (Exception ex) {
1074
                                LOGGER.warn("Search panel has errors during the search", ex);
1075
                                resetTable();
1076
                        } finally {
1077
                                SwingUtilities.invokeLater(() -> {
1078
                                        setEnabled(true);
1079
                                });
1080
                        }
1081
                });
1082
                th.start();
1083
                return STATUS_OK;
1084
        }
1085

    
1086
        @Override
1087
        public int search(SearchParameters searchParams) {
1088
            ((DefaultSearchParameters)searchParams).fix(this.getFeatureType());
1089
            return doSearch(searchParams);
1090
        }
1091
        
1092
        private synchronized int doSearch(SearchParameters searchParams) {
1093
                final MutableObject model = new MutableObject(null);
1094
                final MutableLong rowCount = new MutableLong();
1095
                Cursor savedCursor = this.getCursor();
1096
                SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1097
                status.setAutoremove(true);
1098
                status.add();
1099
                this.taskStatusController.bind(status);
1100
                List<Feature> features = null;
1101
                try {
1102
                    LOGGER.info("Do search");
1103
                        status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Processing_search"));
1104
                        SwingUtilities.invokeLater(() -> {
1105
                            if(this.initialized){
1106
                                this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1107
                            }
1108
                        });
1109
                        List<String> resultColumnNames = searchParams.getResultColumnNames();
1110
                        FeatureQuery myQuery = searchParams.getQueryToApply();
1111
                        if( this.useSelection() ) {
1112
                            myQuery = this.addSelection(this.store, myQuery);
1113
                        }
1114
                        features = store.getFeatures(myQuery, 50);
1115
                        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
1116
                        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1117
                        // al modelo le pasamos el ftype de esas features
1118
                        SimpleFeaturesTableModel tableModel = new SimpleFeaturesTableModelImpl(
1119
                                ftype,
1120
                                resultColumnNames,
1121
                                features
1122
                        );
1123
                        model.setValue(tableModel);
1124
                        rowCount.setValue(features.size());
1125
                        if(rowCount.longValue() > 0){
1126
                            //Force to get first row in this thread
1127
                            Feature f = features.get(0);
1128
                        }
1129
                        resultModel = (SimpleFeaturesTableModel) model.getValue();
1130
                        SwingUtilities.invokeLater(() -> {
1131
                            if(this.initialized){
1132
                                I18nManager i18n = ToolsLocator.getI18nManager();
1133
                                try {
1134
                                        if( this.tabResults.getSelectedIndex()==1 ) {
1135
                                            this.tabResults.setSelectedIndex(0);
1136
                                        }
1137
                                        TableModel oldmodel = tblResults.getModel();
1138
                                        tblResults.setModel(resultModel);
1139
                                        resultModel.setCellRenderers(tblResults, getCustomRenderers(searchParams));
1140
                                        if (oldmodel instanceof SimpleFeaturesTableModelImpl) {
1141
                                                ((SimpleFeaturesTableModelImpl) oldmodel).dispose();
1142
                                        }
1143
                                        if (resultModel.hasErrors()) {
1144
                                                status.setTitle(i18n.getTranslation("_Errors_occurred_during_search"));
1145
                                        } else {
1146
                                                status.setTitle(String.format("%d " + i18n.getTranslation("_elements"), rowCount.getValue()));
1147
                                        }
1148
                                        if (this.parameters != null && this.parameters.getQuery() != null) {
1149
                                                this.history.add(searchParams);
1150
                                        }
1151
                                        this.fireSearchEvent();
1152
                                } catch (Exception ex) {
1153
                                        LOGGER.warn(" Errors occurred during search getting old model", ex);
1154
                                        status.setTitle(i18n.getTranslation("_Errors_occurred_during_search"));
1155
                                } finally {
1156
                                        setEnabled(true);
1157
                                        status.terminate();
1158
                                        this.setCursor(savedCursor);
1159
                                }
1160
                            }
1161
                        });
1162
                        
1163
                } catch (Exception ex) {
1164
                        LOGGER.warn("Search not able to be executed. Can't get features or create table model", ex);
1165
                        status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Errors_getting_new_feature_set") + "...");
1166
                        status.abort();
1167
                        DisposeUtils.disposeQuietly(features);
1168
                        this.lastErrorMessage = this.getLastErrorMessage(ex);
1169
                        if(StringUtils.isNotBlank(this.lastErrorMessage)){
1170
                            status.setTitle(this.lastErrorMessage);
1171
                        }
1172
                        resetTable();
1173
                        return STATUS_ERROR1;
1174
                }
1175
                return STATUS_OK;
1176
        }
1177

    
1178
        @Override
1179
        public SimpleFeaturesTableModel getResultsTableModel() {
1180
            return this.resultModel;
1181
        }
1182
        
1183
        private Map<String, TableCellRenderer> getCustomRenderers(SearchParameters parameters) {
1184
                FeatureType ft = this.store.getDefaultFeatureTypeQuietly();
1185
                HashMap<String, TableCellRenderer> renderers = new HashMap<>();
1186
                for (FeatureAttributeDescriptor attr : ft) {
1187
                        if (attr.getDataType().isNumeric()) {
1188
//                renderers.put(attr.getName(), new ColorRangeRenderer(attr, 20, 50));
1189
                        }
1190
                }
1191
                return renderers;
1192
        }
1193

    
1194
        private void resetTable() {
1195
                if (!SwingUtilities.isEventDispatchThread()) {
1196
                        SwingUtilities.invokeLater(() -> {
1197
                            if(this.initialized){
1198
                                resetTable();
1199
                            }
1200
                        });
1201
                        return;
1202
                }
1203
                List<String> resultColumnNames = null;
1204
                try {
1205
                        resultColumnNames = this.parameters.getResultColumnNames();
1206
                } catch (Exception ex) {
1207

    
1208
                }
1209
                FeatureType ftype = this.store.getDefaultFeatureTypeQuietly();
1210
                SimpleFeaturesTableModelImpl emptyTableModel = new SimpleFeaturesTableModelImpl(
1211
                        ftype,
1212
                        resultColumnNames,
1213
                        null
1214
                );
1215
                this.tblResults.setModel(emptyTableModel);
1216

    
1217
        }
1218

    
1219
        public void setResultColumnNames(List<String> names) {
1220
                this.parameters.getResultColumnNames().clear();
1221
                this.parameters.getResultColumnNames().addAll(names);
1222
//        if (this.conditionPanels == null) {
1223
//            return;
1224
//        }
1225
//        SimpleFeaturesTableModelImpl model;
1226
////        model = (SimpleFeaturesTableModel) this.tblResults.getModel();
1227
//        List<Feature> features = store.getFeatures(this.parameters.getQuery());
1228
//        FacadeOfAFeaturePagingHelper facade = (FacadeOfAFeaturePagingHelper) features;
1229
//        FeatureType ftype = facade.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
1230
//        model = new SimpleFeaturesTableModelImpl(
1231
//                ftype,
1232
//                this.parameters.getResultColumnNames(),
1233
//                features
1234
//        );
1235
//        tblResults.setModel(model);
1236
        }
1237

    
1238
        @Override
1239
        public boolean setFilter(Expression filter) {
1240
                try {
1241
                        if (!this.initialized) { //this.conditionPanels == null) {
1242
                                this.initComponents1();
1243
                        }
1244
                        if (ExpressionUtils.isPhraseEmpty(filter)) {
1245
                                this.clear();
1246
                                return true;
1247
                        }
1248
                        int panel = 0;
1249
                        int selected = PANEL_ADVANCED;
1250
                        for (SearchConditionPanel conditionPanel : conditionPanels) {
1251
                                if (panel != PANEL_ADVANCED && conditionPanel.set(filter)) {
1252
                                        selected = panel;
1253
                                }
1254
                                panel++;
1255
                        }
1256
                        this.tabSearchMode.setSelectedIndex(selected);
1257

    
1258
//            SimpleFeaturesTableModel model = new SimpleFeaturesTableModel(this.getStore());
1259
//            tblResults.setModel(model);
1260
//            lblMsg.setText("");
1261
                        return true;
1262
                } catch (Exception ex) {
1263
                        LOGGER.warn("Can't set current search", ex);
1264
                        return false;
1265
                }
1266
        }
1267

    
1268
        @Override
1269
        public List<SearchConditionPanel> getConditionPanels() {
1270
                return Collections.unmodifiableList(this.conditionPanels);
1271
        }
1272

    
1273
        @Override
1274
        public SearchConditionPanel getConditionPanel(String name) {
1275
                if (conditionPanels == null) {
1276
                        return null;
1277
                }
1278
                for (SearchConditionPanel panel : conditionPanels) {
1279
                        if (StringUtils.equalsIgnoreCase(name, panel.getFactory().getName())) {
1280
                                return panel;
1281
                        }
1282
                }
1283
                return null;
1284
        }
1285

    
1286
        public FeatureSelection getSelectedFeatures() {
1287
                if (!this.initialized) {
1288
                        return null;
1289
                }
1290
                int[] selectedRows = this.tblResults.getSelectedRows();
1291
                if( ArrayUtils.isEmpty(selectedRows) ) {
1292
                    return null;
1293
                }
1294
                if (this.tabResults.getSelectedIndex() == 1) {
1295
                    if (this.currentPostProcess == null) {
1296
                            return null;
1297
                    }
1298
                    try {
1299
                            FeatureSelection selection = this.store.createFeatureSelection();
1300
                            List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1301
                            for (int i = 0; i < selectedRows.length ; i++) {
1302
                                Feature feature = features.get(selectedRows[i]);
1303
                                selection.select(feature);
1304
                            }
1305
                            return selection==null? null:selection;
1306
                    } catch (Exception ex) {
1307
                            LOGGER.warn("Can't build search for the selected feature.", ex);
1308
                            return null;
1309
                    }
1310
                } else {
1311
                    try {
1312
                            FeatureSelection selection = this.store.createFeatureSelection();
1313
                            List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1314
                            for (int i = 0; i < selectedRows.length ; i++) {
1315
                                Feature feature = features.get(selectedRows[i]);
1316
                                selection.select(feature);
1317
                            }
1318
                            return selection==null? null:selection;
1319
                    } catch (Exception ex) {
1320
                            LOGGER.warn("Can't build search for the selected feature.", ex);
1321
                            return null;
1322
                    }
1323
                }
1324
        }
1325
        
1326
        @Override
1327
        public Expression getFilterForSelectedFeatures() {
1328
                int maxfeatures = 100;
1329
                
1330
                if (!this.initialized) {
1331
                        return null;
1332
                }
1333
                int[] selectedRows = this.tblResults.getSelectedRows();
1334
                if( ArrayUtils.isEmpty(selectedRows) ) {
1335
                    return null;
1336
                }
1337
                if( selectedRows.length > maxfeatures ) {
1338
                    this.taskStatusController.message("Too many items selecteds");
1339
                }
1340
                if (this.tabResults.getSelectedIndex() == 1) {
1341
                        if (this.currentPostProcess == null) {
1342
                                return null;
1343
                        }
1344
                        try {
1345
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1346
                                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1347
                                for (int i = 0; i < selectedRows.length && i<maxfeatures; i++) {
1348
                                    Feature feature = features.get(selectedRows[i]);
1349
                                    FeatureType ftype = this.postProcessStore.getDefaultFeatureType();
1350
                                    for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1351
                                            builder.or(
1352
                                                    builder.eq(
1353
                                                            builder.column(attrdesc.getName()),
1354
                                                            builder.constant(feature.get(attrdesc.getName()))
1355
                                                    )
1356
                                            );
1357
                                    }
1358
                                }
1359
                                Expression filter = ExpressionUtils.createExpression(builder.toString());
1360
                                return filter;
1361
                        } catch (Exception ex) {
1362
                                LOGGER.warn("Can't build search for the selected feature.", ex);
1363
                                return null;
1364
                        }
1365
                } else {
1366
                    try {
1367
                            FeatureType ftype = this.store.getDefaultFeatureType();
1368
                            ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1369
                            List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1370
                            for (int i = 0; i < selectedRows.length && i<maxfeatures ; i++) {
1371
                                Feature feature = features.get(selectedRows[i]);
1372
                                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1373
                                        builder.or(
1374
                                                builder.eq(
1375
                                                        builder.column(attrdesc.getName()),
1376
                                                        builder.constant(feature.get(attrdesc.getName()))
1377
                                                )
1378
                                        );
1379
                                }
1380
                            }
1381
                            Expression filter = ExpressionUtils.createExpression(builder.toString());                            
1382
                            return filter;
1383
                    } catch (Exception ex) {
1384
                            LOGGER.warn("Can't build search for the selected feature.", ex);
1385
                            return null;
1386
                    }
1387
                }
1388
        }
1389
        
1390
        @Override
1391
        public Expression getFilterForSelectedFeature() {
1392
                if (!this.initialized) { //this.conditionPanels == null) {
1393
                        return null;
1394
                }
1395
                if (this.tabResults.getSelectedIndex() == 1) {
1396
                        if (this.currentPostProcess == null) {
1397
                                return null;
1398
                        }
1399
                        int selectedRow = this.tblSearchPostProcessResults.getSelectedRow();
1400
                        if (selectedRow < 0) {
1401
                                return null;
1402
                        }
1403
                        try {
1404
                                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblSearchPostProcessResults.getModel()).getFeatures();
1405
                                Feature feature = features.get(selectedRow);
1406

    
1407
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1408
                                FeatureType ftype = this.postProcessStore.getDefaultFeatureType();
1409
                                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1410
                                        builder.and(
1411
                                                builder.eq(
1412
                                                        builder.column(attrdesc.getName()),
1413
                                                        builder.constant(feature.get(attrdesc.getName()))
1414
                                                )
1415
                                        );
1416
                                }
1417
                                Expression filter = ExpressionUtils.createExpression(builder.toString());
1418
                                return filter;
1419
                        } catch (Exception ex) {
1420
                                LOGGER.warn("Can't build search for the selected feature.", ex);
1421
                                return null;
1422
                        }
1423
                } else {
1424
                        int selectedRow = this.tblResults.getSelectedRow();
1425
                        if (selectedRow < 0) {
1426
                                return null;
1427
                        }
1428
                        try {
1429
                                List<Feature> features = ((SimpleFeaturesTableModelImpl) this.tblResults.getModel()).getFeatures();
1430
                                Feature feature = features.get(selectedRow);
1431

    
1432
                                ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
1433
                                FeatureType ftype = this.store.getDefaultFeatureType();
1434
                                for (FeatureAttributeDescriptor attrdesc : ftype.getPrimaryKey()) {
1435
                                        builder.and(
1436
                                                builder.eq(
1437
                                                        builder.column(attrdesc.getName()),
1438
                                                        builder.constant(feature.get(attrdesc.getName()))
1439
                                                )
1440
                                        );
1441
                                }
1442
                                Expression filter = ExpressionUtils.createExpression(builder.toString());
1443
                                return filter;
1444
                        } catch (Exception ex) {
1445
                                LOGGER.warn("Can't build search for the selected feature.", ex);
1446
                                return null;
1447
                        }
1448
                }
1449

    
1450
        }
1451

    
1452
        @Override
1453
        public FeatureStore getStore() {
1454
                return store;
1455
        }
1456

    
1457
        private void doOrderBy() {
1458
            try {
1459
                LOGGER.info("Do show order by");
1460
                I18nManager i18n = ToolsLocator.getI18nManager();
1461
                WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1462
                FeatureQueryOrderPanel orderPanel = DALSwingLocator.getDataSwingManager().createFeatureStoreOrderPanel();
1463
                orderPanel.setStore(store);
1464
                orderPanel.put(parameters.getQuery());
1465
                Dialog dialog = windowManager.createDialog(
1466
                        orderPanel.asJComponent(),
1467
                        i18n.getTranslation("_Select_order"),
1468
                        null,
1469
                        WindowManager_v2.BUTTONS_OK_CANCEL
1470
                );
1471
                dialog.addActionListener((ActionEvent e) -> {
1472
                        if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
1473
                                orderPanel.fetch(this.parameters.getQuery());
1474
                                search();
1475
                        }
1476
                });
1477
                dialog.show(WindowManager.MODE.DIALOG);
1478
            } catch (Exception ex) {
1479
                LOGGER.warn("Can't show dialog", ex);
1480
            }
1481
        }
1482

    
1483
    private void doExportTSV(JTable table) {
1484
        try {
1485
            LOGGER.info("Do export TSV");
1486
            final SimpleFeaturesTableModel model;
1487
            if (table.getModel() instanceof SimpleFeaturesTableModel) {
1488
                model = (SimpleFeaturesTableModel) table.getModel();
1489
            } else {
1490
                model = null;
1491
            }
1492
            I18nManager i18n = ToolsLocator.getI18nManager();
1493
            if (model == null) {
1494
                ToolsSwingLocator.getThreadSafeDialogsManager().messageDialog(
1495
                        i18n.getTranslation("_Not_able_to_export_table_to_TSV"),
1496
                        i18n.getTranslation(EXPORT_TO_TSV_TITLE),
1497
                        JOptionPane.WARNING_MESSAGE);
1498
                return;
1499
            }
1500

    
1501
            FileFilter fileFilter = new FileFilter() {
1502
                @Override
1503
                public boolean accept(File f) {
1504
                    if (f.isDirectory()) {
1505
                        return true;
1506
                    }
1507
                    String extension = FilenameUtils.getExtension(f.getAbsolutePath());
1508
                    return StringUtils.equalsIgnoreCase(TSV_EXTENSION, extension);
1509
                }
1510

    
1511
                @Override
1512
                public String getDescription() {
1513
                    return "TSV file";
1514
                }
1515
            };
1516
            FoldersManager folderManager = ToolsLocator.getFoldersManager();
1517
            File initialFolder = folderManager.getLastPath(EXPORT_TO_TSV_LASTPATHID);
1518

    
1519
            ThreadSafeDialogsManager safeDialogsManager = ToolsSwingLocator.getThreadSafeDialogsManager();
1520
            ImmutablePair<File[], Charset> pair = safeDialogsManager.showChooserDialog(
1521
                    i18n.getTranslation(EXPORT_TO_TSV_TITLE),
1522
                    SAVE_DIALOG,
1523
                    FILES_ONLY,
1524
                    false,
1525
                    initialFolder,
1526
                    fileFilter,
1527
                    initialized,
1528
                    true
1529
            );
1530

    
1531
            if (pair == null) {
1532
                return;
1533
            }
1534
            File[] files = pair.getLeft();
1535
            Charset charset = pair.getRight();
1536
            if (files.length < 1) {
1537
                return;
1538
            }
1539
            File f = files[0];
1540
            if (f == null) {
1541
                return;
1542
            }
1543
            if (f.isDirectory()) {
1544
                return;
1545
            }
1546
            if (FilenameUtils.getExtension(f.getName()).isEmpty()) {
1547
                f = new File(f.getAbsolutePath() + FilenameUtils.EXTENSION_SEPARATOR + "tsv");
1548
            }
1549
            if (f.exists()) {
1550
                int res = safeDialogsManager.confirmDialog(
1551
                        i18n.getTranslation("fichero_ya_existe_seguro_desea_guardarlo"),
1552
                        i18n.getTranslation(EXPORT_TO_TSV_TITLE),
1553
                        WIDTH,
1554
                        HEIGHT
1555
                );
1556
                if (res != YES_OPTION) {
1557
                    return;
1558
                }
1559
            }
1560

    
1561
            final File file = f;
1562

    
1563
            folderManager.setLastPath(EXPORT_TO_TSV_LASTPATHID, file.getParentFile());
1564
            Cursor savedCursor = this.getCursor();
1565
            SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1566
            status.setAutoremove(true);
1567
            status.add();
1568
            this.taskStatusController.bind(status);
1569
            
1570
            SearchParameters searchParams = this.fetch(this.parameters.getCopy()); 
1571
            final FeatureQuery myQuery;
1572
            if( this.useSelection() ) {
1573
                myQuery = this.addSelection(this.store, searchParams.getQueryToApply());
1574
            } else {
1575
                myQuery = searchParams.getQueryToApply();
1576
            }
1577
            
1578
            Thread task = new Thread(() -> {
1579
                try {
1580
                    this.processing = true;
1581
                    this.updateComponentState();
1582
                    SwingUtilities.invokeLater(() -> {
1583
                        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1584
                    });
1585
                    status.setTitle(i18n.getTranslation(EXPORT_TO_TSV_TITLE));
1586

    
1587
                    Pair<Iterator<Feature>, Long> features = buildExportIterator(table, store, myQuery);
1588

    
1589
                    ExportTSV exportTSV = new ExportTSV();
1590
                    exportTSV.process(features.getLeft(), features.getRight(), model, file, charset, status);
1591

    
1592
                } catch (Exception ex) {
1593
                    LOGGER.warn("Not able to export table to TSV", ex);
1594
                } finally {
1595
                    this.processing = false;
1596
                    SwingUtilities.invokeLater(() -> {
1597
                        this.setCursor(savedCursor);
1598
                    });
1599
                    this.updateComponentState();
1600
                }
1601
            }, "SearchPanelExportTSV");
1602
            task.start();
1603
        } catch (Exception ex) {
1604
            LOGGER.warn("Can't export TSV", ex);
1605
        }
1606
    }
1607

    
1608
        private void doCopyRows(JTable table) {
1609
                LOGGER.info("Do copy rows");
1610
                if (!(table.getModel() instanceof SimpleFeaturesTableModel)) {
1611
                    LOGGER.warn("Can't copy rows, wrong model.");
1612
                    return;
1613
                }
1614

    
1615
                final SimpleFeaturesTableModel model = (SimpleFeaturesTableModel) table.getModel();
1616

    
1617
                Cursor savedCursor = this.getCursor();
1618
                SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1619
                status.setAutoremove(true);
1620
                status.add();
1621
                this.taskStatusController.bind(status);
1622
                Thread task = new Thread(() -> {
1623
                        try {
1624
                                this.processing = true;
1625
                                this.updateComponentState();
1626
                                SwingUtilities.invokeLater(() -> {
1627
                                        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1628
                                });
1629
                                String title = ToolsLocator.getI18nManager().getTranslation("_Copying_rows_to_clipboard");
1630
                                status.setTitle(title);
1631
                                status.message("");
1632
                                SearchParameters searchParams = this.fetch(this.parameters.getCopy()); 
1633
                                final FeatureQuery myQuery;
1634
                                if( this.useSelection() ) {
1635
                                    myQuery = this.addSelection(this.store, searchParams.getQueryToApply());
1636
                                } else {
1637
                                    myQuery = searchParams.getQueryToApply();
1638
                                }
1639
                                
1640
                                Pair<Iterator<Feature>, Long> features = buildExportIterator(table, store, myQuery);
1641
                                
1642
                                ExportTSV exportTSV = new ExportTSV();
1643
                                ByteArrayOutputStream fos = new ByteArrayOutputStream();
1644
                                
1645
                                exportTSV.process(
1646
                                        features.getLeft(), 
1647
                                        features.getRight(), 
1648
                                        model, 
1649
                                        fos, 
1650
                                        Charset.defaultCharset(), 
1651
                                        status
1652
                                );
1653

    
1654
                                String toStr = new String(fos.toByteArray(),Charset.defaultCharset());
1655

    
1656
                                SwingUtilities.invokeLater(() -> {
1657
                                        ToolsSwingLocator.getToolsSwingManager().putInClipboard(toStr);
1658
                                        status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Copy_ended"));
1659
                                        status.terminate();
1660
                                });
1661

    
1662
                        } catch (Exception ex) {
1663
                                LOGGER.warn("Not able to copy rows to the clipboard", ex);
1664
                                status.message("Not able to copy rows to the clipboard");
1665
                                status.abort();
1666
                        } finally {
1667
                                this.processing = false;
1668
                                SwingUtilities.invokeLater(() -> {
1669
                                        this.setCursor(savedCursor);
1670
                                });
1671
                                this.updateComponentState();
1672
                        }
1673
                }, "SearchPanelCopyRows");
1674
                task.start();
1675
        }
1676

    
1677
    private Pair<Iterator<Feature>, Long> buildExportIterator(JTable table, FeatureStore store, FeatureQuery query) {
1678
        
1679
        if (!(table.getModel() instanceof SimpleFeaturesTableModel)) {
1680
            return null;
1681
        }
1682

    
1683
        final SimpleFeaturesTableModel model = (SimpleFeaturesTableModel) table.getModel();
1684
        
1685
        int[] selection = table.getSelectedRows();
1686
        
1687
        if(ArrayUtils.isEmpty(selection) || selection.length == model.size()) {
1688
            FeatureSet features = null;
1689
            try {
1690
                features = store.getFeatureSet(query);
1691
                return new ImmutablePair<>(features.fastIterator(),features.size64());
1692
            } catch(Exception e) {
1693
                throw new RuntimeException("Can't get features.", e);
1694
            } finally {
1695
                DisposeUtils.disposeQuietly(features);
1696
            }
1697
        }
1698
        Iterator<Feature> featIterator = new Iterator<Feature>() {
1699
            int row = 0;
1700

    
1701
            @Override
1702
            public boolean hasNext() {
1703
                return row < selection.length;
1704
            }
1705

    
1706
            @Override
1707
            public Feature next() {
1708
                int n = table.convertRowIndexToModel(selection[row++]);
1709
                return model.getFeatureAt(n);
1710
            }
1711
        };
1712
        return new ImmutablePair<>(featIterator, (long)selection.length);
1713

    
1714
    }
1715

    
1716
        @Override
1717
        public ImageIcon loadImage(String imageName) {
1718
            return ToolsSwingUtils.loadImage(this, imageName);
1719
        }
1720

    
1721
        @Override
1722
        public int getSelectedFeatureCount() {
1723
                if (!this.initialized) { //this.conditionPanels == null) {
1724
                        return 0;
1725
                }
1726
                if (this.currentPostProcess != null && this.tabResults.getSelectedIndex() == 1) {
1727
                        return this.tblSearchPostProcessResults.getSelectedRowCount();
1728
                }
1729
                return this.tblResults.getSelectedRowCount();
1730
        }
1731

    
1732
        @Override
1733
        public JComponent getActionButton(String name) {
1734
                ActionButtons actionButton = this.actions.get(name);
1735
                if (actionButton == null) {
1736
                        return null;
1737
                }
1738
                return actionButton.button;
1739
        }
1740

    
1741
        @Override
1742
        public void setShowActions(boolean showActions) {
1743
                this.showActions = showActions;
1744
        }
1745

    
1746
        @Override
1747
        public boolean isShowActions() {
1748
                return this.showActions;
1749
        }
1750

    
1751
        private void doCalculatedColumns() {
1752
            try {
1753
                LOGGER.info("Do show calculate columns");
1754
                WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1755
                I18nManager i18n = ToolsLocator.getI18nManager();
1756
                final FeatureQueryCalculatedColumnsPanel panel = new DefaultFeatureQueryCalculatedColumnsPanel();
1757
                panel.setStore(this.store);
1758
                panel.put(this.parameters.getQuery());
1759
                final Dialog dialog = winmanager.createDialog(
1760
                        panel.asJComponent(),
1761
                        i18n.getTranslation("_Calculated_columns"),
1762
                        null,
1763
                        WindowManager_v2.BUTTONS_OK_CANCEL
1764
                );
1765
                dialog.addActionListener((ActionEvent e) -> {
1766
                        if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1767
                                panel.fetch(this.parameters.getQuery());
1768
                                search();
1769
                        }
1770
                });
1771
                dialog.show(WindowManager.MODE.DIALOG);
1772
            } catch (Exception ex) {
1773
                LOGGER.warn("Can't show dialog", ex);
1774
            }
1775
        }
1776

    
1777
        private void doGroupBy() {
1778
            try {
1779
                LOGGER.info("Do show group by");
1780
                DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
1781
                int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
1782
                if (allowGroupBy != DataType.YES) {
1783
                        // FIXME: mensaje al usaurio.
1784
                        I18nManager i18n = ToolsLocator.getI18nManager();
1785
                        ThreadSafeDialogsManager dialogs = ToolsSwingLocator.getThreadSafeDialogsManager();
1786
                        dialogs.messageDialog(
1787
                                i18n.getTranslation("_The_group_function_is_not_available_for_this_table"),
1788
                                i18n.getTranslation("_Information"),
1789
                                JOptionPane.INFORMATION_MESSAGE
1790
                        );
1791
                        return;
1792
                }
1793

    
1794
                WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1795
                I18nManager i18n = ToolsLocator.getI18nManager();
1796
                final DefaultSearchGroupByPanel panelGroupBy = new DefaultSearchGroupByPanel();
1797
                panelGroupBy.setStore(this.store);
1798
                panelGroupBy.put(this.parameters);
1799
                final Dialog dialog = winmanager.createDialog(
1800
                        panelGroupBy.asJComponent(),
1801
                        i18n.getTranslation("_Select_group_columns_and_aggregate_functions"),
1802
                        null,
1803
                        WindowManager_v2.BUTTONS_OK_CANCEL
1804
                );
1805
                dialog.addActionListener((ActionEvent e) -> {
1806
                        if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1807
                                panelGroupBy.fetch(this.parameters);
1808
                                search();
1809
                        }
1810
                });
1811
                dialog.show(WindowManager.MODE.DIALOG);
1812
            } catch (Exception ex) {
1813
                LOGGER.warn("Can't show dialog", ex);
1814
            }
1815
        }
1816

    
1817
        private void doSelectResultColumnNames() {
1818
            try {
1819
                LOGGER.info("Do select result column names");
1820
                WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
1821
                I18nManager i18n = ToolsLocator.getI18nManager();
1822
                final FeatureAttributesSelectionPanel panelSelectColumns = DALSwingLocator.getManager().createFeatureAttributeSelectionPanel();
1823
                panelSelectColumns.allowCalculatedAttributes(false);
1824
                FeatureType ftype = this.getFeatureType();
1825
                panelSelectColumns.setFeatureType(ftype);
1826
                if(this.parameters.getQuery() != null){
1827
                    panelSelectColumns.setExtraColumns(this.parameters.getQuery().getExtraColumns().getColumns());
1828
                }
1829
                panelSelectColumns.setSelectedNames(this.parameters.getResultColumnNames());
1830
                final Dialog dialog = winmanager.createDialog(
1831
                        panelSelectColumns.asJComponent(),
1832
                        i18n.getTranslation("_Select_the_columns_to_display"),
1833
                        null,
1834
                        WindowManager_v2.BUTTONS_OK_CANCEL
1835
                );
1836
                dialog.addActionListener((ActionEvent e) -> {
1837
                        if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
1838
                                this.setResultColumnNames(panelSelectColumns.getSelectedNames());
1839
                                search();
1840
                        }
1841
                });
1842
                dialog.show(WindowManager.MODE.DIALOG);
1843
            } catch (Exception ex) {
1844
                LOGGER.warn("Can't show dialog", ex);
1845
            }
1846
        }
1847

    
1848
        @Override
1849
        public void put(SearchParameters inParams) {
1850
                this.parameters = (DefaultSearchParameters) inParams;
1851
                for (SearchConditionPanel conditionPanel : this.conditionPanels) {
1852
                        try {
1853
                                conditionPanel.put(inParams);
1854
                        } catch (Exception ex) {
1855
                                LOGGER.warn("Can't open panel", ex);
1856
                        }
1857
                }
1858
                this.tabSearchMode.setSelectedIndex(inParams.getSearchMode());
1859

    
1860
        }
1861

    
1862
        private FeatureQuery getQuery() {
1863
                FeatureQuery query;
1864
                try {
1865
                        int searchMode = this.tabSearchMode.getSelectedIndex();
1866
                        SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1867
                        Expression filter = panel.get();
1868
                        if (searchMode != PANEL_ADVANCED) {
1869
                                this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1870
                        }
1871
                        query = (FeatureQuery) this.parameters.getQuery().clone();
1872
                        query.retrievesAllAttributes();
1873
                        if (ExpressionUtils.isPhraseEmpty(filter)) {
1874
                                return query;
1875
                        }
1876
                        query.setFilter(Expression.cloneQuietly(filter));
1877
                        query.retrievesAllAttributes();
1878
                        return query;
1879
                } catch (Exception ex) {
1880
                        LOGGER.warn("Can't build query.", ex);
1881
                        return null;
1882
                }
1883
        }
1884

    
1885
        @Override
1886
        public SearchParameters fetch(SearchParameters outParams) {
1887
            if(!initialized){
1888
                this.initComponents1();
1889
            }
1890
                // Actualiza el fquery del parameters con los paneles
1891
                for (SearchConditionPanel conditionPanel : conditionPanels) {
1892
                        try {
1893
                                conditionPanel.fetch(this.parameters);
1894
                        } catch (Exception ex) {
1895
                                LOGGER.warn("Panel not able to fetch values", ex);
1896
                        }
1897
                }
1898

    
1899
                // Actualiza el filtro con el panel activo
1900
                int searchMode = this.tabSearchMode.getSelectedIndex();
1901
                SearchConditionPanel panel = this.conditionPanels.get(searchMode);
1902
                Expression filter = panel.get();
1903
                if (searchMode != PANEL_ADVANCED) {
1904
                        this.conditionPanels.get(PANEL_ADVANCED).set(filter);
1905
                }
1906
                this.parameters.setSearchMode(searchMode);
1907
                FeatureQuery query = (FeatureQuery) this.parameters.getQuery();
1908
                this.lastQuery = query.getCopy();
1909
                query.retrievesAllAttributes();
1910
                query.clearFilter();
1911
                if (!ExpressionUtils.isPhraseEmpty(filter)) {
1912
                        query.setFilter(filter);
1913
                        query.retrievesAllAttributes();
1914
                }
1915

    
1916
                if (outParams == null) {
1917
                        return this.parameters.getCopy();
1918
                }
1919
                outParams.copyFrom(this.parameters.getCopy());
1920
                return outParams;
1921
        }
1922

    
1923
        public static void selfRegister() {
1924
            boolean n = ToolsSwingUtils.registerIcons(
1925
                    DefaultSearchPanel.class, 
1926
                    "",
1927
                    LIBRARY_NAME,
1928
                    new String[]{"storeaction", "storeaction-select"},
1929
                    new String[]{"storeaction", "storeaction-select-add"},
1930
                    new String[]{"storeaction", "storeaction-select-filter"},
1931

    
1932
                    new String[]{"storesearch", "search-simplifiedcondition-edit-accumulate"},
1933
                    new String[]{"storesearch", "search-simplifiedcondition-clear-accumulate"},
1934
                    new String[]{"storesearch", "search-simplifiedcondition-add-accumulate"},
1935
                    
1936
                    new String[]{"storesearch", "search-nullbehavior-null"},
1937
                    new String[]{"storesearch", "search-nullbehavior-true"},
1938
                    new String[]{"storesearch", "search-nullbehavior-false"},
1939
                    
1940
                    new String[]{"storesearch", "search-geometry-select"},
1941
                    
1942
                    new String[]{"storesearch", "search-select-column"}
1943

    
1944
            );            
1945
            ToolsSwingUtils.registerGroupIconScreenshot(
1946
                    DefaultDALSwingLibrary.class, 
1947
                    "storesearch",
1948
                    "/org/gvsig/fmap/dal/screenshots/storesearch1.png"
1949
            );
1950
            ConfigurableActionsMamager cfgActionsManager = ToolsUtilLocator.getConfigurableActionsMamager();
1951
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsYesAction());
1952
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsNoAction());
1953
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new UseLabelsBothAction());
1954
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new SelectColumnsAction());
1955
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new CalculatedColumnsAction());
1956
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new GroupByAction());
1957
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new OrderByAction());
1958
            cfgActionsManager.addConfigurableAction(CONFIGURABLE_PANEL_ID, new PropertiesAction());
1959
        }
1960

    
1961
        private void doSelectSearchPostprocess() throws DataException {
1962
                DataSwingManager manager = DALSwingLocator.getDataSwingManager();
1963
                Map<String, SearchPostProcessFactory> searchPostProcessFactoryMap = manager.getSearchPostProcess();
1964

    
1965
                JPopupMenu menu = new JPopupMenu();
1966
                for (String factory : searchPostProcessFactoryMap.keySet()) {
1967
                        JMenuItem item;
1968
                        item = new JMenuItem(factory);
1969
                        SearchParameters searchParams = this.fetch(this.parameters.getCopy());
1970
                        FeatureQuery myQuery = searchParams.getQueryToApply();
1971
                        item.addActionListener((ActionEvent e) -> {
1972
                                doSearchPostProcess(store, myQuery, manager.getSearchPostProcess(factory), searchParams);
1973
                        });
1974
                        menu.add(item);
1975
                }
1976
                menu.show(this.btnSearchPostProcess, 0, this.btnSearchPostProcess.getHeight());
1977
        }
1978

    
1979
        private void doExecuteSearchPostProcess(
1980
                FeatureStore input,
1981
                FeatureQuery query,
1982
                SearchPostProcessFactory factory,
1983
                DynObject parameters
1984
        ) {
1985
                LOGGER.info("Do execute post process");
1986
                Cursor savedCursor = this.getCursor();
1987
                SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("");
1988
                status.setAutoremove(true);
1989
                status.add();
1990
                this.taskStatusController.bind(status);
1991
                Thread task = new Thread(() -> {
1992
                        try {
1993
                                SwingUtilities.invokeLater(() -> {
1994
                                        this.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1995
                                });
1996
                                this.processing = true;
1997
                                this.updateComponentState();
1998
                                SearchPostProcess process = factory.createProcess(factory, input, query, parameters);
1999

    
2000
                                if (parameters != null) {
2001
                                        process.setParameters(parameters);
2002
                                }
2003
                                //Ejecutar el execute en thread para no bloquear el software
2004
                                SearchPostProcess.SearchPostProcessResult output = process.execute(input, query, parameters, status);
2005
                                if (output != null) {
2006
                                        this.postProcessStore = output.getStore();
2007
                                        this.postProcessQuery = output.getQuery();
2008

    
2009
                                        doLoadSearchPostProccessResults(this.postProcessStore);
2010

    
2011
                                }
2012
                                this.currentPostProcess = factory.getName();
2013
                                status.terminate();
2014

    
2015
                        } catch (Exception ex) {
2016
                                LOGGER.warn("SearchPostProcess not able to be executed.", ex);
2017
                                resetPostProcessTable();
2018
                                status.setTitle(ToolsLocator.getI18nManager().getTranslation("_Error_in_post_process_operation"));
2019
                                status.message("");
2020
                                status.abort();
2021
                        } finally {
2022
                                SwingUtilities.invokeLater(() -> {
2023
                                        this.setCursor(savedCursor);
2024
                                });
2025
                                this.processing = false;
2026
                                this.updateComponentState();
2027
                        }
2028
                }, "ExecuteSearchPostProcess");
2029

    
2030
                task.start();
2031

    
2032
        }
2033

    
2034
        private void doLoadSearchPostProccessResults(FeatureStore input) {
2035
                if (!SwingUtilities.isEventDispatchThread()) {
2036
                        SwingUtilities.invokeLater(() -> {
2037
                                doLoadSearchPostProccessResults(input);
2038
                        });
2039
                        return;
2040
                }
2041

    
2042
                final List<Feature> featuresSearchPostProccessResults;
2043
                final FeatureQuery finalQuery;
2044
                finalQuery = null;
2045
                try {
2046
                        this.tabResults.setEnabledAt(1, true);
2047
                        this.tabResults.setSelectedIndex(1);
2048
                        featuresSearchPostProccessResults = input.getFeatures(finalQuery, 20);
2049
                        FacadeOfAFeaturePagingHelper facadeSearchPostProccessResults = (FacadeOfAFeaturePagingHelper) featuresSearchPostProccessResults;
2050
                        FeatureType ftypeSearchPostProccessResults = facadeSearchPostProccessResults.getFeaturePagingHelper().getFeatureSet().getDefaultFeatureType();
2051
                        // al modelo le pasamos el ftype de esas features
2052
                        resultPostProcessModel = new SimpleFeaturesTableModelImpl(
2053
                                ftypeSearchPostProccessResults,
2054
                                this.parameters.getResultColumnNames(),
2055
                                featuresSearchPostProccessResults
2056
                        );
2057

    
2058
                        I18nManager i18n = ToolsLocator.getI18nManager();
2059
                        TableModel oldmodel = tblSearchPostProcessResults.getModel();
2060
                        tblSearchPostProcessResults.setModel(resultPostProcessModel);
2061
                        resultPostProcessModel.setCellRenderers(tblSearchPostProcessResults);
2062
                        if (oldmodel instanceof SimpleFeaturesTableModel) {
2063
                                ((SimpleFeaturesTableModel) oldmodel).dispose();
2064
                        }
2065
                        updateNumberElementsMsg(resultPostProcessModel);
2066
//            if (resultPostProcessModel.hasErrors()) {
2067
//                lblMsg.setText("_Errors_occurred_load_search_post_process");
2068
//            } else {
2069
//                lblMsg.setText(String.format("%d " + i18n.getTranslation("_elements"), resultPostProcessModel.getRowCount()));
2070
//            }
2071
                } catch (Exception ex) {
2072
                        resetPostProcessTable();
2073
                        LOGGER.warn("SearchPostProcess not able to be executed. Can't get features or create table model", ex);
2074
                }
2075
        }
2076

    
2077
        private void updateComponentState() {
2078
                if (!SwingUtilities.isEventDispatchThread()) {
2079
                        SwingUtilities.invokeLater(this::updateComponentState);
2080
                        return;
2081
                }
2082
                this.pgbStatus.setVisible(processing);
2083
                this.setEnabled(!processing);
2084
        }
2085

    
2086
        private void resetPostProcessTable() {
2087
                if (!SwingUtilities.isEventDispatchThread()) {
2088
                        SwingUtilities.invokeLater(this::resetPostProcessTable);
2089
                        return;
2090
                }
2091

    
2092
                this.tblSearchPostProcessResults.setModel(new DefaultTableModel());
2093
        }
2094

    
2095
        private void doSearchPostProcess(FeatureStore store, FeatureQuery query, SearchPostProcessFactory factory, SearchParameters searchParams) {
2096
                LOGGER.info("Do search post process");
2097
                if (factory.hasProcessParameters()) {
2098
                        DynObject parametersPostProcess = factory.createProcessParameters(store, query, searchParams);
2099
                        JDynForm form = DynFormLocator.getDynFormManager().createJDynForm(parametersPostProcess);
2100
                        form.setLayoutMode(JDynForm.USE_SEPARATORS);
2101

    
2102
                        I18nManager i18n = ToolsLocator.getI18nManager();
2103
                        WindowManager_v2 windowManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
2104

    
2105
                        Dialog dialog = windowManager.createDialog(
2106
                                form.asJComponent(),
2107
                                i18n.getTranslation("_Postprocess_parameters"),
2108
                                i18n.getTranslation(
2109
                                        "_Parameters_for_XpostprocessNameX_postprocess_on_XtableNameX",
2110
                                        new String[]{
2111
                                                factory.getName(),
2112
                                                this.store.getName()
2113
                                        }
2114
                                ),
2115
                                WindowManager_v2.BUTTONS_OK_CANCEL);
2116

    
2117
                        ToolsSwingUtils.ensureRowsCols(dialog.asJComponent(), 20, 60, 30, 100);
2118
                        dialog.addActionListener((ActionEvent e2) -> {
2119
                                if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
2120
                                        form.getValues(parametersPostProcess); // actualiza el valor de lo los parametros con los valores introducidos por el usuario
2121
                                        doExecuteSearchPostProcess(store, query, factory, parametersPostProcess);
2122
                                        this.postProcessParams = parametersPostProcess;
2123
                                }
2124
                        });
2125

    
2126
                        dialog.show(WindowManager.MODE.DIALOG);
2127

    
2128
                } else {
2129
                        doExecuteSearchPostProcess(store, query, factory, null);
2130
                }
2131
        }
2132

    
2133
        private void updateNumberElementsMsg(SimpleFeaturesTableModel model) {
2134
                I18nManager i18n = ToolsLocator.getI18nManager();
2135

    
2136
                if (model.hasErrors()) {
2137
                        this.taskStatusController.setTitle(i18n.getTranslation("_Errors_occurred_load_search_post_process"));
2138
                } else {
2139
                        this.taskStatusController.setTitle(String.format("%d " + i18n.getTranslation("_elements"), model.getRowCount()));
2140
                }
2141
        }
2142

    
2143
        @Override
2144
        public boolean isVisible(Object component) {
2145
                if (this.filterOnlyMode || !this.isGroupByEnabled()) {
2146
                        if (component instanceof GroupByAction) {
2147
                                return false;
2148
                        }
2149
//            if( component instanceof OrderByAction ) {
2150
//                return false;
2151
//            }
2152
//            if( component instanceof CalculatedColumnsAction ) {
2153
//                return false;
2154
//            }
2155
                }
2156
                return true;
2157
        }
2158

    
2159
        @Override
2160
        public boolean isEnabled(Object component) {
2161
                if (component instanceof GroupByAction) {
2162
                        DataStoreProviderFactory dataFactory = this.store.getProviderFactory();
2163
                        int allowGroupBy = ((FeatureStoreProviderFactory) dataFactory).allowGroupBy();
2164
                        if (allowGroupBy != DataType.YES) {
2165
                                return false;
2166
                        }
2167
                }
2168
                return true;
2169
        }
2170

    
2171
        @Override
2172
        public void setFilterOnlyMode(boolean filterOnlyMode) {
2173
            if (this.initialized) {
2174
                throw new IllegalStateException("Cannot change filter-only-mode after invoking asJComponent.");
2175
            }
2176
            this.filterOnlyMode = filterOnlyMode;
2177
            this.groupByEnabled = false;
2178
            this.postProcessEnabled = false;
2179
            this.showActions = false;
2180
        }
2181

    
2182
        @Override
2183
        public boolean isFilterOnlyMode() {
2184
                return this.filterOnlyMode;
2185
        }
2186

    
2187
        @Override
2188
        public Feature getLastSelectedFeature() {
2189
                return this.lastSelectedFeature;
2190
        }
2191

    
2192
        @Override
2193
        public Object getProperty(String name) {
2194
                return this.propertiesHelper.getProperty(name);
2195
        }
2196

    
2197
        @Override
2198
        public void setProperty(String name, Object value) {
2199
                this.propertiesHelper.setProperty(name, value);
2200
        }
2201

    
2202
        @Override
2203
        public Map<String, Object> getProperties() {
2204
                return this.propertiesHelper.getProperties();
2205
        }
2206

    
2207
        @Override
2208
    public void setAutomaticallySearch(boolean automaticallySearch){
2209
        this.automaticallySearch = automaticallySearch;
2210
    }
2211
    
2212
        @Override
2213
    public boolean isAutomaticallySearch(){
2214
        return automaticallySearch;
2215
    }
2216

    
2217
    @Override
2218
    public String getLastErrorMessage() {
2219
        return this.lastErrorMessage;
2220
    }
2221
    
2222
    private String getLastErrorMessage(Throwable ex) {
2223
        StringBuilder builder = new StringBuilder();
2224
        while (ex != null){
2225
            if(ex instanceof SQLException){
2226
                builder.append(ex.getLocalizedMessage());
2227
                builder.append("\n");
2228
            }
2229
            ex = ex.getCause();
2230
        }
2231
        return builder.toString();
2232
    }
2233
    
2234
    private void doCopyQueryToCLipboard(FeatureQuery query) {
2235
        ToolsSwingLocator.getToolsSwingManager().putInClipboard(query.toJson().toString());
2236
    }
2237
    
2238
    private void doShowProperties() {
2239
        try {
2240
            LOGGER.info("Do show properties");
2241
            ToolsSwingManager toolSwingManager = ToolsSwingLocator.getToolsSwingManager();
2242
            SearchParameters params = this.fetch(null);
2243
            StringBuilder msg = new StringBuilder();
2244
            params.isValid(this.getFeatureType(), msg);
2245
            I18nManager i18n = ToolsLocator.getI18nManager();
2246
            toolSwingManager.showZoomDialog(
2247
                    this, 
2248
                    i18n.getTranslation("_Properties"), 
2249
                    params.toString() + "\n" + msg.toString(), 
2250
                    false,
2251
                    WindowManager.MODE.DIALOG,
2252
                    ListBuilder.create(
2253
                            new AbstractAction(i18n.getTranslation("_Copy_query")) {
2254
                                @Override
2255
                                public void actionPerformed(ActionEvent e) {
2256
                                    doCopyQueryToCLipboard(params.getQuery());
2257
                                }
2258
                            }
2259
                    )
2260
            );
2261
        } catch (Exception ex) {
2262
            LOGGER.warn("Can't show dialog", ex);
2263
        }
2264
    }
2265

    
2266
    @Override
2267
    public void setPostProcessEnabled(boolean enabled) {
2268
        if (this.initialized) {
2269
            throw new IllegalStateException("Cannot change postProcessEnabled after invoking asJComponent.");
2270
        }
2271
        this.postProcessEnabled = enabled;
2272
    }
2273

    
2274
    @Override
2275
    public void setGroupByEnabled(boolean enabled) {
2276
        if (this.initialized) {
2277
            throw new IllegalStateException("Cannot change groupByEnabled after invoking asJComponent.");
2278
        }
2279
        this.groupByEnabled = enabled;
2280
    }
2281

    
2282
    @Override
2283
    public boolean isPostProcessEnabled() {
2284
        return this.postProcessEnabled;
2285
    }
2286

    
2287
    @Override
2288
    public boolean isGroupByEnabled() {
2289
        return this.groupByEnabled;
2290
    }
2291

    
2292
    private boolean useSelection() {
2293
        boolean x = this.chkUseSelection.isSelected();
2294
        return x;
2295
    }
2296

    
2297
    private FeatureQuery addSelection(FeatureStore store, FeatureQuery query) {
2298
        query = query.getCopy();
2299
        
2300
        if( store.isFeatureSelectionEmpty() ) {
2301
            return  query;
2302
        }
2303
        if( store.getMode()!=FeatureStore.MODE_QUERY ) {
2304
            throw new RuntimeException("Use selection not allowed in editing mode");
2305
        }
2306
        
2307
        FeatureAttributeDescriptor[] pks = store.getDefaultFeatureTypeQuietly().getPrimaryKey();
2308
        if( pks==null ) {
2309
            throw new RuntimeException("Use selection not allowed without primarykey");
2310
        }
2311
        if( pks.length!=1 ) {
2312
            throw new RuntimeException("Use selection not allowed with multifield primarykey");
2313
        }
2314
        ExpressionEvaluatorManager expManager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
2315
        ExpressionBuilder expbuilder = expManager.createExpressionBuilder();
2316

    
2317
        Expression filter = query.getExpressionFilter();
2318
        ExpressionBuilder.Value values = expManager.convertToValue(store.getFeatureSelectionQuietly().referenceIterator());
2319
        if( ExpressionBuilder.isFunction(values, ExpressionBuilder.FUNCTION_TUPLE) ) {
2320
            ((ExpressionBuilder.Function) values).name("");
2321
        }
2322
        String selectionfilter = expbuilder.binaryOperator(
2323
                ExpressionBuilder.OPERATOR_IN,
2324
                expbuilder.variable(pks[0].getName()), 
2325
                values
2326
        ).toString();
2327
        StringBuilder builder = new StringBuilder();
2328
        builder.append(selectionfilter);
2329
        if( filter == null ) {                                    
2330
            query.addFilter(builder.toString());
2331
        } else {
2332
            builder.append(" AND (");
2333
            builder.append(filter.getPhrase());
2334
            builder.append(")");
2335
            filter.setPhrase(builder.toString());
2336
        }
2337
        query.retrievesAllAttributes();
2338
        return query;
2339
    }
2340
    
2341
    @Override
2342
    public void addResultPanel(String name, String title, Component component) {
2343
        int index = -1;
2344
        if( this.additionalResultsPanels.containsKey(name) ) {
2345
            index = this.additionalResultsPanels.get(name).getIndex();
2346
        }
2347
        AdditionalResultsPanel panel = new AdditionalResultsPanel(name, title, component, index);
2348
        this.additionalResultsPanels.put(name, panel);
2349
        if( this.initialized ) {
2350
            if( index < 0 ) {
2351
                panel.setIndex(this.tabResults.getTabCount());
2352
                this.tabResults.addTab(panel.getTitle(), panel.asJComponent());
2353
            } else {
2354
                this.tabResults.setComponentAt(index, panel.asJComponent());
2355
                this.tabResults.setTitleAt(index, panel.getTitle());
2356
            }
2357
        }
2358
    }
2359

    
2360
    @Override
2361
    public void removeResultPanel(String name) {
2362
        int index = -1;
2363
        if( this.additionalResultsPanels.containsKey(name) ) {
2364
            index = this.additionalResultsPanels.get(name).getIndex();
2365
        }
2366
        this.additionalResultsPanels.remove(name);
2367
        if( this.initialized ) {
2368
            this.tabResults.removeTabAt(index);
2369
        }
2370
    }
2371

    
2372
    @Override
2373
    public DALActionFactory.DALActionContext getSearchActionContext() {
2374
        return new SearchActionContext(this);
2375
    }
2376

    
2377
    private void fireSearchEvent() {
2378
        ActionEvent e = new ActionEvent(this, 1, "search");
2379
        for (AdditionalResultsPanel additionalResultsPanel : this.additionalResultsPanels.values()) {
2380
            additionalResultsPanel.fireActionEvent(e);
2381
        }
2382
    }
2383
    
2384
    // https://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html
2385
}