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 / SearchConditionPanelSimplified.java @ 45326

History | View | Annotate | Download (15.4 KB)

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

    
3
import java.awt.event.ActionEvent;
4
import java.util.ArrayList;
5
import java.util.List;
6
import java.util.Map;
7
import javax.json.Json;
8
import javax.json.JsonObject;
9
import javax.json.JsonObjectBuilder;
10
import javax.swing.JButton;
11
import javax.swing.JComboBox;
12
import javax.swing.JComponent;
13
import javax.swing.JLabel;
14
import javax.swing.event.ChangeListener;
15
import org.apache.commons.lang3.StringUtils;
16
import org.gvsig.expressionevaluator.Code;
17
import org.gvsig.expressionevaluator.Expression;
18
import org.gvsig.expressionevaluator.ExpressionBuilder;
19
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_AND;
20
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_OR;
21
import org.gvsig.expressionevaluator.ExpressionUtils;
22
import org.gvsig.expressionevaluator.swing.JExpressionBuilder;
23
import org.gvsig.fmap.dal.complements.Search;
24
import org.gvsig.fmap.dal.exception.DataException;
25
import org.gvsig.fmap.dal.feature.FeatureStore;
26
import org.gvsig.fmap.dal.swing.DALSwingLocator;
27
import org.gvsig.fmap.dal.swing.DataSwingManager;
28
import org.gvsig.fmap.dal.swing.searchpanel.AbstractSearchConditionPanel;
29
import org.gvsig.fmap.dal.swing.searchpanel.SearchConditionPanel;
30
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dataTypes.DataTypeUtils;
33
import org.gvsig.tools.i18n.I18nManager;
34
import org.gvsig.tools.swing.api.ChangeListenerHelper;
35
import org.gvsig.tools.swing.api.ToolsSwingLocator;
36
import org.gvsig.tools.swing.api.windowmanager.Dialog;
37
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
38
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
39
import org.slf4j.Logger;
40
import org.slf4j.LoggerFactory;
41

    
42
/**
43
 *
44
 * @author jjdelcerro
45
 */
46
public class SearchConditionPanelSimplified
47
        extends AbstractSearchConditionPanel
48
        implements SearchConditionPanel {
49

    
50
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchConditionPanelSimplified.class);
51
    public static final String PANEL_NAME = "SearchConditionPanelSimplified";
52

    
53
    @Override
54
    public JComponent asJComponent() {
55
        return null;
56
    }
57

    
58
    @Override
59
    public void put(SearchParameters params) {
60
        Map<String, JsonObject> allPersistenceJson = params.getValues();
61
        JsonObject jsonState = allPersistenceJson.get(PANEL_NAME);
62
        this.fromJson(jsonState);
63
    }
64

    
65
    @Override
66
    public SearchParameters fetch(SearchParameters params) {
67
        if (params == null) {
68
            return null;
69
        }
70
        Map<String, JsonObject> persistenceJson = params.getValues();
71
        JsonObject jsonState = this.toJson();
72
        persistenceJson.put(PANEL_NAME, jsonState);
73
        return params;
74
    }
75

    
76
    private static class SearchConditionPanelAdvancedFactory
77
            implements SearchConditionPanelFactory {
78

    
79
        @Override
80
        public boolean isApplicable(FeatureStore store) {
81
            return true;
82
        }
83

    
84
        @Override
85
        public SearchConditionPanel create(Object... os) {
86
            return null;
87
        }
88

    
89
        @Override
90
        public String getName() {
91
            return "Simplified";
92
        }
93

    
94
    }
95

    
96
    private static final SearchConditionPanelFactory FACTORY = new SearchConditionPanelAdvancedFactory();
97

    
98
    private final FeatureStore store;
99
    private final List<SearchConditionFieldController> searchFieldsControllers;
100
    private int maxSearhFields = 4;
101
    private String accumulatedFilter;
102
    private final JButton btnAddAccumulatedFilter;
103
    private final JButton btnRemoveAccumulatedFilter;
104
    private final JButton btnViewAccumulatedFilter;
105
    private final String baseToolTip;
106
    private SearchConditionPanelFactory factory;
107
    private final ChangeListenerHelper changeListenerHelper;
108

    
109
    public SearchConditionPanelSimplified(
110
            SearchParameters parameters,
111
            FeatureStore store,
112
            JButton btnAddToAccumulatedFilter,
113
            JButton btnRemoveAccumulatedFilter,
114
            JButton btnViewAccumulatedFilter,
115
            JLabel lblField1,
116
            JLabel lblExtraFields1,
117
            JLabel lblRelationalOperator1,
118
            JComboBox cboValue1,
119
            JLabel lblNull1,
120
            JLabel lblLogicalOperators1,
121
            JLabel lblField2,
122
            JLabel lblExtraFields2,
123
            JLabel lblRelationalOperator2,
124
            JComboBox cboValue2,
125
            JLabel lblNull2,
126
            JLabel lblLogicalOperators2,
127
            JLabel lblField3,
128
            JLabel lblExtraFields3,
129
            JLabel lblRelationalOperator3,
130
            JComboBox cboValue3,
131
            JLabel lblNull3,
132
            JLabel lblLogicalOperators3,
133
            JLabel lblField4,
134
            JLabel lblExtraFields4,
135
            JLabel lblRelationalOperator4,
136
            JComboBox cboValue4,
137
            JLabel lblNull4,
138
            JLabel lblLogicalOperators4
139
    ) {
140
        this.changeListenerHelper = ToolsSwingLocator.getToolsSwingManager().createChangeListenerHelper();
141
        this.store = store;
142
        this.searchFieldsControllers = new ArrayList<>();
143
        SearchConditionFieldController controller = new SearchConditionFieldController(
144
                parameters,
145
                store,
146
                lblField1,
147
                lblExtraFields1,
148
                lblRelationalOperator1,
149
                cboValue1,
150
                lblNull1,
151
                lblLogicalOperators1
152
        );
153
        this.searchFieldsControllers.add(controller);
154
        controller = new SearchConditionFieldController(
155
                parameters,
156
                store,
157
                lblField2,
158
                lblExtraFields2,
159
                lblRelationalOperator2,
160
                cboValue2,
161
                lblNull2,
162
                lblLogicalOperators2
163
        );
164
        this.searchFieldsControllers.add(controller);
165
        controller = new SearchConditionFieldController(
166
                parameters,
167
                store,
168
                lblField3,
169
                lblExtraFields3,
170
                lblRelationalOperator3,
171
                cboValue3,
172
                lblNull3,
173
                lblLogicalOperators3
174
        );
175
        this.searchFieldsControllers.add(controller);
176
        controller = new SearchConditionFieldController(
177
                parameters,
178
                store,
179
                lblField4,
180
                lblExtraFields4,
181
                lblRelationalOperator4,
182
                cboValue4,
183
                lblNull4,
184
                null
185
        );
186
        this.searchFieldsControllers.add(controller);
187
        this.accumulatedFilter = null;
188
        this.btnAddAccumulatedFilter = btnAddToAccumulatedFilter;
189
        this.btnRemoveAccumulatedFilter = btnRemoveAccumulatedFilter;
190
        this.btnViewAccumulatedFilter = btnViewAccumulatedFilter;
191
        this.baseToolTip = this.btnAddAccumulatedFilter.getToolTipText();
192
        initComponents();
193
    }
194

    
195
    @Override
196
    public SearchConditionPanelFactory getFactory() {
197
        return FACTORY;
198
    }
199

    
200
    @Override
201
    public boolean isValid(StringBuilder message) {
202
        boolean valid = true;
203
        for (SearchConditionFieldController searchField : searchFieldsControllers) {
204
            if (!searchField.isValid(message)) {
205
                valid = false;
206
            }
207
        }
208
        return valid;
209
    }
210

    
211
    private void initComponents() {
212
        try {
213
            Search search = (Search) ToolsLocator.getComplementsManager().get(
214
                    Search.COMPLEMENT_MANE, this.store.getDefaultFeatureType()
215
            );
216
            List<Search.OrderedAttribute> orderedAttributes = search.getOrderedAttributes(
217
                    Search.BASIC_TYPES_FILTER,
218
                    Search.STR_INT_LONG_LABEL_ORDER,
219
                    5
220
            );
221
            this.maxSearhFields = Integer.min(orderedAttributes.size(), 4);
222
            int n = 0;
223
            for (SearchConditionFieldController searchField : searchFieldsControllers) {
224
                if (n < this.maxSearhFields) {
225
                    searchField.setAttribute(orderedAttributes.get(n++).getDescriptor().getName());
226
                } else {
227
                    searchField.setEnabled(false);
228
                }
229
            }
230
        } catch (DataException ex) {
231
            LOGGER.warn("Can't determine order of attributes", ex);
232
        }
233
        this.btnAddAccumulatedFilter.addActionListener((ActionEvent e) -> {
234
            addToAccumulatedFilter(this.getCurrentFilter());
235
        });
236
        this.btnRemoveAccumulatedFilter.addActionListener((ActionEvent e) -> {
237
            clearAccumulatedFilter();
238
        });
239
        this.btnViewAccumulatedFilter.addActionListener((ActionEvent e) -> {
240
            showAccumulatedFilter();
241
        });
242
        this.btnRemoveAccumulatedFilter.setEnabled(false);
243
        this.btnViewAccumulatedFilter.setEnabled(false);
244
        this.btnAddAccumulatedFilter.setEnabled(true);
245
    }
246

    
247
    public void addToAccumulatedFilter(String filter) {
248
        if (StringUtils.isBlank(filter)) {
249
            return;
250
        }
251
        String theAccumulatedFilter = this.accumulatedFilter;
252
        this.clear();
253
        if (!StringUtils.isBlank(theAccumulatedFilter)) {
254
            filter = "( " + theAccumulatedFilter + ") AND \n( " + filter + ")";
255
        }
256
        this.btnAddAccumulatedFilter.setToolTipText("<html><b>" + this.baseToolTip + "</b><br><br>" + filter.replaceAll("\\n", "<br>") + "</html>");
257
        this.accumulatedFilter = filter;
258
        this.btnRemoveAccumulatedFilter.setEnabled(true);
259
        this.btnViewAccumulatedFilter.setEnabled(true);
260
        this.changeListenerHelper.fireEvent();
261
    }
262

    
263
    public void clearAccumulatedFilter() {
264
        this.accumulatedFilter = null;
265
        this.btnRemoveAccumulatedFilter.setEnabled(false);
266
        this.btnViewAccumulatedFilter.setEnabled(false);
267
        this.btnAddAccumulatedFilter.setToolTipText(this.baseToolTip);
268
        this.changeListenerHelper.fireEvent();
269
    }
270

    
271
    public void showAccumulatedFilter() {
272
        WindowManager_v2 winmanager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
273
        DataSwingManager manager = DALSwingLocator.getDataSwingManager();
274
        I18nManager i18n = ToolsLocator.getI18nManager();
275

    
276
        JExpressionBuilder panel = manager.createQueryFilterExpresion(store);
277
        panel.setExpression(ExpressionUtils.createExpression(this.getAccumulatedFilter()));
278
        Dialog dialog = winmanager.createDialog(
279
                panel.asJComponent(),
280
                i18n.getTranslation("_Expression_builder"),
281
                null,
282
                WindowManager_v2.BUTTONS_OK_CANCEL
283
        );
284
        dialog.addActionListener((ActionEvent e) -> {
285
            if (dialog.getAction() == WindowManager_v2.BUTTON_OK) {
286
                this.clearAccumulatedFilter();
287
                this.addToAccumulatedFilter(panel.getExpression().getPhrase());
288
            }
289
        });
290
        dialog.show(WindowManager.MODE.DIALOG);
291
    }
292

    
293
    @Override
294
    public void setEnabled(boolean enabled) {
295
        if (this.searchFieldsControllers == null) {
296
            initComponents();
297
        }
298
        int n = 0;
299
        for (SearchConditionFieldController searchField : searchFieldsControllers) {
300
            if (n < this.maxSearhFields) {
301
                searchField.setEnabled(enabled);
302
            } else {
303
                searchField.setEnabled(false);
304
            }
305
            n++;
306
        }
307
    }
308

    
309
    @Override
310
    public void clear() {
311
        if (this.searchFieldsControllers == null) {
312
            return;
313
        }
314
        for (SearchConditionFieldController searchField : searchFieldsControllers) {
315
            searchField.clear();
316
        }
317
        this.clearAccumulatedFilter();
318
    }
319

    
320
    @Override
321
    public Expression get() {
322
        String currentFilter = this.getCurrentFilter();
323
        if (StringUtils.isBlank(accumulatedFilter)) {
324
            if (StringUtils.isBlank(currentFilter)) {
325
                return null;
326
            }
327
            return ExpressionUtils.createExpression(currentFilter);
328
        }
329
        if (StringUtils.isBlank(currentFilter)) {
330
            return ExpressionUtils.createExpression(accumulatedFilter);
331
        }
332
        return ExpressionUtils.createExpression("( " + accumulatedFilter + " ) AND ( " + currentFilter + " )");
333
    }
334

    
335
    public String getAccumulatedFilter() {
336
        return this.accumulatedFilter;
337
    }
338

    
339
    public String getCurrentFilter() {
340
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
341
        String relational = OPERATOR_OR;
342
        for (SearchConditionFieldController searchField : searchFieldsControllers) {
343
            ExpressionBuilder.Value cond = searchField.getFilter();
344
            if (cond != null) {
345
                if (relational.equals(OPERATOR_AND)) {
346
                    builder.and(cond);
347
                } else {
348
                    builder.or(cond);
349
                }
350
                relational = searchField.getLogicalOperator();
351
            }
352
        }
353
        if (builder.isEmpty()) {
354
            return null;
355
        }
356
        return builder.toString();
357
    }
358

    
359
    public JsonObject toJson() {
360
        JsonObjectBuilder builder = Json.createObjectBuilder();
361

    
362
        int i = 0;
363
        for (SearchConditionFieldController searchField : searchFieldsControllers) {
364
            JsonObject jsonState = searchField.toJson();
365
            String name = DataTypeUtils.toString(i);
366
            builder.add(name, jsonState);
367
            i++;
368
        }
369

    
370
        JsonObject jsonBuild = builder.build();
371
        return jsonBuild;
372
    }
373

    
374
    public void fromJson(JsonObject json) {
375
        if (json==null) {
376
            return;
377
        }
378
        int i = 0;
379
        for (SearchConditionFieldController searchFieldController : searchFieldsControllers) {
380
            String index = DataTypeUtils.toString(i);
381
            JsonObject jsonField = json.getJsonObject(index);
382
            searchFieldController.fromJson(jsonField);
383
            i++;
384
        }
385
    }
386

    
387
    @Override
388
    public boolean set(Expression filter) {
389
        try {
390
            Code code = filter.getCode();
391
            if (code.code() == Code.CALLABLE) {
392
                SearchConditionFieldController searchField = this.searchFieldsControllers.get(0);
393
                Code.Callable caller = (Code.Callable) code;
394
                if (searchField.isAValidRelationOperator(caller.name())) {
395
                    Code op1 = caller.parameters().get(0);
396
                    Code op2 = caller.parameters().get(1);
397
                    if (op1.code() == Code.IDENTIFIER && op2.code() == Code.CONSTANT) {
398
                        if (searchField.setAttribute(((Code.Identifier) op1).name()) >= 0) {
399
                            searchField.setRelationalOperator(caller.name());
400
                            searchField.setValue(((Code.Constant) op2).value());
401
                            return true;
402
                        }
403
                    }
404
                }
405
            }
406
            return false;
407
        } finally {
408
            this.changeListenerHelper.fireEvent();
409
        }
410
    }
411

    
412
    @Override
413
    public void addChangeListener(ChangeListener listener) {
414
        this.changeListenerHelper.addChangeListener(listener);
415
    }
416

    
417
    @Override
418
    public ChangeListener[] getChangeListeners() {
419
        return this.changeListenerHelper.getChangeListeners();
420
    }
421

    
422
    @Override
423
    public void removeChangeListener(ChangeListener listener) {
424
        this.changeListenerHelper.removeChangeListener(listener);
425
    }
426

    
427
    @Override
428
    public void removeAllChangeListener() {
429
        this.changeListenerHelper.removeAllChangeListener();
430
    }
431

    
432
    @Override
433
    public boolean hasChangeListeners() {
434
        return this.changeListenerHelper.hasChangeListeners();
435
    }
436
}