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

History | View | Annotate | Download (53.8 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

    
87
    private static class Field extends LabeledValueImpl<String> {
88

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

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

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

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

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

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

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

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

    
153
    }
154

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

    
165
    private DropDown ddnFields;
166
    private DropDown ddnLogicalOperators;
167
    private DropDown ddnRelationalOperators;
168
    private DropDown ddnNullBehavior;
169

    
170
    private LabeledValue[] relationalOperators;
171
    private LabeledValue[] logicalOperators;
172
    private LabeledValue[] nullBehaviors;
173
    private ArrayList<ImageIcon> nullOperatorsIcons;
174

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
329
                }
330
            });
331

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

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

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

    
369
    }
370

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

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

    
399
    }
400

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

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

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

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

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

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

    
595
    public void setEnabled(boolean enabled) {
596
        ddnFields.setEnabled(enabled);
597
        if (ddnLogicalOperators != null) {
598
            ddnLogicalOperators.setEnabled(enabled);
599
        }
600
        ddnRelationalOperators.setEnabled(enabled);
601
        lblExtraFields.setEnabled(enabled);
602
        cboValue.setEnabled(enabled);
603
        doUpdateControllerByRelationalOperator();
604
    }
605

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

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

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

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

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

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

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

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

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

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

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

    
833
                }
834

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

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

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

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

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

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

    
925
    public ExpressionBuilder.Value getFilter() {
926
        ExpressionBuilder.Value filter = null;
927

    
928
        Object value = this.getValue();
929
        if (value == null
930
                && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NULL
931
                && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NOT_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_IS_NULL:
951
                filter = getFilterForOperatorNull(parentDescriptor, descriptor, builder, field);
952
                return filter;
953
            case ExpressionBuilder.OPERATOR_IS_NOT_NULL:
954
                filter = getFilterForOperatorNotNull(parentDescriptor, descriptor, builder, field);
955
                return filter;
956
            case ExpressionBuilder.OPERATOR_EQ:
957
            case ExpressionBuilder.OPERATOR_NE:
958
            case ExpressionBuilder.OPERATOR_GT:
959
            case ExpressionBuilder.OPERATOR_GE:
960
            case ExpressionBuilder.OPERATOR_LT:
961
            case ExpressionBuilder.OPERATOR_LE:
962
        try {
963
                value_constant = builder.expression().constant(
964
                        descriptor.getDataType().coerce(value)
965
                );
966
            } catch (CoercionException ex) {
967
                return null;
968
            }
969
            break;
970

    
971
            default:
972
            case ExpressionBuilder.OPERATOR_ILIKE:
973
                value_constant = builder.expression().constant(value);
974
                break;
975
        }
976

    
977
        if (parentDescriptor == null) {
978
            // Se busca en campos de la misma tabla.
979
            filter = builder.expression().binaryOperator(
980
                    this.getRelationalOperator(),
981
                    builder.expression().column(this.store.getName(), descriptor.getName()),
982
                    value_constant
983
            );
984

    
985
            ExpressionBuilder.Value nullValue = builder.expression().column(this.store.getName(), descriptor.getName());
986
            filter = addNullBehavior(builder, filter, nullValue);
987

    
988
        } else {
989
            // Se busca en campos de una tabla relacionada.
990
            switch (parentDescriptor.getRelationType()) {
991
                case DynField.RELATION_TYPE_COLLABORATION:
992
                case DynField.RELATION_TYPE_IDENTITY:
993
                    filter = builder.expression().binaryOperator(
994
                            this.getRelationalOperator(),
995
                            builder.foreing_value(
996
                                    parentDescriptor.getName(),
997
                                    descriptor.getName()
998
                            ),
999
                            value_constant
1000
                    );
1001
                    ExpressionBuilder.Value nullValue = builder.foreing_value(
1002
                            parentDescriptor.getName(),
1003
                            descriptor.getName()
1004
                    );
1005
                    filter = addNullBehavior(builder, filter, nullValue);
1006
                    break;
1007

    
1008
                case DynField.RELATION_TYPE_AGGREGATE:
1009
                case DynField.RELATION_TYPE_COMPOSITION:
1010
                    ExpressionBuilder.Value op_composition = null;
1011
                    op_composition = builder.expression().binaryOperator(
1012
                            this.getRelationalOperator(),
1013
                            builder.expression().column(
1014
                                    field.getFeatureStore().getName(),
1015
                                    descriptor.getName()
1016
                            ),
1017
                            value_constant
1018
                    );
1019
                    ExpressionBuilder.Value null_value = builder.expression().column(
1020
                            field.getFeatureStore().getName(),
1021
                            descriptor.getName()
1022
                    );
1023
                    op_composition = addNullBehavior(builder, op_composition, null_value);
1024

    
1025
                    filter = builder.exists(builder.select()
1026
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1027
                            .from(field.getFeatureStore().getName())
1028
                            .limit(1)
1029
                            .where(
1030
                                    builder.expression().and(
1031
                                            builder.expression().eq(
1032
                                                    builder.expression().column(
1033
                                                            field.getFeatureStore().getName(),
1034
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1035
                                                    ),
1036
                                                    builder.expression().column(
1037
                                                            this.store.getName(),
1038
                                                            getPrimaryKeyName(this.store)
1039
                                                    )
1040
                                            ),
1041
                                            op_composition
1042
                                    )
1043
                            )
1044
                            .toValue()
1045
                    );
1046
                    break;
1047
            }
1048
        }
1049

    
1050
        filter = builder.expression().group(filter);
1051
        return filter;
1052
    }
1053

    
1054
    public JsonObject toJson() {
1055
        JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
1056

    
1057
        JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
1058
        for (FeatureAttributeDescriptor featureAttributeDescriptor : this.getCurrentField().getPath()) {
1059
            JsonArrayBuilder pathArray = Json.createArrayBuilder();
1060

    
1061
            //first value: name field
1062
            String fieldName = featureAttributeDescriptor.getName();
1063
            pathArray.add(fieldName);
1064
            //second value: name store
1065
            String storeName = featureAttributeDescriptor.getFeatureType().getStore().getName();
1066
            pathArray.add(storeName);
1067

    
1068
            arrayBuilder.add(pathArray.build());
1069
        }
1070
        String relational = this.getRelationalOperator();
1071
        Object value = this.getValue();
1072
        String strValue = DataTypeUtils.toString(value);
1073
        String logical = this.getLogicalOperator();
1074

    
1075
        fieldBuilder.add("fieldPath", arrayBuilder.build());
1076
        fieldBuilder.add("relational", relational);
1077
        if (!StringUtils.isEmpty(strValue)) {
1078
            fieldBuilder.add("strValue", strValue);
1079
        }
1080
        if (!StringUtils.isEmpty(logical)) {
1081
            fieldBuilder.add("logical", logical);
1082
        }
1083
        int nullBehavior = this.getNullBehavior();
1084
        fieldBuilder.add("nullBehavior", nullBehavior);
1085
        return fieldBuilder.build();
1086
    }
1087

    
1088
    public void fromJson(JsonObject jsonState) {
1089
        if (jsonState == null) {
1090
            return;
1091
        }
1092

    
1093
        JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
1094

    
1095
        // array of arrays
1096
        String[][] arrayNew = new String[fieldPath.size()][2];
1097
        for (int i = 0; i < fieldPath.size(); i++) {
1098
            String[] arrayField = new String[2];
1099
            arrayField[0] = fieldPath.getJsonArray(i).getString(0);
1100
            arrayField[1] = fieldPath.getJsonArray(i).getString(1);
1101
            arrayNew[i] = arrayField;
1102
        }
1103
        this.setAttributePath(arrayNew);  //usar el doAddAndSelect
1104

    
1105
        String relational = jsonState.getString("relational");
1106
        this.setRelationalOperator(relational);
1107

    
1108
        if (jsonState.containsKey("strValue")) {
1109
            String strValue = jsonState.getString("strValue");
1110
//        SwingUtilities.invokeLater(new Runnable() {
1111
//            @Override
1112
//            public void run() {
1113
            setValue(strValue);
1114
//            }
1115
//        });
1116
        }
1117
        if (jsonState.containsKey("logical")) {
1118
            String logical = jsonState.getString("logical");
1119
            this.setLogicalOperator(logical);
1120
        }
1121
        if (jsonState.containsKey("nullBehavior")) {
1122
            int nullBehavior = jsonState.getInt("nullBehavior");
1123
            this.setNullBehavior(nullBehavior);
1124
        }
1125

    
1126
    }
1127

    
1128
    public void setUpdateValuesLimits(int limit, int featuresLimit) {
1129
        this.updateValuesTimeLimit = limit;
1130
        this.updateValuesFeaturesLimit = featuresLimit;
1131
        doUpdateValuesList();
1132
    }
1133

    
1134
    public int getNullBehavior() {
1135
        return (int) ((LabeledValue) this.ddnNullBehavior.getSelectedItem()).getValue();
1136
    }
1137

    
1138
    public int setNullBehavior(int nullBehaviorValue) {
1139
        int n = 0;
1140
        for (LabeledValue nullBehavior : nullBehaviors) {
1141
            int toInt = (int) nullBehavior.getValue();
1142
            if (nullBehaviorValue == toInt) {
1143
                break;
1144
            }
1145
            n++;
1146
        }
1147
        if (this.nullBehaviors.length <= n) {
1148
            return -1;
1149
        }
1150
        this.ddnNullBehavior.setSelectedIndex(n);
1151
        return n;
1152
    }
1153

    
1154
    private ExpressionBuilder.Value addNullBehavior(DALExpressionBuilder builder, ExpressionBuilder.Value filter, ExpressionBuilder.Value nullValue) {
1155
        if (this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NULL && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
1156
            if (this.getNullBehavior() == NULL_AS_TRUE) {
1157
                ExpressionBuilder.Function null_function = builder.expression().is_null(nullValue);
1158
                filter = builder.expression().or(null_function, filter);
1159
            } else if (this.getNullBehavior() == NULL_AS_FALSE) {
1160
                ExpressionBuilder.Function null_function = builder.expression().not_is_null(nullValue);
1161
                filter = builder.expression().and(null_function, filter);
1162
            }
1163
        }
1164
        return filter;
1165
    }
1166

    
1167
    private ExpressionBuilder.Value getFilterForOperatorNull(
1168
            FeatureAttributeDescriptor parentDescriptor,
1169
            FeatureAttributeDescriptor descriptor,
1170
            DALExpressionBuilder builder,
1171
            Field field) {
1172

    
1173
        ExpressionBuilder.Value filter = null;
1174
        if (parentDescriptor == null) {
1175
            filter = builder.expression().is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
1176
        } else {
1177
            // Se busca en campos de una tabla relacionada.
1178
            switch (parentDescriptor.getRelationType()) {
1179
                case DynField.RELATION_TYPE_COLLABORATION:
1180
                case DynField.RELATION_TYPE_IDENTITY:
1181
                    filter = builder.expression().is_null(builder.foreing_value(
1182
                            parentDescriptor.getName(),
1183
                            descriptor.getName()
1184
                    ));
1185
                case DynField.RELATION_TYPE_AGGREGATE:
1186
                case DynField.RELATION_TYPE_COMPOSITION:
1187
                    ExpressionBuilder.Value op_composition = null;
1188
                    op_composition = builder.expression().is_null(builder.expression().column(
1189
                            field.getFeatureStore().getName(),
1190
                            descriptor.getName()
1191
                    ));
1192
                    filter = builder.exists(builder.select()
1193
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1194
                            .from(field.getFeatureStore().getName())
1195
                            .limit(1)
1196
                            .where(
1197
                                    builder.expression().and(
1198
                                            builder.expression().eq(
1199
                                                    builder.expression().column(
1200
                                                            field.getFeatureStore().getName(),
1201
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1202
                                                    ),
1203
                                                    builder.expression().column(
1204
                                                            this.store.getName(),
1205
                                                            getPrimaryKeyName(this.store)
1206
                                                    )
1207
                                            ),
1208
                                            op_composition
1209
                                    )
1210
                            )
1211
                            .toValue()
1212
                    );
1213
            }
1214
        }
1215

    
1216
        filter = builder.expression().group(filter);
1217
        return filter;
1218
    }
1219

    
1220
    private ExpressionBuilder.Value getFilterForOperatorNotNull(
1221
            FeatureAttributeDescriptor parentDescriptor,
1222
            FeatureAttributeDescriptor descriptor,
1223
            DALExpressionBuilder builder,
1224
            Field field) {
1225

    
1226
        ExpressionBuilder.Value filter = null;
1227
        if (parentDescriptor == null) {
1228
            filter = builder.expression().not_is_null(builder.expression().column(this.store.getName(), descriptor.getName()));
1229
        } else {
1230
            // Se busca en campos de una tabla relacionada.
1231
            switch (parentDescriptor.getRelationType()) {
1232
                case DynField.RELATION_TYPE_COLLABORATION:
1233
                case DynField.RELATION_TYPE_IDENTITY:
1234
                    filter = builder.expression().not_is_null(builder.foreing_value(
1235
                            parentDescriptor.getName(),
1236
                            descriptor.getName()
1237
                    ));
1238
                case DynField.RELATION_TYPE_AGGREGATE:
1239
                case DynField.RELATION_TYPE_COMPOSITION:
1240
                    ExpressionBuilder.Value op_composition = null;
1241
                    op_composition = builder.expression().not_is_null(builder.expression().column(
1242
                            field.getFeatureStore().getName(),
1243
                            descriptor.getName()
1244
                    ));
1245

    
1246
                    filter = builder.exists(builder.select()
1247
                            .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
1248
                            .from(field.getFeatureStore().getName())
1249
                            .limit(1)
1250
                            .where(
1251
                                    builder.expression().and(
1252
                                            builder.expression().eq(
1253
                                                    builder.expression().column(
1254
                                                            field.getFeatureStore().getName(),
1255
                                                            getForeingKeyName(field.getFeatureStore(), this.store)
1256
                                                    ),
1257
                                                    builder.expression().column(
1258
                                                            this.store.getName(),
1259
                                                            getPrimaryKeyName(this.store)
1260
                                                    )
1261
                                            ),
1262
                                            op_composition
1263
                                    )
1264
                            )
1265
                            .toValue()
1266
                    );
1267
            }
1268
        }
1269

    
1270
        filter = builder.expression().group(filter);
1271
        return filter;
1272
    }
1273
}