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

History | View | Annotate | Download (30.7 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.util.ArrayList;
10
import java.util.Arrays;
11
import java.util.HashMap;
12
import java.util.List;
13
import java.util.Map;
14
import java.util.Objects;
15
import javax.json.Json;
16
import javax.json.JsonArray;
17
import javax.json.JsonArrayBuilder;
18
import javax.json.JsonObject;
19
import javax.json.JsonObjectBuilder;
20
import javax.swing.ComboBoxModel;
21
import javax.swing.DefaultComboBoxModel;
22
import javax.swing.ImageIcon;
23
import javax.swing.JComboBox;
24
import javax.swing.JLabel;
25
import javax.swing.JOptionPane;
26
import javax.swing.SwingUtilities;
27
import org.apache.commons.lang3.StringUtils;
28
import org.gvsig.expressionevaluator.ExpressionBuilder;
29
import org.gvsig.fmap.dal.DALLocator;
30
import org.gvsig.fmap.dal.DataManager;
31
import org.gvsig.fmap.dal.DataStore;
32
import org.gvsig.fmap.dal.complements.Search;
33
import org.gvsig.fmap.dal.exception.DataException;
34
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
35
import org.gvsig.fmap.dal.feature.Feature;
36
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
37
import org.gvsig.fmap.dal.feature.FeatureQuery;
38
import org.gvsig.fmap.dal.feature.FeatureSet;
39
import org.gvsig.fmap.dal.feature.FeatureStore;
40
import org.gvsig.fmap.dal.feature.FeatureType;
41
import org.gvsig.fmap.dal.feature.ForeingKey;
42
import org.gvsig.fmap.dal.swing.impl.featuretype.DefaultFeatureAttributeSelectionPanel;
43
import static org.gvsig.fmap.dal.swing.impl.searchpanel.DefaultSearchPanel.getAttributeDescriptorLabel;
44
import org.gvsig.tools.ToolsLocator;
45
import org.gvsig.tools.dataTypes.Coercion;
46
import org.gvsig.tools.dataTypes.CoercionException;
47
import org.gvsig.tools.dataTypes.DataTypeUtils;
48
import org.gvsig.tools.dispose.DisposeUtils;
49
import org.gvsig.tools.dynobject.DynField;
50
import org.gvsig.tools.exception.BaseException;
51
import org.gvsig.tools.i18n.I18nManager;
52
import org.gvsig.tools.swing.api.DropDown;
53
import org.gvsig.tools.swing.api.ToolsSwingLocator;
54
import org.gvsig.tools.swing.api.ToolsSwingManager;
55
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
56
import org.gvsig.tools.swing.api.windowmanager.Dialog;
57
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
58
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
59
import org.gvsig.tools.swing.icontheme.IconTheme;
60
import org.gvsig.tools.util.LabeledValue;
61
import org.gvsig.tools.util.LabeledValueImpl;
62
import org.gvsig.tools.visitor.VisitCanceledException;
63
import org.gvsig.tools.visitor.Visitor;
64
import org.slf4j.Logger;
65
import org.slf4j.LoggerFactory;
66

    
67
/**
68
 *
69
 * @author jjdelcerro
70
 */
71
@SuppressWarnings("UseSpecificCatch")
72
public class SearchConditionFieldController {
73

    
74
  private static final Logger LOGGER = LoggerFactory.getLogger(SearchConditionFieldController.class);
75

    
76
  private static class Field extends LabeledValueImpl<String> {
77

    
78
    FeatureAttributeDescriptor attrdesc;
79
    private final FeatureStore store;
80
    private final int presentationMode;
81
    private final boolean showStoreName;
82
    private final FeatureAttributeDescriptor[] path;
83

    
84
    public Field(FeatureAttributeDescriptor[] path, FeatureStore store, FeatureAttributeDescriptor attrdesc, int presentationMode) {
85
      this(path, store, attrdesc, presentationMode, false);
86
    }
87

    
88
    public Field(
89
            FeatureAttributeDescriptor[] path,
90
            FeatureStore store,
91
            FeatureAttributeDescriptor attrdesc,
92
            int presentationMode,
93
            boolean showStoreName
94
    ) {
95
      super(
96
              getAttributeDescriptorLabel(attrdesc, store.getName()),
97
              attrdesc.getName()
98
      );
99
      this.path = path;
100
      this.store = store;
101
      this.attrdesc = attrdesc;
102
      this.presentationMode = presentationMode;
103
      this.showStoreName = showStoreName;
104
    }
105

    
106
    public FeatureAttributeDescriptor[] getPath() {
107
      return this.path;
108
    }
109

    
110
    @Override
111
    public String getLabel() {
112
      String theLabel = getAttributeDescriptorLabel(attrdesc, showStoreName ? store.getName() : null);
113
      switch (this.presentationMode) {
114
        case Search.OrderedAttribute.TYPE_REGURAL:
115
          break;
116
        case Search.OrderedAttribute.TYPE_FAVORITE:
117
          theLabel = "<html><b>" + theLabel + "</b></html>";
118
          break;
119
        case Search.OrderedAttribute.TYPE_RECENT:
120
          theLabel = "<html><i><b>" + theLabel + "</b></i></html>";
121
          break;
122
      }
123
      return theLabel;
124
    }
125

    
126
    public FeatureAttributeDescriptor getParentDescriptor() {
127
      int l = this.path.length;
128
      if (l < 2) {
129
        return null;
130
      }
131
      return this.path[l - 2];
132
    }
133

    
134
    public FeatureAttributeDescriptor getDescriptor() {
135
      return this.attrdesc;
136
    }
137

    
138
    public FeatureStore getFeatureStore() {
139
      return this.store;
140
    }
141

    
142
  }
143

    
144
  private FeatureStore store;
145
  private final JLabel lblFields;
146
  private final JLabel lblExtraFields;
147
  private final JLabel lblLogicalOperators;
148
  private final JLabel lblRelationalOperators;
149
  private final JComboBox cboValue;
150
  private Object valueAssigned = null;
151

    
152
  private DropDown ddnFields;
153
  private DropDown ddnLogicalOperators;
154
  private DropDown ddnRelationalOperators;
155

    
156
  private LabeledValue[] relationalOperators;
157
  private LabeledValue[] logicalOperators;
158
  private final int SIZE_ORDERED_ATTRIBUTES = 20;
159

    
160
  public SearchConditionFieldController(
161
          FeatureStore store,
162
          JLabel lblFields,
163
          JLabel lblExtraFields,
164
          JLabel lblRelationalOperators,
165
          JComboBox cboValue,
166
          JLabel lblLogicalOperators
167
  ) {
168
    this.store = store;
169
    this.lblFields = lblFields;
170
    this.lblExtraFields = lblExtraFields;
171
    this.lblRelationalOperators = lblRelationalOperators;
172
    this.cboValue = cboValue;
173
    this.lblLogicalOperators = lblLogicalOperators;
174
    this.initComponents();
175
  }
176

    
177
  public boolean isAValidRelationOperator(String name) {
178
    for (LabeledValue relationalOperator : relationalOperators) {
179
      if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
180
        return true;
181
      }
182
    }
183
    return false;
184
  }
185

    
186
  private void initComponents() {
187
    try {
188
      I18nManager i18n = ToolsLocator.getI18nManager();
189
      ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
190

    
191
      relationalOperators = new LabeledValue[]{
192
        new LabeledValueImpl(i18n.getTranslation("_Equals_to"), ExpressionBuilder.OPERATOR_EQ),
193
        new LabeledValueImpl(i18n.getTranslation("_Like_to"), ExpressionBuilder.OPERATOR_ILIKE),
194
        new LabeledValueImpl(i18n.getTranslation("_Not_equals_to"), ExpressionBuilder.OPERATOR_NE),
195
        new LabeledValueImpl(i18n.getTranslation("_Greater_than"), ExpressionBuilder.OPERATOR_GT),
196
        new LabeledValueImpl(i18n.getTranslation("_Greater_or_equal_to"), ExpressionBuilder.OPERATOR_GE),
197
        new LabeledValueImpl(i18n.getTranslation("_Less_than"), ExpressionBuilder.OPERATOR_LT),
198
        new LabeledValueImpl(i18n.getTranslation("_Less_or_equal_to"), ExpressionBuilder.OPERATOR_LE)
199
      };
200

    
201
      logicalOperators = new LabeledValue[]{
202
        new LabeledValueImpl(i18n.getTranslation("_Or"), ExpressionBuilder.OPERATOR_OR),
203
        new LabeledValueImpl(i18n.getTranslation("_And"), ExpressionBuilder.OPERATOR_AND)
204
      };
205

    
206
      this.lblExtraFields.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
207

    
208
      this.ddnFields = toolsSwingManager.createDropDown(lblFields);
209
      this.ddnFields.setVisibleDropdownArrow(false);
210
      this.ddnRelationalOperators = toolsSwingManager.createDropDown(lblRelationalOperators);
211
      this.ddnRelationalOperators.setVisibleDropdownArrow(false);
212
      if (lblLogicalOperators != null) {
213
        this.ddnLogicalOperators = toolsSwingManager.createDropDown(lblLogicalOperators);
214
        this.ddnLogicalOperators.setVisibleDropdownArrow(false);
215
      }
216

    
217
      DefaultComboBoxModel modelRelationalOperators = new DefaultComboBoxModel();
218
      for (LabeledValue op : relationalOperators) {
219
        modelRelationalOperators.addElement(op);
220
      }
221
      this.ddnRelationalOperators.setModel(modelRelationalOperators);
222

    
223
      if (this.ddnLogicalOperators != null) {
224
        DefaultComboBoxModel modelLogicalOperators = new DefaultComboBoxModel();
225
        for (LabeledValue op : logicalOperators) {
226
          modelLogicalOperators.addElement(op);
227
        }
228
        this.ddnLogicalOperators.setModel(modelLogicalOperators);
229
      }
230
      FeatureType featureType = store.getDefaultFeatureType();
231
      Search search = (Search) ToolsLocator.getComplementsManager().get(
232
              Search.COMPLEMENT_MANE, featureType
233
      );
234
      List<Search.OrderedAttribute> orderedAttributes = search.getOrderedAttributes(
235
              Search.BASIC_TYPES_FILTER,
236
              Search.STR_INT_LONG_LABEL_ORDER,
237
              SIZE_ORDERED_ATTRIBUTES
238
      );
239
      List<ImageIcon> icons = new ArrayList<>();
240
//            DataTypesManager dataTypeManager = ToolsLocator.getDataTypesManager();
241
      IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
242
      DefaultComboBoxModel model = new DefaultComboBoxModel();
243
      for (Search.OrderedAttribute attr : orderedAttributes) {
244
        FeatureAttributeDescriptor attrdesc = attr.getDescriptor();
245
        Field field = new Field(
246
                new FeatureAttributeDescriptor[]{attrdesc},
247
                this.store,
248
                attrdesc,
249
                attr.getType()
250
        );
251
        model.addElement(field);
252
        String iconName = attrdesc.getDataType().getIconName();
253
        if (iconTheme.exists(iconName)) {
254
          icons.add(iconTheme.get(iconName));
255
        } else {
256
          icons.add(null);
257
        }
258
      }
259
      this.ddnFields.setIcons(icons);
260
      this.ddnFields.setModel(model);
261
      this.ddnFields.addItemListener(new ItemListener() {
262
        @Override
263
        public void itemStateChanged(ItemEvent e) {
264
          if (e.getStateChange() == ItemEvent.SELECTED) {
265
            doUpdateValuesList();
266
          }
267

    
268
        }
269
      });
270

    
271
      this.lblExtraFields.addMouseListener(new MouseAdapter() {
272
        @Override
273
        public void mouseClicked(MouseEvent e) {
274
          doSelectMoreFields();
275
        }
276
      });
277
      clear();
278
    } catch (Exception ex) {
279
      throw new RuntimeException(ex);
280
    }
281
  }
282

    
283
  private FeatureType getFeatureType() {
284
    try {
285
      return this.store.getDefaultFeatureType();
286
    } catch (DataException ex) {
287
      return null;
288
    }
289
  }
290

    
291
  private void doSelectMoreFields() {
292
    DefaultFeatureAttributeSelectionPanel panel = new DefaultFeatureAttributeSelectionPanel(store);
293
    WindowManager_v2 winManager = (WindowManager_v2) ToolsSwingLocator.getWindowManager();
294
    final Dialog dialog = winManager.createDialog(
295
            panel,
296
            "Select attribute",
297
            null,
298
            WindowManager_v2.BUTTONS_OK_CANCEL
299
    );
300
    dialog.addActionListener((ActionEvent e) -> {
301
      if (dialog.getAction() == WindowManager_v2.BUTTONS_OK) {
302
        doAddAndSelect(
303
                panel.getSelectedStore(),
304
                panel.getSelectedAttributeDescriptor(),
305
                panel.getSelectedPath()
306
        );
307
      }
308
    });
309
    dialog.show(WindowManager.MODE.DIALOG);
310

    
311
  }
312

    
313
  private void doAddAndSelect(FeatureStore theStore, FeatureAttributeDescriptor attrdesc, FeatureAttributeDescriptor[] path) {
314
    DefaultComboBoxModel<Field> model = (DefaultComboBoxModel) this.ddnFields.getModel();
315
    for (int i = 0; i < model.getSize(); i++) {
316
      Field field = model.getElementAt(i);
317
      FeatureAttributeDescriptor attrdescN = field.getDescriptor();
318
      if (isTheSameStore(theStore, attrdescN.getStore())
319
              && StringUtils.equalsIgnoreCase(attrdesc.getName(), attrdescN.getName())) {
320
        this.setAttribute(i);
321
        return;
322
      }
323
    }
324
    Field field = new Field(
325
            path,
326
            theStore,
327
            attrdesc,
328
            Search.OrderedAttribute.TYPE_REGURAL,
329
            !isTheSameStore(store, theStore)
330
    );
331
    ThreadSafeDialogsManager dialogManager = ToolsSwingLocator.getThreadSafeDialogsManager();
332
    if (field.getPath().length > 2) {
333
      dialogManager.messageDialog(
334
              "It not supported to search through this field." + "\n"
335
              + "Too many links.",
336
              "_Warning",
337
              JOptionPane.WARNING_MESSAGE
338
      );
339
      return;
340
    }
341
    FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
342
    if( parentDescriptor!=null ) {
343
        switch (parentDescriptor.getRelationType()) {
344
          case DynField.RELATION_TYPE_AGGREGATE:
345
          case DynField.RELATION_TYPE_COMPOSITION:
346
            if (getForeingKeyName(field.getFeatureStore(), this.store) == null) {
347
              dialogManager.messageDialog(
348
                      "It not supported to search through this field." + "\n"
349
                      + "The link field was not found.",
350
                      "_Warning",
351
                      JOptionPane.WARNING_MESSAGE
352
              );
353
              return;
354
            }
355
            if (getPrimaryKeyName(this.store) == null) {
356
              dialogManager.messageDialog(
357
                      "It not supported to search through this field." + "\n"
358
                      + "A simple primary key was not found.",
359
                      "_Warning",
360
                      JOptionPane.WARNING_MESSAGE
361
              );
362
              return;
363
            }
364
        }
365
    }
366
    model.addElement(field);
367
    IconTheme iconTheme = ToolsSwingLocator.getIconThemeManager().getCurrent();
368
    this.ddnFields.getIcons().add(iconTheme.get(attrdesc.getDataType().getIconName()));
369
    this.setAttribute(model.getSize() - 1);
370
  }
371

    
372
  public void clear() {
373
    this.ddnRelationalOperators.setSelectedIndex(0);
374
    if (this.ddnLogicalOperators != null) {
375
      this.ddnLogicalOperators.setSelectedIndex(1);
376
    }
377
    this.cboValue.setSelectedIndex(-1);
378
  }
379

    
380
  private void doUpdateValuesList() {
381
    final Field field = (Field) this.ddnFields.getSelectedItem();
382
    if (field == null) {
383
      return;
384
    }
385

    
386
    final List<Object> values = new ArrayList<>();
387
    final int limit = 60;
388
    final long timeLimit = System.currentTimeMillis() + limit * 1000;
389
    final DefaultComboBoxModel model = new DefaultComboBoxModel();
390
    this.setEnabled(false);
391
    final FeatureStore theStore = field.getFeatureStore();
392
    final FeatureQuery query = theStore.createFeatureQuery();
393
    query.addAttributeName(field.getDescriptor().getName());
394
    query.setLimit(1000);
395
    Thread th = new Thread(new Runnable() {
396
      @Override
397
      public void run() {
398
        FeatureSet set = null;
399
        try {
400
          set = theStore.getFeatureSet(query);
401
          set.accept(new Visitor() {
402
            @Override
403
            public void visit(Object o) throws VisitCanceledException, BaseException {
404
              Object value = ((Feature) o).get(field.getDescriptor().getName());
405
              if (!values.contains(value)) {
406
                values.add(value);
407
              }
408
              if (System.currentTimeMillis() > timeLimit) {
409
                throw new VisitCanceledException();
410
              }
411
              if (values.size() > 1000) {
412
                throw new VisitCanceledException();
413
              }
414
            }
415
          });
416
        } catch (VisitCanceledException ex) {
417

    
418
        } catch (Exception ex) {
419
          LOGGER.warn("Can't update list of values of '" + field.getLabel() + "'.", ex);
420
        } finally {
421
            DisposeUtils.disposeQuietly(set);
422
        }
423
        List<LabeledValue> elements = new ArrayList<>();
424
        if (!values.isEmpty()) {
425
          LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
426
          Map<String, String> availableValuesMap = new HashMap<>();
427
          if (availableValues != null) {
428
            for (LabeledValue availableValue : availableValues) {
429
              availableValuesMap.put(
430
                      Objects.toString(availableValue.getValue()),
431
                      availableValue.getLabel()
432
              );
433
            }
434
          }
435
          elements.add(new LabeledValueImpl("", null));
436
          for (Object value : values) {
437
            String key = Objects.toString(value);
438
            String label = availableValuesMap.getOrDefault(key, key);
439
            elements.add(new LabeledValueImpl(label, value));
440
          }
441
          elements.sort(null);
442

    
443
        }
444
        for (LabeledValue element : elements) {
445
          model.addElement(element);
446
        }
447
        SwingUtilities.invokeLater(new Runnable() {
448
          @Override
449
          public void run() {
450
            cboValue.setModel(model);
451
            if (valueAssigned != null) {
452
              cboValue.setSelectedItem(valueAssigned);
453
              valueAssigned = null;
454
            }
455
            setEnabled(true);
456
          }
457
        });
458
      }
459
    });
460
    th.start();
461
  }
462

    
463
  public void setEnabled(boolean enabled) {
464
    this.ddnFields.setEnabled(enabled);
465
    if (this.ddnLogicalOperators != null) {
466
      this.ddnLogicalOperators.setEnabled(enabled);
467
    }
468
    this.ddnRelationalOperators.setEnabled(enabled);
469
    this.lblExtraFields.setEnabled(enabled);
470
  }
471

    
472
  public String getRelationalOperator() {
473
    LabeledValue<String> op = (LabeledValue) this.ddnRelationalOperators.getSelectedItem();
474
    if (op == null) {
475
      return null;
476
    }
477
    return op.getValue();
478
  }
479

    
480
  public int setRelationalOperator(String name) {
481
    int n = 0;
482
    for (LabeledValue relationalOperator : relationalOperators) {
483
      if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
484
        break;
485
      }
486
      n++;
487
    }
488
    if (this.relationalOperators.length <= n) {
489
      return -1;
490
    }
491
    this.ddnRelationalOperators.setSelectedIndex(n);
492
    return n;
493
  }
494

    
495
  public String getLogicalOperator() {
496
    if (this.ddnLogicalOperators == null) {
497
      return null;
498
    }
499
    LabeledValue<String> rel = (LabeledValue) this.ddnLogicalOperators.getSelectedItem();
500
    if (rel == null) {
501
      return null;
502
    }
503
    return rel.getValue();
504
  }
505

    
506
  public void setLogicalOperator(String operator) {
507
    if (this.ddnLogicalOperators == null) {
508
      return;
509
    }
510
    ComboBoxModel model = this.ddnLogicalOperators.getModel();
511
    for (int i = 0; i < model.getSize(); i++) {
512
      LabeledValue modelValue = (LabeledValue) model.getElementAt(i);
513
      String value = (String) modelValue.getValue();
514
      if (StringUtils.equals(value, operator)) {
515
        this.ddnLogicalOperators.setSelectedIndex(i);
516
        break;
517
      }
518
    }
519
  }
520

    
521
  public Object getValue() {
522
    final Field field = (Field) this.ddnFields.getSelectedItem();
523
    if (field == null) {
524
      return null;
525
    }
526
    Object v = this.cboValue.getSelectedItem();
527
    if (v == null) {
528
      return null;
529
    }
530
    if (v instanceof LabeledValue) {
531
      v = ((LabeledValue) v).getValue();
532
      if (v == null) {
533
        return null;
534
      }
535
    }
536
    if (v instanceof CharSequence) {
537
      if (StringUtils.isBlank((CharSequence) v)) {
538
        return null;
539
      }
540
    }
541
    Coercion coercion = field.getDescriptor().getDataType().getCoercion();
542
    try {
543
      return coercion.coerce(v);
544
    } catch (CoercionException ex) {
545
      return null;
546
    }
547
  }
548

    
549
  public void setValue(Object value) {
550
    this.cboValue.setSelectedItem(value);
551
    this.valueAssigned = value;
552
  }
553

    
554
  private Field getCurrentField() {
555
    final Field field = (Field) this.ddnFields.getSelectedItem();
556
    return field;
557
  }
558

    
559
  public int setAttribute(String name) {
560
    ComboBoxModel<Field> model = this.ddnFields.getModel();
561
    for (int i = 0; i < model.getSize(); i++) {
562
      Field x = model.getElementAt(i);
563
      if (StringUtils.equalsIgnoreCase(name, x.getValue())) {
564
        this.setAttribute(i);
565
        return i;
566
      }
567
    }
568
    this.setAttribute(-1);
569
    return -1;
570
  }
571

    
572
  public void setAttribute(int index) {
573
    try {
574
      this.ddnFields.setSelectedIndex(index);
575
    } catch (Exception ex) {
576
      this.ddnFields.setSelectedIndex(-1);
577
    }
578
    doUpdateValuesList();
579
  }
580

    
581
  public int setAttributePath(String[][] pathNames) {
582
    // [[attributeName, storeName],...]
583
    try {
584
      if (pathNames.length == 1) {
585
        String[] path = pathNames[pathNames.length - 1];
586
        String name = path[0];
587
        int index = this.setAttribute(name);
588
        if (index == -1) {
589
          try {
590
            FeatureAttributeDescriptor attrDescriptor = store.getDefaultFeatureType().getAttributeDescriptor(name);
591
            FeatureAttributeDescriptor[] attributePath = new FeatureAttributeDescriptor[]{attrDescriptor};
592
            doAddAndSelect(store, store.getDefaultFeatureType().getAttributeDescriptor(name), attributePath);
593
          } catch (Exception ex) {
594
            LOGGER.warn("Not able to set single path into controller", ex);
595
            return -1;
596
          }
597
        }
598
        return index;
599
      } else {
600
        ComboBoxModel<Field> model = this.ddnFields.getModel();
601
        String[] singleArrayPathNameDescriptors = new String[pathNames.length];
602
        for (int i = 0; i < pathNames.length; i++) {
603
          singleArrayPathNameDescriptors[i] = pathNames[i][0];
604
        }
605
        // check the drop
606
        for (int i = 0; i < model.getSize(); i++) {
607
          Field x = model.getElementAt(i);
608
          String[] arrayDescriptors = new String[x.getPath().length];
609
          FeatureAttributeDescriptor[] path = x.getPath();
610
          for (int j = 0; j < path.length; j++) {
611
            arrayDescriptors[j] = path[j].getName();
612
          }
613
          if (Arrays.equals(singleArrayPathNameDescriptors, arrayDescriptors)) {
614
            this.setAttribute(i);
615
            return i;
616
          }
617
        }
618
        // if not, addit to the drop
619
        DataManager dataManager = DALLocator.getDataManager();
620
        String tableName = pathNames[pathNames.length - 1][1]; // del ultimo path, coger el nombre tabla
621
        FeatureStore theStore = (FeatureStore) dataManager.getStoresRepository().getStore(tableName);
622
        String attributeName = pathNames[pathNames.length - 1][0]; // del ultimo path, coger el nombre attribute
623
        if (theStore != null) {
624
          FeatureAttributeDescriptor attr;
625
          try {
626
            attr = theStore.getDefaultFeatureType().getAttributeDescriptor(attributeName);
627
            FeatureAttributeDescriptor[] attributePath = new FeatureAttributeDescriptor[2];
628
            String firstAttrName = pathNames[0][0];
629
            FeatureAttributeDescriptor firstAttr = store.getDefaultFeatureType().getAttributeDescriptor(firstAttrName);
630
            attributePath[0] = firstAttr;
631

    
632
            attributePath[1] = attr;
633
            doAddAndSelect(theStore, attr, attributePath);
634
            return SIZE_ORDERED_ATTRIBUTES - 1;
635
          } catch (Exception ex) {
636
            LOGGER.warn("Not able to set foreign path into controller", ex);
637
          }
638

    
639
        }
640

    
641
      }
642
    } catch (Exception ex) {
643
      LOGGER.warn("Controller not set.", ex);
644
    }
645
    this.setAttribute(-1);
646
    return -1;
647
  }
648

    
649
  private boolean isTheSameStore(DataStore store1, DataStore store2) {
650
    String store1FullName = store1.getFullName();
651
    String store2FullName = store2.getFullName();
652
    return StringUtils.equalsIgnoreCase(store1FullName, store2FullName);
653
  }
654

    
655
  private String getPrimaryKeyName(FeatureStore store) {
656
    try {
657
      FeatureAttributeDescriptor[] pk = store.getDefaultFeatureType().getPrimaryKey();
658
      if (pk == null || pk.length != 1) {
659
        return null;
660
      }
661
      return pk[0].getName();
662
    } catch (DataException ex) {
663
      return null;
664
    }
665
  }
666

    
667
  private String getForeingKeyName(FeatureStore store, FeatureStore foreingStore) {
668
    try {
669
      for (FeatureAttributeDescriptor descriptor : store.getDefaultFeatureType()) {
670
        if (descriptor.isForeingKey()) {
671
          ForeingKey foreingKey = descriptor.getForeingKey();
672
          if (isTheSameStore(foreingStore, foreingKey.getFeatureStore(null))) {
673
            return descriptor.getName();
674
          }
675
        }
676
      }
677
    } catch (DataException ex) {
678
      return null;
679
    }
680
    return null;
681
  }
682

    
683
  public boolean isValid(StringBuilder message) {
684
    Object value = this.getValue();
685
    if (value == null) {
686
      return true;
687
    }
688
    Field field = this.getCurrentField();
689
    if (field == null) {
690
      return true;
691
    }
692
    if (field.getPath().length > 2) {
693
      message.append("Invalid field '").append(field.getLabel()).append("'.\n");
694
      return false;
695
    }
696
    FeatureAttributeDescriptor descriptor = field.getDescriptor();
697
    switch (this.getRelationalOperator()) {
698
      case ExpressionBuilder.OPERATOR_EQ:
699
      case ExpressionBuilder.OPERATOR_NE:
700
      case ExpressionBuilder.OPERATOR_GT:
701
      case ExpressionBuilder.OPERATOR_GE:
702
      case ExpressionBuilder.OPERATOR_LT:
703
      case ExpressionBuilder.OPERATOR_LE:
704
        try {
705
        descriptor.getDataType().coerce(value);
706
      } catch (CoercionException ex) {
707
        message.append("Invalid value '")
708
                .append(Objects.toString(value))
709
                .append("' for field '")
710
                .append(descriptor.getLabel())
711
                .append("'.");
712
        message.append("\n");
713
        message.append(ex.getMessage());
714
        message.append("\n");
715
        return false;
716
      }
717
      break;
718

    
719
      default:
720
      case ExpressionBuilder.OPERATOR_ILIKE:
721
        break;
722
    }
723
    return true;
724
  }
725

    
726
  public ExpressionBuilder.Value getFilter() {
727
    ExpressionBuilder.Value filter = null;
728

    
729
    Object value = this.getValue();
730
    if (value == null) {
731
      return null;
732
    }
733
    Field field = this.getCurrentField();
734
    if (field == null) {
735
      return null;
736
    }
737
    if (field.getPath().length > 2) {
738
      // No soportado
739
      return null;
740
    }
741
    DataManager dataManager = DALLocator.getDataManager();
742
    DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
743
    FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
744
    FeatureAttributeDescriptor descriptor = field.getDescriptor();
745

    
746
    ExpressionBuilder.Constant value_constant = null;
747

    
748
    switch (this.getRelationalOperator()) {
749
      case ExpressionBuilder.OPERATOR_EQ:
750
      case ExpressionBuilder.OPERATOR_NE:
751
      case ExpressionBuilder.OPERATOR_GT:
752
      case ExpressionBuilder.OPERATOR_GE:
753
      case ExpressionBuilder.OPERATOR_LT:
754
      case ExpressionBuilder.OPERATOR_LE:
755
        try {
756
        value_constant = builder.expression().constant(
757
                descriptor.getDataType().coerce(value)
758
        );
759
      } catch (CoercionException ex) {
760
        return null;
761
      }
762
      break;
763

    
764
      default:
765
      case ExpressionBuilder.OPERATOR_ILIKE:
766
        value_constant = builder.expression().constant(value);
767
        break;
768
    }
769

    
770
    if (parentDescriptor == null) {
771
      // Se busca en campos de la misma tabla.
772
      filter = builder.expression().binaryOperator(
773
              this.getRelationalOperator(),
774
              builder.expression().column(this.store.getName(),descriptor.getName()),
775
              value_constant
776
      );
777
    } else {
778
      // Se busca en campos de una tabla relacionada.
779
      switch (parentDescriptor.getRelationType()) {
780
        case DynField.RELATION_TYPE_COLLABORATION:
781
        case DynField.RELATION_TYPE_IDENTITY:
782
          filter = builder.expression().binaryOperator(
783
                  this.getRelationalOperator(),
784
                  builder.foreing_value(
785
                          parentDescriptor.getName(),
786
                          descriptor.getName()
787
                  ),
788
                  value_constant
789
          );
790
          break;
791

    
792
        case DynField.RELATION_TYPE_AGGREGATE:
793
        case DynField.RELATION_TYPE_COMPOSITION:
794
          filter = builder.exists(builder.select()
795
                  .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
796
                  .from(field.getFeatureStore().getName())
797
                  .limit(1)
798
                  .where(
799
                          builder.expression().and(
800
                                  builder.expression().eq(
801
                                          builder.expression().column(
802
                                                  field.getFeatureStore().getName(),
803
                                                  getForeingKeyName(field.getFeatureStore(), this.store)
804
                                          ),
805
                                          builder.expression().column(
806
                                                  this.store.getName(),
807
                                                  getPrimaryKeyName(this.store)
808
                                          )
809
                                  ),
810
                                  builder.expression().binaryOperator(
811
                                          this.getRelationalOperator(),
812
                                          builder.expression().column(this.store.getName(),descriptor.getName()),
813
                                          value_constant
814
                                  )
815
                          )
816
                  )
817
                  .toValue()
818
          );
819
          break;
820
      }
821
    }
822
    return filter;
823
  }
824

    
825
  public JsonObject toJson() {
826
    JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
827

    
828
    JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
829
    for (FeatureAttributeDescriptor featureAttributeDescriptor : this.getCurrentField().getPath()) {
830
      JsonArrayBuilder pathArray = Json.createArrayBuilder();
831

    
832
      //first value: name field
833
      String fieldName = featureAttributeDescriptor.getName();
834
      pathArray.add(fieldName);
835
      //second value: name store
836
      String storeName = featureAttributeDescriptor.getFeatureType().getStore().getName();
837
      pathArray.add(storeName);
838

    
839
      arrayBuilder.add(pathArray.build());
840
    }
841
    String relational = this.getRelationalOperator();
842
    Object value = this.getValue();
843
    String strValue = DataTypeUtils.toString(value);
844
    String logical = this.getLogicalOperator();
845

    
846
    fieldBuilder.add("fieldPath", arrayBuilder.build());
847
    fieldBuilder.add("relational", relational);
848
    if (!StringUtils.isEmpty(strValue)) {
849
      fieldBuilder.add("strValue", strValue);
850
    }
851
    if (!StringUtils.isEmpty(logical)) {
852
      fieldBuilder.add("logical", logical);
853
    }
854
    return fieldBuilder.build();
855
  }
856

    
857
  public void fromJson(JsonObject jsonState) {
858
    if (jsonState == null) {
859
      return;
860
    }
861

    
862
    JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
863

    
864
    // array of arrays
865
    String[][] arrayNew = new String[fieldPath.size()][2];
866
    for (int i = 0; i < fieldPath.size(); i++) {
867
      String[] arrayField = new String[2];
868
      arrayField[0] = fieldPath.getJsonArray(i).getString(0);
869
      arrayField[1] = fieldPath.getJsonArray(i).getString(1);
870
      arrayNew[i] = arrayField;
871
    }
872
    this.setAttributePath(arrayNew);  //usar el doAddAndSelect
873

    
874
    String relational = jsonState.getString("relational");
875
    this.setRelationalOperator(relational);
876

    
877
    if (jsonState.containsKey("strValue")) {
878
      String strValue = jsonState.getString("strValue");
879
      this.setValue(strValue);
880
    }
881
    if (jsonState.containsKey("logical")) {
882
      String logical = jsonState.getString("logical");
883
      this.setLogicalOperator(logical);
884
    }
885

    
886
  }
887
}