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

History | View | Annotate | Download (55.5 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.complements.Search;
37
import org.gvsig.fmap.dal.exception.DataException;
38
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
39
import org.gvsig.fmap.dal.feature.Feature;
40
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
41
import org.gvsig.fmap.dal.feature.FeatureQuery;
42
import org.gvsig.fmap.dal.feature.FeatureSet;
43
import org.gvsig.fmap.dal.feature.FeatureStore;
44
import org.gvsig.fmap.dal.feature.FeatureType;
45
import org.gvsig.fmap.dal.feature.ForeingKey;
46
import org.gvsig.fmap.dal.swing.DALSwingLocator;
47
import org.gvsig.fmap.dal.swing.impl.featuretype.DefaultFeatureAttributeSelectionPanel;
48
import static org.gvsig.fmap.dal.swing.impl.searchpanel.SearchConditionPanelSimplified.PANEL_NAME;
49
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NOT_HANDLE_NULL;
50
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NULL_AS_FALSE;
51
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NULL_AS_TRUE;
52
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.dataTypes.Coercion;
55
import org.gvsig.tools.dataTypes.CoercionException;
56
import org.gvsig.tools.dataTypes.DataTypeUtils;
57
import org.gvsig.tools.dataTypes.DataTypes;
58
import org.gvsig.tools.dispose.DisposeUtils;
59
import org.gvsig.tools.dynobject.DynField;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.i18n.I18nManager;
62
import org.gvsig.tools.swing.api.DropDown;
63
import org.gvsig.tools.swing.api.ToolsSwingLocator;
64
import org.gvsig.tools.swing.api.ToolsSwingManager;
65
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
66
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
67
import org.gvsig.tools.swing.api.windowmanager.Dialog;
68
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
69
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
70
import org.gvsig.tools.swing.icontheme.IconTheme;
71
import org.gvsig.tools.util.LabeledValue;
72
import org.gvsig.tools.util.LabeledValueImpl;
73
import org.gvsig.tools.visitor.VisitCanceledException;
74
import org.gvsig.tools.visitor.Visitor;
75
import org.slf4j.Logger;
76
import org.slf4j.LoggerFactory;
77

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

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

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

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

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

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

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

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

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

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

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

    
156
    }
157

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
332
                }
333
            });
334

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

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

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

    
372
    }
373

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

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

    
406
    }
407

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

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

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

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

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

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

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

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

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

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

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

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

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

    
757
    private Field getCurrentField() {
758
        final Field field = (Field) this.ddnFields.getSelectedItem();
759
        return field;
760
    }
761

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

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

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

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

    
854
                }
855

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

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

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

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

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

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

    
946
    public ExpressionBuilder.Value getFilter() {
947
        ExpressionBuilder.Value filter = null;
948

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

    
968
        ExpressionBuilder.Constant value_constant = null;
969

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

    
992
            default:
993
            case ExpressionBuilder.OPERATOR_ILIKE:
994
                value_constant = builder.expression().constant(value);
995
                break;
996
        }
997

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

    
1006
            ExpressionBuilder.Value nullValue = builder.expression().column(this.store.getName(), descriptor.getName());
1007
            filter = addNullBehavior(builder, filter, nullValue);
1008

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

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

    
1046
                    filter = builder.exists(builder.select()
1047
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1048
                            .from(field.getFeatureStore().getName())
1049
                            .limit(1)
1050
                            .where(
1051
                                    builder.expression().and(
1052
                                            builder.expression().eq(
1053
                                                    builder.expression().column(
1054
                                                            field.getFeatureStore().getName(),
1055
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1056
                                                    ),
1057
                                                    builder.expression().column(
1058
                                                            this.store.getName(),
1059
                                                            getPrimaryKeyName(this.store)
1060
                                                    )
1061
                                            ),
1062
                                            op_composition
1063
                                    )
1064
                            )
1065
                            .toValue()
1066
                    );
1067
                    break;
1068
            }
1069
        }
1070

    
1071
        filter = builder.expression().group(filter);
1072
        return filter;
1073
    }
1074

    
1075
    public JsonObject toJson() {
1076
        JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
1077

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

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

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

    
1134
        JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
1135

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

    
1146
        String relational = jsonState.getString("relational");
1147
        this.setRelationalOperator(relational);
1148

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

    
1167
    }
1168

    
1169
    public void setUpdateValuesLimits(int limit, int featuresLimit) {
1170
        this.updateValuesTimeLimit = limit;
1171
        this.updateValuesFeaturesLimit = featuresLimit;
1172
        doUpdateValuesList();
1173
    }
1174

    
1175
    public int getNullBehavior() {
1176
        return (int) ((LabeledValue) this.ddnNullBehavior.getSelectedItem()).getValue();
1177
    }
1178

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

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

    
1208
    private ExpressionBuilder.Value getFilterForOperatorNull(
1209
            FeatureAttributeDescriptor parentDescriptor,
1210
            FeatureAttributeDescriptor descriptor,
1211
            DALExpressionBuilder builder,
1212
            Field field) {
1213

    
1214
        ExpressionBuilder.Value filter = null;
1215
        if (parentDescriptor == null) {
1216
            filter = builder.expression().is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
1217
        } else {
1218
            // Se busca en campos de una tabla relacionada.
1219
            switch (parentDescriptor.getRelationType()) {
1220
                case DynField.RELATION_TYPE_COLLABORATION:
1221
                case DynField.RELATION_TYPE_IDENTITY:
1222
                    filter = builder.expression().is_null(builder.foreing_value(
1223
                            parentDescriptor.getName(),
1224
                            descriptor.getName()
1225
                    ));
1226
                case DynField.RELATION_TYPE_AGGREGATE:
1227
                case DynField.RELATION_TYPE_COMPOSITION:
1228
                    ExpressionBuilder.Value op_composition = null;
1229
                    op_composition = builder.expression().is_null(builder.expression().column(
1230
                            field.getFeatureStore().getName(),
1231
                            descriptor.getName()
1232
                    ));
1233
                    filter = builder.exists(builder.select()
1234
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1235
                            .from(field.getFeatureStore().getName())
1236
                            .limit(1)
1237
                            .where(
1238
                                    builder.expression().and(
1239
                                            builder.expression().eq(
1240
                                                    builder.expression().column(
1241
                                                            field.getFeatureStore().getName(),
1242
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1243
                                                    ),
1244
                                                    builder.expression().column(
1245
                                                            this.store.getName(),
1246
                                                            getPrimaryKeyName(this.store)
1247
                                                    )
1248
                                            ),
1249
                                            op_composition
1250
                                    )
1251
                            )
1252
                            .toValue()
1253
                    );
1254
            }
1255
        }
1256

    
1257
        filter = builder.expression().group(filter);
1258
        return filter;
1259
    }
1260

    
1261
    private ExpressionBuilder.Value getFilterForOperatorNotNull(
1262
            FeatureAttributeDescriptor parentDescriptor,
1263
            FeatureAttributeDescriptor descriptor,
1264
            DALExpressionBuilder builder,
1265
            Field field) {
1266

    
1267
        ExpressionBuilder.Value filter = null;
1268
        if (parentDescriptor == null) {
1269
            filter = builder.expression().not_is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
1270
        } else {
1271
            // Se busca en campos de una tabla relacionada.
1272
            switch (parentDescriptor.getRelationType()) {
1273
                case DynField.RELATION_TYPE_COLLABORATION:
1274
                case DynField.RELATION_TYPE_IDENTITY:
1275
                    filter = builder.expression().not_is_null(builder.foreing_value(
1276
                            parentDescriptor.getName(),
1277
                            descriptor.getName()
1278
                    ));
1279
                case DynField.RELATION_TYPE_AGGREGATE:
1280
                case DynField.RELATION_TYPE_COMPOSITION:
1281
                    ExpressionBuilder.Value op_composition = null;
1282
                    op_composition = builder.expression().not_is_null(builder.expression().column(
1283
                            field.getFeatureStore().getName(),
1284
                            descriptor.getName()
1285
                    ));
1286

    
1287
                    filter = builder.exists(builder.select()
1288
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1289
                            .from(field.getFeatureStore().getName())
1290
                            .limit(1)
1291
                            .where(
1292
                                    builder.expression().and(
1293
                                            builder.expression().eq(
1294
                                                    builder.expression().column(
1295
                                                            field.getFeatureStore().getName(),
1296
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1297
                                                    ),
1298
                                                    builder.expression().column(
1299
                                                            this.store.getName(),
1300
                                                            getPrimaryKeyName(this.store)
1301
                                                    )
1302
                                            ),
1303
                                            op_composition
1304
                                    )
1305
                            )
1306
                            .toValue()
1307
                    );
1308
            }
1309
        }
1310

    
1311
        filter = builder.expression().group(filter);
1312
        return filter;
1313
    }
1314
}