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 @ 46452
History | View | Annotate | Download (11.5 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 | 44351 | jjdelcerro | import static org.gvsig.fmap.dal.swing.impl.searchpanel.DefaultSearchPanel.getAttributeDescriptorLabel; |
27 | 44262 | jjdelcerro | import org.gvsig.tools.ToolsLocator; |
28 | 44740 | jjdelcerro | import org.gvsig.tools.dynobject.DynField; |
29 | 44262 | jjdelcerro | import org.gvsig.tools.util.LabeledValue; |
30 | import org.gvsig.tools.util.LabeledValueImpl; |
||
31 | 44740 | jjdelcerro | import org.slf4j.Logger; |
32 | import org.slf4j.LoggerFactory; |
||
33 | 44752 | jjdelcerro | import org.gvsig.expressionevaluator.Code.Callable; |
34 | 45295 | omartinez | import org.gvsig.tools.dispose.Disposable; |
35 | import org.gvsig.tools.dispose.DisposeUtils; |
||
36 | 44262 | jjdelcerro | |
37 | /**
|
||
38 | *
|
||
39 | * @author jjdelcerro
|
||
40 | */
|
||
41 | 44263 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
42 | 44713 | jjdelcerro | public class FeatureAttributeTreeModel |
43 | 45295 | omartinez | implements TreeModel, Disposable { |
44 | 44262 | jjdelcerro | |
45 | 44740 | jjdelcerro | private static final Logger LOGGER = LoggerFactory.getLogger(FeatureAttributeTreeModel.class); |
46 | 44262 | jjdelcerro | |
47 | 45295 | omartinez | |
48 | public interface Node extends LabeledValue<FeatureAttributeDescriptor>, Disposable { |
||
49 | |||
50 | 44740 | jjdelcerro | public FeatureStore getFeatureStore();
|
51 | 44262 | jjdelcerro | |
52 | 44740 | jjdelcerro | public boolean isRoot(); |
53 | 44262 | jjdelcerro | |
54 | 44740 | jjdelcerro | public boolean isLeaf(); |
55 | 44262 | jjdelcerro | |
56 | 44740 | jjdelcerro | public List<Node> getChildren(); |
57 | } |
||
58 | 44262 | jjdelcerro | |
59 | 44740 | jjdelcerro | private class DefaultNode |
60 | extends LabeledValueImpl<FeatureAttributeDescriptor>
|
||
61 | implements Node {
|
||
62 | 44262 | jjdelcerro | |
63 | 44740 | jjdelcerro | private List<Node> childs; |
64 | private final FeatureStore store; |
||
65 | private final int type; |
||
66 | 44263 | jjdelcerro | |
67 | 44740 | jjdelcerro | public DefaultNode(FeatureStore store, List<OrderedAttribute> attributes) { |
68 | super(store == null ? "" : store.getName(), null); |
||
69 | 45295 | omartinez | DisposeUtils.bind(store); |
70 | 44740 | jjdelcerro | this.store = store;
|
71 | this.type = OrderedAttribute.TYPE_REGURAL;
|
||
72 | this.childs = new ArrayList<>(); |
||
73 | for (OrderedAttribute attribute : attributes) {
|
||
74 | this.childs.add(new DefaultNode(store, attribute.getDescriptor(), attribute.getType())); |
||
75 | } |
||
76 | } |
||
77 | 44262 | jjdelcerro | |
78 | 44740 | jjdelcerro | private DefaultNode(FeatureStore store, FeatureAttributeDescriptor attribute, int type) { |
79 | super(attribute.getLocalizedLabel(), attribute);
|
||
80 | 45295 | omartinez | DisposeUtils.bind(store); |
81 | 44740 | jjdelcerro | this.store = store;
|
82 | this.type = type;
|
||
83 | this.childs = null; |
||
84 | 44262 | jjdelcerro | } |
85 | |||
86 | 44740 | jjdelcerro | public String getLabel(int type) { |
87 | String theLabel;
|
||
88 | FeatureAttributeDescriptor attrdesc = this.getValue();
|
||
89 | if (attrdesc == null) { |
||
90 | theLabel = super.getLabel();
|
||
91 | } else {
|
||
92 | String tableName = null; |
||
93 | if (attrdesc.isForeingKey()) {
|
||
94 | ForeingKey foreingKey = attrdesc.getForeingKey(); |
||
95 | tableName = foreingKey.getTableName(); |
||
96 | 44263 | jjdelcerro | } |
97 | 44740 | jjdelcerro | theLabel = getAttributeDescriptorLabel(attrdesc, tableName); |
98 | } |
||
99 | switch (type) {
|
||
100 | case Search.OrderedAttribute.TYPE_REGURAL:
|
||
101 | break;
|
||
102 | case Search.OrderedAttribute.TYPE_FAVORITE:
|
||
103 | theLabel = "<html><b>" + theLabel + "</b></html>"; |
||
104 | break;
|
||
105 | case Search.OrderedAttribute.TYPE_RECENT:
|
||
106 | theLabel = "<html><i><b>" + theLabel + "</b></i></html>"; |
||
107 | break;
|
||
108 | } |
||
109 | return theLabel;
|
||
110 | 44262 | jjdelcerro | } |
111 | |||
112 | @Override
|
||
113 | 44740 | jjdelcerro | public String getLabel() { |
114 | return this.getLabel(this.type); |
||
115 | 44262 | jjdelcerro | } |
116 | |||
117 | @Override
|
||
118 | 44740 | jjdelcerro | public FeatureStore getFeatureStore() {
|
119 | return this.store; |
||
120 | 44262 | jjdelcerro | } |
121 | |||
122 | @Override
|
||
123 | 44740 | jjdelcerro | public boolean isRoot() { |
124 | return this.getValue() == null; |
||
125 | 44262 | jjdelcerro | } |
126 | |||
127 | @Override
|
||
128 | 44740 | jjdelcerro | public List<Node> getChildren() { |
129 | if (showRelations && this.childs == null) { |
||
130 | FeatureAttributeDescriptor descriptor = this.getValue();
|
||
131 | 44262 | jjdelcerro | try {
|
132 | 44744 | jjdelcerro | this.childs = Collections.EMPTY_LIST; |
133 | 44740 | jjdelcerro | switch (descriptor.getRelationType()) {
|
134 | case DynField.RELATION_TYPE_IDENTITY:
|
||
135 | case DynField.RELATION_TYPE_COLLABORATION:
|
||
136 | if (this.getValue().isForeingKey()) { |
||
137 | ForeingKey foreingKey = this.getValue().getForeingKey();
|
||
138 | ContextForeingKey context = foreingKey.createContext(); |
||
139 | // Ojo, no liberamos el contexto para que no se destruya el store.
|
||
140 | 45180 | omartinez | try {
|
141 | FeatureStore theStore = foreingKey.getFeatureStore(context); |
||
142 | if (theStore == null) { |
||
143 | this.childs = Collections.EMPTY_LIST; |
||
144 | } else {
|
||
145 | FeatureType featureType = foreingKey.getFeatureType(context); |
||
146 | String fullName = theStore.getFullName();
|
||
147 | if (stores.contains(fullName)) {
|
||
148 | // Si ya hemos a?adido el store al arbol no lo volvemos a a?adir.
|
||
149 | this.childs = Collections.EMPTY_LIST; |
||
150 | } else {
|
||
151 | Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get( |
||
152 | Search.COMPLEMENT_MANE, featureType |
||
153 | ); |
||
154 | List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
|
||
155 | filterByDataType, |
||
156 | Search.LABEL_ORDER, |
||
157 | -1
|
||
158 | ); |
||
159 | this.childs = new ArrayList<>(); |
||
160 | for (Search.OrderedAttribute attribute : attributes) {
|
||
161 | this.childs.add(new DefaultNode(theStore, attribute.getDescriptor(), attribute.getType())); |
||
162 | } |
||
163 | stores.add(fullName); |
||
164 | } |
||
165 | 44740 | jjdelcerro | } |
166 | 45180 | omartinez | } finally {
|
167 | context.dispose(); |
||
168 | 44262 | jjdelcerro | } |
169 | 44740 | jjdelcerro | } |
170 | break;
|
||
171 | 44262 | jjdelcerro | |
172 | 44740 | jjdelcerro | case DynField.RELATION_TYPE_COMPOSITION:
|
173 | case DynField.RELATION_TYPE_AGGREGATE:
|
||
174 | FeatureAttributeEmulator emulator = descriptor.getFeatureAttributeEmulator(); |
||
175 | if( emulator instanceof FeatureAttributeEmulatorExpression) { |
||
176 | FeatureAttributeEmulatorExpression emulatorExp = (FeatureAttributeEmulatorExpression) emulator; |
||
177 | Code code = emulatorExp.getExpression().getCode(); |
||
178 | 44752 | jjdelcerro | if( code.code()==Code.CALLABLE ) {
|
179 | Callable caller = (Callable) code; |
||
180 | 44748 | jjdelcerro | if( StringUtils.equalsIgnoreCase(caller.name(), "SELECT") ) { |
181 | Codes parameters = caller.parameters(); |
||
182 | 44750 | jjdelcerro | String tableName = (String) ((Code.Identifier)(parameters.get(1))).name(); |
183 | 44740 | jjdelcerro | DataManager dataManager = DALLocator.getDataManager(); |
184 | FeatureStore theStore = (FeatureStore) dataManager.getStoresRepository().getStore(tableName); |
||
185 | if (theStore == null) { |
||
186 | this.childs = Collections.EMPTY_LIST; |
||
187 | } else {
|
||
188 | FeatureType featureType = theStore.getDefaultFeatureType(); |
||
189 | String fullName = theStore.getFullName();
|
||
190 | if (stores.contains(fullName)) {
|
||
191 | // Si ya hemos a?adido el store al arbol no lo volvemos a a?adir.
|
||
192 | this.childs = Collections.EMPTY_LIST; |
||
193 | } else {
|
||
194 | Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get( |
||
195 | Search.COMPLEMENT_MANE, featureType |
||
196 | ); |
||
197 | List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
|
||
198 | filterByDataType, |
||
199 | Search.LABEL_ORDER, |
||
200 | -1
|
||
201 | ); |
||
202 | this.childs = new ArrayList<>(); |
||
203 | for (Search.OrderedAttribute attribute : attributes) {
|
||
204 | this.childs.add(new DefaultNode(theStore, attribute.getDescriptor(), attribute.getType())); |
||
205 | } |
||
206 | stores.add(fullName); |
||
207 | 45295 | omartinez | DisposeUtils.disposeQuietly(theStore); |
208 | 44740 | jjdelcerro | } |
209 | } |
||
210 | } |
||
211 | } |
||
212 | } |
||
213 | break;
|
||
214 | |||
215 | case DynField.RELATION_TYPE_NONE:
|
||
216 | default:
|
||
217 | break;
|
||
218 | } |
||
219 | } catch(Exception ex) { |
||
220 | this.childs = Collections.EMPTY_LIST; |
||
221 | LOGGER.warn("Can't get childs of "+descriptor.getName(),ex);
|
||
222 | 44262 | jjdelcerro | } |
223 | 44740 | jjdelcerro | } |
224 | return this.childs; |
||
225 | 44262 | jjdelcerro | } |
226 | |||
227 | @Override
|
||
228 | 44740 | jjdelcerro | public boolean isLeaf() { |
229 | return this.getChildren().isEmpty(); |
||
230 | 44262 | jjdelcerro | } |
231 | 45295 | omartinez | |
232 | @Override
|
||
233 | public void dispose() { |
||
234 | DisposeUtils.disposeQuietly(store); |
||
235 | if (this.childs!=null) { |
||
236 | for (Node child : childs) {
|
||
237 | child.dispose(); |
||
238 | } |
||
239 | } |
||
240 | } |
||
241 | 44740 | jjdelcerro | } |
242 | 44262 | jjdelcerro | |
243 | 44740 | jjdelcerro | private final Set<String> stores; |
244 | private final DefaultNode root; |
||
245 | private final Predicate<FeatureAttributeDescriptor> filterByDataType; |
||
246 | private boolean showRelations; |
||
247 | |||
248 | 45227 | omartinez | public FeatureAttributeTreeModel(FeatureStore store, FeatureType featureType, boolean showRelations, Predicate<FeatureAttributeDescriptor> filterByDataType) { |
249 | 44740 | jjdelcerro | if (filterByDataType == null) { |
250 | this.filterByDataType = Search.ALL_FILTER;
|
||
251 | } else {
|
||
252 | this.filterByDataType = filterByDataType;
|
||
253 | 44262 | jjdelcerro | } |
254 | 45227 | omartinez | if (featureType==null) { |
255 | featureType = store.getDefaultFeatureTypeQuietly(); |
||
256 | 44740 | jjdelcerro | } |
257 | 45227 | omartinez | |
258 | 44740 | jjdelcerro | Search featureTypeSearch = (Search) ToolsLocator.getComplementsManager().get( |
259 | Search.COMPLEMENT_MANE, featureType |
||
260 | ); |
||
261 | List<Search.OrderedAttribute> attributes = featureTypeSearch.getOrderedAttributes(
|
||
262 | filterByDataType, |
||
263 | Search.LABEL_ORDER, |
||
264 | -1
|
||
265 | ); |
||
266 | this.root = new DefaultNode(store, attributes); |
||
267 | this.stores = new HashSet<>(); |
||
268 | this.showRelations = showRelations;
|
||
269 | } |
||
270 | 44262 | jjdelcerro | |
271 | 44740 | jjdelcerro | @Override
|
272 | public Object getRoot() { |
||
273 | return this.root; |
||
274 | } |
||
275 | |||
276 | @Override
|
||
277 | public int getChildCount(Object parent) { |
||
278 | DefaultNode node = (DefaultNode) parent; |
||
279 | return node.getChildren().size();
|
||
280 | } |
||
281 | |||
282 | @Override
|
||
283 | public Object getChild(Object parent, int index) { |
||
284 | DefaultNode node = (DefaultNode) parent; |
||
285 | 45180 | omartinez | if(node.getChildren()==null) { |
286 | return null; |
||
287 | } |
||
288 | 44740 | jjdelcerro | return node.getChildren().get(index);
|
289 | } |
||
290 | |||
291 | @Override
|
||
292 | public boolean isLeaf(Object node) { |
||
293 | return ((DefaultNode) node).isLeaf();
|
||
294 | } |
||
295 | |||
296 | @Override
|
||
297 | public int getIndexOfChild(Object parent, Object child) { |
||
298 | try {
|
||
299 | DefaultNode parantNode = (DefaultNode) parent; |
||
300 | DefaultNode childNode = (DefaultNode) child; |
||
301 | int index = 0; |
||
302 | for (Node node : parantNode.getChildren()) {
|
||
303 | if (StringUtils.equalsIgnoreCase(childNode.getValue().getName(), node.getValue().getName())) {
|
||
304 | return index;
|
||
305 | } |
||
306 | index++; |
||
307 | } |
||
308 | } catch (Exception ex) { |
||
309 | |||
310 | 44262 | jjdelcerro | } |
311 | 44740 | jjdelcerro | return 0; |
312 | } |
||
313 | 44262 | jjdelcerro | |
314 | 44740 | jjdelcerro | @Override
|
315 | public void valueForPathChanged(TreePath path, Object newValue) { |
||
316 | } |
||
317 | |||
318 | @Override
|
||
319 | public void addTreeModelListener(TreeModelListener l) { |
||
320 | } |
||
321 | |||
322 | @Override
|
||
323 | public void removeTreeModelListener(TreeModelListener l) { |
||
324 | } |
||
325 | 45295 | omartinez | |
326 | @Override
|
||
327 | public void dispose() { |
||
328 | if(this.root!=null) { |
||
329 | this.root.dispose();
|
||
330 | } |
||
331 | } |
||
332 | |||
333 | |||
334 | 44740 | jjdelcerro | |
335 | 44262 | jjdelcerro | } |