2 * Copyright 2011 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
12 * 2. Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials
15 * provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
30 * The views and conclusions contained in the software and
31 * documentation are those of the authors and should not be
32 * interpreted as representing official policies, either expressed
33 * or implied, of GRNET S.A.
35 package gr.grnet.pithos.web.client;
37 import gr.grnet.pithos.web.client.CellTreeViewModel.ClearSelection;
38 import gr.grnet.pithos.web.client.rest.GetCommand;
39 import gr.grnet.pithos.web.client.rest.RestException;
40 import gr.grnet.pithos.web.client.rest.resource.FolderResource;
41 import gr.grnet.pithos.web.client.rest.resource.MyFolderResource;
42 import gr.grnet.pithos.web.client.rest.resource.OtherUserResource;
43 import gr.grnet.pithos.web.client.rest.resource.OthersFolderResource;
44 import gr.grnet.pithos.web.client.rest.resource.OthersResource;
45 import gr.grnet.pithos.web.client.rest.resource.RestResource;
46 import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper;
47 import gr.grnet.pithos.web.client.rest.resource.SharedResource;
48 import gr.grnet.pithos.web.client.rest.resource.TrashFolderResource;
49 import gr.grnet.pithos.web.client.rest.resource.TrashResource;
50 import gr.grnet.pithos.web.client.rest.resource.UserResource;
51 import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTree;
53 import java.util.Arrays;
55 import com.google.gwt.core.client.GWT;
56 import com.google.gwt.resources.client.ClientBundle;
57 import com.google.gwt.resources.client.ImageResource;
58 import com.google.gwt.resources.client.ImageResource.ImageOptions;
59 import com.google.gwt.user.cellview.client.CellTree;
60 import com.google.gwt.user.cellview.client.TreeNode;
61 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
62 import com.google.gwt.user.client.DeferredCommand;
63 import com.google.gwt.user.client.Event;
64 import com.google.gwt.user.client.IncrementalCommand;
65 import com.google.gwt.user.client.ui.Composite;
66 import com.google.gwt.user.client.ui.Tree;
67 import com.google.gwt.view.client.ProvidesKey;
68 import com.google.gwt.view.client.SelectionChangeEvent;
69 import com.google.gwt.view.client.SingleSelectionModel;
70 import com.google.gwt.view.client.TreeViewModel;
71 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
72 import com.google.gwt.view.client.TreeViewModel.NodeInfo;
75 public class CellTreeView extends Composite{
76 public static final boolean DONE = false;
79 SingleSelectionModel<RestResource> selectionModel = new SingleSelectionModel<RestResource>(new ProvidesKey<RestResource>() {
82 public Object getKey(RestResource item) {
83 return item.getClass().getName()+":"+item.getUri();
85 FolderContextMenu menu;
88 MyFolderResource myFolders=null;
89 TrashResource trash = null;
90 SharedResource myshared = null;
91 OthersResource others = null;
93 CellTreeViewModel model;
94 CellTreeViewUtils utils;
96 public interface Images extends ClientBundle,Tree.Resources, FolderContextMenu.Images {
98 @Source("gr/grnet/pithos/resources/folder_home.png")
101 @Source("gr/grnet/pithos/resources/folder_yellow.png")
102 ImageResource folderYellow();
104 @Source("gr/grnet/pithos/resources/mimetypes/document.png")
105 ImageResource document();
107 @Source("gr/grnet/pithos/resources/internet.png")
108 ImageResource othersShared();
110 @Source("gr/grnet/pithos/resources/edit_user.png")
111 ImageResource myShared();
113 @Source("gr/grnet/pithos/resources/folder_user.png")
114 ImageResource sharedFolder();
116 @Source("gr/grnet/pithos/resources/trashcan_empty.png")
117 ImageResource trash();
119 DragAndDropCellTree tree;
120 /*public interface BasicResources extends CellTree.BasicResources{
121 @ImageOptions(flipRtl = true)
122 @Source("cellTreeLoadingBasic.gif")
123 ImageResource cellTreeLoading();
125 @Source({"GssCellTreeBasic.css"})
126 CellTree.Style cellTreeStyle();
128 public interface BasicResources extends CellTree.Resources {
130 @ImageOptions(flipRtl = true)
131 @Source("cellTreeClosedItem.gif")
132 ImageResource cellTreeClosedItem();
134 @ImageOptions(flipRtl = true)
135 @Source("cellTreeLoadingBasic.gif")
136 ImageResource cellTreeLoading();
138 @ImageOptions(flipRtl = true)
139 @Source("cellTreeOpenItem.gif")
140 ImageResource cellTreeOpenItem();
142 //@Source({CellTree.Style.DEFAULT_CSS,"GssCellTreeBasic.css"})
143 @Source({"GssCellTreeBasic.css"})
144 CellTree.Style cellTreeStyle();
149 public CellTreeView(final Images _images) {
151 model = new CellTreeViewModel(images,selectionModel);
153 * Create the tree using the model. We use <code>null</code> as the default
154 * value of the root node. The default value will be passed to
155 * CustomTreeModel#getNodeInfo();
157 CellTree.Resources res = GWT.create(BasicResources.class);
158 tree = new DragAndDropCellTree(model,null, res){
160 public void onBrowserEvent(Event event) {
161 // TODO Auto-generated method stub
162 super.onBrowserEvent(event);
165 utils=new CellTreeViewUtils(tree);
166 tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
167 /*tree.addOpenHandler(new OpenHandler<TreeNode>() {
170 public void onOpen(OpenEvent<TreeNode> event) {
171 Window.alert("[NODE OPENED]"+event.getTarget());
175 tree.addOverDroppableHandler(new OverDroppableEventHandler() {
178 public void onOverDroppable(OverDroppableEvent event) {
179 GWT.log("OVER:"+event);
183 tree.addAttachHandler(new AttachEvent.Handler() {
186 public void onAttachOrDetach(AttachEvent event) {
187 GWT.log("ATTACH:"+event.getSource());
191 Handler selectionHandler = new SelectionChangeEvent.Handler() {
193 public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
194 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
195 if(nodeInfo==null || nodeInfo.getValueUpdater()==null){
196 GSS.get().showFileList(getSelection());
199 nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
200 GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
205 selectionModel.addSelectionChangeHandler(selectionHandler);
206 sinkEvents(Event.ONCONTEXTMENU);
207 sinkEvents(Event.ONMOUSEUP);
209 FolderResource loadingResource = new FolderResource("loading");
210 loadingResource.setName("Loading....");
211 loadingResource.setShared(false);
212 RestResourceWrapper loading = new RestResourceWrapper(loadingResource);
213 model.getRootNodes().setList(Arrays.asList((RestResource)loading));
215 DeferredCommand.addCommand(new IncrementalCommand() {
218 public boolean execute() {
219 return fetchRootFolders();
224 public void updateNode(RestResource resource){
225 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(resource);
228 if(nodeInfo.getValueUpdater()==null){}
230 nodeInfo.getValueUpdater().update(resource);
234 public void updateNodeChildren(final RestResource resource){
236 if(resource instanceof RestResourceWrapper){
237 boolean updated=false;
238 if(((RestResourceWrapper)resource).getResource().getFolders().size()==0){
239 if(((RestResourceWrapper)resource).getResource().getParentURI().equals(getMyFolders().getUri())){
240 updateNodeChildren(getMyFolders().getUri());
243 if(model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
244 model.getMymap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
247 if(model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
248 model.getOthersmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
251 if(model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI())!=null){
252 model.getSharedmap().get(((RestResourceWrapper)resource).getResource().getParentURI()).refresh(null);
256 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
257 updateMySharedNode();
259 else if(tree.getRootTreeNode().isChildOpen(2)){
260 utils.refreshNodeContainingResource(tree.getRootTreeNode().setChildOpen(2,true),resource.getUri());
267 utils.refreshNodeContainingResource(resource);
268 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource.getUri())){
269 updateMySharedNode();
271 else if(tree.getRootTreeNode().isChildOpen(2)){
272 GWT.log("REFRESH THE OTHER WAY 2:"+resource);
273 utils.refreshNodeContainingResource(tree.getRootTreeNode().setChildOpen(2,true),resource.getUri());
277 public void updateNodeChildrenForRemove(final String resource){
278 GWT.log("********************************");
279 GWT.log("[UPDATENODECHILDREN]"+resource);
280 GWT.log("********************************");
281 boolean updated=false;
283 TreeNode sharedNode=null;
284 if(tree.getRootTreeNode().isChildOpen(0)){
285 node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(0,true), resource);
287 GWT.log("CHECK NODE1:"+node+" "+resource);
289 if(tree.getRootTreeNode().isChildOpen(2)){
290 GWT.log("CHECK NODE2:"+node);
292 node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(2,true), resource);
296 if(tree.getRootTreeNode().isChildOpen(3)){
297 GWT.log("CHECK NODE3:"+node);
298 node = utils.getNodeContainingResource2(tree.getRootTreeNode().setChildOpen(3,true), resource);
300 if(node != null && node.getValue() instanceof RestResourceWrapper){
301 GWT.log("*********************"+((RestResourceWrapper) node.getValue()).getResource().getFolders().size());
302 RestResourceWrapper wrapper = (RestResourceWrapper) node.getValue();
303 if(wrapper.getResource().countNotDeletedSubfolders()==1||wrapper.getResource().countNotDeletedSubfolders()==0){
304 updateNodeChildren(((RestResourceWrapper) node.getValue()).getResource().getParentURI());
305 if(((RestResourceWrapper) node.getValue()).getResource().getParentURI().equals(myFolders.getUri())){
306 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)||utils.doesSharedNodeContainsResourceIn2ndLevel(resource)){
307 updateMySharedNode();
313 updateNodeChildren(((RestResource) node.getValue()).getUri());
316 updateNodeChildren(resource);
318 public void updateNodeChildren(final String resource){
321 GWT.log("REFRESH THE OTHER WAY");
322 utils.refreshNodeContainingResource(resource);
323 if(utils.doesSharedNodeContainsResourceIn1stLevel(resource)||utils.doesSharedNodeContainsResourceIn2ndLevel(resource)){
324 GWT.log("REFRESH THE OTHER WAY 1:"+resource);
325 updateMySharedNode();
327 else if(tree.getRootTreeNode().isChildOpen(2)){
328 GWT.log("REFRESH THE OTHER WAY 2:"+resource);
329 utils.refreshNodeContainingResource(tree.getRootTreeNode().setChildOpen(2,true),resource);
333 protected void showPopup(final int x, final int y) {
334 if (selectionModel.getSelectedObject() == null)
338 menu = new FolderContextMenu(images);
339 menu.setPopupPosition(x, y);
342 private boolean init=false;
343 public boolean fetchRootFolders() {
344 UserResource userResource = GSS.get().getCurrentUserResource();
345 if (userResource == null)
348 final String path = userResource.getFilesPath();
349 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
352 public void onComplete() {
353 myFolders = new MyFolderResource(getResult());
354 //selectionModel.setSelected(myFolders, true);
355 //rootNodes.setList(Arrays.asList((RestResource)rootResource));
356 //tree.getRootTreeNode().setChildOpen(0, true);
360 public void onError(Throwable t) {
361 GWT.log("Error fetching root folder", t);
362 GSS.get().displayError("Unable to fetch root folder");
366 DeferredCommand.addCommand(gf);
367 DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
369 public void onComplete() {
374 public void onError(Throwable t) {
375 if(t instanceof RestException){
376 int statusCode = ((RestException)t).getHttpStatusCode();
377 // On IE status code 1223 may be returned instead of 204.
378 if(statusCode == 204 || statusCode == 1223){
379 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
383 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
384 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
389 GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, userResource.getSharedPath(), null) {
392 public void onComplete() {
393 myshared=getResult();
397 public void onError(Throwable t) {
398 GWT.log("Error fetching Shared Root folder", t);
399 GSS.get().displayError("Unable to fetch Shared Root folder");
402 DeferredCommand.addCommand(gs);
403 GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
404 userResource.getOthersPath(), null) {
407 public void onComplete() {
408 others = getResult();
412 public void onError(Throwable t) {
413 GWT.log("Error fetching Others Root folder", t);
414 GSS.get().displayError("Unable to fetch Others Root folder");
417 DeferredCommand.addCommand(go);
419 if(myFolders==null||trash==null||myshared==null||others==null)
421 model.getRootNodes().setList(Arrays.asList((RestResource)myFolders,(RestResource)trash,(RestResource)myshared,(RestResource)others));
422 tree.getRootTreeNode().setChildOpen(0, true);
423 selectionModel.setSelected(myFolders, true);
427 public Images getImages() {
432 public void updateTrashNode(){
433 DeferredCommand.addCommand(new GetCommand<TrashResource>(TrashResource.class, GSS.get().getCurrentUserResource().getTrashPath(), null) {
435 public void onComplete() {
437 boolean trashIsOpen = tree.getRootTreeNode().isChildOpen(1);
438 model.getRootNodes().getList().set(1, trash);
439 model.getRootNodes().refresh();
440 tree.getRootTreeNode().setChildOpen(1, true);
444 public void onError(Throwable t) {
445 if(t instanceof RestException){
446 int statusCode = ((RestException)t).getHttpStatusCode();
447 // On IE status code 1223 may be returned instead of 204.
448 if(statusCode == 204 || statusCode == 1223){
449 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
450 model.getRootNodes().getList().set(1, trash);
451 //model.getRootNodes().refresh();
455 GSS.get().displayError("Unable to fetch trash folder:"+t.getMessage());
456 trash = new TrashResource(GSS.get().getCurrentUserResource().getTrashPath());
457 model.getRootNodes().getList().set(1, trash);
458 //model.getRootNodes().refresh();
465 public void updateRootNode(){
466 final String path = GSS.get().getCurrentUserResource().getFilesPath();
467 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, path, null) {
470 public void onComplete() {
471 myFolders = new MyFolderResource(getResult());
472 model.getRootNodes().getList().set(0, myFolders);
473 model.getRootNodes().refresh();
474 tree.getRootTreeNode().setChildOpen(0, true);
479 public void onError(Throwable t) {
480 GWT.log("Error fetching root folder", t);
481 GSS.get().displayError("Unable to fetch root folder");
485 DeferredCommand.addCommand(gf);
488 public void updateMySharedNode(){
489 GetCommand<SharedResource> gs = new GetCommand<SharedResource>(SharedResource.class, GSS.get().getCurrentUserResource().getSharedPath(), null) {
492 public void onComplete() {
493 myshared=getResult();
494 model.getRootNodes().getList().set(2, myshared);
498 public void onError(Throwable t) {
499 GWT.log("Error fetching Shared Root folder", t);
500 GSS.get().displayError("Unable to fetch Shared Root folder");
503 DeferredCommand.addCommand(gs);
506 public void updateOtherNode(){
507 GetCommand<OthersResource> go = new GetCommand<OthersResource>(OthersResource.class,
508 GSS.get().getCurrentUserResource().getOthersPath(), null) {
511 public void onComplete() {
512 others = getResult();
513 model.getRootNodes().getList().set(3, others);
517 public void onError(Throwable t) {
518 GWT.log("Error fetching Others Root folder", t);
519 GSS.get().displayError("Unable to fetch Others Root folder");
522 DeferredCommand.addCommand(go);
526 public RestResource getSelection(){
527 return selectionModel.getSelectedObject();
530 public void clearSelection(){
531 if(GSS.get().getCurrentSelection().equals(getSelection()))
532 GSS.get().setCurrentSelection(null);
533 selectionModel.setSelected(getSelection(), false);
538 * Retrieve the myFolders.
540 * @return the myFolders
542 public MyFolderResource getMyFolders() {
548 * Retrieve the myshared.
550 * @return the myshared
552 public SharedResource getMyshared() {
558 * Retrieve the trash.
562 public TrashResource getTrash() {
568 * Retrieve the others.
572 public OthersResource getOthers() {
578 * Retrieve the model.
582 public TreeViewModel getModel() {
589 * Retrieve the utils.
593 public CellTreeViewUtils getUtils() {
597 public interface RefreshHandler{
602 public boolean isTrashOrTrashFolderSelected(){
603 return (getSelection() instanceof TrashResource) || (getSelection() instanceof TrashFolderResource);
606 public OtherUserResource getOtherUserResourceOfOtherFolder(OthersFolderResource res){
607 TreeNode n = utils.getNodeContainingResource(tree.getRootTreeNode().setChildOpen(3, true), res);
610 if(n.getValue() instanceof OtherUserResource)
611 return (OtherUserResource) n.getValue();
612 TreeNode parent = n.getParent();
614 while (parent!=null){
615 if(parent.getValue() instanceof OtherUserResource)
616 return (OtherUserResource) parent.getValue();
617 parent = parent.getParent();
623 public void refreshCurrentNode(boolean clearSelection){
624 NodeInfo<RestResource> nodeInfo = (NodeInfo<RestResource>) getModel().getNodeInfo(selectionModel.getSelectedObject());
625 if(nodeInfo==null || nodeInfo.getValueUpdater()==null){
626 GSS.get().showFileList(getSelection(),clearSelection);
630 ((ClearSelection)nodeInfo.getValueUpdater()).setClearSelection(clearSelection);
631 nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());