Statistics
| Branch: | Tag: | Revision:

root / src / gr / ebs / gss / client / CellTreeView.java @ 861377e7

History | View | Annotate | Download (19.4 kB)

1
/*
2
 * Copyright 2011 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package gr.ebs.gss.client;
20

    
21
import gr.ebs.gss.client.CellTreeViewModel.MyFolderDataProvider;
22
import gr.ebs.gss.client.rest.GetCommand;
23
import gr.ebs.gss.client.rest.RestException;
24
import gr.ebs.gss.client.rest.resource.FolderResource;
25
import gr.ebs.gss.client.rest.resource.MyFolderResource;
26
import gr.ebs.gss.client.rest.resource.OtherUserResource;
27
import gr.ebs.gss.client.rest.resource.OthersFolderResource;
28
import gr.ebs.gss.client.rest.resource.OthersResource;
29
import gr.ebs.gss.client.rest.resource.RestResource;
30
import gr.ebs.gss.client.rest.resource.RestResourceWrapper;
31
import gr.ebs.gss.client.rest.resource.SharedResource;
32
import gr.ebs.gss.client.rest.resource.TrashFolderResource;
33
import gr.ebs.gss.client.rest.resource.TrashResource;
34
import gr.ebs.gss.client.rest.resource.UserResource;
35
import gwtquery.plugins.draggable.client.DragAndDropManager;
36
import gwtquery.plugins.droppable.client.events.DragAndDropContext;
37
import gwtquery.plugins.droppable.client.events.OverDroppableEvent;
38
import gwtquery.plugins.droppable.client.events.OverDroppableEvent.OverDroppableEventHandler;
39
import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTree;
40

    
41
import java.util.Arrays;
42

    
43
import com.google.gwt.core.client.GWT;
44
import com.google.gwt.event.logical.shared.AttachEvent;
45
import com.google.gwt.event.logical.shared.OpenEvent;
46
import com.google.gwt.event.logical.shared.OpenHandler;
47
import com.google.gwt.query.client.plugins.GQueryUi;
48
import com.google.gwt.resources.client.ClientBundle;
49
import com.google.gwt.resources.client.ImageResource;
50
import com.google.gwt.resources.client.ImageResource.ImageOptions;
51
import com.google.gwt.user.cellview.client.CellTree;
52
import com.google.gwt.user.cellview.client.TreeNode;
53
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
54
import com.google.gwt.user.client.DeferredCommand;
55
import com.google.gwt.user.client.Event;
56
import com.google.gwt.user.client.IncrementalCommand;
57
import com.google.gwt.user.client.Window;
58
import com.google.gwt.user.client.ui.Composite;
59
import com.google.gwt.user.client.ui.Tree;
60
import com.google.gwt.view.client.ProvidesKey;
61
import com.google.gwt.view.client.SelectionChangeEvent;
62
import com.google.gwt.view.client.SingleSelectionModel;
63
import com.google.gwt.view.client.TreeViewModel;
64
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
65
import com.google.gwt.view.client.TreeViewModel.NodeInfo;
66

    
67

    
68
/**
69
 * @author kman
70
 *
71
 */
72
public class CellTreeView extends Composite{
73
        public static final boolean DONE = false;
74
        Images images;
75
        
76
        SingleSelectionModel<RestResource> selectionModel = new SingleSelectionModel<RestResource>(new ProvidesKey<RestResource>() {
77

    
78
                @Override
79
                public Object getKey(RestResource item) {
80
                        return item.getClass().getName()+":"+item.getUri();
81
                }});
82
        FolderContextMenu menu;
83
        
84
        
85
        MyFolderResource myFolders=null;
86
        TrashResource trash = null;
87
        SharedResource myshared = null;
88
        OthersResource others = null;
89
        
90
        CellTreeViewModel model;
91
        CellTreeViewUtils utils;
92
        
93
        public interface Images extends ClientBundle,Tree.Resources, FolderContextMenu.Images {
94

    
95
        @Source("gr/ebs/gss/resources/folder_home.png")
96
        ImageResource home();
97

    
98
        @Source("gr/ebs/gss/resources/folder_yellow.png")
99
        ImageResource folderYellow();
100

    
101
        @Source("gr/ebs/gss/resources/mimetypes/document.png")
102
        ImageResource document();
103

    
104
        @Source("gr/ebs/gss/resources/internet.png")
105
        ImageResource othersShared();
106

    
107
        @Source("gr/ebs/gss/resources/edit_user.png")
108
        ImageResource myShared();
109

    
110
        @Source("gr/ebs/gss/resources/folder_user.png")
111
        ImageResource sharedFolder();
112

    
113
        @Source("gr/ebs/gss/resources/trashcan_empty.png")
114
        ImageResource trash();
115
        }
116
        DragAndDropCellTree tree;
117
        /*public interface BasicResources extends CellTree.BasicResources{
118
                @ImageOptions(flipRtl = true)
119
            @Source("cellTreeLoadingBasic.gif")
120
            ImageResource cellTreeLoading();
121
                
122
                @Source({"GssCellTreeBasic.css"})
123
            CellTree.Style cellTreeStyle();
124
        }*/
125
        public interface BasicResources extends CellTree.Resources {
126

    
127
            @ImageOptions(flipRtl = true)
128
            @Source("cellTreeClosedItem.gif")
129
            ImageResource cellTreeClosedItem();
130

    
131
            @ImageOptions(flipRtl = true)
132
            @Source("cellTreeLoadingBasic.gif")
133
            ImageResource cellTreeLoading();
134

    
135
            @ImageOptions(flipRtl = true)
136
            @Source("cellTreeOpenItem.gif")
137
            ImageResource cellTreeOpenItem();
138

    
139
            //@Source({CellTree.Style.DEFAULT_CSS,"GssCellTreeBasic.css"})
140
            @Source({"GssCellTreeBasic.css"})
141
            CellTree.Style cellTreeStyle();
142
          }
143
        /**
144
         * 
145
         */
146
        public CellTreeView(final Images _images) {
147
                images = _images;
148
                model = new CellTreeViewModel(images,selectionModel);
149
            /*
150
             * Create the tree using the model. We use <code>null</code> as the default
151
             * value of the root node. The default value will be passed to
152
             * CustomTreeModel#getNodeInfo();
153
             */
154
                CellTree.Resources res = GWT.create(BasicResources.class);
155
            tree = new DragAndDropCellTree(model,null, res){
156
                    @Override
157
                    public void onBrowserEvent(Event event) {
158
                            // TODO Auto-generated method stub
159
                            super.onBrowserEvent(event);
160
                    }
161
            };
162
            utils=new CellTreeViewUtils(tree);
163
            tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
164
            /*tree.addOpenHandler(new OpenHandler<TreeNode>() {
165
                        
166
                        @Override
167
                        public void onOpen(OpenEvent<TreeNode> event) {
168
                                Window.alert("[NODE OPENED]"+event.getTarget());
169
                                
170
                        }
171
                });
172
            tree.addOverDroppableHandler(new OverDroppableEventHandler() {
173
                        
174
                        @Override
175
                        public void onOverDroppable(OverDroppableEvent event) {
176
                                GWT.log("OVER:"+event);
177
                                
178
                        }
179
                });
180
            tree.addAttachHandler(new AttachEvent.Handler() {
181
                        
182
                        @Override
183
                        public void onAttachOrDetach(AttachEvent event) {
184
                                GWT.log("ATTACH:"+event.getSource());
185
                                
186
                        }
187
                });*/
188
            Handler selectionHandler = new SelectionChangeEvent.Handler() { 
189
            @Override 
190
            public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
191
                    NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
192
                    
193
                    //GWT.log("SLECTED NODE INFO:"+nodeInfo+"   "+tree.getRootTreeNode().getChildValue(1));
194
                    //((DefaultNodeInfo<RestResource>)nodeInfo).getValueUpdater().update(selectionModel.getSelectedObject());
195
                    //if(nodeInfo.getProvidesKey() instanceof FolderDataProvider)
196
                            //((FolderDataProvider)nodeInfo.getProvidesKey()).onRangeChanged(null);
197
                    if(nodeInfo==null || nodeInfo.getValueUpdater()==null){}
198
                            
199
                    else
200
                            nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
201
                    GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
202
                    GSS.get().showFileList(true);
203
                    //tree.fireEvent(new OpenEvent<RestResource>(selectionModel.getSelectedObject()));
204
                    
205
            }
206
        };
207
        //OpenEvent<RestResource>.fire(tree, selectionModel.getSelectedObject());
208
        selectionModel.addSelectionChangeHandler(selectionHandler);
209
            sinkEvents(Event.ONCONTEXTMENU);
210
                sinkEvents(Event.ONMOUSEUP);
211
            initWidget(tree);
212
                
213
            DeferredCommand.addCommand(new IncrementalCommand() {
214

    
215
                        @Override
216
                        public boolean execute() {
217
                                return fetchRootFolders();
218
                        }
219
                });
220
        }
221
        
222
        public void updateNode(RestResource resource){
223
                NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
224
                
225
                if(nodeInfo!=null){
226
                    if(nodeInfo.getValueUpdater()==null){}
227
                    else
228
                            nodeInfo.getValueUpdater().update(resource);
229
            }
230
        }
231
        
232
        public void updateNodeChildren(final RestResource resource){
233
                
234
                if(resource instanceof RestResourceWrapper){
235
                        boolean updated=false;
236
                        if(((RestResourceWrapper)resource).getResource().getFolders().size()==0){
237
                                if(model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
238
                                        model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
239
                                        updated=true;
240
                                }
241
                                if(model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
242
                                        model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
243
                                        updated=true;
244
                                }
245
                                if(model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
246
                                        model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
247
                                        updated=true;
248
                                }
249
                                if(updated){
250
                                        if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
251
                                                updateMySharedNode();
252
                                        }
253
                                        return;
254
                                }
255
                        }
256
                }
257
                
258
                utils.refreshNodeContainingResource(resource);
259
                if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
260
                        updateMySharedNode();
261
                }
262
                
263
        }
264
        public void updateNodeChildrenForRemove(final String resource){
265
                GWT.log("********************************");
266
                GWT.log("[UPDATENODECHILDREN]"+resource);
267
                GWT.log("********************************");
268
                boolean updated=false;
269
                TreeNode node=null;
270
                if(tree.getRootTreeNode().isChildOpen(0)){
271
                        node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(0,true), resource);
272
                }
273
                        GWT.log("CHECK NODE1:"+node+" "+resource);
274
                        if(node==null)
275
                                if(tree.getRootTreeNode().isChildOpen(2)){
276
                                        GWT.log("CHECK NODE2:"+node);
277
                                        node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(2,true), resource);
278
                                }
279
                        if(node==null)
280
                                if(tree.getRootTreeNode().isChildOpen(3)){
281
                                        GWT.log("CHECK NODE3:"+node);
282
                                        node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(3,true), resource);
283
                                }
284
                        
285
                        if(node != null && node.getValue() instanceof RestResourceWrapper){
286
                                GWT.log("*********************"+((RestResourceWrapper) node.getValue()).getResource().getFolders().size());
287
                                if(((RestResourceWrapper) node.getValue()).getResource().getFolders().size()==1||((RestResourceWrapper) node.getValue()).getResource().getFolders().size()==0)
288
                                        updateNodeChildren(((RestResourceWrapper) node.getValue()).getResource().getParentURI());
289
                                else
290
                                        updateNodeChildren(((RestResource) node.getValue()).getUri());
291
                                return;
292
                                /*GWT.log("INSIDE:"+node);
293
                                RestResourceWrapper rw = (RestResourceWrapper) node.getValue();
294
                                //if(rw.getResource().getFolders().size()==0){
295
                                        if(model.getMymap().get(rw.getResource().getUri())!=null){
296
                                                model.getMymap().get(rw.getResource().getUri()).refresh(null);
297
                                                updated=true;
298
                                        }
299
                                        if(model.getOthersmap().get(rw.getResource().getUri())!=null){
300
                                                model.getOthersmap().get(rw.getResource().getUri()).refresh(null);
301
                                                updated=true;
302
                                        }
303
                                        if(model.getSharedmap().get(rw.getResource().getUri())!=null){
304
                                                model.getSharedmap().get(rw.getResource().getUri()).refresh(null);
305
                                                updated=true;
306
                                        }
307
                                        if(updated){
308
                                                if(doesSharedNodeContainsResourceIn1stLevel(resource)){
309
                                                        updateMySharedNode();
310
                                                }
311
                                                return;
312
                                        }
313
                                }
314
                        //}*/
315
                        
316
                }
317
                        updateNodeChildren(resource);
318
        }
319
        public void updateNodeChildren(final String resource){
320
                
321
                        
322
                GWT.log("REFRESH THE OTHER WAY");
323
                utils.refreshNodeContainingResource(resource);
324
                if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)){
325
                        updateMySharedNode();
326
                }
327
        }
328
        
329
        protected void showPopup(final int x, final int y) {
330
                if (selectionModel.getSelectedObject() == null)
331
                        return;
332
                if (menu != null)
333
                        menu.hide();
334
                menu = new FolderContextMenu(images);
335
                menu.setPopupPosition(x, y);
336
                menu.show();
337
        }
338
        private boolean init=false;
339
        public boolean fetchRootFolders() {
340
                UserResource userResource = GSS.get().getCurrentUserResource();
341
                if (userResource == null)
342
                        return !DONE;
343
                if(!init){
344
                        final String path = userResource.getFilesPath();
345
                        GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
346
        
347
                                @Override
348
                                public void onComplete() {
349
                                        myFolders = new MyFolderResource(getResult());
350
                                        //selectionModel.setSelected(myFolders, true);
351
                                        //rootNodes.setList(Arrays.asList((RestResource)rootResource));
352
                                        //tree.getRootTreeNode().setChildOpen(0, true);
353
                                }
354
        
355
                                @Override
356
                                public void onError(Throwable t) {
357
                                        GWT.log("Error fetching root folder", t);
358
                                        GSS.get().displayError("Unable to fetch root folder");
359
                                }
360
        
361
                        };
362
                        DeferredCommand.addCommand(gf);
363
                        DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
364
                                @Override
365
                                public void onComplete() {
366
                                        trash = getResult();
367
                                }
368

    
369
                                @Override
370
                                public void onError(Throwable t) {
371
                                        if(t instanceof RestException){
372
                                                int statusCode = ((RestException)t).getHttpStatusCode();
373
                                                // On IE status code 1223 may be returned instead of 204.
374
                                                if(statusCode == 204 || statusCode == 1223){
375
                                                        trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
376
                                        }
377
                                        else{
378
                                                GWT.log("", t);
379
                                                GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
380
                                                trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
381
                                        }
382
                                }
383
                        }
384
                        });
385
                        GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
386

    
387
                                @Override
388
                                public void onComplete() {
389
                                        myshared=getResult();
390
                                }
391

    
392
                                @Override
393
                                public void onError(Throwable t) {
394
                                        GWT.log("Error fetching Shared Root folder", t);
395
                                        GSS.get().displayError("Unable to fetch Shared Root folder");
396
                                }
397
                        };
398
                        DeferredCommand.addCommand(gs);
399
                        GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
400
                                                userResource.getOthersPath(), null) {
401

    
402
                                @Override
403
                                public void onComplete() {
404
                                        others = getResult();
405
                                        GSS.get().removeGlassPanel();
406
                                }
407

    
408
                                @Override
409
                                public void onError(Throwable t) {
410
                                        GWT.log("Error fetching Others Root folder", t);
411
                                        GSS.get().displayError("Unable to fetch Others Root folder");
412
                                }
413
                        };
414
                        DeferredCommand.addCommand(go);
415
                }
416
                if(myFolders==null||trash==null||myshared==null||others==null)
417
                        return !DONE;
418
                model.getRootNodes().setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
419
                tree.getRootTreeNode().setChildOpen(0, true);
420
                selectionModel.setSelected(myFolders, true);
421
                return DONE;
422
        }
423

    
424
        public Images getImages() {
425
                return images;
426
        }
427
        
428
        
429
        public void updateTrashNode(){
430
                DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
431
                        @Override
432
                        public void onComplete() {
433
                                trash = getResult();
434
                                model.getRootNodes().getList().set(1, trash);
435
                                //model.getRootNodes().refresh();
436
                        }
437

    
438
                        @Override
439
                        public void onError(Throwable t) {
440
                                if(t instanceof RestException){
441
                                        int statusCode = ((RestException)t).getHttpStatusCode();
442
                                        // On IE status code 1223 may be returned instead of 204.
443
                                        if(statusCode == 204 || statusCode == 1223){
444
                                                trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
445
                                                model.getRootNodes().getList().set(1, trash);
446
                                                //model.getRootNodes().refresh();
447
                                }
448
                                else{
449
                                        GWT.log("", t);
450
                                        GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
451
                                        trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
452
                                        model.getRootNodes().getList().set(1, trash);
453
                                        //model.getRootNodes().refresh();
454
                                }
455
                        }
456
                }
457
                });
458
        }
459
        
460
        public void updateRootNode(){
461
                final String path = GSS.get().getCurrentUserResource().getFilesPath();
462
                GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
463

    
464
                        @Override
465
                        public void onComplete() {
466
                                myFolders = new MyFolderResource(getResult());
467
                                model.getRootNodes().getList().set(0, myFolders);
468
                                model.getRootNodes().refresh();
469
                                tree.getRootTreeNode().setChildOpen(0, true);
470
                                
471
                        }
472

    
473
                        @Override
474
                        public void onError(Throwable t) {
475
                                GWT.log("Error fetching root folder", t);
476
                                GSS.get().displayError("Unable to fetch root folder");
477
                        }
478

    
479
                };
480
                DeferredCommand.addCommand(gf);
481
        }
482
        
483
        public void updateMySharedNode(){
484
                GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
485

    
486
                        @Override
487
                        public void onComplete() {
488
                                myshared=getResult();
489
                                model.getRootNodes().getList().set(2, myshared);
490
                        }
491

    
492
                        @Override
493
                        public void onError(Throwable t) {
494
                                GWT.log("Error fetching Shared Root folder", t);
495
                                GSS.get().displayError("Unable to fetch Shared Root folder");
496
                        }
497
                };
498
                DeferredCommand.addCommand(gs);
499
        }
500
        
501
        public void updateOtherNode(){
502
                GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
503
                                        GSS.get().getCurrentUserResource().getOthersPath(), null) {
504

    
505
                        @Override
506
                        public void onComplete() {
507
                                others = getResult();
508
                                model.getRootNodes().getList().set(3, others);
509
                        }
510

    
511
                        @Override
512
                        public void onError(Throwable t) {
513
                                GWT.log("Error fetching Others Root folder", t);
514
                                GSS.get().displayError("Unable to fetch Others Root folder");
515
                        }
516
                };
517
                DeferredCommand.addCommand(go);
518
        }
519
        
520
        
521
        public RestResource getSelection(){
522
                return selectionModel.getSelectedObject();
523
        }
524
        
525
        public void clearSelection(){
526
                if(GSS.get().getCurrentSelection().equals(getSelection()))
527
                        GSS.get().setCurrentSelection(null);
528
                selectionModel.setSelected(getSelection(), false);
529
        }
530
        
531
        
532
        /**
533
         * Retrieve the myFolders.
534
         *
535
         * @return the myFolders
536
         */
537
        public MyFolderResource getMyFolders() {
538
                return myFolders;
539
        }
540
        
541
        
542
        /**
543
         * Retrieve the myshared.
544
         *
545
         * @return the myshared
546
         */
547
        public SharedResource getMyshared() {
548
                return myshared;
549
        }
550
        
551
        
552
        /**
553
         * Retrieve the trash.
554
         *
555
         * @return the trash
556
         */
557
        public TrashResource getTrash() {
558
                return trash;
559
        }
560
        
561
        
562
        /**
563
         * Retrieve the others.
564
         *
565
         * @return the others
566
         */
567
        public OthersResource getOthers() {
568
                return others;
569
        }
570
        
571
        
572
        /**
573
         * Retrieve the model.
574
         *
575
         * @return the model
576
         */
577
        public TreeViewModel getModel() {
578
                return model;
579
        }
580
        
581
        
582
        
583
        /**
584
         * Retrieve the utils.
585
         *
586
         * @return the utils
587
         */
588
        public CellTreeViewUtils getUtils() {
589
                return utils;
590
        }
591
        
592
        public interface RefreshHandler{
593
                void onRefresh();                
594
        }
595
        
596
        
597
        public boolean isTrashOrTrashFolderSelected(){
598
                return (getSelection() instanceof TrashResource) || (getSelection() instanceof TrashFolderResource);
599
        }
600
        
601
        public OtherUserResource getOtherUserResourceOfOtherFolder(OthersFolderResource res){
602
                TreeNode n = utils.getNodeContainingResource(tree.getRootTreeNode().setChildOpen(3, true), res);
603
                
604
                if(n!=null){
605
                        if(n.getValue() instanceof OtherUserResource)
606
                                return (OtherUserResource) n.getValue();
607
                        TreeNode parent = n.getParent();
608
                        
609
                        while (parent!=null){
610
                                if(parent.getValue() instanceof OtherUserResource)
611
                                        return (OtherUserResource) parent.getValue();
612
                                parent = parent.getParent();
613
                        }
614
                }
615
                return null;
616
        }
617
        
618
        
619
}