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