Since WebDriver instance is common for both FileUtils and FolderUtils a new class...
[pithos] / src / gr / ebs / gss / client / CellTreeView.java
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                                 RestResourceWrapper wrapper  = (RestResourceWrapper) node.getValue();
288                                 if(wrapper.getResource().countNotDeletedSubfolders()==1||wrapper.getResource().countNotDeletedSubfolders()==0)
289                                         updateNodeChildren(((RestResourceWrapper) node.getValue()).getResource().getParentURI());
290                                 else
291                                         updateNodeChildren(((RestResource) node.getValue()).getUri());
292                                 return;
293                                 /*GWT.log("INSIDE:"+node);
294                                 RestResourceWrapper rw = (RestResourceWrapper) node.getValue();
295                                 //if(rw.getResource().getFolders().size()==0){
296                                         if(model.getMymap().get(rw.getResource().getUri())!=null){
297                                                 model.getMymap().get(rw.getResource().getUri()).refresh(null);
298                                                 updated=true;
299                                         }
300                                         if(model.getOthersmap().get(rw.getResource().getUri())!=null){
301                                                 model.getOthersmap().get(rw.getResource().getUri()).refresh(null);
302                                                 updated=true;
303                                         }
304                                         if(model.getSharedmap().get(rw.getResource().getUri())!=null){
305                                                 model.getSharedmap().get(rw.getResource().getUri()).refresh(null);
306                                                 updated=true;
307                                         }
308                                         if(updated){
309                                                 if(doesSharedNodeContainsResourceIn1stLevel(resource)){
310                                                         updateMySharedNode();
311                                                 }
312                                                 return;
313                                         }
314                                 }
315                         //}*/
316                         
317                 }
318                         updateNodeChildren(resource);
319         }
320         public void updateNodeChildren(final String resource){
321                 
322                         
323                 GWT.log("REFRESH THE OTHER WAY");
324                 utils.refreshNodeContainingResource(resource);
325                 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)){
326                         updateMySharedNode();
327                 }
328         }
329         
330         protected void showPopup(final int x, final int y) {
331                 if (selectionModel.getSelectedObject() == null)
332                         return;
333                 if (menu != null)
334                         menu.hide();
335                 menu = new FolderContextMenu(images);
336                 menu.setPopupPosition(x, y);
337                 menu.show();
338         }
339         private boolean init=false;
340         public boolean fetchRootFolders() {
341                 UserResource userResource = GSS.get().getCurrentUserResource();
342                 if (userResource == null)
343                         return !DONE;
344                 if(!init){
345                         final String path = userResource.getFilesPath();
346                         GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
347         
348                                 @Override
349                                 public void onComplete() {
350                                         myFolders = new MyFolderResource(getResult());
351                                         //selectionModel.setSelected(myFolders, true);
352                                         //rootNodes.setList(Arrays.asList((RestResource)rootResource));
353                                         //tree.getRootTreeNode().setChildOpen(0, true);
354                                 }
355         
356                                 @Override
357                                 public void onError(Throwable t) {
358                                         GWT.log("Error fetching root folder", t);
359                                         GSS.get().displayError("Unable to fetch root folder");
360                                 }
361         
362                         };
363                         DeferredCommand.addCommand(gf);
364                         DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
365                                 @Override
366                                 public void onComplete() {
367                                         trash = getResult();
368                                 }
369
370                                 @Override
371                                 public void onError(Throwable t) {
372                                         if(t instanceof RestException){
373                                                 int statusCode = ((RestException)t).getHttpStatusCode();
374                                                 // On IE status code 1223 may be returned instead of 204.
375                                                 if(statusCode == 204 || statusCode == 1223){
376                                                         trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
377                                         }
378                                         else{
379                                                 GWT.log("", t);
380                                                 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
381                                                 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
382                                         }
383                                 }
384                         }
385                         });
386                         GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
387
388                                 @Override
389                                 public void onComplete() {
390                                         myshared=getResult();
391                                 }
392
393                                 @Override
394                                 public void onError(Throwable t) {
395                                         GWT.log("Error fetching Shared Root folder", t);
396                                         GSS.get().displayError("Unable to fetch Shared Root folder");
397                                 }
398                         };
399                         DeferredCommand.addCommand(gs);
400                         GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
401                                                 userResource.getOthersPath(), null) {
402
403                                 @Override
404                                 public void onComplete() {
405                                         others = getResult();
406                                         GSS.get().removeGlassPanel();
407                                 }
408
409                                 @Override
410                                 public void onError(Throwable t) {
411                                         GWT.log("Error fetching Others Root folder", t);
412                                         GSS.get().displayError("Unable to fetch Others Root folder");
413                                 }
414                         };
415                         DeferredCommand.addCommand(go);
416                 }
417                 if(myFolders==null||trash==null||myshared==null||others==null)
418                         return !DONE;
419                 model.getRootNodes().setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
420                 tree.getRootTreeNode().setChildOpen(0, true);
421                 selectionModel.setSelected(myFolders, true);
422                 return DONE;
423         }
424
425         public Images getImages() {
426                 return images;
427         }
428         
429         
430         public void updateTrashNode(){
431                 DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
432                         @Override
433                         public void onComplete() {
434                                 trash = getResult();
435                                 model.getRootNodes().getList().set(1, trash);
436                                 //model.getRootNodes().refresh();
437                         }
438
439                         @Override
440                         public void onError(Throwable t) {
441                                 if(t instanceof RestException){
442                                         int statusCode = ((RestException)t).getHttpStatusCode();
443                                         // On IE status code 1223 may be returned instead of 204.
444                                         if(statusCode == 204 || statusCode == 1223){
445                                                 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
446                                                 model.getRootNodes().getList().set(1, trash);
447                                                 //model.getRootNodes().refresh();
448                                 }
449                                 else{
450                                         GWT.log("", t);
451                                         GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
452                                         trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
453                                         model.getRootNodes().getList().set(1, trash);
454                                         //model.getRootNodes().refresh();
455                                 }
456                         }
457                 }
458                 });
459         }
460         
461         public void updateRootNode(){
462                 final String path = GSS.get().getCurrentUserResource().getFilesPath();
463                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
464
465                         @Override
466                         public void onComplete() {
467                                 myFolders = new MyFolderResource(getResult());
468                                 model.getRootNodes().getList().set(0, myFolders);
469                                 model.getRootNodes().refresh();
470                                 tree.getRootTreeNode().setChildOpen(0, true);
471                                 
472                         }
473
474                         @Override
475                         public void onError(Throwable t) {
476                                 GWT.log("Error fetching root folder", t);
477                                 GSS.get().displayError("Unable to fetch root folder");
478                         }
479
480                 };
481                 DeferredCommand.addCommand(gf);
482         }
483         
484         public void updateMySharedNode(){
485                 GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
486
487                         @Override
488                         public void onComplete() {
489                                 myshared=getResult();
490                                 model.getRootNodes().getList().set(2, myshared);
491                         }
492
493                         @Override
494                         public void onError(Throwable t) {
495                                 GWT.log("Error fetching Shared Root folder", t);
496                                 GSS.get().displayError("Unable to fetch Shared Root folder");
497                         }
498                 };
499                 DeferredCommand.addCommand(gs);
500         }
501         
502         public void updateOtherNode(){
503                 GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
504                                         GSS.get().getCurrentUserResource().getOthersPath(), null) {
505
506                         @Override
507                         public void onComplete() {
508                                 others = getResult();
509                                 model.getRootNodes().getList().set(3, others);
510                         }
511
512                         @Override
513                         public void onError(Throwable t) {
514                                 GWT.log("Error fetching Others Root folder", t);
515                                 GSS.get().displayError("Unable to fetch Others Root folder");
516                         }
517                 };
518                 DeferredCommand.addCommand(go);
519         }
520         
521         
522         public RestResource getSelection(){
523                 return selectionModel.getSelectedObject();
524         }
525         
526         public void clearSelection(){
527                 if(GSS.get().getCurrentSelection().equals(getSelection()))
528                         GSS.get().setCurrentSelection(null);
529                 selectionModel.setSelected(getSelection(), false);
530         }
531         
532         
533         /**
534          * Retrieve the myFolders.
535          *
536          * @return the myFolders
537          */
538         public MyFolderResource getMyFolders() {
539                 return myFolders;
540         }
541         
542         
543         /**
544          * Retrieve the myshared.
545          *
546          * @return the myshared
547          */
548         public SharedResource getMyshared() {
549                 return myshared;
550         }
551         
552         
553         /**
554          * Retrieve the trash.
555          *
556          * @return the trash
557          */
558         public TrashResource getTrash() {
559                 return trash;
560         }
561         
562         
563         /**
564          * Retrieve the others.
565          *
566          * @return the others
567          */
568         public OthersResource getOthers() {
569                 return others;
570         }
571         
572         
573         /**
574          * Retrieve the model.
575          *
576          * @return the model
577          */
578         public TreeViewModel getModel() {
579                 return model;
580         }
581         
582         
583         
584         /**
585          * Retrieve the utils.
586          *
587          * @return the utils
588          */
589         public CellTreeViewUtils getUtils() {
590                 return utils;
591         }
592         
593         public interface RefreshHandler{
594                 void onRefresh();               
595         }
596         
597         
598         public boolean isTrashOrTrashFolderSelected(){
599                 return (getSelection() instanceof TrashResource) || (getSelection() instanceof TrashFolderResource);
600         }
601         
602         public OtherUserResource getOtherUserResourceOfOtherFolder(OthersFolderResource res){
603                 TreeNode n = utils.getNodeContainingResource(tree.getRootTreeNode().setChildOpen(3, true), res);
604                 
605                 if(n!=null){
606                         if(n.getValue() instanceof OtherUserResource)
607                                 return (OtherUserResource) n.getValue();
608                         TreeNode parent = n.getParent();
609                         
610                         while (parent!=null){
611                                 if(parent.getValue() instanceof OtherUserResource)
612                                         return (OtherUserResource) parent.getValue();
613                                 parent = parent.getParent();
614                         }
615                 }
616                 return null;
617         }
618         
619         
620 }