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 44713 jjdelcerro
package org.gvsig.fmap.dal.swing.impl.featuretype;
2 44262 jjdelcerro
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.HashSet;
6
import java.util.List;
7 47784 jjdelcerro
import java.util.Locale;
8 44262 jjdelcerro
import java.util.Set;
9 44263 jjdelcerro
import java.util.function.Predicate;
10 47784 jjdelcerro
import java.util.function.Supplier;
11 44262 jjdelcerro
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 44740 jjdelcerro
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 44262 jjdelcerro
import org.gvsig.fmap.dal.complements.Search;
20 44337 jjdelcerro
import org.gvsig.fmap.dal.complements.Search.OrderedAttribute;
21 44740 jjdelcerro
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
22 44262 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
23 44740 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
24 44262 jjdelcerro
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 44740 jjdelcerro
import org.gvsig.tools.dynobject.DynField;
30 44262 jjdelcerro
import org.gvsig.tools.util.LabeledValue;
31
import org.gvsig.tools.util.LabeledValueImpl;
32 44740 jjdelcerro
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34 44752 jjdelcerro
import org.gvsig.expressionevaluator.Code.Callable;
35 47784 jjdelcerro
import org.gvsig.fmap.dal.StoresRepository;
36 46501 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
37
import org.gvsig.fmap.dal.feature.FeatureQuery;
38 47784 jjdelcerro
import org.gvsig.fmap.dal.feature.OpenFeatureStoreParameters;
39 46485 fdiaz
import org.gvsig.fmap.dal.swing.DALSwingLocator;
40 45295 omartinez
import org.gvsig.tools.dispose.Disposable;
41
import org.gvsig.tools.dispose.DisposeUtils;
42 44262 jjdelcerro
43
/**
44
 *
45
 * @author jjdelcerro
46
 */
47 44263 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
48 44713 jjdelcerro
public class FeatureAttributeTreeModel
49 45295 omartinez
        implements TreeModel, Disposable {
50 44262 jjdelcerro
51 44740 jjdelcerro
  private static final Logger LOGGER = LoggerFactory.getLogger(FeatureAttributeTreeModel.class);
52 46501 jjdelcerro
    private final FeatureQuery query;
53 44262 jjdelcerro
54 45295 omartinez
55
  public interface Node extends LabeledValue<FeatureAttributeDescriptor>, Disposable {
56
57 44740 jjdelcerro
    public FeatureStore getFeatureStore();
58 44262 jjdelcerro
59 44740 jjdelcerro
    public boolean isRoot();
60 44262 jjdelcerro
61 44740 jjdelcerro
    public boolean isLeaf();
62 44262 jjdelcerro
63 44740 jjdelcerro
    public List<Node> getChildren();
64
  }
65 44262 jjdelcerro
66 44740 jjdelcerro
  private class DefaultNode
67
          extends LabeledValueImpl<FeatureAttributeDescriptor>
68
          implements Node {
69 44262 jjdelcerro
70 44740 jjdelcerro
    private List<Node> childs;
71 47784 jjdelcerro
    private Supplier<FeatureStore> store;
72 44740 jjdelcerro
    private final int type;
73 44263 jjdelcerro
74 47784 jjdelcerro
    public DefaultNode(String name, Supplier<FeatureStore> store, List<OrderedAttribute> attributes) {
75
      super(name, null);
76 45295 omartinez
      DisposeUtils.bind(store);
77 44740 jjdelcerro
      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 44262 jjdelcerro
85 47784 jjdelcerro
    private DefaultNode(Supplier<FeatureStore> store, FeatureAttributeDescriptor attribute, int type) {
86 44740 jjdelcerro
      super(attribute.getLocalizedLabel(), attribute);
87 45295 omartinez
      DisposeUtils.bind(store);
88 46586 fdiaz
//      LOGGER.info("BIND "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
89 44740 jjdelcerro
      this.store = store;
90
      this.type = type;
91
      this.childs = null;
92 44262 jjdelcerro
    }
93
94 44740 jjdelcerro
    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 44263 jjdelcerro
        }
105 46485 fdiaz
        theLabel = DALSwingLocator.getDataSwingManager().getAttributeDescriptorLabel(attrdesc, tableName);
106 44740 jjdelcerro
      }
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 44262 jjdelcerro
    }
119
120
    @Override
121 44740 jjdelcerro
    public String getLabel() {
122
      return this.getLabel(this.type);
123 44262 jjdelcerro
    }
124
125
    @Override
126 44740 jjdelcerro
    public FeatureStore getFeatureStore() {
127 47784 jjdelcerro
      return this.store.get();
128 44262 jjdelcerro
    }
129
130
    @Override
131 44740 jjdelcerro
    public boolean isRoot() {
132
      return this.getValue() == null;
133 44262 jjdelcerro
    }
134
135
    @Override
136 44740 jjdelcerro
    public List<Node> getChildren() {
137
      if (showRelations && this.childs == null) {
138
        FeatureAttributeDescriptor descriptor = this.getValue();
139 44262 jjdelcerro
        try {
140 44744 jjdelcerro
          this.childs = Collections.EMPTY_LIST;
141 44740 jjdelcerro
          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 45180 omartinez
                try {
149 47784 jjdelcerro
//                    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 45180 omartinez
                      this.childs = Collections.EMPTY_LIST;
157
                    } else {
158 47784 jjdelcerro
                      String fullName = theStoreParams.getSourceId();
159 45180 omartinez
                      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 44740 jjdelcerro
                    }
178 45180 omartinez
                } finally {
179
                    context.dispose();
180 44262 jjdelcerro
                }
181 44740 jjdelcerro
              }
182
              break;
183 44262 jjdelcerro
184 44740 jjdelcerro
            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 44752 jjdelcerro
                if( code.code()==Code.CALLABLE ) {
191
                  Callable caller = (Callable) code;
192 44748 jjdelcerro
                  if( StringUtils.equalsIgnoreCase(caller.name(), "SELECT") ) {
193
                    Codes parameters = caller.parameters();
194 44750 jjdelcerro
                    String tableName = (String) ((Code.Identifier)(parameters.get(1))).name();
195 44740 jjdelcerro
                    DataManager dataManager = DALLocator.getDataManager();
196 47784 jjdelcerro
//                    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 44740 jjdelcerro
                      this.childs = Collections.EMPTY_LIST;
203
                    } else {
204 47784 jjdelcerro
//                      FeatureType featureType = theStore.getDefaultFeatureType();
205
                      String fullName = theStoreParams.getSourceId();
206 44740 jjdelcerro
                      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 47784 jjdelcerro
//                        DisposeUtils.disposeQuietly(theStore);
224 44740 jjdelcerro
                      }
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 44262 jjdelcerro
        }
239 44740 jjdelcerro
      }
240
      return this.childs;
241 44262 jjdelcerro
    }
242
243
    @Override
244 44740 jjdelcerro
    public boolean isLeaf() {
245
      return this.getChildren().isEmpty();
246 44262 jjdelcerro
    }
247 45295 omartinez
248
    @Override
249
    public void dispose() {
250 46586 fdiaz
//       LOGGER.info("DISPOSE "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
251 47784 jjdelcerro
//       DisposeUtils.disposeQuietly(this.store);
252 46586 fdiaz
       this.store = null;
253 45295 omartinez
       if (this.childs!=null) {
254 46586 fdiaz
           for (Node child : this.childs) {
255 45295 omartinez
               child.dispose();
256
           }
257 46586 fdiaz
           this.childs = null;
258 45295 omartinez
       }
259
    }
260 44740 jjdelcerro
  }
261 44262 jjdelcerro
262 44740 jjdelcerro
  private final Set<String> stores;
263
  private final DefaultNode root;
264
  private final Predicate<FeatureAttributeDescriptor> filterByDataType;
265
  private boolean showRelations;
266
267 45227 omartinez
  public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType) {
268 46501 jjdelcerro
    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 44740 jjdelcerro
    if (filterByDataType == null) {
274
      this.filterByDataType = Search.ALL_FILTER;
275
    } else {
276
      this.filterByDataType = filterByDataType;
277 44262 jjdelcerro
    }
278 45227 omartinez
    if (featureType==null) {
279
        featureType = store.getDefaultFeatureTypeQuietly();
280 44740 jjdelcerro
    }
281 46501 jjdelcerro
    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 45227 omartinez
292 44740 jjdelcerro
    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 46501 jjdelcerro
            -1,
299
            extra
300 44740 jjdelcerro
    );
301 47784 jjdelcerro
    this.root = new DefaultNode(
302
            store.getName(),
303
            () -> store,
304
            attributes
305
    );
306 44740 jjdelcerro
    this.stores = new HashSet<>();
307
    this.showRelations = showRelations;
308
  }
309 46501 jjdelcerro
310 44740 jjdelcerro
  @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 45180 omartinez
    if(node.getChildren()==null) {
325
        return null;
326
    }
327 44740 jjdelcerro
    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 44262 jjdelcerro
    }
350 44740 jjdelcerro
    return 0;
351
  }
352 44262 jjdelcerro
353 44740 jjdelcerro
  @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 45295 omartinez
365
    @Override
366
    public void dispose() {
367
       if(this.root!=null) {
368
           this.root.dispose();
369
       }
370
    }
371
372
373 44740 jjdelcerro
374 44262 jjdelcerro
}