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 / SearchConditionFieldController.java @ 46517

History | View | Annotate | Download (53 KB)

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

    
3
import java.awt.Cursor;
4
import java.awt.event.ActionEvent;
5
import java.awt.event.ItemEvent;
6
import java.awt.event.ItemListener;
7
import java.awt.event.MouseAdapter;
8
import java.awt.event.MouseEvent;
9
import java.text.DateFormat;
10
import java.util.ArrayList;
11
import java.util.Arrays;
12
import java.util.Date;
13
import java.util.HashMap;
14
import java.util.List;
15
import java.util.Locale;
16
import java.util.Map;
17
import java.util.Objects;
18
import javax.json.Json;
19
import javax.json.JsonArray;
20
import javax.json.JsonArrayBuilder;
21
import javax.json.JsonObject;
22
import javax.json.JsonObjectBuilder;
23
import javax.swing.ComboBoxModel;
24
import javax.swing.DefaultComboBoxModel;
25
import javax.swing.ImageIcon;
26
import javax.swing.JComboBox;
27
import javax.swing.JLabel;
28
import javax.swing.JOptionPane;
29
import javax.swing.SwingUtilities;
30
import javax.swing.text.JTextComponent;
31
import org.apache.commons.lang3.StringUtils;
32
import org.gvsig.expressionevaluator.ExpressionBuilder;
33
import org.gvsig.fmap.dal.DALLocator;
34
import org.gvsig.fmap.dal.DataManager;
35
import org.gvsig.fmap.dal.DataStore;
36
import org.gvsig.fmap.dal.SQLBuilder;
37
import org.gvsig.fmap.dal.complements.Search;
38
import org.gvsig.fmap.dal.exception.DataException;
39
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
40
import org.gvsig.fmap.dal.feature.Feature;
41
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
42
import org.gvsig.fmap.dal.feature.FeatureQuery;
43
import org.gvsig.fmap.dal.feature.FeatureSet;
44
import org.gvsig.fmap.dal.feature.FeatureStore;
45
import org.gvsig.fmap.dal.feature.FeatureType;
46
import org.gvsig.fmap.dal.feature.ForeingKey;
47
import org.gvsig.fmap.dal.swing.DALSwingLocator;
48
import org.gvsig.fmap.dal.swing.impl.featuretype.DefaultFeatureAttributeSelectionPanel;
49
import static org.gvsig.fmap.dal.swing.impl.searchpanel.SearchConditionPanelSimplified.PANEL_NAME;
50
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NOT_HANDLE_NULL;
51
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NULL_AS_FALSE;
52
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NULL_AS_TRUE;
53
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
54
import org.gvsig.tools.ToolsLocator;
55
import org.gvsig.tools.dataTypes.Coercion;
56
import org.gvsig.tools.dataTypes.CoercionException;
57
import org.gvsig.tools.dataTypes.DataTypeUtils;
58
import org.gvsig.tools.dataTypes.DataTypes;
59
import org.gvsig.tools.dispose.DisposeUtils;
60
import org.gvsig.tools.dynobject.DynField;
61
import org.gvsig.tools.exception.BaseException;
62
import org.gvsig.tools.i18n.I18nManager;
63
import org.gvsig.tools.swing.api.DropDown;
64
import org.gvsig.tools.swing.api.ToolsSwingLocator;
65
import org.gvsig.tools.swing.api.ToolsSwingManager;
66
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
67
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
68
import org.gvsig.tools.swing.api.windowmanager.Dialog;
69
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
70
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
71
import org.gvsig.tools.swing.icontheme.IconTheme;
72
import org.gvsig.tools.util.LabeledValue;
73
import org.gvsig.tools.util.LabeledValueImpl;
74
import org.gvsig.tools.visitor.VisitCanceledException;
75
import org.gvsig.tools.visitor.Visitor;
76
import org.slf4j.Logger;
77
import org.slf4j.LoggerFactory;
78

    
79
/**
80
 *
81
 * @author jjdelcerro
82
 */
83
@SuppressWarnings("UseSpecificCatch")
84
public class SearchConditionFieldController {
85

    
86
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchConditionFieldController.class);
87
    private static final Class LOAD_MORE_ELEMENTS = SearchConditionFieldController.class;
88

    
89
    private static final int MAXLEN_IN_COMBOS = 70;
90
    
91
    private static class Field extends LabeledValueImpl<String> {
92

    
93
        FeatureAttributeDescriptor attrdesc;
94
        private final FeatureStore store;
95
        private final int presentationMode;
96
        private final boolean showStoreName;
97
        private final FeatureAttributeDescriptor[] path;
98

    
99
        public Field(FeatureAttributeDescriptor[] path, FeatureStore store, FeatureAttributeDescriptor attrdesc, int presentationMode) {
100
            this(path, store, attrdesc, presentationMode, false);
101
        }
102

    
103
        public Field(
104
                FeatureAttributeDescriptor[] path,
105
                FeatureStore store,
106
                FeatureAttributeDescriptor attrdesc,
107
                int presentationMode,
108
                boolean showStoreName
109
        ) {
110
            super(
111
                    DALSwingLocator.getDataSwingManager().getAttributeDescriptorLabel(attrdesc, store.getName()),
112
                    attrdesc.getName()
113
            );
114
            this.path = path;
115
            this.store = store;
116
            this.attrdesc = attrdesc;
117
            this.presentationMode = presentationMode;
118
            this.showStoreName = showStoreName;
119
        }
120

    
121
        public FeatureAttributeDescriptor[] getPath() {
122
            return this.path;
123
        }
124

    
125
        @Override
126
        public String getLabel() {
127
            String theLabel = DALSwingLocator.getDataSwingManager().getAttributeDescriptorLabel(attrdesc, showStoreName ? store.getName() : null);
128
            switch (this.presentationMode) {
129
                case Search.OrderedAttribute.TYPE_REGURAL:
130
                    break;
131
                case Search.OrderedAttribute.TYPE_FAVORITE:
132
                    theLabel = "<html><b>" + theLabel + "</b></html>";
133
                    break;
134
                case Search.OrderedAttribute.TYPE_RECENT:
135
                    theLabel = "<html><i><b>" + theLabel + "</b></i></html>";
136
                    break;
137
            }
138
            return theLabel;
139
        }
140

    
141
        public FeatureAttributeDescriptor getParentDescriptor() {
142
            int l = this.path.length;
143
            if (l < 2) {
144
                return null;
145
            }
146
            return this.path[l - 2];
147
        }
148

    
149
        public FeatureAttributeDescriptor getDescriptor() {
150
            return this.attrdesc;
151
        }
152

    
153
        public FeatureStore getFeatureStore() {
154
            return this.store;
155
        }
156

    
157
    }
158

    
159
    private FeatureStore store;
160
    private SearchParameters parameters;
161
    private final JLabel lblFields;
162
    private final JLabel lblExtraFields;
163
    private final JLabel lblLogicalOperators;
164
    private final JLabel lblRelationalOperators;
165
    private final JComboBox cboValue;
166
    private final JLabel lblNull;
167
    private Object valueAssigned = null;
168

    
169
    private DropDown ddnFields;
170
    private DropDown ddnLogicalOperators;
171
    private DropDown ddnRelationalOperators;
172
    private DropDown ddnNullBehavior;
173

    
174
    private LabeledValue[] relationalOperators;
175
    private LabeledValue[] logicalOperators;
176
    private LabeledValue[] nullBehaviors;
177
    private ArrayList<ImageIcon> nullOperatorsIcons;
178

    
179
    private final int SIZE_ORDERED_ATTRIBUTES = 20;
180
    private DatePickerController dateController = null;
181

    
182
    private int updateValuesTimeLimit;
183
    private int updateValuesFeaturesLimit;
184
    private boolean canHasMoreElements;
185

    
186
    public SearchConditionFieldController(
187
            SearchParameters parameters,
188
            FeatureStore store,
189
            JLabel lblFields,
190
            JLabel lblExtraFields,
191
            JLabel lblRelationalOperators,
192
            JComboBox cboValue,
193
            JLabel lblNull,
194
            JLabel lblLogicalOperators
195
    ) {
196
        this.parameters = parameters;
197
        this.store = store;
198
        this.lblFields = lblFields;
199
        this.lblExtraFields = lblExtraFields;
200
        this.lblRelationalOperators = lblRelationalOperators;
201
        this.cboValue = cboValue;
202
        this.lblNull = lblNull;
203
        this.lblLogicalOperators = lblLogicalOperators;
204
        this.updateValuesTimeLimit = 60;
205
        this.updateValuesFeaturesLimit = 1000;
206
        this.canHasMoreElements = false;
207
        this.initComponents();
208
    }
209

    
210
    public boolean isAValidRelationOperator(String name) {
211
        for (LabeledValue relationalOperator : relationalOperators) {
212
            if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
213
                return true;
214
            }
215
        }
216
        return false;
217
    }
218

    
219
    private void initComponents() {
220
        try {
221
            I18nManager i18n = ToolsLocator.getI18nManager();
222
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
223

    
224
            relationalOperators = new LabeledValue[]{
225
                new LabeledValueImpl(i18n.getTranslation("_Equals_to"), ExpressionBuilder.OPERATOR_EQ),
226
                new LabeledValueImpl(i18n.getTranslation("_Like_to"), ExpressionBuilder.OPERATOR_ILIKE),
227
                new LabeledValueImpl(i18n.getTranslation("_Not_equals_to"), ExpressionBuilder.OPERATOR_NE),
228
                new LabeledValueImpl(i18n.getTranslation("_Greater_than"), ExpressionBuilder.OPERATOR_GT),
229
                new LabeledValueImpl(i18n.getTranslation("_Greater_or_equal_to"), ExpressionBuilder.OPERATOR_GE),
230
                new LabeledValueImpl(i18n.getTranslation("_Less_than"), ExpressionBuilder.OPERATOR_LT),
231
                new LabeledValueImpl(i18n.getTranslation("_Less_or_equal_to"), ExpressionBuilder.OPERATOR_LE),
232
                new LabeledValueImpl(i18n.getTranslation("_Is_null"), ExpressionBuilder.OPERATOR_IS_NULL),
233
                new LabeledValueImpl(i18n.getTranslation("_Is_not_null"), ExpressionBuilder.OPERATOR_IS_NOT_NULL)
234
            };
235

    
236
            logicalOperators = new LabeledValue[]{
237
                new LabeledValueImpl(i18n.getTranslation("_Or"), ExpressionBuilder.OPERATOR_OR),
238
                new LabeledValueImpl(i18n.getTranslation("_And"), ExpressionBuilder.OPERATOR_AND)
239
            };
240

    
241
            nullBehaviors = new LabeledValue[]{
242
                new LabeledValueImpl(i18n.getTranslation("_Not_handle_null_values"), NOT_HANDLE_NULL),
243
                new LabeledValueImpl(i18n.getTranslation("_Null_values_as_true"), NULL_AS_TRUE),
244
                new LabeledValueImpl(i18n.getTranslation("_Null_values_as_false"), NULL_AS_FALSE)
245
            };
246

    
247
            nullOperatorsIcons = new ArrayList<ImageIcon>();
248
            nullOperatorsIcons.add(ToolsSwingLocator.getIconThemeManager().getCurrent().get("search-nullbehavior-null"));
249
            nullOperatorsIcons.add(ToolsSwingLocator.getIconThemeManager().getCurrent().get("search-nullbehavior-true"));
250
            nullOperatorsIcons.add(ToolsSwingLocator.getIconThemeManager().getCurrent().get("search-nullbehavior-false2"));
251

    
252
            this.lblExtraFields.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
253

    
254
            this.ddnFields = toolsSwingManager.createDropDown(lblFields);
255
            this.ddnFields.setVisibleDropdownArrow(false);
256
            this.ddnRelationalOperators = toolsSwingManager.createDropDown(lblRelationalOperators);
257
            this.ddnRelationalOperators.setVisibleDropdownArrow(false);
258
            if (lblLogicalOperators != null) {
259
                this.ddnLogicalOperators = toolsSwingManager.createDropDown(lblLogicalOperators);
260
                this.ddnLogicalOperators.setVisibleDropdownArrow(false);
261
            }
262

    
263
            DefaultComboBoxModel modelRelationalOperators = new DefaultComboBoxModel();
264
            for (LabeledValue op : relationalOperators) {
265
                modelRelationalOperators.addElement(op);
266
            }
267
            this.ddnRelationalOperators.setModel(modelRelationalOperators);
268
            this.ddnRelationalOperators.addItemListener(new ItemListener() {
269
                @Override
270
                public void itemStateChanged(ItemEvent ie) {
271
                    doUpdateControllerByRelationalOperator();
272
                }
273
            });
274

    
275
            if (this.ddnLogicalOperators != null) {
276
                DefaultComboBoxModel modelLogicalOperators = new DefaultComboBoxModel();
277
                for (LabeledValue op : logicalOperators) {
278
                    modelLogicalOperators.addElement(op);
279
                }
280
                this.ddnLogicalOperators.setModel(modelLogicalOperators);
281
                this.ddnLogicalOperators.setSelectedIndex(1);
282
            }
283

    
284
//            this.ddnNullOperators = new DropDownLabelIcon(lblNull);
285
            this.ddnNullBehavior = toolsSwingManager.createDropDownIcon(lblNull);
286
            this.ddnNullBehavior.setVisibleDropdownArrow(false);
287
            DefaultComboBoxModel modelNullOperators = new DefaultComboBoxModel();
288
            for (LabeledValue op : nullBehaviors) {
289
                modelNullOperators.addElement(op);
290
            }
291
            this.ddnNullBehavior.setModel(modelNullOperators);
292
            this.ddnNullBehavior.setIcons(nullOperatorsIcons);
293
            this.ddnNullBehavior.setSelectedIndex(0);
294
            FeatureType featureType = parameters.getFeatureType(store);
295
            Search search = (Search) ToolsLocator.getComplementsManager().get(
296
                    Search.COMPLEMENT_MANE, featureType
297
            );
298
            List<Search.OrderedAttribute> orderedAttributes = search.getOrderedAttributes(
299
                    Search.BASIC_TYPES_FILTER,
300
                    Search.STR_INT_LONG_LABEL_ORDER,
301
                    SIZE_ORDERED_ATTRIBUTES
302
            );
303
            List<ImageIcon> icons = new ArrayList<>();
304
//            DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
305
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
306
            DefaultComboBoxModel model = new DefaultComboBoxModel();
307
            for (Search.OrderedAttribute attr : orderedAttributes) {
308
                FeatureAttributeDescriptor attrdesc = attr.getDescriptor();
309
                Field field = new Field(
310
                        new FeatureAttributeDescriptor[]{attrdesc},
311
                        this.store,
312
                        attrdesc,
313
                        attr.getType()
314
                );
315
                model.addElement(field);
316
                String iconName = attrdesc.getDataType().getIconName();
317
                if (iconTheme.exists(iconName)) {
318
                    icons.add(iconTheme.get(iconName));
319
                } else {
320
                    icons.add(null);
321
                }
322
            }
323

    
324
            this.ddnFields.setIcons(icons);
325
            this.ddnFields.setModel(model);
326
            this.ddnFields.addItemListener(new ItemListener() {
327
                @Override
328
                public void itemStateChanged(ItemEvent e) {
329
                    if (e.getStateChange() == ItemEvent.SELECTED) {
330
                        doUpdateValuesList();
331
                    }
332

    
333
                }
334
            });
335

    
336
            this.cboValue.addItemListener(new ItemListener() {
337
                @Override
338
                public void itemStateChanged(ItemEvent e) {
339
                    if (e.getStateChange() == ItemEvent.SELECTED) {
340
                        if (cboValue.getSelectedItem() != null && cboValue.getSelectedItem() instanceof LabeledValue) {
341
                            if (Objects.equals(((LabeledValue) cboValue.getSelectedItem()).getValue(), LOAD_MORE_ELEMENTS)) {
342
                                setUpdateValuesLimits(updateValuesTimeLimit + 10, updateValuesFeaturesLimit + 20000);
343
                            }
344
                        }
345
                    }
346
                }
347
            });
348

    
349
            this.lblExtraFields.addMouseListener(new MouseAdapter() {
350
                @Override
351
                public void mouseClicked(MouseEvent e) {
352
                    doSelectMoreFields();
353
                }
354
            });
355
            doUpdateControllerByRelationalOperator();
356
//      clear();
357
        } catch (Exception ex) {
358
            throw new RuntimeException(ex);
359
        }
360
    }
361

    
362
    private void doUpdateControllerByRelationalOperator() {
363
        Object item = ((LabeledValue) ddnRelationalOperators.getSelectedItem()).getValue();
364
        if (ExpressionBuilder.OPERATOR_IS_NULL.equals(item) || ExpressionBuilder.OPERATOR_IS_NOT_NULL.equals(item)) {
365
            lblNull.setEnabled(false);
366
            cboValue.setEnabled(false);
367
            cboValue.setSelectedIndex(-1);
368
        } else {
369
            lblNull.setEnabled(true);
370
            cboValue.setEnabled(true);
371
        }
372

    
373
    }
374

    
375
    private FeatureType getFeatureType() {
376
        try {
377
            return this.store.getDefaultFeatureType();
378
        } catch (DataException ex) {
379
            return null;
380
        }
381
    }
382

    
383
    private void doSelectMoreFields() {
384
        DefaultFeatureAttributeSelectionPanel panel = new DefaultFeatureAttributeSelectionPanel(
385
                store, 
386
                parameters.getFeatureType(store),
387
                parameters.getQuery()
388
        );
389
        WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
390
        final Dialog dialog = winManager.createDialog(
391
                panel,
392
                "Select attribute",
393
                null,
394
                WindowManager_v2.BUTTONS_OK_CANCEL
395
        );
396
        dialog.addActionListener((ActionEvent e) -> {
397
            if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
398
                doAddAndSelect(
399
                        panel.getSelectedStore(),
400
                        panel.getSelectedAttributeDescriptor(),
401
                        panel.getSelectedPath()
402
                );
403
            }
404
        });
405
        dialog.show(WindowManager.MODE.DIALOG);
406

    
407
    }
408

    
409
    private void doAddAndSelect(FeatureStore theStore, FeatureAttributeDescriptor attrdesc, FeatureAttributeDescriptor[] path) {
410
        ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
411
        I18nManager i18n = ToolsLocator.getI18nManager();
412
        DefaultComboBoxModel<Field> model = (DefaultComboBoxModel) this.ddnFields.getModel();
413
        if (attrdesc == null) {
414
            dialogManager.messageDialog(
415
                    i18n.getTranslation("_It_is_not_supported_to_search_through_this_field") + "\n"
416
                    + i18n.getTranslation("_Field_not_found"),
417
                    "_Warning",
418
                    JOptionPane.WARNING_MESSAGE
419
            );
420
            return;
421
        }
422

    
423
        for (int i = 0; i < model.getSize(); i++) {
424
            Field field = model.getElementAt(i);
425
            FeatureAttributeDescriptor attrdescN = field.getDescriptor();
426
            if (theStore!=null && attrdescN.getStore()!=null && isTheSameStore(theStore, attrdescN.getStore())
427
                    && StringUtils.equalsIgnoreCase(attrdesc.getName(), attrdescN.getName())) {
428
                this.setAttribute(i);
429
                return;
430
            }
431
        }
432
        Field field = new Field(
433
                path,
434
                theStore,
435
                attrdesc,
436
                Search.OrderedAttribute.TYPE_REGURAL,
437
                !isTheSameStore(store, theStore)
438
        );
439
        if (field.getPath().length > 2) {
440
            dialogManager.messageDialog(
441
                    i18n.getTranslation("_It_is_not_supported_to_search_through_this_field") + "\n"
442
                    + i18n.getTranslation("_To_many_links"),
443
                    "_Warning",
444
                    JOptionPane.WARNING_MESSAGE
445
            );
446
            return;
447
        }
448
        FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
449
        if (parentDescriptor != null) {
450
            switch (parentDescriptor.getRelationType()) {
451
                case DynField.RELATION_TYPE_AGGREGATE:
452
                case DynField.RELATION_TYPE_COMPOSITION:
453
                    if (getForeingKeyName(field.getFeatureStore(), this.store) == null) {
454
                        dialogManager.messageDialog(
455
                                "It not supported to search through this field." + "\n"
456
                                + "The link field was not found.",
457
                                "_Warning",
458
                                JOptionPane.WARNING_MESSAGE
459
                        );
460
                        return;
461
                    }
462
                    if (getPrimaryKeyName(this.store) == null) {
463
                        dialogManager.messageDialog(
464
                                "It not supported to search through this field." + "\n"
465
                                + "A simple primary key was not found.",
466
                                "_Warning",
467
                                JOptionPane.WARNING_MESSAGE
468
                        );
469
                        return;
470
                    }
471
            }
472
        }
473
        model.addElement(field);
474
        IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
475
        this.ddnFields.getIcons().add(iconTheme.get(attrdesc.getDataType().getIconName()));
476
        this.setAttribute(model.getSize() - 1);
477
    }
478

    
479
    public void clear() {
480
        this.ddnRelationalOperators.setSelectedIndex(0);
481
        if (this.ddnLogicalOperators != null) {
482
            this.ddnLogicalOperators.setSelectedIndex(1);
483
        }
484
        this.cboValue.setSelectedIndex(-1);
485
        this.ddnNullBehavior.setSelectedIndex(0);
486
        doUpdateControllerByRelationalOperator();
487
    }
488

    
489
    private String lastNameInUpdateValuesList = null;
490
    private int lastUpdateValuesFeaturesLimit = -1;
491
    private int lastUpdateValuesTimeLimit = -1;
492
    
493
    private void doUpdateValuesList() {
494
        final Field field = (Field) this.ddnFields.getSelectedItem();
495
        if (field == null) {
496
            return;
497
        }
498
        FeatureAttributeDescriptor descriptor = field.getDescriptor();
499
        if(StringUtils.equalsIgnoreCase(lastNameInUpdateValuesList, descriptor.getName()) && 
500
                updateValuesFeaturesLimit == lastUpdateValuesFeaturesLimit && 
501
                updateValuesTimeLimit == lastUpdateValuesTimeLimit
502
                ){
503
            return;
504
        }
505
        lastNameInUpdateValuesList = descriptor.getName();
506
        lastUpdateValuesFeaturesLimit = updateValuesFeaturesLimit;
507
        lastUpdateValuesTimeLimit = updateValuesTimeLimit;
508
        
509
        if (descriptor.getType() == DataTypes.DATE) {
510
            if (this.dateController == null) {
511
                this.dateController = ToolsSwingLocator.getToolsSwingManager().createDatePickerController(
512
                        (JTextComponent) this.cboValue.getEditor().getEditorComponent(),
513
                        null
514
                );
515
            }
516
        } else {
517
            if (this.dateController != null) {
518
                this.dateController.uninstall();
519
                this.dateController = null;
520
            }
521
        }
522

    
523
        final List<Object> values = new ArrayList<>();
524
        final DefaultComboBoxModel model = new DefaultComboBoxModel();
525
        final FeatureStore theStore = field.getFeatureStore();
526
        final FeatureQuery query;
527
        query = theStore.createFeatureQuery();
528
        query.addAttributeName(field.getDescriptor().getName());
529
        query.setFilter("");
530
        query.setLimit(updateValuesFeaturesLimit);
531
        query.getGroupByColumns().clear();
532
        query.getAggregateFunctions().clear();
533
        Thread th = new Thread(new Runnable() {
534
            @Override
535
            public void run() {
536
                FeatureSet set = null;
537
                try {
538
                    canHasMoreElements = false;
539
                    set = theStore.getFeatureSet(query);
540
                    if (set.size() >= updateValuesFeaturesLimit) {
541
                        canHasMoreElements = true;
542
                    }
543
                    final long timeLimit = System.currentTimeMillis() + updateValuesTimeLimit * 1000;
544
                    set.accept(new Visitor() {
545
                        @Override
546
                        public void visit(Object o) throws VisitCanceledException, BaseException {
547
                            Object value = ((Feature) o).get(field.getDescriptor().getName());
548
                            if (value!=null && !values.contains(value)) {
549
                                values.add(value);
550
                            }
551
                            if (System.currentTimeMillis() > timeLimit) {
552
                                canHasMoreElements = true;
553
                                throw new VisitCanceledException();
554
                            }
555
                            if (values.size() > 1000) {
556
                                canHasMoreElements = true;
557
                                throw new VisitCanceledException();
558
                            }
559
                        }
560
                    });
561
                } catch (VisitCanceledException ex) {
562
                    canHasMoreElements = true;
563
                } catch (Exception ex) {
564
                    LOGGER.warn("Can't update list of values of '" + field.getLabel() + "'.", ex);
565
                } finally {
566
                    DisposeUtils.disposeQuietly(set);
567
                }
568
                List<LabeledValue> elements = new ArrayList<>();
569
                if (!values.isEmpty()) {
570
                    LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
571
                    Map<String, String> availableValuesMap = new HashMap<>();
572
                    if (availableValues != null) {
573
                        for (LabeledValue availableValue : availableValues) {
574
                            availableValuesMap.put(
575
                                    Objects.toString(availableValue.getValue()),
576
                                    availableValue.getLabel()
577
                            );
578
                        }
579
                    }
580
                    elements.add(new LabeledValueImpl("", null, MAXLEN_IN_COMBOS));
581
                    for (Object value : values) {
582
                        String key;
583
                        key = DataTypeUtils.toString(value);
584
                        String label = availableValuesMap.getOrDefault(key, key);
585
                        elements.add(new LabeledValueImpl(label, value, MAXLEN_IN_COMBOS));
586
                    }
587
                    elements.sort(null);
588

    
589
                }
590
                for (LabeledValue element : elements) {
591
                    model.addElement(element);
592
                }
593
                if (canHasMoreElements) {
594
                    model.addElement(new LabeledValueImpl("...", LOAD_MORE_ELEMENTS));
595
                }
596
                SwingUtilities.invokeLater(new Runnable() {
597
                    @Override
598
                    public void run() {
599
                        setEnabled(false);
600
                        cboValue.setModel(model);
601
                        if (valueAssigned != null) {
602
                            cboValue.setSelectedItem(valueAssigned);
603
                            valueAssigned = null;
604
                        }
605
                        setEnabled(true);
606
                    }
607
                });
608
            }
609
        });
610
        th.start();
611
    }
612

    
613
    public void setEnabled(boolean enabled) {
614
        ddnFields.setEnabled(enabled);
615
        if (ddnLogicalOperators != null) {
616
            ddnLogicalOperators.setEnabled(enabled);
617
        }
618
        ddnRelationalOperators.setEnabled(enabled);
619
        lblExtraFields.setEnabled(enabled);
620
        cboValue.setEnabled(enabled);
621
        doUpdateControllerByRelationalOperator();
622
    }
623

    
624
    public String getRelationalOperator() {
625
        LabeledValue<String> op = (LabeledValue) this.ddnRelationalOperators.getSelectedItem();
626
        if (op == null) {
627
            return null;
628
        }
629
        return op.getValue();
630
    }
631

    
632
    public int setRelationalOperator(String name) {
633
        int n = 0;
634
        for (LabeledValue relationalOperator : relationalOperators) {
635
            if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
636
                break;
637
            }
638
            n++;
639
        }
640
        if (this.relationalOperators.length <= n) {
641
            return -1;
642
        }
643
        this.ddnRelationalOperators.setSelectedIndex(n);
644
        doUpdateControllerByRelationalOperator();
645
        return n;
646
    }
647

    
648
    public String getLogicalOperator() {
649
        if (this.ddnLogicalOperators == null) {
650
            return null;
651
        }
652
        LabeledValue<String> rel = (LabeledValue) this.ddnLogicalOperators.getSelectedItem();
653
        if (rel == null) {
654
            return null;
655
        }
656
        return rel.getValue();
657
    }
658

    
659
    public void setLogicalOperator(String operator) {
660
        if (this.ddnLogicalOperators == null) {
661
            return;
662
        }
663
        ComboBoxModel model = this.ddnLogicalOperators.getModel();
664
        for (int i = 0; i < model.getSize(); i++) {
665
            LabeledValue modelValue = (LabeledValue) model.getElementAt(i);
666
            String value = (String) modelValue.getValue();
667
            if (StringUtils.equals(value, operator)) {
668
                this.ddnLogicalOperators.setSelectedIndex(i);
669
                break;
670
            }
671
        }
672
    }
673

    
674
    public Object getValue() {
675
        final Field field = (Field) this.ddnFields.getSelectedItem();
676
        if (field == null) {
677
            return null;
678
        }
679
        Object v;
680
        if (this.dateController == null) {
681
            v = this.cboValue.getSelectedItem();
682
        } else {
683
            v = this.dateController.get();
684
        }
685
        if (v == null) {
686
            return null;
687
        }
688
        if (v instanceof LabeledValue) {
689
            v = ((LabeledValue) v).getValue();
690
            if (v == null || v == LOAD_MORE_ELEMENTS) {
691
                return null;
692
            }
693
        }
694
        if (v instanceof CharSequence) {
695
            if (StringUtils.isBlank((CharSequence) v)) {
696
                return null;
697
            }
698
        }
699
        Coercion coercion = field.getDescriptor().getDataType().getCoercion();
700
        try {
701
            return coercion.coerce(v);
702
        } catch (CoercionException ex) {
703
            return null;
704
        }
705
    }
706

    
707
    public void setValue(Object value) {
708
        //this.cboValue.setSelectedItem(value);
709
        SwingUtilities.invokeLater(new Runnable() {
710
            @Override
711
            public void run() {
712
                DefaultComboBoxModel model = (DefaultComboBoxModel) cboValue.getModel();
713
                for (int i = 0; i < model.getSize(); i++) {
714
                    Object item = model.getElementAt(i);
715
                    if (item.equals(value)) {
716
                        cboValue.setSelectedIndex(i);
717
                        valueAssigned = value;
718
                        return;
719
                    }
720
                }
721
                // si no lo encuentra en el modelo lo a?ade
722
                final Field field = (Field) ddnFields.getSelectedItem();
723
                if (field == null) {
724
                    return;
725
                } else {
726
                    LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
727
                    Map<String, String> availableValuesMap = new HashMap<>();
728
                    if (availableValues != null) {
729
                        for (LabeledValue availableValue : availableValues) {
730
                            availableValuesMap.put(
731
                                    Objects.toString(availableValue.getValue()),
732
                                    availableValue.getLabel()
733
                            );
734
                        }
735
                    }
736
                    String key;
737
                    if (value instanceof Date) {
738
                        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
739
                        df.setLenient(false);
740
                        key = df.format(value);
741
                    } else {
742
                        key = Objects.toString(value);
743
                    }
744
                    String label = availableValuesMap.getOrDefault(key, key);
745
                    LabeledValueImpl newItem = new LabeledValueImpl(label, value);
746
                    model.addElement(newItem);
747
                    cboValue.setSelectedItem(newItem);
748
                    valueAssigned = newItem;
749
                }
750
            }
751
        });
752
    }
753

    
754
    private Field getCurrentField() {
755
        final Field field = (Field) this.ddnFields.getSelectedItem();
756
        return field;
757
    }
758

    
759
    public int setAttribute(String name) {
760
        ComboBoxModel<Field> model = this.ddnFields.getModel();
761
        for (int i = 0; i < model.getSize(); i++) {
762
            Field x = model.getElementAt(i);
763
            if (StringUtils.equalsIgnoreCase(name, x.getValue())) {
764
                this.setAttribute(i);
765
                return i;
766
            }
767
        }
768
        this.setAttribute(-1);
769
        return -1;
770
    }
771

    
772
    public void setAttribute(int index) {
773
        try {
774
            this.ddnFields.setSelectedIndex(index);
775
        } catch (Exception ex) {
776
            this.ddnFields.setSelectedIndex(-1);
777
        }
778
        doUpdateValuesList();
779
    }
780

    
781
    public int setAttributePath(String[][] pathNames) {
782
        // [[attributeName, storeName],...]
783
        try {
784
            if (pathNames.length == 1) {
785
                String[] path = pathNames[pathNames.length - 1];
786
                String name = path[0];
787
                int index = this.setAttribute(name);
788
                if (index == -1) {
789
                    try {
790
                        FeatureAttributeDescriptor attrDescriptor = store.getDefaultFeatureType().getAttributeDescriptor(name);
791
                        FeatureAttributeDescriptor[] attributePath = new FeatureAttributeDescriptor[]{attrDescriptor};
792
                        if (attrDescriptor == null) {
793
                            I18nManager i18n = ToolsLocator.getI18nManager();
794
                            ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
795
                            dialogManager.messageDialog(
796
                                    i18n.getTranslation("_It_is_not_supported_to_search_through_this_field") + ":\n " + name + "\n"
797
                                    + i18n.getTranslation("_Field_not_found_in_this_table"),
798
                                    "_Warning",
799
                                    JOptionPane.WARNING_MESSAGE
800
                            );
801
                            this.cboValue.setModel(new DefaultComboBoxModel());
802
                        } else {
803
                            doAddAndSelect(store, store.getDefaultFeatureType().getAttributeDescriptor(name), attributePath);
804
                        }
805
                    } catch (Exception ex) {
806
                        LOGGER.warn("Not able to set single path into controller", ex);
807
                        return -1;
808
                    }
809
                }
810
                return index;
811
            } else {
812
                ComboBoxModel<Field> model = this.ddnFields.getModel();
813
                String[] singleArrayPathNameDescriptors = new String[pathNames.length];
814
                for (int i = 0; i < pathNames.length; i++) {
815
                    singleArrayPathNameDescriptors[i] = pathNames[i][0];
816
                }
817
                // check the drop
818
                for (int i = 0; i < model.getSize(); i++) {
819
                    Field x = model.getElementAt(i);
820
                    String[] arrayDescriptors = new String[x.getPath().length];
821
                    FeatureAttributeDescriptor[] path = x.getPath();
822
                    for (int j = 0; j < path.length; j++) {
823
                        arrayDescriptors[j] = path[j].getName();
824
                    }
825
                    if (Arrays.equals(singleArrayPathNameDescriptors, arrayDescriptors)) {
826
                        this.setAttribute(i);
827
                        return i;
828
                    }
829
                }
830
                // if not, addit to the drop
831
                DataManager dataManager = DALLocator.getDataManager();
832
                String tableName = pathNames[pathNames.length - 1][1]; // del ultimo path, coger el nombre tabla
833
                FeatureStore theStore = (FeatureStore) dataManager.getStoresRepository().getStore(tableName);
834
                String attributeName = pathNames[pathNames.length - 1][0]; // del ultimo path, coger el nombre attribute
835
                if (theStore != null) {
836
                    FeatureAttributeDescriptor attr;
837
                    try {
838
                        attr = theStore.getDefaultFeatureType().getAttributeDescriptor(attributeName);
839
                        FeatureAttributeDescriptor[] attributePath = new FeatureAttributeDescriptor[2];
840
                        String firstAttrName = pathNames[0][0];
841
                        FeatureAttributeDescriptor firstAttr = store.getDefaultFeatureType().getAttributeDescriptor(firstAttrName);
842
                        attributePath[0] = firstAttr;
843

    
844
                        attributePath[1] = attr;
845
                        doAddAndSelect(theStore, attr, attributePath);
846
                        return SIZE_ORDERED_ATTRIBUTES - 1;
847
                    } catch (Exception ex) {
848
                        LOGGER.warn("Not able to set foreign path into controller", ex);
849
                    }
850

    
851
                }
852

    
853
            }
854
        } catch (Exception ex) {
855
            LOGGER.warn("Controller not set.", ex);
856
        }
857
        this.setAttribute(-1);
858
        return -1;
859
    }
860

    
861
    private boolean isTheSameStore(DataStore store1, DataStore store2) {
862
        String store1FullName = store1.getFullName();
863
        String store2FullName = store2.getFullName();
864
        return StringUtils.equalsIgnoreCase(store1FullName, store2FullName);
865
    }
866

    
867
    private String getPrimaryKeyName(FeatureStore store) {
868
        try {
869
            FeatureAttributeDescriptor[] pk = store.getDefaultFeatureType().getPrimaryKey();
870
            if (pk == null || pk.length != 1) {
871
                return null;
872
            }
873
            return pk[0].getName();
874
        } catch (DataException ex) {
875
            return null;
876
        }
877
    }
878

    
879
    private String getForeingKeyName(FeatureStore store, FeatureStore foreingStore) {
880
        try {
881
            for (FeatureAttributeDescriptor descriptor : store.getDefaultFeatureType()) {
882
                if (descriptor.isForeingKey()) {
883
                    ForeingKey foreingKey = descriptor.getForeingKey();
884
                    if (isTheSameStore(foreingStore, foreingKey.getFeatureStore(null))) {
885
                        return descriptor.getName();
886
                    }
887
                }
888
            }
889
        } catch (DataException ex) {
890
            return null;
891
        }
892
        return null;
893
    }
894

    
895
    public boolean isValid(StringBuilder message) {
896
        try {
897
            Object value = this.getValue();
898
            if (value == null) {
899
                return true;
900
            }
901
            Field field = this.getCurrentField();
902
            if (field == null) {
903
                return true;
904
            }
905
            if (field.getPath().length > 2) {
906
                message.append("Invalid field '").append(field.getLabel()).append("'.\n");
907
                return false;
908
            }
909
            FeatureAttributeDescriptor descriptor = field.getDescriptor();
910
            switch (this.getRelationalOperator()) {
911
                case ExpressionBuilder.OPERATOR_EQ:
912
                case ExpressionBuilder.OPERATOR_NE:
913
                case ExpressionBuilder.OPERATOR_GT:
914
                case ExpressionBuilder.OPERATOR_GE:
915
                case ExpressionBuilder.OPERATOR_LT:
916
                case ExpressionBuilder.OPERATOR_LE:
917
        try {
918
                    descriptor.getDataType().coerce(value);
919
                } catch (CoercionException ex) {
920
                    message.append("Invalid value '")
921
                            .append(Objects.toString(value))
922
                            .append("' for field '")
923
                            .append(descriptor.getLabel())
924
                            .append("'.");
925
                    message.append("\n");
926
                    message.append(ex.getMessage());
927
                    message.append("\n");
928
                    return false;
929
                }
930
                break;
931

    
932
                default:
933
                case ExpressionBuilder.OPERATOR_ILIKE:
934
                    break;
935
            }
936
            return true;
937
        } catch (Exception ex) {
938
            message.append("Invalid values '").append(ex.toString());
939
            return false;
940
        }
941
    }
942

    
943
    public ExpressionBuilder.Value getFilter() {
944
        ExpressionBuilder.Value filter = null;
945

    
946
        Object value = this.getValue();
947
        if (value == null
948
                && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NULL
949
                && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
950
            return null;
951
        }
952
        Field field = this.getCurrentField();
953
        if (field == null) {
954
            return null;
955
        }
956
        if (field.getPath().length > 2) {
957
            // No soportado
958
            return null;
959
        }
960
        DataManager dataManager = DALLocator.getDataManager();
961
        DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
962
        FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
963
        FeatureAttributeDescriptor descriptor = field.getDescriptor();
964

    
965
        ExpressionBuilder.Constant value_constant = null;
966

    
967
        switch (this.getRelationalOperator()) {
968
            case ExpressionBuilder.OPERATOR_IS_NULL:
969
                filter = getFilterForOperatorNull(parentDescriptor, descriptor, builder, field);
970
                return filter;
971
            case ExpressionBuilder.OPERATOR_IS_NOT_NULL:
972
                filter = getFilterForOperatorNotNull(parentDescriptor, descriptor, builder, field);
973
                return filter;
974
            case ExpressionBuilder.OPERATOR_EQ:
975
            case ExpressionBuilder.OPERATOR_NE:
976
            case ExpressionBuilder.OPERATOR_GT:
977
            case ExpressionBuilder.OPERATOR_GE:
978
            case ExpressionBuilder.OPERATOR_LT:
979
            case ExpressionBuilder.OPERATOR_LE:
980
        try {
981
                value_constant = builder.expression().constant(
982
                        descriptor.getDataType().coerce(value)
983
                );
984
            } catch (CoercionException ex) {
985
                return null;
986
            }
987
            break;
988

    
989
            default:
990
            case ExpressionBuilder.OPERATOR_ILIKE:
991
                value_constant = builder.expression().constant(value);
992
                break;
993
        }
994

    
995
        if (parentDescriptor == null) {
996
            // Se busca en campos de la misma tabla.
997
            filter = builder.expression().binaryOperator(
998
                    this.getRelationalOperator(),
999
                    builder.expression().column(this.store.getName(), descriptor.getName()),
1000
                    value_constant
1001
            );
1002

    
1003
            ExpressionBuilder.Value nullValue = builder.expression().column(this.store.getName(), descriptor.getName());
1004
            filter = addNullBehavior(builder, filter, nullValue);
1005

    
1006
        } else {
1007
            // Se busca en campos de una tabla relacionada.
1008
            switch (parentDescriptor.getRelationType()) {
1009
                case DynField.RELATION_TYPE_COLLABORATION:
1010
                case DynField.RELATION_TYPE_IDENTITY:
1011
                    filter = builder.expression().binaryOperator(
1012
                            this.getRelationalOperator(),
1013
                            builder.foreing_value(
1014
                                    parentDescriptor.getName(),
1015
                                    descriptor.getName()
1016
                            ),
1017
                            value_constant
1018
                    );
1019
                    ExpressionBuilder.Value nullValue = builder.foreing_value(
1020
                            parentDescriptor.getName(),
1021
                            descriptor.getName()
1022
                    );
1023
                    filter = addNullBehavior(builder, filter, nullValue);
1024
                    break;
1025

    
1026
                case DynField.RELATION_TYPE_AGGREGATE:
1027
                case DynField.RELATION_TYPE_COMPOSITION:
1028
                    ExpressionBuilder.Value op_composition = null;
1029
                    op_composition = builder.expression().binaryOperator(
1030
                            this.getRelationalOperator(),
1031
                            builder.expression().column(
1032
                                    field.getFeatureStore().getName(),
1033
                                    descriptor.getName()
1034
                            ),
1035
                            value_constant
1036
                    );
1037
                    ExpressionBuilder.Value null_value = builder.expression().column(
1038
                            field.getFeatureStore().getName(),
1039
                            descriptor.getName()
1040
                    );
1041
                    op_composition = addNullBehavior(builder, op_composition, null_value);
1042

    
1043
                    filter = buildExists(builder, field, op_composition);
1044
                    break;
1045
            }
1046
        }
1047

    
1048
        filter = builder.expression().group(filter);
1049
        return filter;
1050
    }
1051

    
1052
    private ExpressionBuilder.Value buildExists(DALExpressionBuilder builder, Field field, ExpressionBuilder.Value op_composition) {
1053
        ExpressionBuilder.Value filter;
1054
        SQLBuilder.SelectBuilder select = builder.select();
1055
        select.from().table().name(field.getFeatureStore().getName());
1056
        //select.column().name(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName());
1057
        select.column().value(builder.expression().constant(1));
1058
        select.limit(1);
1059
        select.where().value(
1060
                builder.expression().and(
1061
                        builder.expression().eq(
1062
                                builder.expression().column(
1063
                                        field.getFeatureStore().getName(),
1064
                                        getForeingKeyName(field.getFeatureStore(), this.store)
1065
                                ),
1066
                                builder.expression().column(
1067
                                        this.store.getName(),
1068
                                        getPrimaryKeyName(this.store)
1069
                                )
1070
                        ),
1071
                        op_composition
1072
                )
1073
        );
1074
        filter = builder.exists(select);
1075
        return filter;
1076
    }
1077

    
1078
    public JsonObject toJson() {
1079
        JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
1080

    
1081
        JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
1082
        FeatureAttributeDescriptor[] path = this.getCurrentField().getPath();
1083
        for (int i = 0; i < path.length; i++) {
1084
            FeatureAttributeDescriptor featureAttributeDescriptor = path[i];
1085
            JsonArrayBuilder pathArray = Json.createArrayBuilder();
1086

    
1087
            //first value: name field
1088
            String fieldName = featureAttributeDescriptor.getName();
1089
            pathArray.add(fieldName);
1090
            //second value: name store
1091
            if(i==0){
1092
                pathArray.add(this.store.getName());
1093
            } else {
1094
                FeatureType featureType = featureAttributeDescriptor.getFeatureType();
1095
                String storeName = featureType.getStore().getName();
1096
                pathArray.add(storeName);
1097
            }
1098
            arrayBuilder.add(pathArray.build());
1099
        }
1100
        String relational = this.getRelationalOperator();
1101
        Object value = this.getValue();
1102
        String strValue = DataTypeUtils.toString(value);
1103
        String logical = this.getLogicalOperator();
1104

    
1105
        fieldBuilder.add("fieldPath", arrayBuilder.build());
1106
        fieldBuilder.add("relational", relational);
1107
        if (!StringUtils.isEmpty(strValue)) {
1108
            fieldBuilder.add("strValue", strValue);
1109
        }
1110
        if (!StringUtils.isEmpty(logical)) {
1111
            fieldBuilder.add("logical", logical);
1112
        }
1113
        int nullBehavior = this.getNullBehavior();
1114
        fieldBuilder.add("nullBehavior", nullBehavior);
1115
        return fieldBuilder.build();
1116
    }
1117
    
1118
    public void put(SearchParameters params, int index) {
1119
        this.parameters = params;
1120
        Map<String, JsonObject> values = params.getValues();
1121
        if( values == null ) {
1122
            return;
1123
        }
1124
        JsonObject panelState = values.getOrDefault(PANEL_NAME, null);
1125
        if( panelState == null ) {
1126
            return;
1127
        }
1128
        String name = DataTypeUtils.toString(index);
1129
        this.fromJson(panelState.getJsonObject(name));
1130
    }
1131
    
1132
    public void fromJson(JsonObject jsonState) {
1133
        if (jsonState == null) {
1134
            return;
1135
        }
1136

    
1137
        JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
1138

    
1139
        // array of arrays
1140
        String[][] arrayNew = new String[fieldPath.size()][2];
1141
        for (int i = 0; i < fieldPath.size(); i++) {
1142
            String[] arrayField = new String[2];
1143
            arrayField[0] = fieldPath.getJsonArray(i).getString(0);
1144
            arrayField[1] = fieldPath.getJsonArray(i).getString(1);
1145
            arrayNew[i] = arrayField;
1146
        }
1147
        this.setAttributePath(arrayNew);  //usar el doAddAndSelect
1148

    
1149
        String relational = jsonState.getString("relational");
1150
        this.setRelationalOperator(relational);
1151

    
1152
        if (jsonState.containsKey("strValue")) {
1153
            String strValue = jsonState.getString("strValue");
1154
//        SwingUtilities.invokeLater(new Runnable() {
1155
//            @Override
1156
//            public void run() {
1157
            setValue(strValue);
1158
//            }
1159
//        });
1160
        }
1161
        if (jsonState.containsKey("logical")) {
1162
            String logical = jsonState.getString("logical");
1163
            this.setLogicalOperator(logical);
1164
        }
1165
        if (jsonState.containsKey("nullBehavior")) {
1166
            int nullBehavior = jsonState.getInt("nullBehavior");
1167
            this.setNullBehavior(nullBehavior);
1168
        }
1169

    
1170
    }
1171

    
1172
    public void setUpdateValuesLimits(int limit, int featuresLimit) {
1173
        this.updateValuesTimeLimit = limit;
1174
        this.updateValuesFeaturesLimit = featuresLimit;
1175
        doUpdateValuesList();
1176
    }
1177

    
1178
    public int getNullBehavior() {
1179
        return (int) ((LabeledValue) this.ddnNullBehavior.getSelectedItem()).getValue();
1180
    }
1181

    
1182
    public int setNullBehavior(int nullBehaviorValue) {
1183
        int n = 0;
1184
        for (LabeledValue nullBehavior : nullBehaviors) {
1185
            int toInt = (int) nullBehavior.getValue();
1186
            if (nullBehaviorValue == toInt) {
1187
                break;
1188
            }
1189
            n++;
1190
        }
1191
        if (this.nullBehaviors.length <= n) {
1192
            return -1;
1193
        }
1194
        this.ddnNullBehavior.setSelectedIndex(n);
1195
        return n;
1196
    }
1197

    
1198
    private ExpressionBuilder.Value addNullBehavior(DALExpressionBuilder builder, ExpressionBuilder.Value filter, ExpressionBuilder.Value nullValue) {
1199
        if (this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NULL && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
1200
            if (this.getNullBehavior() == NULL_AS_TRUE) {
1201
                ExpressionBuilder.Function null_function = builder.expression().is_null(nullValue);
1202
                filter = builder.expression().or(null_function, filter);
1203
            } else if (this.getNullBehavior() == NULL_AS_FALSE) {
1204
                ExpressionBuilder.Function null_function = builder.expression().not_is_null(nullValue);
1205
                filter = builder.expression().and(null_function, filter);
1206
            }
1207
        }
1208
        return filter;
1209
    }
1210

    
1211
    private ExpressionBuilder.Value getFilterForOperatorNull(
1212
            FeatureAttributeDescriptor parentDescriptor,
1213
            FeatureAttributeDescriptor descriptor,
1214
            DALExpressionBuilder builder,
1215
            Field field) {
1216

    
1217
        ExpressionBuilder.Value filter = null;
1218
        if (parentDescriptor == null) {
1219
            filter = builder.expression().is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
1220
        } else {
1221
            // Se busca en campos de una tabla relacionada.
1222
            switch (parentDescriptor.getRelationType()) {
1223
                case DynField.RELATION_TYPE_COLLABORATION:
1224
                case DynField.RELATION_TYPE_IDENTITY:
1225
                    filter = builder.expression().is_null(builder.foreing_value(
1226
                            parentDescriptor.getName(),
1227
                            descriptor.getName()
1228
                    ));
1229
                case DynField.RELATION_TYPE_AGGREGATE:
1230
                case DynField.RELATION_TYPE_COMPOSITION:
1231
                    ExpressionBuilder.Value op_composition = null;
1232
                    op_composition = builder.expression().is_null(builder.expression().column(
1233
                            field.getFeatureStore().getName(),
1234
                            descriptor.getName()
1235
                    ));
1236
                    filter = buildExists(builder, field, op_composition);
1237
            }
1238
        }
1239

    
1240
        filter = builder.expression().group(filter);
1241
        return filter;
1242
    }
1243

    
1244
    private ExpressionBuilder.Value getFilterForOperatorNotNull(
1245
            FeatureAttributeDescriptor parentDescriptor,
1246
            FeatureAttributeDescriptor descriptor,
1247
            DALExpressionBuilder builder,
1248
            Field field) {
1249

    
1250
        ExpressionBuilder.Value filter = null;
1251
        if (parentDescriptor == null) {
1252
            filter = builder.expression().not_is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
1253
        } else {
1254
            // Se busca en campos de una tabla relacionada.
1255
            switch (parentDescriptor.getRelationType()) {
1256
                case DynField.RELATION_TYPE_COLLABORATION:
1257
                case DynField.RELATION_TYPE_IDENTITY:
1258
                    filter = builder.expression().not_is_null(builder.foreing_value(
1259
                            parentDescriptor.getName(),
1260
                            descriptor.getName()
1261
                    ));
1262
                case DynField.RELATION_TYPE_AGGREGATE:
1263
                case DynField.RELATION_TYPE_COMPOSITION:
1264
                    ExpressionBuilder.Value op_composition = null;
1265
                    op_composition = builder.expression().not_is_null(builder.expression().column(
1266
                            field.getFeatureStore().getName(),
1267
                            descriptor.getName()
1268
                    ));
1269

    
1270
                    filter = buildExists(builder, field, op_composition);
1271
            }
1272
        }
1273

    
1274
        filter = builder.expression().group(filter);
1275
        return filter;
1276
    }
1277
}