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

History | View | Annotate | Download (51.9 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.impl.featuretype.DefaultFeatureAttributeSelectionPanel;
47
import static org.gvsig.fmap.dal.swing.impl.searchpanel.DefaultSearchPanel.getAttributeDescriptorLabel;
48
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NOT_HANDLE_NULL;
49
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NULL_AS_FALSE;
50
import static org.gvsig.fmap.dal.swing.searchpanel.FeatureStoreSearchPanel.NULL_AS_TRUE;
51
import org.gvsig.fmap.dal.swing.searchpanel.SearchParameters;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.dataTypes.Coercion;
54
import org.gvsig.tools.dataTypes.CoercionException;
55
import org.gvsig.tools.dataTypes.DataTypeUtils;
56
import org.gvsig.tools.dataTypes.DataTypes;
57
import org.gvsig.tools.dispose.DisposeUtils;
58
import org.gvsig.tools.dynobject.DynField;
59
import org.gvsig.tools.exception.BaseException;
60
import org.gvsig.tools.i18n.I18nManager;
61
import org.gvsig.tools.swing.api.DropDown;
62
import org.gvsig.tools.swing.api.ToolsSwingLocator;
63
import org.gvsig.tools.swing.api.ToolsSwingManager;
64
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
65
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
66
import org.gvsig.tools.swing.api.windowmanager.Dialog;
67
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
68
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
69
import org.gvsig.tools.swing.icontheme.IconTheme;
70
import org.gvsig.tools.util.LabeledValue;
71
import org.gvsig.tools.util.LabeledValueImpl;
72
import org.gvsig.tools.visitor.VisitCanceledException;
73
import org.gvsig.tools.visitor.Visitor;
74
import org.slf4j.Logger;
75
import org.slf4j.LoggerFactory;
76

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

    
84
    private static final Logger LOGGER = LoggerFactory.getLogger(SearchConditionFieldController.class);
85
    private static final Class LOAD_MORE_ELEMENTS = SearchConditionFieldController.class;
86
    private static class Field extends LabeledValueImpl<String> {
87

    
88
        FeatureAttributeDescriptor attrdesc;
89
        private final FeatureStore store;
90
        private final int presentationMode;
91
        private final boolean showStoreName;
92
        private final FeatureAttributeDescriptor[] path;
93

    
94
        public Field(FeatureAttributeDescriptor[] path, FeatureStore store, FeatureAttributeDescriptor attrdesc, int presentationMode) {
95
            this(path, store, attrdesc, presentationMode, false);
96
        }
97

    
98
        public Field(
99
                FeatureAttributeDescriptor[] path,
100
                FeatureStore store,
101
                FeatureAttributeDescriptor attrdesc,
102
                int presentationMode,
103
                boolean showStoreName
104
        ) {
105
            super(
106
                    getAttributeDescriptorLabel(attrdesc, store.getName()),
107
                    attrdesc.getName()
108
            );
109
            this.path = path;
110
            this.store = store;
111
            this.attrdesc = attrdesc;
112
            this.presentationMode = presentationMode;
113
            this.showStoreName = showStoreName;
114
        }
115

    
116
        public FeatureAttributeDescriptor[] getPath() {
117
            return this.path;
118
        }
119

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

    
136
        public FeatureAttributeDescriptor getParentDescriptor() {
137
            int l = this.path.length;
138
            if (l < 2) {
139
                return null;
140
            }
141
            return this.path[l - 2];
142
        }
143

    
144
        public FeatureAttributeDescriptor getDescriptor() {
145
            return this.attrdesc;
146
        }
147

    
148
        public FeatureStore getFeatureStore() {
149
            return this.store;
150
        }
151

    
152
    }
153

    
154
    private FeatureStore store;
155
    private SearchParameters parameters;
156
    private final JLabel lblFields;
157
    private final JLabel lblExtraFields;
158
    private final JLabel lblLogicalOperators;
159
    private final JLabel lblRelationalOperators;
160
    private final JComboBox cboValue;
161
    private final JLabel lblNull;
162
    private Object valueAssigned = null;
163

    
164
    private DropDown ddnFields;
165
    private DropDown ddnLogicalOperators;
166
    private DropDown ddnRelationalOperators;
167
    private DropDown ddnNullBehavior;
168
    
169
    private LabeledValue[] relationalOperators;
170
    private LabeledValue[] logicalOperators;
171
    private LabeledValue[] nullBehaviors;
172
    private ArrayList<ImageIcon> nullOperatorsIcons;
173

    
174
    private final int SIZE_ORDERED_ATTRIBUTES = 20;
175
    private DatePickerController dateController = null;
176

    
177
    private int updateValuesTimeLimit;
178
    private int updateValuesFeaturesLimit;
179
    private boolean canHasMoreElements;
180

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

    
205
    public boolean isAValidRelationOperator(String name) {
206
        for (LabeledValue relationalOperator : relationalOperators) {
207
            if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
208
                return true;
209
            }
210
        }
211
        return false;
212
    }
213

    
214
    private void initComponents() {
215
        try {
216
            I18nManager i18n = ToolsLocator.getI18nManager();
217
            ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
218

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

    
231
            logicalOperators = new LabeledValue[]{
232
                new LabeledValueImpl(i18n.getTranslation("_Or"), ExpressionBuilder.OPERATOR_OR),
233
                new LabeledValueImpl(i18n.getTranslation("_And"), ExpressionBuilder.OPERATOR_AND)
234
            };
235

    
236
            nullBehaviors = new LabeledValue[]{
237
                new LabeledValueImpl(i18n.getTranslation("_Not_handle_null_values"), NOT_HANDLE_NULL),
238
                new LabeledValueImpl(i18n.getTranslation("_Null_values_as_true"), NULL_AS_TRUE),
239
                new LabeledValueImpl(i18n.getTranslation("_Null_values_as_false"), NULL_AS_FALSE)
240
            };
241

    
242
            nullOperatorsIcons = new ArrayList<ImageIcon>();
243
            nullOperatorsIcons.add(ToolsSwingLocator.getIconThemeManager().getCurrent().get("search-nullbehavior-null"));
244
            nullOperatorsIcons.add(ToolsSwingLocator.getIconThemeManager().getCurrent().get("search-nullbehavior-true"));
245
            nullOperatorsIcons.add(ToolsSwingLocator.getIconThemeManager().getCurrent().get("search-nullbehavior-false2"));
246

    
247
            this.lblExtraFields.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
248

    
249
            this.ddnFields = toolsSwingManager.createDropDown(lblFields);
250
            this.ddnFields.setVisibleDropdownArrow(false);
251
            this.ddnRelationalOperators = toolsSwingManager.createDropDown(lblRelationalOperators);
252
            this.ddnRelationalOperators.setVisibleDropdownArrow(false);
253
            if (lblLogicalOperators != null) {
254
                this.ddnLogicalOperators = toolsSwingManager.createDropDown(lblLogicalOperators);
255
                this.ddnLogicalOperators.setVisibleDropdownArrow(false);
256
            }
257
            
258
            DefaultComboBoxModel modelRelationalOperators = new DefaultComboBoxModel();
259
            for (LabeledValue op : relationalOperators) {
260
                modelRelationalOperators.addElement(op);
261
            }
262
            this.ddnRelationalOperators.setModel(modelRelationalOperators);
263
            this.ddnRelationalOperators.addItemListener(new ItemListener() {
264
                @Override
265
                public void itemStateChanged(ItemEvent ie) {
266
                    if (ie.getStateChange() == ItemEvent.SELECTED) {
267
                      Object item = ((LabeledValue)ie.getItemSelectable().getSelectedObjects()[0]).getValue();
268
                    if (ExpressionBuilder.OPERATOR_IS_NULL.equals(item) || ExpressionBuilder.OPERATOR_IS_NOT_NULL.equals(item)) {
269
                        lblNull.setEnabled(false);
270
                        lblNull.setVisible(false);
271
                        cboValue.setEnabled(false);
272
                        cboValue.setVisible(false);
273
                    } else {
274
                        lblNull.setEnabled(true);
275
                        lblNull.setVisible(true);
276
                        cboValue.setEnabled(true);
277
                        cboValue.setVisible(true);
278
                    }
279
                    }
280
                }
281
            });
282
            
283
            if (this.ddnLogicalOperators != null) {
284
                DefaultComboBoxModel modelLogicalOperators = new DefaultComboBoxModel();
285
                for (LabeledValue op : logicalOperators) {
286
                    modelLogicalOperators.addElement(op);
287
                }
288
                this.ddnLogicalOperators.setModel(modelLogicalOperators);
289
                this.ddnLogicalOperators.setSelectedIndex(1);
290
            }
291
            
292
//            this.ddnNullOperators = new DropDownLabelIcon(lblNull);
293
            this.ddnNullBehavior = toolsSwingManager.createDropDownIcon(lblNull);
294
            this.ddnNullBehavior.setVisibleDropdownArrow(false);
295
            DefaultComboBoxModel modelNullOperators = new DefaultComboBoxModel();
296
            for (LabeledValue op : nullBehaviors) {
297
                modelNullOperators.addElement(op);
298
            }
299
            this.ddnNullBehavior.setModel(modelNullOperators);
300
            this.ddnNullBehavior.setIcons(nullOperatorsIcons);
301
            this.ddnNullBehavior.setSelectedIndex(0);
302
            FeatureType featureType = parameters.getFeatureType(store);
303
            Search search = (Search) ToolsLocator.getComplementsManager().get(
304
                    Search.COMPLEMENT_MANE, featureType
305
            );
306
            List<Search.OrderedAttribute> orderedAttributes = search.getOrderedAttributes(
307
                    Search.BASIC_TYPES_FILTER,
308
                    Search.STR_INT_LONG_LABEL_ORDER,
309
                    SIZE_ORDERED_ATTRIBUTES
310
            );
311
            List<ImageIcon> icons = new ArrayList<>();
312
//            DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
313
            IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
314
            DefaultComboBoxModel model = new DefaultComboBoxModel();
315
            for (Search.OrderedAttribute attr : orderedAttributes) {
316
                FeatureAttributeDescriptor attrdesc = attr.getDescriptor();
317
                Field field = new Field(
318
                        new FeatureAttributeDescriptor[]{attrdesc},
319
                        this.store,
320
                        attrdesc,
321
                        attr.getType()
322
                );
323
                model.addElement(field);
324
                String iconName = attrdesc.getDataType().getIconName();
325
                if (iconTheme.exists(iconName)) {
326
                    icons.add(iconTheme.get(iconName));
327
                } else {
328
                    icons.add(null);
329
                }
330
            }
331

    
332
            this.ddnFields.setIcons(icons);
333
            this.ddnFields.setModel(model);
334
            this.ddnFields.addItemListener(new ItemListener() {
335
                @Override
336
                public void itemStateChanged(ItemEvent e) {
337
                    if (e.getStateChange() == ItemEvent.SELECTED) {
338
                        doUpdateValuesList();
339
                    }
340

    
341
                }
342
            });
343

    
344
            this.cboValue.addItemListener(new ItemListener() {
345
                @Override
346
                public void itemStateChanged(ItemEvent e) {
347
                    if (e.getStateChange() == ItemEvent.SELECTED) {
348
                        if (cboValue.getSelectedItem() != null && cboValue.getSelectedItem() instanceof LabeledValue) {
349
                            if (Objects.equals(((LabeledValue) cboValue.getSelectedItem()).getValue(), LOAD_MORE_ELEMENTS)) {
350
                                setUpdateValuesLimits(updateValuesTimeLimit + 10, updateValuesFeaturesLimit + 20000);
351
                            }
352
                        }
353
                    }
354
                }
355
            });
356

    
357
            this.lblExtraFields.addMouseListener(new MouseAdapter() {
358
                @Override
359
                public void mouseClicked(MouseEvent e) {
360
                    doSelectMoreFields();
361
                }
362
            });
363

    
364
//      clear();
365
        } catch (Exception ex) {
366
            throw new RuntimeException(ex);
367
        }
368
    }
369

    
370
    private FeatureType getFeatureType() {
371
        try {
372
            return this.store.getDefaultFeatureType();
373
        } catch (DataException ex) {
374
            return null;
375
        }
376
    }
377

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

    
398
    }
399

    
400
    private void doAddAndSelect(FeatureStore theStore, FeatureAttributeDescriptor attrdesc, FeatureAttributeDescriptor[] path) {
401
        ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
402
        I18nManager i18n = ToolsLocator.getI18nManager();
403
        DefaultComboBoxModel<Field> model = (DefaultComboBoxModel) this.ddnFields.getModel();
404
        if (attrdesc == null) {
405
            dialogManager.messageDialog(
406
                    i18n.getTranslation("_It_is_not_supported_to_search_through_this_field") + "\n"
407
                    + i18n.getTranslation("_Field_not_found"),
408
                    "_Warning",
409
                    JOptionPane.WARNING_MESSAGE
410
            );
411
            return;
412
        }
413

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

    
470
    public void clear() {
471
        this.ddnRelationalOperators.setSelectedIndex(0);
472
        if (this.ddnLogicalOperators != null) {
473
            this.ddnLogicalOperators.setSelectedIndex(1);
474
        }
475
        this.cboValue.setSelectedIndex(-1);
476
        this.ddnNullBehavior.setSelectedIndex(0);
477
    }
478

    
479
    private void doUpdateValuesList() {
480
        final Field field = (Field) this.ddnFields.getSelectedItem();
481
        if (field == null) {
482
            return;
483
        }
484
        FeatureAttributeDescriptor descriptor = field.getDescriptor();
485
        if (descriptor.getType() == DataTypes.DATE) {
486
            if (this.dateController == null) {
487
                this.dateController = ToolsSwingLocator.getToolsSwingManager().createDatePickerController(
488
                        (JTextComponent) this.cboValue.getEditor().getEditorComponent(),
489
                        null
490
                );
491
            }
492
        } else {
493
            if (this.dateController != null) {
494
                this.dateController.uninstall();
495
                this.dateController = null;
496
            }
497
        }
498

    
499
        final List<Object> values = new ArrayList<>();
500
        final DefaultComboBoxModel model = new DefaultComboBoxModel();
501
        final FeatureStore theStore = field.getFeatureStore();
502
        final FeatureQuery query;
503
        if (this.store == theStore) {
504
            query = parameters.getQuery().getCopy(); // theStore.createFeatureQuery();
505
        } else {
506
            query = theStore.createFeatureQuery();
507
        }
508
        query.addAttributeName(field.getDescriptor().getName());
509
        query.setFilter("");
510
        query.setLimit(updateValuesFeaturesLimit);
511
        query.getGroupByColumns().clear();
512
        query.getAggregateFunctions().clear();
513
        Thread th = new Thread(new Runnable() {
514
            @Override
515
            public void run() {
516
                FeatureSet set = null;
517
                try {
518
                    canHasMoreElements = false;
519
                    set = theStore.getFeatureSet(query);
520
                    if (set.size() >= updateValuesFeaturesLimit) {
521
                        canHasMoreElements = true;
522
                    }
523
                    final long timeLimit = System.currentTimeMillis() + updateValuesTimeLimit * 1000;
524
                    set.accept(new Visitor() {
525
                        @Override
526
                        public void visit(Object o) throws VisitCanceledException, BaseException {
527
                            Object value = ((Feature) o).get(field.getDescriptor().getName());
528
                            if (!values.contains(value)) {
529
                                values.add(value);
530
                            }
531
                            if (System.currentTimeMillis() > timeLimit) {
532
                                canHasMoreElements = true;
533
                                throw new VisitCanceledException();
534
                            }
535
                            if (values.size() > 1000) {
536
                                canHasMoreElements = true;
537
                                throw new VisitCanceledException();
538
                            }
539
                        }
540
                    });
541
                } catch (VisitCanceledException ex) {
542
                    canHasMoreElements = true;
543
                } catch (Exception ex) {
544
                    LOGGER.warn("Can't update list of values of '" + field.getLabel() + "'.", ex);
545
                } finally {
546
                    DisposeUtils.disposeQuietly(set);
547
                }
548
                List<LabeledValue> elements = new ArrayList<>();
549
                if (!values.isEmpty()) {
550
                    LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
551
                    Map<String, String> availableValuesMap = new HashMap<>();
552
                    if (availableValues != null) {
553
                        for (LabeledValue availableValue : availableValues) {
554
                            availableValuesMap.put(
555
                                    Objects.toString(availableValue.getValue()),
556
                                    availableValue.getLabel()
557
                            );
558
                        }
559
                    }
560
                    elements.add(new LabeledValueImpl("", null));
561
                    for (Object value : values) {
562
                        String key;
563
                        if (value instanceof Date) {
564
                            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
565
                            df.setLenient(false);
566
                            key = df.format(value);
567
                        } else {
568
                            key = Objects.toString(value);
569
                        }
570
                        String label = availableValuesMap.getOrDefault(key, key);
571
                        elements.add(new LabeledValueImpl(label, value));
572
                    }
573
                    elements.sort(null);
574

    
575
                }
576
                for (LabeledValue element : elements) {
577
                    model.addElement(element);
578
                }
579
                if (canHasMoreElements) {
580
                    model.addElement(new LabeledValueImpl("...", LOAD_MORE_ELEMENTS));
581
                }
582
                SwingUtilities.invokeLater(new Runnable() {
583
                    @Override
584
                    public void run() {
585
                        setEnabled(false);
586
                        cboValue.setModel(model);
587
                        if (valueAssigned != null) {
588
                            cboValue.setSelectedItem(valueAssigned);
589
                            valueAssigned = null;
590
                        }
591
                        setEnabled(true);
592
                    }
593
                });
594
            }
595
        });
596
        th.start();
597
    }
598

    
599
    public void setEnabled(boolean enabled) {
600
        ddnFields.setEnabled(enabled);
601
        if (ddnLogicalOperators != null) {
602
            ddnLogicalOperators.setEnabled(enabled);
603
        }
604
        ddnRelationalOperators.setEnabled(enabled);
605
        lblExtraFields.setEnabled(enabled);
606
        cboValue.setEnabled(enabled);
607
    }
608

    
609
    public String getRelationalOperator() {
610
        LabeledValue<String> op = (LabeledValue) this.ddnRelationalOperators.getSelectedItem();
611
        if (op == null) {
612
            return null;
613
        }
614
        return op.getValue();
615
    }
616

    
617
    public int setRelationalOperator(String name) {
618
        int n = 0;
619
        for (LabeledValue relationalOperator : relationalOperators) {
620
            if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
621
                break;
622
            }
623
            n++;
624
        }
625
        if (this.relationalOperators.length <= n) {
626
            return -1;
627
        }
628
        this.ddnRelationalOperators.setSelectedIndex(n);
629
        return n;
630
    }
631

    
632
    public String getLogicalOperator() {
633
        if (this.ddnLogicalOperators == null) {
634
            return null;
635
        }
636
        LabeledValue<String> rel = (LabeledValue) this.ddnLogicalOperators.getSelectedItem();
637
        if (rel == null) {
638
            return null;
639
        }
640
        return rel.getValue();
641
    }
642

    
643
    public void setLogicalOperator(String operator) {
644
        if (this.ddnLogicalOperators == null) {
645
            return;
646
        }
647
        ComboBoxModel model = this.ddnLogicalOperators.getModel();
648
        for (int i = 0; i < model.getSize(); i++) {
649
            LabeledValue modelValue = (LabeledValue) model.getElementAt(i);
650
            String value = (String) modelValue.getValue();
651
            if (StringUtils.equals(value, operator)) {
652
                this.ddnLogicalOperators.setSelectedIndex(i);
653
                break;
654
            }
655
        }
656
    }
657

    
658
    public Object getValue() {
659
        final Field field = (Field) this.ddnFields.getSelectedItem();
660
        if (field == null) {
661
            return null;
662
        }
663
        Object v;
664
        if (this.dateController == null) {
665
            v = this.cboValue.getSelectedItem();
666
        } else {
667
            v = this.dateController.get();
668
        }
669
        if (v == null) {
670
            return null;
671
        }
672
        if (v instanceof LabeledValue) {
673
            v = ((LabeledValue) v).getValue();
674
            if (v == null) {
675
                return null;
676
            }
677
        }
678
        if (v instanceof CharSequence) {
679
            if (StringUtils.isBlank((CharSequence) v)) {
680
                return null;
681
            }
682
        }
683
        Coercion coercion = field.getDescriptor().getDataType().getCoercion();
684
        try {
685
            return coercion.coerce(v);
686
        } catch (CoercionException ex) {
687
            return null;
688
        }
689
    }
690

    
691
    public void setValue(Object value) {
692
        //this.cboValue.setSelectedItem(value);
693
        SwingUtilities.invokeLater(new Runnable() {
694
            @Override
695
            public void run() {
696
                DefaultComboBoxModel model = (DefaultComboBoxModel) cboValue.getModel();
697
                for (int i = 0; i < model.getSize(); i++) {
698
                    Object item = model.getElementAt(i);
699
                    if (item.equals(value)) {
700
                        cboValue.setSelectedIndex(i);
701
                        valueAssigned = value;
702
                        return;
703
                    }
704
                }
705
                // si no lo encuentra en el modelo lo a?ade
706
                final Field field = (Field) ddnFields.getSelectedItem();
707
                if (field == null) {
708
                    return;
709
                } else {
710
                    LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
711
                    Map<String, String> availableValuesMap = new HashMap<>();
712
                    if (availableValues != null) {
713
                        for (LabeledValue availableValue : availableValues) {
714
                            availableValuesMap.put(
715
                                    Objects.toString(availableValue.getValue()),
716
                                    availableValue.getLabel()
717
                            );
718
                        }
719
                    }
720
                    String key;
721
                    if (value instanceof Date) {
722
                        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
723
                        df.setLenient(false);
724
                        key = df.format(value);
725
                    } else {
726
                        key = Objects.toString(value);
727
                    }
728
                    String label = availableValuesMap.getOrDefault(key, key);
729
                    LabeledValueImpl newItem = new LabeledValueImpl(label, value);
730
                    model.addElement(newItem);
731
                    cboValue.setSelectedItem(newItem);
732
                    valueAssigned = newItem;
733
                }
734
            }
735
        });
736
    }
737

    
738
    private Field getCurrentField() {
739
        final Field field = (Field) this.ddnFields.getSelectedItem();
740
        return field;
741
    }
742

    
743
    public int setAttribute(String name) {
744
        ComboBoxModel<Field> model = this.ddnFields.getModel();
745
        for (int i = 0; i < model.getSize(); i++) {
746
            Field x = model.getElementAt(i);
747
            if (StringUtils.equalsIgnoreCase(name, x.getValue())) {
748
                this.setAttribute(i);
749
                return i;
750
            }
751
        }
752
        this.setAttribute(-1);
753
        return -1;
754
    }
755

    
756
    public void setAttribute(int index) {
757
        try {
758
            this.ddnFields.setSelectedIndex(index);
759
        } catch (Exception ex) {
760
            this.ddnFields.setSelectedIndex(-1);
761
        }
762
        doUpdateValuesList();
763
    }
764

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

    
828
                        attributePath[1] = attr;
829
                        doAddAndSelect(theStore, attr, attributePath);
830
                        return SIZE_ORDERED_ATTRIBUTES - 1;
831
                    } catch (Exception ex) {
832
                        LOGGER.warn("Not able to set foreign path into controller", ex);
833
                    }
834

    
835
                }
836

    
837
            }
838
        } catch (Exception ex) {
839
            LOGGER.warn("Controller not set.", ex);
840
        }
841
        this.setAttribute(-1);
842
        return -1;
843
    }
844

    
845
    private boolean isTheSameStore(DataStore store1, DataStore store2) {
846
        String store1FullName = store1.getFullName();
847
        String store2FullName = store2.getFullName();
848
        return StringUtils.equalsIgnoreCase(store1FullName, store2FullName);
849
    }
850

    
851
    private String getPrimaryKeyName(FeatureStore store) {
852
        try {
853
            FeatureAttributeDescriptor[] pk = store.getDefaultFeatureType().getPrimaryKey();
854
            if (pk == null || pk.length != 1) {
855
                return null;
856
            }
857
            return pk[0].getName();
858
        } catch (DataException ex) {
859
            return null;
860
        }
861
    }
862

    
863
    private String getForeingKeyName(FeatureStore store, FeatureStore foreingStore) {
864
        try {
865
            for (FeatureAttributeDescriptor descriptor : store.getDefaultFeatureType()) {
866
                if (descriptor.isForeingKey()) {
867
                    ForeingKey foreingKey = descriptor.getForeingKey();
868
                    if (isTheSameStore(foreingStore, foreingKey.getFeatureStore(null))) {
869
                        return descriptor.getName();
870
                    }
871
                }
872
            }
873
        } catch (DataException ex) {
874
            return null;
875
        }
876
        return null;
877
    }
878

    
879
    public boolean isValid(StringBuilder message) {
880
        try {
881
            Object value = this.getValue();
882
            if (value == null) {
883
                return true;
884
            }
885
            Field field = this.getCurrentField();
886
            if (field == null) {
887
                return true;
888
            }
889
            if (field.getPath().length > 2) {
890
                message.append("Invalid field '").append(field.getLabel()).append("'.\n");
891
                return false;
892
            }
893
            FeatureAttributeDescriptor descriptor = field.getDescriptor();
894
            switch (this.getRelationalOperator()) {
895
                case ExpressionBuilder.OPERATOR_EQ:
896
                case ExpressionBuilder.OPERATOR_NE:
897
                case ExpressionBuilder.OPERATOR_GT:
898
                case ExpressionBuilder.OPERATOR_GE:
899
                case ExpressionBuilder.OPERATOR_LT:
900
                case ExpressionBuilder.OPERATOR_LE:
901
        try {
902
                    descriptor.getDataType().coerce(value);
903
                } catch (CoercionException ex) {
904
                    message.append("Invalid value '")
905
                            .append(Objects.toString(value))
906
                            .append("' for field '")
907
                            .append(descriptor.getLabel())
908
                            .append("'.");
909
                    message.append("\n");
910
                    message.append(ex.getMessage());
911
                    message.append("\n");
912
                    return false;
913
                }
914
                break;
915

    
916
                default:
917
                case ExpressionBuilder.OPERATOR_ILIKE:
918
                    break;
919
            }
920
            return true;
921
        } catch (Exception ex) {
922
            message.append("Invalid values '").append(ex.toString());
923
            return false;
924
        }
925
    }
926

    
927
    public ExpressionBuilder.Value getFilter() {
928
        ExpressionBuilder.Value filter = null;
929

    
930
        Object value = this.getValue();
931
        if (value == null) {
932
            return null;
933
        }
934
        Field field = this.getCurrentField();
935
        if (field == null) {
936
            return null;
937
        }
938
        if (field.getPath().length > 2) {
939
            // No soportado
940
            return null;
941
        }
942
        DataManager dataManager = DALLocator.getDataManager();
943
        DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
944
        FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
945
        FeatureAttributeDescriptor descriptor = field.getDescriptor();
946

    
947
        ExpressionBuilder.Constant value_constant = null;
948

    
949
        switch (this.getRelationalOperator()) {
950
            case ExpressionBuilder.OPERATOR_EQ:
951
            case ExpressionBuilder.OPERATOR_NE:
952
            case ExpressionBuilder.OPERATOR_GT:
953
            case ExpressionBuilder.OPERATOR_GE:
954
            case ExpressionBuilder.OPERATOR_LT:
955
            case ExpressionBuilder.OPERATOR_LE:
956
        try {
957
                value_constant = builder.expression().constant(
958
                        descriptor.getDataType().coerce(value)
959
                );
960
            } catch (CoercionException ex) {
961
                return null;
962
            }
963
            break;
964

    
965
            default:
966
            case ExpressionBuilder.OPERATOR_ILIKE:
967
                value_constant = builder.expression().constant(value);
968
                break;
969
        }
970

    
971
        if (parentDescriptor == null) {
972
            if (this.getRelationalOperator() == ExpressionBuilder.OPERATOR_IS_NULL) {
973
                filter = builder.expression().is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
974
            } else if (this.getRelationalOperator() == ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
975
                filter = builder.expression().not_is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
976
            } else {
977
                // Se busca en campos de la misma tabla.
978
                filter = builder.expression().binaryOperator(
979
                        this.getRelationalOperator(),
980
                        builder.expression().column(this.store.getName(), descriptor.getName()),
981
                        value_constant
982
                );
983
            }
984

    
985
            ExpressionBuilder.Value null_value_constant = null;
986
            ExpressionBuilder.Function null_function = null;
987
            if (this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NULL && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
988
                if (this.getNullBehavior() == NULL_AS_TRUE) {
989
                    null_value_constant = builder.expression().column(this.store.getName(), descriptor.getName());
990
                    null_function = builder.expression().is_null(null_value_constant);
991
                    filter = builder.expression().or(null_function, filter);
992
                } else if (this.getNullBehavior() == NULL_AS_FALSE) {
993
                    null_value_constant = builder.expression().column(this.store.getName(), descriptor.getName());
994
                    null_function = builder.expression().not_is_null(null_value_constant);
995
                    filter = builder.expression().and(null_function, filter);
996
                }
997
            }
998

    
999
        } else {
1000
            // Se busca en campos de una tabla relacionada.
1001
            switch (parentDescriptor.getRelationType()) {
1002
                case DynField.RELATION_TYPE_COLLABORATION:
1003
                case DynField.RELATION_TYPE_IDENTITY:
1004
                    if (this.getRelationalOperator() ==ExpressionBuilder.OPERATOR_IS_NULL) {
1005
                        filter = builder.expression().is_null(builder.foreing_value(
1006
                                parentDescriptor.getName(),
1007
                                descriptor.getName()
1008
                        ));
1009
                    } else if (this.getRelationalOperator() == ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
1010
                        filter = builder.expression().not_is_null(builder.foreing_value(
1011
                                parentDescriptor.getName(),
1012
                                descriptor.getName()
1013
                        ));
1014
                    } else {
1015
                        filter = builder.expression().binaryOperator(
1016
                                this.getRelationalOperator(),
1017
                                builder.foreing_value(
1018
                                        parentDescriptor.getName(),
1019
                                        descriptor.getName()
1020
                                ),
1021
                                value_constant
1022
                        );
1023
                        ExpressionBuilder.Value null_value_constant = null;
1024
                        ExpressionBuilder.Function null_function = null;
1025
                        if (this.getNullBehavior() == NULL_AS_TRUE) {
1026
                            null_value_constant = builder.foreing_value(
1027
                                    parentDescriptor.getName(),
1028
                                    descriptor.getName()
1029
                            );
1030
                            null_function = builder.expression().is_null(null_value_constant);
1031
                            filter = builder.expression().or(null_function, filter);
1032
                        } else if (this.getNullBehavior() == NULL_AS_FALSE) {
1033
                            null_value_constant = builder.foreing_value(
1034
                                    parentDescriptor.getName(),
1035
                                    descriptor.getName()
1036
                            );
1037
                            null_function = builder.expression().not_is_null(null_value_constant);
1038
                            filter = builder.expression().and(null_function, filter);
1039
                        }
1040

    
1041
                    }
1042
                    break;
1043

    
1044
                case DynField.RELATION_TYPE_AGGREGATE:
1045
                case DynField.RELATION_TYPE_COMPOSITION:
1046
                    ExpressionBuilder.Value op_composition = null;
1047
                    if (this.getRelationalOperator() == ExpressionBuilder.OPERATOR_IS_NULL) {
1048
                        op_composition = builder.expression().is_null(builder.expression().column(
1049
                                field.getFeatureStore().getName(),
1050
                                descriptor.getName()
1051
                        ));
1052
                    } else if (this.getRelationalOperator() == ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
1053
                        op_composition = builder.expression().not_is_null(builder.expression().column(
1054
                                field.getFeatureStore().getName(),
1055
                                descriptor.getName()
1056
                        ));
1057
                    } else {
1058
                        op_composition = builder.expression().binaryOperator(
1059
                                this.getRelationalOperator(),
1060
                                builder.expression().column(
1061
                                        field.getFeatureStore().getName(),
1062
                                        descriptor.getName()
1063
                                ),
1064
                                value_constant
1065
                        );
1066
                        ExpressionBuilder.Value null_value_constant = null;
1067
                        ExpressionBuilder.Function null_function = null;
1068
                        if (this.getNullBehavior() == NULL_AS_TRUE) {
1069
                            null_value_constant = builder.expression().column(
1070
                                    field.getFeatureStore().getName(),
1071
                                    descriptor.getName()
1072
                            );
1073
                            null_function = builder.expression().is_null(null_value_constant);
1074
                            op_composition = builder.expression().or(null_function, op_composition);
1075
                        } else if (this.getNullBehavior() == NULL_AS_FALSE) {
1076
                            null_value_constant = builder.expression().column(
1077
                                    field.getFeatureStore().getName(),
1078
                                    descriptor.getName()
1079
                            );
1080
                            null_function = builder.expression().not_is_null(null_value_constant);
1081
                            op_composition = builder.expression().and(null_function, op_composition);
1082
                        }
1083
                    }
1084

    
1085
                    filter = builder.exists(builder.select()
1086
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1087
                            .from(field.getFeatureStore().getName())
1088
                            .limit(1)
1089
                            .where(
1090
                                    builder.expression().and(
1091
                                            builder.expression().eq(
1092
                                                    builder.expression().column(
1093
                                                            field.getFeatureStore().getName(),
1094
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1095
                                                    ),
1096
                                                    builder.expression().column(
1097
                                                            this.store.getName(),
1098
                                                            getPrimaryKeyName(this.store)
1099
                                                    )
1100
                                            ),
1101
                                            op_composition
1102
                                    )
1103
                            )
1104
                            .toValue()
1105
                    );
1106
                    break;
1107
            }
1108
        }
1109
        
1110
        filter = builder.expression().group(filter);
1111
        return filter;
1112
    }
1113

    
1114
    public JsonObject toJson() {
1115
        JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
1116

    
1117
        JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
1118
        for (FeatureAttributeDescriptor featureAttributeDescriptor : this.getCurrentField().getPath()) {
1119
            JsonArrayBuilder pathArray = Json.createArrayBuilder();
1120

    
1121
            //first value: name field
1122
            String fieldName = featureAttributeDescriptor.getName();
1123
            pathArray.add(fieldName);
1124
            //second value: name store
1125
            String storeName = featureAttributeDescriptor.getFeatureType().getStore().getName();
1126
            pathArray.add(storeName);
1127

    
1128
            arrayBuilder.add(pathArray.build());
1129
        }
1130
        String relational = this.getRelationalOperator();
1131
        Object value = this.getValue();
1132
        String strValue = DataTypeUtils.toString(value);
1133
        String logical = this.getLogicalOperator();
1134

    
1135
        fieldBuilder.add("fieldPath", arrayBuilder.build());
1136
        fieldBuilder.add("relational", relational);
1137
        if (!StringUtils.isEmpty(strValue)) {
1138
            fieldBuilder.add("strValue", strValue);
1139
        }
1140
        if (!StringUtils.isEmpty(logical)) {
1141
            fieldBuilder.add("logical", logical);
1142
        }
1143
        int nullBehavior = this.getNullBehavior();
1144
        fieldBuilder.add("nullBehavior", nullBehavior);
1145
        return fieldBuilder.build();
1146
    }
1147

    
1148
    public void fromJson(JsonObject jsonState) {
1149
        if (jsonState == null) {
1150
            return;
1151
        }
1152

    
1153
        JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
1154

    
1155
        // array of arrays
1156
        String[][] arrayNew = new String[fieldPath.size()][2];
1157
        for (int i = 0; i < fieldPath.size(); i++) {
1158
            String[] arrayField = new String[2];
1159
            arrayField[0] = fieldPath.getJsonArray(i).getString(0);
1160
            arrayField[1] = fieldPath.getJsonArray(i).getString(1);
1161
            arrayNew[i] = arrayField;
1162
        }
1163
        this.setAttributePath(arrayNew);  //usar el doAddAndSelect
1164

    
1165
        String relational = jsonState.getString("relational");
1166
        this.setRelationalOperator(relational);
1167

    
1168
        if (jsonState.containsKey("strValue")) {
1169
            String strValue = jsonState.getString("strValue");
1170
//        SwingUtilities.invokeLater(new Runnable() {
1171
//            @Override
1172
//            public void run() {
1173
            setValue(strValue);
1174
//            }
1175
//        });
1176
        }
1177
        if (jsonState.containsKey("logical")) {
1178
            String logical = jsonState.getString("logical");
1179
            this.setLogicalOperator(logical);
1180
        }
1181
        if (jsonState.containsKey("nullBehavior")) {
1182
            int nullBehavior = jsonState.getInt("nullBehavior");
1183
            this.setNullBehavior(nullBehavior);
1184
        }
1185

    
1186
    }
1187

    
1188
    public void setUpdateValuesLimits(int limit, int featuresLimit) {
1189
        this.updateValuesTimeLimit = limit;
1190
        this.updateValuesFeaturesLimit = featuresLimit;
1191
        doUpdateValuesList();
1192
    }
1193

    
1194
    public int getNullBehavior() {
1195
        return (int) ((LabeledValue) this.ddnNullBehavior.getSelectedItem()).getValue();
1196
    }
1197
    
1198
    
1199
    public int setNullBehavior(int nullBehaviorValue) {
1200
       int n = 0;
1201
        for (LabeledValue nullBehavior : nullBehaviors) {
1202
            int toInt = (int) nullBehavior.getValue();
1203
            if (nullBehaviorValue == toInt) {
1204
                break;
1205
            }
1206
            n++;
1207
        }
1208
        if (this.nullBehaviors.length <= n) {
1209
            return -1;
1210
        }
1211
        this.ddnNullBehavior.setSelectedIndex(n);
1212
        return n;
1213
    }
1214
}