comparison gwt-client/src/main/java/org/dive4elements/river/client/client/ui/DatacageWidget.java @ 9220:e3c2ae1887e8

Allow to filter contents of datacage on client side. Allow to override column label of datacage Some code cleanup
author gernotbelger
date Wed, 04 Jul 2018 12:00:51 +0200
parents 93da474506e7
children 84397da33d17
comparison
equal deleted inserted replaced
9219:8642a76f22be 9220:e3c2ae1887e8
6 * documentation coming with Dive4Elements River for details. 6 * documentation coming with Dive4Elements River for details.
7 */ 7 */
8 8
9 package org.dive4elements.river.client.client.ui; 9 package org.dive4elements.river.client.client.ui;
10 10
11 import com.google.gwt.core.client.GWT;
12
13 import com.google.gwt.user.client.rpc.AsyncCallback;
14
15 import com.smartgwt.client.types.SelectionStyle;
16 import com.smartgwt.client.types.TreeModelType;
17
18 import com.smartgwt.client.util.SC;
19
20 import com.smartgwt.client.widgets.Button;
21
22 import com.smartgwt.client.widgets.events.ClickEvent;
23 import com.smartgwt.client.widgets.events.ClickHandler;
24
25 import com.smartgwt.client.widgets.grid.HoverCustomizer;
26 import com.smartgwt.client.widgets.grid.ListGridRecord;
27
28 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
29 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
30
31 import com.smartgwt.client.widgets.layout.VLayout;
32
33 import com.smartgwt.client.widgets.tree.Tree;
34 import com.smartgwt.client.widgets.tree.TreeGrid;
35 import com.smartgwt.client.widgets.tree.TreeNode;
36
37 import java.util.ArrayList; 11 import java.util.ArrayList;
12 import java.util.Collection;
38 import java.util.List; 13 import java.util.List;
39 import java.util.MissingResourceException; 14 import java.util.MissingResourceException;
40 import java.util.Stack; 15 import java.util.Stack;
41 16
42 import org.dive4elements.river.client.client.Config; 17 import org.dive4elements.river.client.client.Config;
43 import org.dive4elements.river.client.client.FLYSConstants; 18 import org.dive4elements.river.client.client.FLYSConstants;
44
45 import org.dive4elements.river.client.client.event.DatacageDoubleClickHandler; 19 import org.dive4elements.river.client.client.event.DatacageDoubleClickHandler;
46 import org.dive4elements.river.client.client.event.DatacageHandler; 20 import org.dive4elements.river.client.client.event.DatacageHandler;
47
48 import org.dive4elements.river.client.client.services.MetaDataService; 21 import org.dive4elements.river.client.client.services.MetaDataService;
49 import org.dive4elements.river.client.client.services.MetaDataServiceAsync; 22 import org.dive4elements.river.client.client.services.MetaDataServiceAsync;
50
51 import org.dive4elements.river.client.shared.model.Artifact;
52 import org.dive4elements.river.client.shared.model.AttrList; 23 import org.dive4elements.river.client.shared.model.AttrList;
53 import org.dive4elements.river.client.shared.model.DataCageNode; 24 import org.dive4elements.river.client.shared.model.DataCageNode;
54 import org.dive4elements.river.client.shared.model.DataCageTree; 25 import org.dive4elements.river.client.shared.model.DataCageTree;
55 import org.dive4elements.river.client.shared.model.ToLoad; 26 import org.dive4elements.river.client.shared.model.ToLoad;
56 import org.dive4elements.river.client.shared.model.User; 27 import org.dive4elements.river.client.shared.model.User;
57 28
29 import com.google.gwt.core.client.GWT;
30 import com.google.gwt.user.client.rpc.AsyncCallback;
31 import com.smartgwt.client.types.SelectionStyle;
32 import com.smartgwt.client.types.TreeModelType;
33 import com.smartgwt.client.util.SC;
34 import com.smartgwt.client.widgets.Button;
35 import com.smartgwt.client.widgets.events.ClickEvent;
36 import com.smartgwt.client.widgets.events.ClickHandler;
37 import com.smartgwt.client.widgets.grid.HoverCustomizer;
38 import com.smartgwt.client.widgets.grid.ListGridRecord;
39 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
40 import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
41 import com.smartgwt.client.widgets.layout.VLayout;
42 import com.smartgwt.client.widgets.tree.Tree;
43 import com.smartgwt.client.widgets.tree.TreeGrid;
44 import com.smartgwt.client.widgets.tree.TreeNode;
45
58 // TODO: refactor, extract ~DataCageGrid 46 // TODO: refactor, extract ~DataCageGrid
59 /** 47 /**
60 * Display tree of, for example, previous calculations and allows 48 * Display tree of, for example, previous calculations and allows
61 * selection in order to access/clone these. 49 * selection in order to access/clone these.
62 */ 50 */
63 public class DatacageWidget 51 public class DatacageWidget extends VLayout {
64 extends VLayout
65 {
66 public static final int MAX_OPEN = 30; 52 public static final int MAX_OPEN = 30;
67 53
68 protected MetaDataServiceAsync metaDataService = 54 public interface DatacageFilter {
69 GWT.create(MetaDataService.class); 55 boolean accept(DataCageNode node);
70 56 }
71 protected FLYSConstants messages = 57
72 GWT.create(FLYSConstants.class); 58 public static final DatacageFilter ACCEPT_ALL_FILTER = new DatacageFilter() {
73 59 @Override
74 protected Artifact artifact; 60 public boolean accept(final DataCageNode node) {
75 protected User user; 61 return true;
76 protected String outs; 62 }
77 protected String parameters; 63 };
78 64
79 protected TreeGrid treeGrid; 65 private final MetaDataServiceAsync metaDataService = GWT.create(MetaDataService.class);
80 protected Tree tree; 66
81 67 private final FLYSConstants messages = GWT.create(FLYSConstants.class);
82 protected ToLoad toLoad; 68
83 69 private final List<DatacageHandler> handlers = new ArrayList<DatacageHandler>();
84 protected List<DatacageHandler> handlers; 70
85 protected List<DatacageDoubleClickHandler> doubleHandlers; 71 private final List<DatacageDoubleClickHandler> doubleHandlers = new ArrayList<DatacageDoubleClickHandler>();
72
73 private final TreeGrid treeGrid;
74
75 private Tree tree;
76
77 private ToLoad toLoad;
86 78
87 /** Layout to show spinning wheel of joy. */ 79 /** Layout to show spinning wheel of joy. */
88 protected VLayout lockScreen; 80 private VLayout lockScreen;
89 81
90 82 private DataCageTree dcTree;
91 public DatacageWidget() { 83
92 handlers = new ArrayList<DatacageHandler>(); 84 private DatacageFilter filter = ACCEPT_ALL_FILTER;
93 doubleHandlers = new ArrayList<DatacageDoubleClickHandler>(); 85
94 } 86 private DatacageWidgetData data;
95 87
96 88 public DatacageWidget(final DatacageWidgetData data) {
97 public DatacageWidget(Artifact artifact, User user) { 89
98 this(artifact, user, null); 90 this.data = data;
99 } 91
100 92 this.toLoad = new ToLoad();
101 public DatacageWidget(Artifact artifact, User user, String outs) {
102 this(artifact, user, outs, true);
103 }
104
105 public DatacageWidget(
106 Artifact artifact,
107 User user,
108 String outs,
109 boolean showButton
110 ) {
111 this(artifact, user, outs, null, showButton);
112 }
113
114
115 public DatacageWidget(
116 Artifact artifact,
117 User user,
118 String outs,
119 String parameters,
120 boolean showButton
121 ) {
122 this();
123
124 this.artifact = artifact;
125 this.user = user;
126 this.outs = outs;
127 this.parameters = parameters;
128
129 toLoad = new ToLoad();
130 93
131 setWidth100(); 94 setWidth100();
132 95
133 tree = new Tree(); 96 this.treeGrid = new TreeGrid();
134 tree.setModelType(TreeModelType.CHILDREN); 97
135 tree.setNameProperty("name"); 98 final String columnLabel = this.data.getColumnLabel();
136 tree.setIdField("id"); 99 if (columnLabel != null)
137 tree.setChildrenProperty("children-nodes"); 100 this.treeGrid.setTreeFieldTitle(columnLabel);
138 tree.setShowRoot(false); 101
139 102 this.treeGrid.setLoadDataOnDemand(false);
140 treeGrid = new TreeGrid(); 103 this.treeGrid.setWidth100();
141 treeGrid.setLoadDataOnDemand(false); 104 this.treeGrid.setHeight100();
142 treeGrid.setWidth100(); 105 this.treeGrid.setShowRoot(false);
143 treeGrid.setHeight100(); 106 this.treeGrid.setNodeIcon("[SKIN]/../blank.gif");
144 treeGrid.setShowRoot(false); 107 this.treeGrid.setShowConnectors(true);
145 treeGrid.setNodeIcon("[SKIN]/../blank.gif"); 108 this.treeGrid.setLoadingMessage(this.messages.databasket_loading());
146 treeGrid.setShowConnectors(true); 109 this.treeGrid.setLoadingDataMessage(this.messages.databasket_loading());
147 treeGrid.setLoadingMessage(messages.databasket_loading()); 110
148 treeGrid.setEmptyMessage(messages.databasket_loading()); 111 // FIXME: other message
149 treeGrid.setLoadingDataMessage(messages.databasket_loading()); 112 this.treeGrid.setEmptyMessage(this.messages.databasket_loading());
150 113
151 treeGrid.setHoverMoveWithMouse(true); 114 this.treeGrid.setHoverMoveWithMouse(true);
152 treeGrid.setCanHover(true); 115 this.treeGrid.setCanHover(true);
153 treeGrid.setShowHover(true); 116 this.treeGrid.setShowHover(true);
154 treeGrid.setHoverOpacity(75); 117 this.treeGrid.setHoverOpacity(75);
155 treeGrid.setHoverWidth(120); 118 this.treeGrid.setHoverWidth(120);
156 119
157 treeGrid.setHoverCustomizer(new HoverCustomizer() { 120 this.treeGrid.setHoverCustomizer(new HoverCustomizer() {
158 @Override 121 @Override
159 public String hoverHTML(Object value, 122 public String hoverHTML(final Object value, final ListGridRecord record, final int rowNum, final int colNum) {
160 ListGridRecord record, 123 if (record instanceof TreeNode) {
161 int rowNum, 124 final TreeNode hoveredTreeNode = (TreeNode) record;
162 int colNum
163 ) {
164 if(record instanceof TreeNode) {
165 TreeNode hoveredTreeNode = (TreeNode)record;
166 String info = hoveredTreeNode.getAttribute("info"); 125 String info = hoveredTreeNode.getAttribute("info");
167 if (info == null) { 126 if (info == null) {
168 info = hoveredTreeNode.getName(); 127 info = hoveredTreeNode.getName();
169 } 128 }
170 return info; 129 return info;
171 } 130 }
172 else { 131
173 return "";// should not happen 132 return "";// should not happen
174 }
175 } 133 }
176 }); 134 });
177 135
178 treeGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() { 136 this.treeGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() {
179 @Override 137 @Override
180 public void onRecordDoubleClick(RecordDoubleClickEvent event) { 138 public void onRecordDoubleClick(final RecordDoubleClickEvent event) {
181 doubleClickedOnTree(event); 139 doubleClickedOnTree(event);
182 } 140 }
183 }); 141 });
184 142
185 addMember(treeGrid); 143 addMember(this.treeGrid);
186 144
187 if (showButton) { 145 if (data.isShowButton())
188 addMember(createPlusButton()); 146 addMember(createPlusButton());
189 }
190 147
191 triggerTreeBuilding(); 148 triggerTreeBuilding();
192 } 149 }
193 150
151 public void setFilter(final DatacageFilter filter) {
152 assert (filter != null);
153
154 this.filter = filter;
155
156 if (this.dcTree != null)
157 updateTree(this.dcTree);
158 }
159
194 /** Disable input, show spinning wheel of joy. */ 160 /** Disable input, show spinning wheel of joy. */
195 public void lockUI() { 161 private void lockUI() {
196 lockScreen = ScreenLock.lockUI(this, lockScreen); 162 this.lockScreen = ScreenLock.lockUI(this, this.lockScreen);
197 } 163 }
198 164
199 /** Enable input, remove grey, remove spinning wheel of joy. */ 165 /** Enable input, remove grey, remove spinning wheel of joy. */
200 public void unlockUI() { 166 protected final void unlockUI() {
201 ScreenLock.unlockUI(this, lockScreen); 167 ScreenLock.unlockUI(this, this.lockScreen);
202 } 168 }
203
204 /**
205 * @param handler Handler to be added (notified on add-action).
206 */
207 public DatacageWidget(Artifact artifact, User user, String outs,
208 DatacageHandler handler) {
209 this(artifact, user, outs);
210 this.addDatacageHandler(handler);
211 }
212
213
214 public DatacageWidget(
215 Artifact artifact,
216 User user,
217 String outs,
218 DatacageHandler handler,
219 String parameters
220 ) {
221 this(artifact, user, outs, handler);
222 this.parameters = parameters;
223 }
224
225 169
226 /** 170 /**
227 * Sets whether more than one item can be selected. 171 * Sets whether more than one item can be selected.
228 * @param multi if true, allow mutliple selections. 172 *
229 */ 173 * @param multi
230 public void setIsMutliSelectable(boolean multi) { 174 * if true, allow mutliple selections.
175 */
176 public void setIsMutliSelectable(final boolean multi) {
231 if (multi) { 177 if (multi) {
232 treeGrid.setSelectionType(SelectionStyle.MULTIPLE); 178 this.treeGrid.setSelectionType(SelectionStyle.MULTIPLE);
233 } 179 } else {
234 else { 180 this.treeGrid.setSelectionType(SelectionStyle.SINGLE);
235 treeGrid.setSelectionType(SelectionStyle.SINGLE); 181 }
236 } 182 }
237 } 183
238 184 /**
239 185 * @param handler
240 /** 186 * Handler to be added (notified on add-action).
241 * @param handler Handler to be added (notified on add-action). 187 */
242 */ 188 public void addDatacageHandler(final DatacageHandler handler) {
243 public void addDatacageHandler(DatacageHandler handler) { 189 if (!this.handlers.contains(handler)) {
244 if (!handlers.contains(handler)) { 190 this.handlers.add(handler);
245 handlers.add(handler); 191 }
246 } 192 }
247 } 193
248 194 /**
249 195 * @param h
250 /** 196 * Handler to be added (notified on Double click on node).
251 * @param h Handler to be added (notified on Double click on node). 197 */
252 */ 198 public void addDatacageDoubleClickHandler(final DatacageDoubleClickHandler h) {
253 public void addDatacageDoubleClickHandler(DatacageDoubleClickHandler h) { 199 if (!this.doubleHandlers.contains(h)) {
254 if (!doubleHandlers.contains(h)) { 200 this.doubleHandlers.add(h);
255 doubleHandlers.add(h); 201 }
256 } 202 }
257 } 203
258 204 /**
259 205 * @param handler
260 /** 206 * Handler to remove from list.
261 * @param handler Handler to remove from list. 207 */
262 */ 208 public void removeDatacageHandler(final DatacageHandler handler) {
263 public void removeDatacageHandler(DatacageHandler handler) { 209 this.handlers.remove(handler);
264 handlers.remove(handler); 210 }
265 }
266
267
268 public ToLoad getToLoad() {
269 return toLoad;
270 }
271
272 211
273 public ToLoad getSelection() { 212 public ToLoad getSelection() {
274 // Reset content of toLoads. 213 // Reset content of toLoads.
275 toLoad = new ToLoad(); 214 this.toLoad = new ToLoad();
276 215
277 if (treeGrid == null) { 216 if (this.treeGrid == null) {
278 return toLoad; 217 return this.toLoad;
279 } 218 }
280 219
281 ListGridRecord [] selection = treeGrid.getSelectedRecords(); 220 final ListGridRecord[] selection = this.treeGrid.getSelectedRecords();
282 221
283 if (selection != null) { 222 if (selection != null) {
284 for (ListGridRecord record: selection) { 223 for (final ListGridRecord record : selection) {
285 if (record instanceof TreeNode) { 224 if (record instanceof TreeNode) {
286 collectToLoads((TreeNode)record); 225 collectToLoads((TreeNode) record);
287 } 226 }
288 } 227 }
289 } 228 }
290 229
291 return toLoad; 230 return this.toLoad;
292 } 231 }
293
294 232
295 public List<TreeNode> getPlainSelection() { 233 public List<TreeNode> getPlainSelection() {
296 ListGridRecord [] selection = treeGrid.getSelectedRecords(); 234 final ListGridRecord[] selection = this.treeGrid.getSelectedRecords();
297 List<TreeNode> nodes = new ArrayList<TreeNode>(); 235 final List<TreeNode> nodes = new ArrayList<TreeNode>();
298 if (selection != null) { 236 if (selection != null) {
299 for (ListGridRecord record: selection) { 237 for (final ListGridRecord record : selection) {
300 if (record instanceof TreeNode) { 238 if (record instanceof TreeNode) {
301 nodes.add((TreeNode)record); 239 nodes.add((TreeNode) record);
302 } 240 }
303 } 241 }
304 } 242 }
305 return nodes; 243 return nodes;
306 } 244 }
307 245
308
309 /** 246 /**
310 * Returns the titles of selected items (if any). 247 * Returns the titles of selected items (if any).
311 */ 248 */
312 public String[] getSelectionTitles() { 249 public String[] getSelectionTitles() {
313 if (treeGrid == null) { 250 if (this.treeGrid == null) {
314 return new String[] {}; 251 return new String[] {};
315 } 252 }
316 253
317 ListGridRecord [] selection = treeGrid.getSelectedRecords(); 254 final ListGridRecord[] selection = this.treeGrid.getSelectedRecords();
318 255
319 if (selection == null) { 256 if (selection == null) {
320 return new String[] {}; 257 return new String[] {};
321 } 258 }
322 259
323 List<String> titleList = new ArrayList<String>(); 260 final List<String> titleList = new ArrayList<String>();
324 for (ListGridRecord record: selection) { 261 for (final ListGridRecord record : selection) {
325 if (record instanceof TreeNode) { 262 if (record instanceof TreeNode) {
326 titleList.add(((TreeNode)record).getAttribute("name")); 263 titleList.add(((TreeNode) record).getAttribute("name"));
327 } 264 }
328 } 265 }
329 266
330 return titleList.toArray(new String[titleList.size()]); 267 return titleList.toArray(new String[titleList.size()]);
331 } 268 }
332
333 269
334 /** 270 /**
335 * Callback for add-button. 271 * Callback for add-button.
336 * Fires to load for every selected element and handler. 272 * Fires to load for every selected element and handler.
337 */ 273 */
338 public void plusClicked() { 274 protected final void plusClicked() {
339 if (!getSelection().isEmpty()) { 275 if (!getSelection().isEmpty()) {
340 fireToLoad(); 276 fireToLoad();
341 } 277 }
342 } 278 }
343 279
344 280 private Button createPlusButton() {
345 protected Button createPlusButton() { 281 final Button plusBtn = new Button(this.messages.datacageAdd());
346 Button plusBtn = new Button(messages.datacageAdd());
347 plusBtn.addClickHandler(new ClickHandler() { 282 plusBtn.addClickHandler(new ClickHandler() {
348 @Override 283 @Override
349 public void onClick(ClickEvent event) { 284 public void onClick(final ClickEvent event) {
350 plusClicked(); 285 plusClicked();
351 } 286 }
352 }); 287 });
353 return plusBtn; 288 return plusBtn;
354 } 289 }
355 290
356 291 private void fireToLoad() {
357 protected void fireToLoad() { 292 for (final DatacageHandler handler : this.handlers) {
358 for (DatacageHandler handler: handlers) { 293 handler.toLoad(this.toLoad);
359 handler.toLoad(toLoad); 294 }
360 } 295 }
361 }
362
363 296
364 /** Notify DatacageDoubleClickHandlers that a doubleclick happened. */ 297 /** Notify DatacageDoubleClickHandlers that a doubleclick happened. */
365 protected void fireOnDoubleClick() { 298 private void fireOnDoubleClick() {
366 for (DatacageDoubleClickHandler handler: doubleHandlers) { 299 for (final DatacageDoubleClickHandler handler : this.doubleHandlers) {
367 handler.onDoubleClick(toLoad); 300 handler.onDoubleClick(this.toLoad);
368 } 301 }
369 } 302 }
370 303
371 304 protected final void doubleClickedOnTree(final RecordDoubleClickEvent event) {
372 protected void doubleClickedOnTree(RecordDoubleClickEvent event) { 305 final TreeNode node = (TreeNode) event.getRecord();
373 TreeNode node = (TreeNode)event.getRecord();
374 collectToLoads(node); 306 collectToLoads(node);
375 fireOnDoubleClick(); 307 fireOnDoubleClick();
376 } 308 }
377
378 309
379 /** 310 /**
380 * Adds to toLoad, from info in node. 311 * Adds to toLoad, from info in node.
381 * Afterwards, add all children of node to stack to parse (next time 312 * Afterwards, add all children of node to stack to parse (next time
382 * collectToLoads is called). 313 * collectToLoads is called).
383 */ 314 */
384 protected void collectToLoads(TreeNode node) { 315 private void collectToLoads(TreeNode node) {
385 Stack<TreeNode> stack = new Stack<TreeNode>(); 316 final Stack<TreeNode> stack = new Stack<TreeNode>();
386 317
387 stack.push(node); 318 stack.push(node);
388 319
389 while (!stack.isEmpty()) { 320 while (!stack.isEmpty()) {
390 node = stack.pop(); 321 node = stack.pop();
391 String factory = node.getAttribute("factory"); 322 final String factory = node.getAttribute("factory");
392 if (factory != null) { // we need at least a factory 323 if (factory != null) { // we need at least a factory
393 String artifact = node.getAttribute("artifact-id"); 324 final String artifact = node.getAttribute("artifact-id");
394 String out = node.getAttribute("out"); 325 final String out = node.getAttribute("out");
395 String name = node.getAttribute("facet"); 326 final String name = node.getAttribute("facet");
396 String ids = node.getAttribute("ids"); 327 final String ids = node.getAttribute("ids");
397 String displayname = node.getAttribute("name"); 328 final String displayname = node.getAttribute("name");
398 String targetOut = node.getAttribute("target_out"); 329 final String targetOut = node.getAttribute("target_out");
399 String debugAttributeValues = ""; 330 String debugAttributeValues = "";
400 for (String attr: node.getAttributes()) { 331 for (final String attr : node.getAttributes()) {
401 debugAttributeValues += ("[" + attr +": " 332 debugAttributeValues += ("[" + attr + ": " + node.getAttributeAsString(attr) + "] ");
402 + node.getAttributeAsString(attr) + "] ");
403 } 333 }
404 GWT.log("DatacageWidget.collectToLoad, attributes are " 334 GWT.log("DatacageWidget.collectToLoad, attributes are " + debugAttributeValues);
405 + debugAttributeValues); 335
406 336 this.toLoad.add(artifact, factory, out, name, ids, displayname, targetOut);
407 toLoad.add(artifact, 337 }
408 factory, 338 final TreeNode[] children = this.tree.getChildren(node);
409 out,
410 name,
411 ids,
412 displayname,
413 targetOut);
414 }
415 TreeNode [] children = tree.getChildren(node);
416 if (children != null) { 339 if (children != null) {
417 for (TreeNode child: children) { 340 for (final TreeNode child : children) {
418 stack.push(child); 341 stack.push(child);
419 } 342 }
420 } 343 }
421 } 344 }
422 } 345 }
423 346
424
425 /** Get meta-data and populate tree with it. */ 347 /** Get meta-data and populate tree with it. */
426 protected void triggerTreeBuilding() { 348 private void triggerTreeBuilding() {
427 Config config = Config.getInstance();
428 String locale = config.getLocale();
429
430 String artifactId = artifact.getUuid();
431 String userId = (user != null) ? user.identifier() : null;
432
433 lockUI(); 349 lockUI();
434 350
435 metaDataService.getMetaData( 351 final String locale = Config.getInstance().getLocale();
436 locale, 352
437 artifactId, 353 final String artifactId = this.data.getArtifact().getUuid();
438 userId, 354 final User user = this.data.getUser();
439 outs, 355 final String userId = user != null ? user.identifier() : null;
440 parameters, 356 final String outs = this.data.getOuts();
441 new AsyncCallback<DataCageTree>() { 357 final String parameters = this.data.getParameters();
442 @Override 358
443 public void onFailure(Throwable caught) { 359 this.metaDataService.getMetaData(locale, artifactId, userId, outs, parameters, new AsyncCallback<DataCageTree>() {
444 GWT.log("Could not load meta data."); 360 @Override
445 SC.warn(caught.getMessage()); 361 public void onFailure(final Throwable caught) {
446 unlockUI(); 362 GWT.log("Could not load meta data.");
447 } 363 SC.warn(caught.getMessage());
448 364 unlockUI();
449 @Override 365 }
450 public void onSuccess(DataCageTree dcTree) { 366
451 GWT.log("Successfully loaded meta data."); 367 @Override
452 IdGenerator idGenerator = new IdGenerator(); 368 public void onSuccess(final DataCageTree dcData) {
453 DataCageNode dcRoot = dcTree.getRoot(); 369 GWT.log("Successfully loaded meta data.");
454 TreeNode root = buildRecursiveChildren( 370
455 dcRoot, idGenerator); 371 setDatacageData(dcData);
456 tree.setRoot(root); 372 unlockUI();
457 373 }
458 TreeNode[] nodes = tree.getChildren(root); 374 });
459 for (TreeNode node: nodes) { 375 }
460 if (node.getAttribute("factory") == null && 376
461 !tree.hasChildren(node)) { 377 protected final void setDatacageData(final DataCageTree dcTree) {
462 node.setIsFolder(true); 378
463 } 379 this.dcTree = dcTree;
464 } 380
465 381 if (this.tree != null)
466 if (idGenerator.current() < MAX_OPEN) { 382 this.tree.destroy();
467 tree.openAll(); 383
468 } 384 updateTree(this.dcTree);
469 treeGrid.setData(tree); 385 }
470 unlockUI(); 386
471 } 387 private void updateTree(final DataCageTree data) {
472 }); 388
389 this.tree = new Tree();
390 this.tree.setModelType(TreeModelType.CHILDREN);
391 this.tree.setNameProperty("name");
392 this.tree.setIdField("id");
393 this.tree.setChildrenProperty("children-nodes");
394 this.tree.setShowRoot(false);
395
396 final IdGenerator idGenerator = new IdGenerator();
397 final DataCageNode dcRoot = data.getRoot();
398 final TreeNode root = buildRecursiveChildren(dcRoot, idGenerator);
399 if (root != null) {
400 this.tree.setRoot(root);
401
402 // FIXME: why is this necessary? an it only happens for the first level...
403 final TreeNode[] nodes = this.tree.getChildren(root);
404 for (final TreeNode node : nodes) {
405 if (node.getAttribute("factory") == null && !this.tree.hasChildren(node))
406 node.setIsFolder(true);
407 }
408 }
409
410 if (idGenerator.current() < MAX_OPEN)
411 this.tree.openAll();
412
413 this.treeGrid.setData(this.tree);
473 } 414 }
474 415
475 private static final class IdGenerator { 416 private static final class IdGenerator {
476 protected int current; 417 protected int current;
477 418
478 public IdGenerator() { 419 public IdGenerator() {
479 } 420 }
480 421
481 public int next() { 422 public int next() {
482 return current++; 423 return this.current++;
483 } 424 }
484 425
485 public int current() { 426 public int current() {
486 return current; 427 return this.current;
487 } 428 }
488 } // class IdGenerator 429 } // class IdGenerator
489 430
490 private String i18n(String s) { 431 private String i18n(String s) {
491 if (!(s.startsWith("${") && s.endsWith("}"))) { 432 if (!(s.startsWith("${") && s.endsWith("}"))) {
492 return s; 433 return s;
493 } 434 }
494 435
495 s = s.substring(2, s.length()-1); 436 s = s.substring(2, s.length() - 1);
496 437
497 try { 438 try {
498 return messages.getString(s); 439 return this.messages.getString(s);
499 } 440 }
500 catch (MissingResourceException mre) { 441 catch (final MissingResourceException mre) {
501 GWT.log("cannot find i18n for + '" + s + "'"); 442 GWT.log("cannot find i18n for + '" + s + "'");
502 return s; 443 return s;
503 } 444 }
504 } 445 }
505 446
506 protected TreeNode buildRecursiveChildren( 447 private TreeNode buildRecursiveChildren(final DataCageNode node, final IdGenerator idGenerator) {
507 DataCageNode node, 448
508 IdGenerator idGenerator 449 if (!this.filter.accept(node))
509 ) { 450 return null;
510 TreeNode tn = new TreeNode(); 451
452 final List<DataCageNode> children = node.getChildren();
453
454 final Collection<TreeNode> tns = new ArrayList<TreeNode>();
455
456 if (children != null && !children.isEmpty()) {
457
458 for (final DataCageNode child : children) {
459
460 final TreeNode childNode = buildRecursiveChildren(child, idGenerator);
461 if (childNode != null)
462 tns.add(childNode);
463 }
464
465 /* if we should have children, but all got filtered, hide this node as well */
466 if (tns.isEmpty())
467 return null;
468 }
469
470 final TreeNode tn = new TreeNode();
511 tn.setAttribute("id", idGenerator.next()); 471 tn.setAttribute("id", idGenerator.next());
512 472
513 List<DataCageNode> children = node.getChildren(); 473 if (!tns.isEmpty())
514 474 tn.setAttribute("children-nodes", tns.toArray(new TreeNode[tns.size()]));
515 if (children != null) {
516 TreeNode [] tns = new TreeNode[children.size()];
517 for (int i = 0; i < tns.length; ++i) {
518 DataCageNode child = children.get(i);
519 tns[i] = buildRecursiveChildren(child, idGenerator);
520 }
521 tn.setAttribute("children-nodes", tns);
522 }
523 475
524 tn.setAttribute("name", i18n(node.getDescription())); 476 tn.setAttribute("name", i18n(node.getDescription()));
525 tn.setAttribute("facet", node.getName()); 477 tn.setAttribute("facet", node.getName());
526 478
527 AttrList attrs = node.getAttributes(); 479 final AttrList attrs = node.getAttributes();
528 if (attrs != null) { 480 if (attrs != null) {
529 for (int i = 0, N = attrs.size(); i < N; ++i) { 481 for (int i = 0, N = attrs.size(); i < N; ++i) {
530 String key = attrs.getKey(i); 482 final String key = attrs.getKey(i);
531 String value = attrs.getValue(i); 483 final String value = attrs.getValue(i);
532 tn.setAttribute(key, value); 484 tn.setAttribute(key, value);
533 } 485 }
534 } 486 }
535 487
536 return tn; 488 return tn;
537 } 489 }
538 } 490 }
539 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org