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 | } |