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 / featuretype / FeatureAttributeTreeModel.java @ 47693

History | View | Annotate | Download (12.6 KB)

1
package org.gvsig.fmap.dal.swing.impl.featuretype;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.HashSet;
6
import java.util.List;
7
import java.util.Set;
8
import java.util.function.Predicate;
9
import javax.swing.event.TreeModelListener;
10
import javax.swing.tree.TreeModel;
11
import javax.swing.tree.TreePath;
12
import org.apache.commons.lang3.StringUtils;
13
import org.gvsig.expressionevaluator.Code;
14
import org.gvsig.expressionevaluator.Codes;
15
import org.gvsig.fmap.dal.DALLocator;
16
import org.gvsig.fmap.dal.DataManager;
17
import org.gvsig.fmap.dal.complements.Search;
18
import org.gvsig.fmap.dal.complements.Search.OrderedAttribute;
19
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
20
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
21
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
22
import org.gvsig.fmap.dal.feature.FeatureStore;
23
import org.gvsig.fmap.dal.feature.FeatureType;
24
import org.gvsig.fmap.dal.feature.ForeingKey;
25
import org.gvsig.fmap.dal.feature.ForeingKey.ContextForeingKey;
26
import org.gvsig.tools.ToolsLocator;
27
import org.gvsig.tools.dynobject.DynField;
28
import org.gvsig.tools.util.LabeledValue;
29
import org.gvsig.tools.util.LabeledValueImpl;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32
import org.gvsig.expressionevaluator.Code.Callable;
33
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
34
import org.gvsig.fmap.dal.feature.FeatureQuery;
35
import org.gvsig.fmap.dal.swing.DALSwingLocator;
36
import org.gvsig.tools.dispose.Disposable;
37
import org.gvsig.tools.dispose.DisposeUtils;
38

    
39
/**
40
 *
41
 * @author jjdelcerro
42
 */
43
@SuppressWarnings("UseSpecificCatch")
44
public class FeatureAttributeTreeModel
45
        implements TreeModel, Disposable {
46

    
47
  private static final Logger LOGGER = LoggerFactory.getLogger(FeatureAttributeTreeModel.class);
48
    private final FeatureQuery query;
49

    
50

    
51
  public interface Node extends LabeledValue<FeatureAttributeDescriptor>, Disposable {
52

    
53
    public FeatureStore getFeatureStore();
54

    
55
    public boolean isRoot();
56

    
57
    public boolean isLeaf();
58

    
59
    public List<Node> getChildren();
60
  }
61

    
62
  private class DefaultNode
63
          extends LabeledValueImpl<FeatureAttributeDescriptor>
64
          implements Node {
65

    
66
    private List<Node> childs;
67
    private FeatureStore store;
68
    private final int type;
69

    
70
    public DefaultNode(FeatureStore store, List<OrderedAttribute> attributes) {
71
      super(store == null ? "" : store.getName(), null);
72
      DisposeUtils.bind(store);
73
      this.store = store;
74
      this.type = OrderedAttribute.TYPE_REGURAL;
75
      this.childs = new ArrayList<>();
76
      for (OrderedAttribute attribute : attributes) {
77
        this.childs.add(new DefaultNode(store, attribute.getDescriptor(), attribute.getType()));
78
      }
79
    }
80

    
81
    private DefaultNode(FeatureStore store, FeatureAttributeDescriptor attribute, int type) {
82
      super(attribute.getLocalizedLabel(), attribute);
83
      DisposeUtils.bind(store);
84
//      LOGGER.info("BIND "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
85
      this.store = store;
86
      this.type = type;
87
      this.childs = null;
88
    }
89

    
90
    public String getLabel(int type) {
91
      String theLabel;
92
      FeatureAttributeDescriptor attrdesc = this.getValue();
93
      if (attrdesc == null) {
94
        theLabel = super.getLabel();
95
      } else {
96
        String tableName = null;
97
        if (attrdesc.isForeingKey()) {
98
          ForeingKey foreingKey = attrdesc.getForeingKey();
99
          tableName = foreingKey.getTableName();
100
        }
101
        theLabel = DALSwingLocator.getDataSwingManager().getAttributeDescriptorLabel(attrdesc, tableName);
102
      }
103
      switch (type) {
104
        case Search.OrderedAttribute.TYPE_REGURAL:
105
          break;
106
        case Search.OrderedAttribute.TYPE_FAVORITE:
107
          theLabel = "<html><b>" + theLabel + "</b></html>";
108
          break;
109
        case Search.OrderedAttribute.TYPE_RECENT:
110
          theLabel = "<html><i><b>" + theLabel + "</b></i></html>";
111
          break;
112
      }
113
      return theLabel;
114
    }
115

    
116
    @Override
117
    public String getLabel() {
118
      return this.getLabel(this.type);
119
    }
120

    
121
    @Override
122
    public FeatureStore getFeatureStore() {
123
      return this.store;
124
    }
125

    
126
    @Override
127
    public boolean isRoot() {
128
      return this.getValue() == null;
129
    }
130

    
131
    @Override
132
    public List<Node> getChildren() {
133
      if (showRelations && this.childs == null) {
134
        FeatureAttributeDescriptor descriptor = this.getValue();
135
        try {
136
          this.childs = Collections.EMPTY_LIST;
137
          switch (descriptor.getRelationType()) {
138
            case DynField.RELATION_TYPE_IDENTITY:
139
            case DynField.RELATION_TYPE_COLLABORATION:
140
              if (this.getValue().isForeingKey()) {
141
                ForeingKey foreingKey = this.getValue().getForeingKey();
142
                ContextForeingKey context = foreingKey.createContext();
143
                // Ojo, no liberamos el contexto para que no se destruya el store.
144
                try {
145
                    FeatureStore theStore = foreingKey.getFeatureStore(context);
146
                    if (theStore == null) {
147
                      this.childs = Collections.EMPTY_LIST;
148
                    } else {
149
                      FeatureType featureType = foreingKey.getFeatureType(context);
150
                      String fullName = theStore.getFullName();
151
                      if (stores.contains(fullName)) {
152
                        // Si ya hemos a?adido el store al arbol no lo volvemos a a?adir.
153
                        this.childs = Collections.EMPTY_LIST;
154
                      } else {
155
                        Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get(
156
                                Search.COMPLEMENT_MANE, featureType
157
                        );
158
                        List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
159
                                filterByDataType,
160
                                Search.LABEL_ORDER,
161
                                -1
162
                        );
163
                        this.childs = new ArrayList<>();
164
                        for (Search.OrderedAttribute attribute : attributes) {
165
                          this.childs.add(new DefaultNode(theStore, attribute.getDescriptor(), attribute.getType()));
166
                        }
167
                        stores.add(fullName);
168
                      }
169
                    }
170
                } finally {
171
                    context.dispose();
172
                }
173
              }
174
              break;
175

    
176
            case DynField.RELATION_TYPE_COMPOSITION:
177
            case DynField.RELATION_TYPE_AGGREGATE:
178
              FeatureAttributeEmulator emulator = descriptor.getFeatureAttributeEmulator();
179
              if( emulator instanceof FeatureAttributeEmulatorExpression) {
180
                FeatureAttributeEmulatorExpression emulatorExp = (FeatureAttributeEmulatorExpression) emulator;
181
                Code code = emulatorExp.getExpression().getCode();
182
                if( code.code()==Code.CALLABLE ) {
183
                  Callable caller = (Callable) code;
184
                  if( StringUtils.equalsIgnoreCase(caller.name(), "SELECT") ) {
185
                    Codes parameters = caller.parameters();
186
                    String tableName = (String) ((Code.Identifier)(parameters.get(1))).name();
187
                    DataManager dataManager = DALLocator.getDataManager();
188
                    FeatureStore theStore = (FeatureStore) dataManager.getStoresRepository().getStore(tableName);
189
                    if (theStore == null) {
190
                      this.childs = Collections.EMPTY_LIST;
191
                    } else {
192
                      FeatureType featureType = theStore.getDefaultFeatureType();
193
                      String fullName = theStore.getFullName();
194
                      if (stores.contains(fullName)) {
195
                        // Si ya hemos a?adido el store al arbol no lo volvemos a a?adir.
196
                        this.childs = Collections.EMPTY_LIST;
197
                      } else {
198
                        Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get(
199
                                Search.COMPLEMENT_MANE, featureType
200
                        );
201
                        List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
202
                                filterByDataType,
203
                                Search.LABEL_ORDER,
204
                                -1
205
                        );
206
                        this.childs = new ArrayList<>();
207
                        for (Search.OrderedAttribute attribute : attributes) {
208
                          this.childs.add(new DefaultNode(theStore, attribute.getDescriptor(), attribute.getType()));
209
                        }
210
                        stores.add(fullName);
211
                        DisposeUtils.disposeQuietly(theStore);
212
                      }
213
                    }
214
                  }
215
                }
216
              }
217
              break;
218

    
219
            case DynField.RELATION_TYPE_NONE: 
220
            default:
221
              break;
222
          }
223
        } catch(Exception ex) {
224
          this.childs = Collections.EMPTY_LIST;
225
          LOGGER.warn("Can't get childs of "+descriptor.getName(),ex);
226
        }
227
      }
228
      return this.childs;
229
    }
230

    
231
    @Override
232
    public boolean isLeaf() {
233
      return this.getChildren().isEmpty();
234
    }
235

    
236
    @Override
237
    public void dispose() {
238
//       LOGGER.info("DISPOSE "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
239
       DisposeUtils.disposeQuietly(this.store);
240
       this.store = null;
241
       if (this.childs!=null) {
242
           for (Node child : this.childs) {
243
               child.dispose();
244
           }
245
           this.childs = null;
246
       }
247
    }
248
  }
249

    
250
  private final Set<String> stores;
251
  private final DefaultNode root;
252
  private final Predicate<FeatureAttributeDescriptor> filterByDataType;
253
  private boolean showRelations;
254

    
255
  public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType) {
256
    this(store, featureType, showRelations, filterByDataType, null);
257
  }
258
  
259
  public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType, FeatureQuery query) {
260
      this.query = query;
261
    if (filterByDataType == null) {
262
      this.filterByDataType = Search.ALL_FILTER;
263
    } else {
264
      this.filterByDataType = filterByDataType;
265
    }
266
    if (featureType==null) {
267
        featureType = store.getDefaultFeatureTypeQuietly();
268
    }
269
    List<FeatureAttributeDescriptor> extra = null;
270
    if( this.query != null ) {
271
        FeatureExtraColumns extraColumns = this.query.getExtraColumns();
272
        if( !extraColumns.isEmpty() ) {
273
            extra = new ArrayList<>();
274
            for (FeatureAttributeDescriptor extraColumn : extraColumns) {
275
                extra.add(extraColumn);
276
            }
277
        }
278
    }
279

    
280
    Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get(
281
            Search.COMPLEMENT_MANE, featureType
282
    );
283
    List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
284
            filterByDataType,
285
            Search.LABEL_ORDER,
286
            -1,
287
            extra
288
    );
289
    this.root = new DefaultNode(store, attributes);
290
    this.stores = new HashSet<>();
291
    this.showRelations = showRelations;
292
  }
293
  
294
  @Override
295
  public Object getRoot() {
296
    return this.root;
297
  }
298

    
299
  @Override
300
  public int getChildCount(Object parent) {
301
    DefaultNode node = (DefaultNode) parent;
302
    return node.getChildren().size();
303
  }
304

    
305
  @Override
306
  public Object getChild(Object parent, int index) {
307
    DefaultNode node = (DefaultNode) parent;
308
    if(node.getChildren()==null) {
309
        return null;
310
    }
311
    return node.getChildren().get(index);
312
  }
313

    
314
  @Override
315
  public boolean isLeaf(Object node) {
316
    return ((DefaultNode) node).isLeaf();
317
  }
318

    
319
  @Override
320
  public int getIndexOfChild(Object parent, Object child) {
321
    try {
322
      DefaultNode parantNode = (DefaultNode) parent;
323
      DefaultNode childNode = (DefaultNode) child;
324
      int index = 0;
325
      for (Node node : parantNode.getChildren()) {
326
        if (StringUtils.equalsIgnoreCase(childNode.getValue().getName(), node.getValue().getName())) {
327
          return index;
328
        }
329
        index++;
330
      }
331
    } catch (Exception ex) {
332

    
333
    }
334
    return 0;
335
  }
336

    
337
  @Override
338
  public void valueForPathChanged(TreePath path, Object newValue) {
339
  }
340

    
341
  @Override
342
  public void addTreeModelListener(TreeModelListener l) {
343
  }
344

    
345
  @Override
346
  public void removeTreeModelListener(TreeModelListener l) {
347
  }
348
  
349
    @Override
350
    public void dispose() {
351
       if(this.root!=null) {
352
           this.root.dispose();
353
       } 
354
    }
355
  
356
  
357

    
358
}