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

History | View | Annotate | Download (31.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 javax.swing.text.JTextComponent;
28
import org.apache.commons.lang3.StringUtils;
29
import org.gvsig.expressionevaluator.ExpressionBuilder;
30
import org.gvsig.fmap.dal.DALLocator;
31
import org.gvsig.fmap.dal.DataManager;
32
import org.gvsig.fmap.dal.DataStore;
33
import org.gvsig.fmap.dal.complements.Search;
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.expressionevaluator.DALExpressionBuilder;
36
import org.gvsig.fmap.dal.feature.Feature;
37
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
38
import org.gvsig.fmap.dal.feature.FeatureQuery;
39
import org.gvsig.fmap.dal.feature.FeatureSet;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.feature.ForeingKey;
43
import org.gvsig.fmap.dal.swing.impl.featuretype.DefaultFeatureAttributeSelectionPanel;
44
import static org.gvsig.fmap.dal.swing.impl.searchpanel.DefaultSearchPanel.getAttributeDescriptorLabel;
45
import org.gvsig.tools.ToolsLocator;
46
import org.gvsig.tools.dataTypes.Coercion;
47
import org.gvsig.tools.dataTypes.CoercionException;
48
import org.gvsig.tools.dataTypes.DataTypeUtils;
49
import org.gvsig.tools.dataTypes.DataTypes;
50
import org.gvsig.tools.dispose.DisposeUtils;
51
import org.gvsig.tools.dynobject.DynField;
52
import org.gvsig.tools.exception.BaseException;
53
import org.gvsig.tools.i18n.I18nManager;
54
import org.gvsig.tools.swing.api.DropDown;
55
import org.gvsig.tools.swing.api.ToolsSwingLocator;
56
import org.gvsig.tools.swing.api.ToolsSwingManager;
57
import org.gvsig.tools.swing.api.pickercontroller.DatePickerController;
58
import org.gvsig.tools.swing.api.threadsafedialogs.ThreadSafeDialogsManager;
59
import org.gvsig.tools.swing.api.windowmanager.Dialog;
60
import org.gvsig.tools.swing.api.windowmanager.WindowManager;
61
import org.gvsig.tools.swing.api.windowmanager.WindowManager_v2;
62
import org.gvsig.tools.swing.icontheme.IconTheme;
63
import org.gvsig.tools.util.LabeledValue;
64
import org.gvsig.tools.util.LabeledValueImpl;
65
import org.gvsig.tools.visitor.VisitCanceledException;
66
import org.gvsig.tools.visitor.Visitor;
67
import org.slf4j.Logger;
68
import org.slf4j.LoggerFactory;
69

    
70
/**
71
 *
72
 * @author jjdelcerro
73
 */
74
@SuppressWarnings("UseSpecificCatch")
75
public class SearchConditionFieldController {
76

    
77
  private static final Logger LOGGER = LoggerFactory.getLogger(SearchConditionFieldController.class);
78

    
79
  private static class Field extends LabeledValueImpl<String> {
80

    
81
    FeatureAttributeDescriptor attrdesc;
82
    private final FeatureStore store;
83
    private final int presentationMode;
84
    private final boolean showStoreName;
85
    private final FeatureAttributeDescriptor[] path;
86

    
87
    public Field(FeatureAttributeDescriptor[] path, FeatureStore store, FeatureAttributeDescriptor attrdesc, int presentationMode) {
88
      this(path, store, attrdesc, presentationMode, false);
89
    }
90

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

    
109
    public FeatureAttributeDescriptor[] getPath() {
110
      return this.path;
111
    }
112

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

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

    
137
    public FeatureAttributeDescriptor getDescriptor() {
138
      return this.attrdesc;
139
    }
140

    
141
    public FeatureStore getFeatureStore() {
142
      return this.store;
143
    }
144

    
145
  }
146

    
147
  private FeatureStore store;
148
  private final JLabel lblFields;
149
  private final JLabel lblExtraFields;
150
  private final JLabel lblLogicalOperators;
151
  private final JLabel lblRelationalOperators;
152
  private final JComboBox cboValue;
153
  private Object valueAssigned = null;
154

    
155
  private DropDown ddnFields;
156
  private DropDown ddnLogicalOperators;
157
  private DropDown ddnRelationalOperators;
158

    
159
  private LabeledValue[] relationalOperators;
160
  private LabeledValue[] logicalOperators;
161
  private final int SIZE_ORDERED_ATTRIBUTES = 20;
162
  
163
  private DatePickerController dateController = null;
164

    
165
  public SearchConditionFieldController(
166
          FeatureStore store,
167
          JLabel lblFields,
168
          JLabel lblExtraFields,
169
          JLabel lblRelationalOperators,
170
          JComboBox cboValue,
171
          JLabel lblLogicalOperators
172
  ) {
173
    this.store = store;
174
    this.lblFields = lblFields;
175
    this.lblExtraFields = lblExtraFields;
176
    this.lblRelationalOperators = lblRelationalOperators;
177
    this.cboValue = cboValue;
178
    this.lblLogicalOperators = lblLogicalOperators;
179
    this.initComponents();
180
  }
181

    
182
  public boolean isAValidRelationOperator(String name) {
183
    for (LabeledValue relationalOperator : relationalOperators) {
184
      if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
185
        return true;
186
      }
187
    }
188
    return false;
189
  }
190

    
191
  private void initComponents() {
192
    try {
193
      I18nManager i18n = ToolsLocator.getI18nManager();
194
      ToolsSwingManager toolsSwingManager = ToolsSwingLocator.getToolsSwingManager();
195

    
196
      relationalOperators = new LabeledValue[]{
197
        new LabeledValueImpl(i18n.getTranslation("_Equals_to"), ExpressionBuilder.OPERATOR_EQ),
198
        new LabeledValueImpl(i18n.getTranslation("_Like_to"), ExpressionBuilder.OPERATOR_ILIKE),
199
        new LabeledValueImpl(i18n.getTranslation("_Not_equals_to"), ExpressionBuilder.OPERATOR_NE),
200
        new LabeledValueImpl(i18n.getTranslation("_Greater_than"), ExpressionBuilder.OPERATOR_GT),
201
        new LabeledValueImpl(i18n.getTranslation("_Greater_or_equal_to"), ExpressionBuilder.OPERATOR_GE),
202
        new LabeledValueImpl(i18n.getTranslation("_Less_than"), ExpressionBuilder.OPERATOR_LT),
203
        new LabeledValueImpl(i18n.getTranslation("_Less_or_equal_to"), ExpressionBuilder.OPERATOR_LE)
204
      };
205

    
206
      logicalOperators = new LabeledValue[]{
207
        new LabeledValueImpl(i18n.getTranslation("_Or"), ExpressionBuilder.OPERATOR_OR),
208
        new LabeledValueImpl(i18n.getTranslation("_And"), ExpressionBuilder.OPERATOR_AND)
209
      };
210

    
211
      this.lblExtraFields.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
212

    
213
      this.ddnFields = toolsSwingManager.createDropDown(lblFields);
214
      this.ddnFields.setVisibleDropdownArrow(false);
215
      this.ddnRelationalOperators = toolsSwingManager.createDropDown(lblRelationalOperators);
216
      this.ddnRelationalOperators.setVisibleDropdownArrow(false);
217
      if (lblLogicalOperators != null) {
218
        this.ddnLogicalOperators = toolsSwingManager.createDropDown(lblLogicalOperators);
219
        this.ddnLogicalOperators.setVisibleDropdownArrow(false);
220
      }
221

    
222
      DefaultComboBoxModel modelRelationalOperators = new DefaultComboBoxModel();
223
      for (LabeledValue op : relationalOperators) {
224
        modelRelationalOperators.addElement(op);
225
      }
226
      this.ddnRelationalOperators.setModel(modelRelationalOperators);
227

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

    
273
        }
274
      });
275

    
276
      this.lblExtraFields.addMouseListener(new MouseAdapter() {
277
        @Override
278
        public void mouseClicked(MouseEvent e) {
279
          doSelectMoreFields();
280
        }
281
      });
282
      clear();
283
    } catch (Exception ex) {
284
      throw new RuntimeException(ex);
285
    }
286
  }
287

    
288
  private FeatureType getFeatureType() {
289
    try {
290
      return this.store.getDefaultFeatureType();
291
    } catch (DataException ex) {
292
      return null;
293
    }
294
  }
295

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

    
316
  }
317

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

    
377
  public void clear() {
378
    this.ddnRelationalOperators.setSelectedIndex(0);
379
    if (this.ddnLogicalOperators != null) {
380
      this.ddnLogicalOperators.setSelectedIndex(1);
381
    }
382
    this.cboValue.setSelectedIndex(-1);
383
  }
384

    
385
  private void doUpdateValuesList() {
386
    final Field field = (Field) this.ddnFields.getSelectedItem();
387
    if (field == null) {
388
      return;
389
    }
390
    FeatureAttributeDescriptor descriptor = field.getDescriptor();
391
    if( descriptor.getType()==DataTypes.DATE ) {
392
        if( this.dateController == null ) {
393
            this.dateController = ToolsSwingLocator.getToolsSwingManager().createDatePickerController(
394
                    (JTextComponent) this.cboValue.getEditor().getEditorComponent(), 
395
                    null
396
            );
397
        }
398
    } else {
399
        if( this.dateController != null ) {
400
            this.dateController.uninstall();
401
            this.dateController = null;
402
        }
403
    }
404

    
405
    final List<Object> values = new ArrayList<>();
406
    final int limit = 60;
407
    final long timeLimit = System.currentTimeMillis() + limit * 1000;
408
    final DefaultComboBoxModel model = new DefaultComboBoxModel();
409
    this.setEnabled(false);
410
    final FeatureStore theStore = field.getFeatureStore();
411
    final FeatureQuery query = theStore.createFeatureQuery();
412
    query.addAttributeName(field.getDescriptor().getName());
413
    query.setLimit(1000);
414
    Thread th = new Thread(new Runnable() {
415
      @Override
416
      public void run() {
417
        FeatureSet set = null;
418
        try {
419
          set = theStore.getFeatureSet(query);
420
          set.accept(new Visitor() {
421
            @Override
422
            public void visit(Object o) throws VisitCanceledException, BaseException {
423
              Object value = ((Feature) o).get(field.getDescriptor().getName());
424
              if (!values.contains(value)) {
425
                values.add(value);
426
              }
427
              if (System.currentTimeMillis() > timeLimit) {
428
                throw new VisitCanceledException();
429
              }
430
              if (values.size() > 1000) {
431
                throw new VisitCanceledException();
432
              }
433
            }
434
          });
435
        } catch (VisitCanceledException ex) {
436

    
437
        } catch (Exception ex) {
438
          LOGGER.warn("Can't update list of values of '" + field.getLabel() + "'.", ex);
439
        } finally {
440
            DisposeUtils.disposeQuietly(set);
441
        }
442
        List<LabeledValue> elements = new ArrayList<>();
443
        if (!values.isEmpty()) {
444
          LabeledValue[] availableValues = field.getDescriptor().getAvailableValues();
445
          Map<String, String> availableValuesMap = new HashMap<>();
446
          if (availableValues != null) {
447
            for (LabeledValue availableValue : availableValues) {
448
              availableValuesMap.put(
449
                      Objects.toString(availableValue.getValue()),
450
                      availableValue.getLabel()
451
              );
452
            }
453
          }
454
          elements.add(new LabeledValueImpl("", null));
455
          for (Object value : values) {
456
            String key = Objects.toString(value);
457
            String label = availableValuesMap.getOrDefault(key, key);
458
            elements.add(new LabeledValueImpl(label, value));
459
          }
460
          elements.sort(null);
461

    
462
        }
463
        for (LabeledValue element : elements) {
464
          model.addElement(element);
465
        }
466
        SwingUtilities.invokeLater(new Runnable() {
467
          @Override
468
          public void run() {
469
            cboValue.setModel(model);
470
            if (valueAssigned != null) {
471
              cboValue.setSelectedItem(valueAssigned);
472
              valueAssigned = null;
473
            }
474
            setEnabled(true);
475
          }
476
        });
477
      }
478
    });
479
    th.start();
480
  }
481

    
482
  public void setEnabled(boolean enabled) {
483
    this.ddnFields.setEnabled(enabled);
484
    if (this.ddnLogicalOperators != null) {
485
      this.ddnLogicalOperators.setEnabled(enabled);
486
    }
487
    this.ddnRelationalOperators.setEnabled(enabled);
488
    this.lblExtraFields.setEnabled(enabled);
489
  }
490

    
491
  public String getRelationalOperator() {
492
    LabeledValue<String> op = (LabeledValue) this.ddnRelationalOperators.getSelectedItem();
493
    if (op == null) {
494
      return null;
495
    }
496
    return op.getValue();
497
  }
498

    
499
  public int setRelationalOperator(String name) {
500
    int n = 0;
501
    for (LabeledValue relationalOperator : relationalOperators) {
502
      if (StringUtils.equalsIgnoreCase(name, (CharSequence) relationalOperator.getValue())) {
503
        break;
504
      }
505
      n++;
506
    }
507
    if (this.relationalOperators.length <= n) {
508
      return -1;
509
    }
510
    this.ddnRelationalOperators.setSelectedIndex(n);
511
    return n;
512
  }
513

    
514
  public String getLogicalOperator() {
515
    if (this.ddnLogicalOperators == null) {
516
      return null;
517
    }
518
    LabeledValue<String> rel = (LabeledValue) this.ddnLogicalOperators.getSelectedItem();
519
    if (rel == null) {
520
      return null;
521
    }
522
    return rel.getValue();
523
  }
524

    
525
  public void setLogicalOperator(String operator) {
526
    if (this.ddnLogicalOperators == null) {
527
      return;
528
    }
529
    ComboBoxModel model = this.ddnLogicalOperators.getModel();
530
    for (int i = 0; i < model.getSize(); i++) {
531
      LabeledValue modelValue = (LabeledValue) model.getElementAt(i);
532
      String value = (String) modelValue.getValue();
533
      if (StringUtils.equals(value, operator)) {
534
        this.ddnLogicalOperators.setSelectedIndex(i);
535
        break;
536
      }
537
    }
538
  }
539

    
540
  public Object getValue() {
541
    final Field field = (Field) this.ddnFields.getSelectedItem();
542
    if (field == null) {
543
      return null;
544
    }
545
    Object v;
546
    if( this.dateController==null ) {
547
        v = this.cboValue.getSelectedItem();
548
    } else {
549
        v = this.dateController.get();
550
    }
551
    if (v == null) {
552
      return null;
553
    }
554
    if (v instanceof LabeledValue) {
555
      v = ((LabeledValue) v).getValue();
556
      if (v == null) {
557
        return null;
558
      }
559
    }
560
    if (v instanceof CharSequence) {
561
      if (StringUtils.isBlank((CharSequence) v)) {
562
        return null;
563
      }
564
    }
565
    Coercion coercion = field.getDescriptor().getDataType().getCoercion();
566
    try {
567
      return coercion.coerce(v);
568
    } catch (CoercionException ex) {
569
      return null;
570
    }
571
  }
572

    
573
  public void setValue(Object value) {
574
    this.cboValue.setSelectedItem(value);
575
    this.valueAssigned = value;
576
  }
577

    
578
  private Field getCurrentField() {
579
    final Field field = (Field) this.ddnFields.getSelectedItem();
580
    return field;
581
  }
582

    
583
  public int setAttribute(String name) {
584
    ComboBoxModel<Field> model = this.ddnFields.getModel();
585
    for (int i = 0; i < model.getSize(); i++) {
586
      Field x = model.getElementAt(i);
587
      if (StringUtils.equalsIgnoreCase(name, x.getValue())) {
588
        this.setAttribute(i);
589
        return i;
590
      }
591
    }
592
    this.setAttribute(-1);
593
    return -1;
594
  }
595

    
596
  public void setAttribute(int index) {
597
    try {
598
      this.ddnFields.setSelectedIndex(index);
599
    } catch (Exception ex) {
600
      this.ddnFields.setSelectedIndex(-1);
601
    }
602
    doUpdateValuesList();
603
  }
604

    
605
  public int setAttributePath(String[][] pathNames) {
606
    // [[attributeName, storeName],...]
607
    try {
608
      if (pathNames.length == 1) {
609
        String[] path = pathNames[pathNames.length - 1];
610
        String name = path[0];
611
        int index = this.setAttribute(name);
612
        if (index == -1) {
613
          try {
614
            FeatureAttributeDescriptor attrDescriptor = store.getDefaultFeatureType().getAttributeDescriptor(name);
615
            FeatureAttributeDescriptor[] attributePath = new FeatureAttributeDescriptor[]{attrDescriptor};
616
            doAddAndSelect(store, store.getDefaultFeatureType().getAttributeDescriptor(name), attributePath);
617
          } catch (Exception ex) {
618
            LOGGER.warn("Not able to set single path into controller", ex);
619
            return -1;
620
          }
621
        }
622
        return index;
623
      } else {
624
        ComboBoxModel<Field> model = this.ddnFields.getModel();
625
        String[] singleArrayPathNameDescriptors = new String[pathNames.length];
626
        for (int i = 0; i < pathNames.length; i++) {
627
          singleArrayPathNameDescriptors[i] = pathNames[i][0];
628
        }
629
        // check the drop
630
        for (int i = 0; i < model.getSize(); i++) {
631
          Field x = model.getElementAt(i);
632
          String[] arrayDescriptors = new String[x.getPath().length];
633
          FeatureAttributeDescriptor[] path = x.getPath();
634
          for (int j = 0; j < path.length; j++) {
635
            arrayDescriptors[j] = path[j].getName();
636
          }
637
          if (Arrays.equals(singleArrayPathNameDescriptors, arrayDescriptors)) {
638
            this.setAttribute(i);
639
            return i;
640
          }
641
        }
642
        // if not, addit to the drop
643
        DataManager dataManager = DALLocator.getDataManager();
644
        String tableName = pathNames[pathNames.length - 1][1]; // del ultimo path, coger el nombre tabla
645
        FeatureStore theStore = (FeatureStore) dataManager.getStoresRepository().getStore(tableName);
646
        String attributeName = pathNames[pathNames.length - 1][0]; // del ultimo path, coger el nombre attribute
647
        if (theStore != null) {
648
          FeatureAttributeDescriptor attr;
649
          try {
650
            attr = theStore.getDefaultFeatureType().getAttributeDescriptor(attributeName);
651
            FeatureAttributeDescriptor[] attributePath = new FeatureAttributeDescriptor[2];
652
            String firstAttrName = pathNames[0][0];
653
            FeatureAttributeDescriptor firstAttr = store.getDefaultFeatureType().getAttributeDescriptor(firstAttrName);
654
            attributePath[0] = firstAttr;
655

    
656
            attributePath[1] = attr;
657
            doAddAndSelect(theStore, attr, attributePath);
658
            return SIZE_ORDERED_ATTRIBUTES - 1;
659
          } catch (Exception ex) {
660
            LOGGER.warn("Not able to set foreign path into controller", ex);
661
          }
662

    
663
        }
664

    
665
      }
666
    } catch (Exception ex) {
667
      LOGGER.warn("Controller not set.", ex);
668
    }
669
    this.setAttribute(-1);
670
    return -1;
671
  }
672

    
673
  private boolean isTheSameStore(DataStore store1, DataStore store2) {
674
    String store1FullName = store1.getFullName();
675
    String store2FullName = store2.getFullName();
676
    return StringUtils.equalsIgnoreCase(store1FullName, store2FullName);
677
  }
678

    
679
  private String getPrimaryKeyName(FeatureStore store) {
680
    try {
681
      FeatureAttributeDescriptor[] pk = store.getDefaultFeatureType().getPrimaryKey();
682
      if (pk == null || pk.length != 1) {
683
        return null;
684
      }
685
      return pk[0].getName();
686
    } catch (DataException ex) {
687
      return null;
688
    }
689
  }
690

    
691
  private String getForeingKeyName(FeatureStore store, FeatureStore foreingStore) {
692
    try {
693
      for (FeatureAttributeDescriptor descriptor : store.getDefaultFeatureType()) {
694
        if (descriptor.isForeingKey()) {
695
          ForeingKey foreingKey = descriptor.getForeingKey();
696
          if (isTheSameStore(foreingStore, foreingKey.getFeatureStore(null))) {
697
            return descriptor.getName();
698
          }
699
        }
700
      }
701
    } catch (DataException ex) {
702
      return null;
703
    }
704
    return null;
705
  }
706

    
707
  public boolean isValid(StringBuilder message) {
708
    Object value = this.getValue();
709
    if (value == null) {
710
      return true;
711
    }
712
    Field field = this.getCurrentField();
713
    if (field == null) {
714
      return true;
715
    }
716
    if (field.getPath().length > 2) {
717
      message.append("Invalid field '").append(field.getLabel()).append("'.\n");
718
      return false;
719
    }
720
    FeatureAttributeDescriptor descriptor = field.getDescriptor();
721
    switch (this.getRelationalOperator()) {
722
      case ExpressionBuilder.OPERATOR_EQ:
723
      case ExpressionBuilder.OPERATOR_NE:
724
      case ExpressionBuilder.OPERATOR_GT:
725
      case ExpressionBuilder.OPERATOR_GE:
726
      case ExpressionBuilder.OPERATOR_LT:
727
      case ExpressionBuilder.OPERATOR_LE:
728
        try {
729
        descriptor.getDataType().coerce(value);
730
      } catch (CoercionException ex) {
731
        message.append("Invalid value '")
732
                .append(Objects.toString(value))
733
                .append("' for field '")
734
                .append(descriptor.getLabel())
735
                .append("'.");
736
        message.append("\n");
737
        message.append(ex.getMessage());
738
        message.append("\n");
739
        return false;
740
      }
741
      break;
742

    
743
      default:
744
      case ExpressionBuilder.OPERATOR_ILIKE:
745
        break;
746
    }
747
    return true;
748
  }
749

    
750
  public ExpressionBuilder.Value getFilter() {
751
    ExpressionBuilder.Value filter = null;
752

    
753
    Object value = this.getValue();
754
    if (value == null) {
755
      return null;
756
    }
757
    Field field = this.getCurrentField();
758
    if (field == null) {
759
      return null;
760
    }
761
    if (field.getPath().length > 2) {
762
      // No soportado
763
      return null;
764
    }
765
    DataManager dataManager = DALLocator.getDataManager();
766
    DALExpressionBuilder builder = dataManager.createDALExpressionBuilder();
767
    FeatureAttributeDescriptor parentDescriptor = field.getParentDescriptor();
768
    FeatureAttributeDescriptor descriptor = field.getDescriptor();
769

    
770
    ExpressionBuilder.Constant value_constant = null;
771

    
772
    switch (this.getRelationalOperator()) {
773
      case ExpressionBuilder.OPERATOR_EQ:
774
      case ExpressionBuilder.OPERATOR_NE:
775
      case ExpressionBuilder.OPERATOR_GT:
776
      case ExpressionBuilder.OPERATOR_GE:
777
      case ExpressionBuilder.OPERATOR_LT:
778
      case ExpressionBuilder.OPERATOR_LE:
779
        try {
780
        value_constant = builder.expression().constant(
781
                descriptor.getDataType().coerce(value)
782
        );
783
      } catch (CoercionException ex) {
784
        return null;
785
      }
786
      break;
787

    
788
      default:
789
      case ExpressionBuilder.OPERATOR_ILIKE:
790
        value_constant = builder.expression().constant(value);
791
        break;
792
    }
793

    
794
    if (parentDescriptor == null) {
795
      // Se busca en campos de la misma tabla.
796
      filter = builder.expression().binaryOperator(
797
              this.getRelationalOperator(),
798
              builder.expression().column(this.store.getName(),descriptor.getName()),
799
              value_constant
800
      );
801
    } else {
802
      // Se busca en campos de una tabla relacionada.
803
      switch (parentDescriptor.getRelationType()) {
804
        case DynField.RELATION_TYPE_COLLABORATION:
805
        case DynField.RELATION_TYPE_IDENTITY:
806
          filter = builder.expression().binaryOperator(
807
                  this.getRelationalOperator(),
808
                  builder.foreing_value(
809
                          parentDescriptor.getName(),
810
                          descriptor.getName()
811
                  ),
812
                  value_constant
813
          );
814
          break;
815

    
816
        case DynField.RELATION_TYPE_AGGREGATE:
817
        case DynField.RELATION_TYPE_COMPOSITION:
818
          filter = builder.exists(builder.select()
819
                  .column(parentDescriptor.getFeatureType().getPrimaryKey()[0].getName())
820
                  .from(field.getFeatureStore().getName())
821
                  .limit(1)
822
                  .where(
823
                          builder.expression().and(
824
                                  builder.expression().eq(
825
                                          builder.expression().column(
826
                                                  field.getFeatureStore().getName(),
827
                                                  getForeingKeyName(field.getFeatureStore(), this.store)
828
                                          ),
829
                                          builder.expression().column(
830
                                                  this.store.getName(),
831
                                                  getPrimaryKeyName(this.store)
832
                                          )
833
                                  ),
834
                                  builder.expression().binaryOperator(
835
                                          this.getRelationalOperator(),
836
                                          builder.expression().column(
837
                                                  field.getFeatureStore().getName(),
838
                                                  descriptor.getName()
839
                                          ),
840
                                          value_constant
841
                                  )
842
                          )
843
                  )
844
                  .toValue()
845
          );
846
          break;
847
      }
848
    }
849
    return filter;
850
  }
851

    
852
  public JsonObject toJson() {
853
    JsonObjectBuilder fieldBuilder = Json.createObjectBuilder();
854

    
855
    JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
856
    for (FeatureAttributeDescriptor featureAttributeDescriptor : this.getCurrentField().getPath()) {
857
      JsonArrayBuilder pathArray = Json.createArrayBuilder();
858

    
859
      //first value: name field
860
      String fieldName = featureAttributeDescriptor.getName();
861
      pathArray.add(fieldName);
862
      //second value: name store
863
      String storeName = featureAttributeDescriptor.getFeatureType().getStore().getName();
864
      pathArray.add(storeName);
865

    
866
      arrayBuilder.add(pathArray.build());
867
    }
868
    String relational = this.getRelationalOperator();
869
    Object value = this.getValue();
870
    String strValue = DataTypeUtils.toString(value);
871
    String logical = this.getLogicalOperator();
872

    
873
    fieldBuilder.add("fieldPath", arrayBuilder.build());
874
    fieldBuilder.add("relational", relational);
875
    if (!StringUtils.isEmpty(strValue)) {
876
      fieldBuilder.add("strValue", strValue);
877
    }
878
    if (!StringUtils.isEmpty(logical)) {
879
      fieldBuilder.add("logical", logical);
880
    }
881
    return fieldBuilder.build();
882
  }
883

    
884
  public void fromJson(JsonObject jsonState) {
885
    if (jsonState == null) {
886
      return;
887
    }
888

    
889
    JsonArray fieldPath = jsonState.getJsonArray("fieldPath");
890

    
891
    // array of arrays
892
    String[][] arrayNew = new String[fieldPath.size()][2];
893
    for (int i = 0; i < fieldPath.size(); i++) {
894
      String[] arrayField = new String[2];
895
      arrayField[0] = fieldPath.getJsonArray(i).getString(0);
896
      arrayField[1] = fieldPath.getJsonArray(i).getString(1);
897
      arrayNew[i] = arrayField;
898
    }
899
    this.setAttributePath(arrayNew);  //usar el doAddAndSelect
900

    
901
    String relational = jsonState.getString("relational");
902
    this.setRelationalOperator(relational);
903

    
904
    if (jsonState.containsKey("strValue")) {
905
      String strValue = jsonState.getString("strValue");
906
      this.setValue(strValue);
907
    }
908
    if (jsonState.containsKey("logical")) {
909
      String logical = jsonState.getString("logical");
910
      this.setLogicalOperator(logical);
911
    }
912

    
913
  }
914
}