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

History | View | Annotate | Download (13.7 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.Locale;
8
import java.util.Set;
9
import java.util.function.Predicate;
10
import java.util.function.Supplier;
11
import javax.swing.event.TreeModelListener;
12
import javax.swing.tree.TreeModel;
13
import javax.swing.tree.TreePath;
14
import org.apache.commons.lang3.StringUtils;
15
import org.gvsig.expressionevaluator.Code;
16
import org.gvsig.expressionevaluator.Codes;
17
import org.gvsig.fmap.dal.DALLocator;
18
import org.gvsig.fmap.dal.DataManager;
19
import org.gvsig.fmap.dal.complements.Search;
20
import org.gvsig.fmap.dal.complements.Search.OrderedAttribute;
21
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
22
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
23
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
24
import org.gvsig.fmap.dal.feature.FeatureStore;
25
import org.gvsig.fmap.dal.feature.FeatureType;
26
import org.gvsig.fmap.dal.feature.ForeingKey;
27
import org.gvsig.fmap.dal.feature.ForeingKey.ContextForeingKey;
28
import org.gvsig.tools.ToolsLocator;
29
import org.gvsig.tools.dynobject.DynField;
30
import org.gvsig.tools.util.LabeledValue;
31
import org.gvsig.tools.util.LabeledValueImpl;
32
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34
import org.gvsig.expressionevaluator.Code.Callable;
35
import org.gvsig.fmap.dal.StoresRepository;
36
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
37
import org.gvsig.fmap.dal.feature.FeatureQuery;
38
import org.gvsig.fmap.dal.feature.OpenFeatureStoreParameters;
39
import org.gvsig.fmap.dal.swing.DALSwingLocator;
40
import org.gvsig.tools.dispose.Disposable;
41
import org.gvsig.tools.dispose.DisposeUtils;
42

    
43
/**
44
 *
45
 * @author jjdelcerro
46
 */
47
@SuppressWarnings("UseSpecificCatch")
48
public class FeatureAttributeTreeModel
49
        implements TreeModel, Disposable {
50

    
51
  private static final Logger LOGGER = LoggerFactory.getLogger(FeatureAttributeTreeModel.class);
52
    private final FeatureQuery query;
53

    
54

    
55
  public interface Node extends LabeledValue<FeatureAttributeDescriptor>, Disposable {
56

    
57
    public FeatureStore getFeatureStore();
58

    
59
    public boolean isRoot();
60

    
61
    public boolean isLeaf();
62

    
63
    public List<Node> getChildren();
64
  }
65

    
66
  private class DefaultNode
67
          extends LabeledValueImpl<FeatureAttributeDescriptor>
68
          implements Node {
69

    
70
    private List<Node> childs;
71
    private Supplier<FeatureStore> store;
72
    private final int type;
73

    
74
    public DefaultNode(String name, Supplier<FeatureStore> store, List<OrderedAttribute> attributes) {
75
      super(name, null);
76
      DisposeUtils.bind(store);
77
      this.store = store;
78
      this.type = OrderedAttribute.TYPE_REGURAL;
79
      this.childs = new ArrayList<>();
80
      for (OrderedAttribute attribute : attributes) {
81
        this.childs.add(new DefaultNode(store, attribute.getDescriptor(), attribute.getType()));
82
      }
83
    }
84

    
85
    private DefaultNode(Supplier<FeatureStore> store, FeatureAttributeDescriptor attribute, int type) {
86
      super(attribute.getLocalizedLabel(), attribute);
87
      DisposeUtils.bind(store);
88
//      LOGGER.info("BIND "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
89
      this.store = store;
90
      this.type = type;
91
      this.childs = null;
92
    }
93

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

    
120
    @Override
121
    public String getLabel() {
122
      return this.getLabel(this.type);
123
    }
124

    
125
    @Override
126
    public FeatureStore getFeatureStore() {
127
      return this.store.get();
128
    }
129

    
130
    @Override
131
    public boolean isRoot() {
132
      return this.getValue() == null;
133
    }
134

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

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

    
231
            case DynField.RELATION_TYPE_NONE: 
232
            default:
233
              break;
234
          }
235
        } catch(Exception ex) {
236
          this.childs = Collections.EMPTY_LIST;
237
          LOGGER.warn("Can't get childs of "+descriptor.getName(),ex);
238
        }
239
      }
240
      return this.childs;
241
    }
242

    
243
    @Override
244
    public boolean isLeaf() {
245
      return this.getChildren().isEmpty();
246
    }
247

    
248
    @Override
249
    public void dispose() {
250
//       LOGGER.info("DISPOSE "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
251
//       DisposeUtils.disposeQuietly(this.store);
252
       this.store = null;
253
       if (this.childs!=null) {
254
           for (Node child : this.childs) {
255
               child.dispose();
256
           }
257
           this.childs = null;
258
       }
259
    }
260
  }
261

    
262
  private final Set<String> stores;
263
  private final DefaultNode root;
264
  private final Predicate<FeatureAttributeDescriptor> filterByDataType;
265
  private boolean showRelations;
266

    
267
  public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType) {
268
    this(store, featureType, showRelations, filterByDataType, null);
269
  }
270
  
271
  public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType, FeatureQuery query) {
272
      this.query = query;
273
    if (filterByDataType == null) {
274
      this.filterByDataType = Search.ALL_FILTER;
275
    } else {
276
      this.filterByDataType = filterByDataType;
277
    }
278
    if (featureType==null) {
279
        featureType = store.getDefaultFeatureTypeQuietly();
280
    }
281
    List<FeatureAttributeDescriptor> extra = null;
282
    if( this.query != null ) {
283
        FeatureExtraColumns extraColumns = this.query.getExtraColumns();
284
        if( !extraColumns.isEmpty() ) {
285
            extra = new ArrayList<>();
286
            for (FeatureAttributeDescriptor extraColumn : extraColumns) {
287
                extra.add(extraColumn);
288
            }
289
        }
290
    }
291

    
292
    Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get(
293
            Search.COMPLEMENT_MANE, featureType
294
    );
295
    List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
296
            filterByDataType,
297
            Search.LABEL_ORDER,
298
            -1,
299
            extra
300
    );
301
    this.root = new DefaultNode(
302
            store.getName(), 
303
            () -> store,
304
            attributes
305
    );
306
    this.stores = new HashSet<>();
307
    this.showRelations = showRelations;
308
  }
309
  
310
  @Override
311
  public Object getRoot() {
312
    return this.root;
313
  }
314

    
315
  @Override
316
  public int getChildCount(Object parent) {
317
    DefaultNode node = (DefaultNode) parent;
318
    return node.getChildren().size();
319
  }
320

    
321
  @Override
322
  public Object getChild(Object parent, int index) {
323
    DefaultNode node = (DefaultNode) parent;
324
    if(node.getChildren()==null) {
325
        return null;
326
    }
327
    return node.getChildren().get(index);
328
  }
329

    
330
  @Override
331
  public boolean isLeaf(Object node) {
332
    return ((DefaultNode) node).isLeaf();
333
  }
334

    
335
  @Override
336
  public int getIndexOfChild(Object parent, Object child) {
337
    try {
338
      DefaultNode parantNode = (DefaultNode) parent;
339
      DefaultNode childNode = (DefaultNode) child;
340
      int index = 0;
341
      for (Node node : parantNode.getChildren()) {
342
        if (StringUtils.equalsIgnoreCase(childNode.getValue().getName(), node.getValue().getName())) {
343
          return index;
344
        }
345
        index++;
346
      }
347
    } catch (Exception ex) {
348

    
349
    }
350
    return 0;
351
  }
352

    
353
  @Override
354
  public void valueForPathChanged(TreePath path, Object newValue) {
355
  }
356

    
357
  @Override
358
  public void addTreeModelListener(TreeModelListener l) {
359
  }
360

    
361
  @Override
362
  public void removeTreeModelListener(TreeModelListener l) {
363
  }
364
  
365
    @Override
366
    public void dispose() {
367
       if(this.root!=null) {
368
           this.root.dispose();
369
       } 
370
    }
371
  
372
  
373

    
374
}