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

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

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

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

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

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

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

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

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

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

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

    
155
    }
156

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
331
                }
332
            });
333

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

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

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

    
371
    }
372

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

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

    
401
    }
402

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

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

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

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

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

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

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

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

    
616
    public int setRelationalOperator(String name) {
617
        int n = 0;
618
        for (LabeledValue relationalOperator : relationalOperators) {
619
            if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
620
                break;
621
            }
622
            n++;
623
        }
624
        if (this.relationalOperators.length <= n) {
625
            return -1;
626
        }
627
        this.ddnRelationalOperators.setSelectedIndex(n);
628
        doUpdateControllerByRelationalOperator();
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
                && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NULL
933
                && this.getRelationalOperator() != ExpressionBuilder.OPERATOR_IS_NOT_NULL) {
934
            return null;
935
        }
936
        Field field = this.getCurrentField();
937
        if (field == null) {
938
            return null;
939
        }
940
        if (field.getPath().length > 2) {
941
            // No soportado
942
            return null;
943
        }
944
        DataManager dataManager = DALLocator.getDataManager();
945
        DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
946
        FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
947
        FeatureAttributeDescriptor descriptor = field.getDescriptor();
948

    
949
        ExpressionBuilder.Constant value_constant = null;
950

    
951
        switch (this.getRelationalOperator()) {
952
            case ExpressionBuilder.OPERATOR_IS_NULL:
953
                filter = getFilterForOperatorNull(parentDescriptor, descriptor, builder, field);
954
                return filter;
955
            case ExpressionBuilder.OPERATOR_IS_NOT_NULL:
956
                filter = getFilterForOperatorNotNull(parentDescriptor, descriptor, builder, field);
957
                return filter;
958
            case ExpressionBuilder.OPERATOR_EQ:
959
            case ExpressionBuilder.OPERATOR_NE:
960
            case ExpressionBuilder.OPERATOR_GT:
961
            case ExpressionBuilder.OPERATOR_GE:
962
            case ExpressionBuilder.OPERATOR_LT:
963
            case ExpressionBuilder.OPERATOR_LE:
964
        try {
965
                value_constant = builder.expression().constant(
966
                        descriptor.getDataType().coerce(value)
967
                );
968
            } catch (CoercionException ex) {
969
                return null;
970
            }
971
            break;
972

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

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

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

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

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

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

    
1052
        filter = builder.expression().group(filter);
1053
        return filter;
1054
    }
1055

    
1056
    public JsonObject toJson() {
1057
        JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
1058

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

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

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

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

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

    
1095
        JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
1096

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

    
1107
        String relational = jsonState.getString("relational");
1108
        this.setRelationalOperator(relational);
1109

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

    
1128
    }
1129

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

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

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

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

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

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

    
1218
        filter = builder.expression().group(filter);
1219
        return filter;
1220
    }
1221

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

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

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

    
1272
        filter = builder.expression().group(filter);
1273
        return filter;
1274
    }
1275
}