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 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
import java.util.Set;
8 44263 jjdelcerro
import java.util.function.Predicate;
9 44262 jjdelcerro
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 44740 jjdelcerro
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 44262 jjdelcerro
import org.gvsig.fmap.dal.complements.Search;
18 44337 jjdelcerro
import org.gvsig.fmap.dal.complements.Search.OrderedAttribute;
19 44740 jjdelcerro
import org.gvsig.fmap.dal.expressionevaluator.FeatureAttributeEmulatorExpression;
20 44262 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
21 44740 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureAttributeEmulator;
22 44262 jjdelcerro
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 44740 jjdelcerro
import org.gvsig.tools.dynobject.DynField;
28 44262 jjdelcerro
import org.gvsig.tools.util.LabeledValue;
29
import org.gvsig.tools.util.LabeledValueImpl;
30 44740 jjdelcerro
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32 44752 jjdelcerro
import org.gvsig.expressionevaluator.Code.Callable;
33 46501 jjdelcerro
import org.gvsig.fmap.dal.feature.FeatureExtraColumns;
34
import org.gvsig.fmap.dal.feature.FeatureQuery;
35 46485 fdiaz
import org.gvsig.fmap.dal.swing.DALSwingLocator;
36 45295 omartinez
import org.gvsig.tools.dispose.Disposable;
37
import org.gvsig.tools.dispose.DisposeUtils;
38 44262 jjdelcerro
39
/**
40
 *
41
 * @author jjdelcerro
42
 */
43 44263 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
44 44713 jjdelcerro
public class FeatureAttributeTreeModel
45 45295 omartinez
        implements TreeModel, Disposable {
46 44262 jjdelcerro
47 44740 jjdelcerro
  private static final Logger LOGGER = LoggerFactory.getLogger(FeatureAttributeTreeModel.class);
48 46501 jjdelcerro
    private final FeatureQuery query;
49 44262 jjdelcerro
50 45295 omartinez
51
  public interface Node extends LabeledValue<FeatureAttributeDescriptor>, Disposable {
52
53 44740 jjdelcerro
    public FeatureStore getFeatureStore();
54 44262 jjdelcerro
55 44740 jjdelcerro
    public boolean isRoot();
56 44262 jjdelcerro
57 44740 jjdelcerro
    public boolean isLeaf();
58 44262 jjdelcerro
59 44740 jjdelcerro
    public List<Node> getChildren();
60
  }
61 44262 jjdelcerro
62 44740 jjdelcerro
  private class DefaultNode
63
          extends LabeledValueImpl<FeatureAttributeDescriptor>
64
          implements Node {
65 44262 jjdelcerro
66 44740 jjdelcerro
    private List<Node> childs;
67 46586 fdiaz
    private FeatureStore store;
68 44740 jjdelcerro
    private final int type;
69 44263 jjdelcerro
70 44740 jjdelcerro
    public DefaultNode(FeatureStore store, List<OrderedAttribute> attributes) {
71
      super(store == null ? "" : store.getName(), null);
72 45295 omartinez
      DisposeUtils.bind(store);
73 44740 jjdelcerro
      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 44262 jjdelcerro
81 44740 jjdelcerro
    private DefaultNode(FeatureStore store, FeatureAttributeDescriptor attribute, int type) {
82
      super(attribute.getLocalizedLabel(), attribute);
83 45295 omartinez
      DisposeUtils.bind(store);
84 46586 fdiaz
//      LOGGER.info("BIND "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
85 44740 jjdelcerro
      this.store = store;
86
      this.type = type;
87
      this.childs = null;
88 44262 jjdelcerro
    }
89
90 44740 jjdelcerro
    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 44263 jjdelcerro
        }
101 46485 fdiaz
        theLabel = DALSwingLocator.getDataSwingManager().getAttributeDescriptorLabel(attrdesc, tableName);
102 44740 jjdelcerro
      }
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 44262 jjdelcerro
    }
115
116
    @Override
117 44740 jjdelcerro
    public String getLabel() {
118
      return this.getLabel(this.type);
119 44262 jjdelcerro
    }
120
121
    @Override
122 44740 jjdelcerro
    public FeatureStore getFeatureStore() {
123
      return this.store;
124 44262 jjdelcerro
    }
125
126
    @Override
127 44740 jjdelcerro
    public boolean isRoot() {
128
      return this.getValue() == null;
129 44262 jjdelcerro
    }
130
131
    @Override
132 44740 jjdelcerro
    public List<Node> getChildren() {
133
      if (showRelations && this.childs == null) {
134
        FeatureAttributeDescriptor descriptor = this.getValue();
135 44262 jjdelcerro
        try {
136 44744 jjdelcerro
          this.childs = Collections.EMPTY_LIST;
137 44740 jjdelcerro
          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 45180 omartinez
                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 44740 jjdelcerro
                    }
170 45180 omartinez
                } finally {
171
                    context.dispose();
172 44262 jjdelcerro
                }
173 44740 jjdelcerro
              }
174
              break;
175 44262 jjdelcerro
176 44740 jjdelcerro
            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 44752 jjdelcerro
                if( code.code()==Code.CALLABLE ) {
183
                  Callable caller = (Callable) code;
184 44748 jjdelcerro
                  if( StringUtils.equalsIgnoreCase(caller.name(), "SELECT") ) {
185
                    Codes parameters = caller.parameters();
186 44750 jjdelcerro
                    String tableName = (String) ((Code.Identifier)(parameters.get(1))).name();
187 44740 jjdelcerro
                    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 45295 omartinez
                        DisposeUtils.disposeQuietly(theStore);
212 44740 jjdelcerro
                      }
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 44262 jjdelcerro
        }
227 44740 jjdelcerro
      }
228
      return this.childs;
229 44262 jjdelcerro
    }
230
231
    @Override
232 44740 jjdelcerro
    public boolean isLeaf() {
233
      return this.getChildren().isEmpty();
234 44262 jjdelcerro
    }
235 45295 omartinez
236
    @Override
237
    public void dispose() {
238 46586 fdiaz
//       LOGGER.info("DISPOSE "+store.hashCode()+", "+this.getLabel()+", "+this.hashCode());
239
       DisposeUtils.disposeQuietly(this.store);
240
       this.store = null;
241 45295 omartinez
       if (this.childs!=null) {
242 46586 fdiaz
           for (Node child : this.childs) {
243 45295 omartinez
               child.dispose();
244
           }
245 46586 fdiaz
           this.childs = null;
246 45295 omartinez
       }
247
    }
248 44740 jjdelcerro
  }
249 44262 jjdelcerro
250 44740 jjdelcerro
  private final Set<String> stores;
251
  private final DefaultNode root;
252
  private final Predicate<FeatureAttributeDescriptor> filterByDataType;
253
  private boolean showRelations;
254
255 45227 omartinez
  public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType) {
256 46501 jjdelcerro
    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 44740 jjdelcerro
    if (filterByDataType == null) {
262
      this.filterByDataType = Search.ALL_FILTER;
263
    } else {
264
      this.filterByDataType = filterByDataType;
265 44262 jjdelcerro
    }
266 45227 omartinez
    if (featureType==null) {
267
        featureType = store.getDefaultFeatureTypeQuietly();
268 44740 jjdelcerro
    }
269 46501 jjdelcerro
    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 45227 omartinez
280 44740 jjdelcerro
    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 46501 jjdelcerro
            -1,
287
            extra
288 44740 jjdelcerro
    );
289
    this.root = new DefaultNode(store, attributes);
290
    this.stores = new HashSet<>();
291
    this.showRelations = showRelations;
292
  }
293 46501 jjdelcerro
294 44740 jjdelcerro
  @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 45180 omartinez
    if(node.getChildren()==null) {
309
        return null;
310
    }
311 44740 jjdelcerro
    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 44262 jjdelcerro
    }
334 44740 jjdelcerro
    return 0;
335
  }
336 44262 jjdelcerro
337 44740 jjdelcerro
  @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 45295 omartinez
349
    @Override
350
    public void dispose() {
351
       if(this.root!=null) {
352
           this.root.dispose();
353
       }
354
    }
355
356
357 44740 jjdelcerro
358 44262 jjdelcerro
}