Fixed bug when displaying folder tree after the second level. Now the tree works...
authorChristos Stathis <chstath@ebs.gr>
Thu, 23 Jun 2011 14:33:11 +0000 (17:33 +0300)
committerChristos Stathis <chstath@ebs.gr>
Thu, 23 Jun 2011 14:33:11 +0000 (17:33 +0300)
src/gr/grnet/pithos/web/client/FileMenu.java
src/gr/grnet/pithos/web/client/GSS.java
src/gr/grnet/pithos/web/client/StatusPanel.java
src/gr/grnet/pithos/web/client/foldertree/AccountResource.java
src/gr/grnet/pithos/web/client/foldertree/ContainerResource.java [deleted file]
src/gr/grnet/pithos/web/client/foldertree/Folder.java
src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java
src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java
src/gr/grnet/pithos/web/client/foldertree/Resource.java
src/gr/grnet/pithos/web/client/rest/GetRequest.java

index 91a7448..071544f 100644 (file)
@@ -158,8 +158,10 @@ public class FileMenu extends PopupPanel implements ClickHandler {
                                preDownloadCheck();
                        }
                };
-               //
-               RestResource selectedItem = GSS.get().getTreeView().getSelection();
+        CellTreeView treeView = GSS.get().getTreeView();
+        if (treeView == null)
+            return contextMenu;
+               RestResource selectedItem = treeView.getSelection();
                boolean downloadVisible = GSS.get().getCurrentSelection() != null && GSS.get().getCurrentSelection() instanceof FileResource;
                boolean propertiesVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource 
                                        //|| folders.isOthersShared(selectedItem) || selectedItem.getUserObject() instanceof GroupUserResource 
index f844904..568f6a1 100644 (file)
@@ -7,10 +7,13 @@ import com.google.gwt.core.client.Scheduler;
 import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.user.client.ui.DockPanel;
 import com.google.gwt.user.client.ui.HasVerticalAlignment;
+import com.google.gwt.view.client.ListDataProvider;
 import gr.grnet.pithos.web.client.clipboard.Clipboard;
 import gr.grnet.pithos.web.client.commands.GetUserCommand;
 import gr.grnet.pithos.web.client.foldertree.AccountResource;
+import gr.grnet.pithos.web.client.foldertree.Folder;
 import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
+import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
 import gr.grnet.pithos.web.client.rest.GetRequest;
 import gr.grnet.pithos.web.client.rest.RestException;
 import gr.grnet.pithos.web.client.rest.resource.FileResource;
@@ -25,6 +28,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 
 import com.google.gwt.core.client.EntryPoint;
@@ -191,7 +195,9 @@ public class GSS implements EntryPoint, ResizeHandler {
      */
     private String token;
 
-    private FolderTreeView folderTreeView = new FolderTreeView();
+    private FolderTreeViewModel folderTreeViewModel = new FolderTreeViewModel();
+
+    private FolderTreeView folderTreeView = new FolderTreeView(folderTreeViewModel);
 
     private AccountResource account;
 
@@ -268,13 +274,20 @@ public class GSS implements EntryPoint, ResizeHandler {
         // Call the window resized handler to get the initial sizes setup. Doing
         // this in a deferred command causes it to occur after all widgets'
         // sizes have been computed by the browser.
-        DeferredCommand.addCommand(new Command() {
+        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
 
             @Override
             public void execute() {
                 onWindowResized(Window.getClientHeight());
             }
         });
+
+        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
+            @Override
+            public void execute() {
+                fetchAccount();
+            }
+        });
     }
 
        /**
@@ -313,6 +326,30 @@ public class GSS implements EntryPoint, ResizeHandler {
         Window.Location.assign(GWT.getModuleBaseURL() + "GSS.html");
        }
 
+    private void fetchAccount() {
+        String path = getApiPath() + username + "?format=json";
+
+        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
+            @Override
+            public void onSuccess(AccountResource result) {
+                account = result;
+                statusPanel.displayStats(account);
+                folderTreeViewModel.initialize(account);
+            }
+
+            @Override
+            public void onError(Throwable t) {
+                GWT.log("Error getting account", t);
+                if (t instanceof RestException)
+                    GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
+                else
+                    GSS.get().displayError("System error fetching user data: " + t.getMessage());
+            }
+        };
+
+        Scheduler.get().scheduleDeferred(getAccount);
+    }
+
        /**
         * Clear the cookie and redirect the user to the logout page.
         */
index 369bcf2..79141f1 100644 (file)
@@ -21,6 +21,7 @@ import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.HTML;
 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
 import com.google.gwt.user.client.ui.HorizontalPanel;
+import java.util.Date;
 
 /**
  * The panel that displays a status bar with quota information.
@@ -102,20 +103,12 @@ public class StatusPanel extends Composite {
                outer.setCellHorizontalAlignment(right, HasHorizontalAlignment.ALIGN_RIGHT);
 
                initWidget(outer);
-
-        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-            @Override
-            public void execute() {
-                AccountResource account = GSS.get().getAccount();
-                displayStats(account);
-            }
-        });
        }
 
        /**
         * Refresh the widget with the provided statistics.
         */
-       private void displayStats(AccountResource account) {
+       public void displayStats(AccountResource account) {
                if (account.getNumberOfObjects() == 1)
                        fileCountLabel.setHTML("1 object");
                else
@@ -133,14 +126,18 @@ public class StatusPanel extends Composite {
                        quotaLabel.setHTML(account.getQuotaLeftAsString() +" free");
                }
                final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
-               lastLoginLabel.setHTML(formatter.format(account.getLastLogin()));
-               currentLoginLabel.setHTML(formatter.format(account.getCurrentLogin()));
+        Date login = account.getLastLogin();
+               lastLoginLabel.setHTML(login == null ? "" : formatter.format(login));
+
+        login = account.getCurrentLogin();
+               currentLoginLabel.setHTML(login == null ? "" : formatter.format(login));
        }
 
        /**
         * Requests updated quota information from the server and refreshes
         * the display.
         */
+    //TODO: This should not be done here
        public void updateStats() {
                final GSS app = GSS.get();
         String path = app.getApiPath() + app.getUsername();
index 95bc2ab..df7aef0 100644 (file)
@@ -140,7 +140,7 @@ public class AccountResource extends Resource {
                 JSONObject o = array.get(i).isObject();
                 if (o != null) {
                     Folder f = new Folder();
-                    f.populate(o);
+                    f.populate(o, null);
                     containers.add(f);
                 }
             }
diff --git a/src/gr/grnet/pithos/web/client/foldertree/ContainerResource.java b/src/gr/grnet/pithos/web/client/foldertree/ContainerResource.java
deleted file mode 100644 (file)
index 6b96447..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2011 Greek Research and Technology Network
- */
-
-package gr.grnet.pithos.web.client.foldertree;
-
-import com.google.gwt.http.client.Header;
-import com.google.gwt.json.client.JSONObject;
-import com.google.gwt.json.client.JSONParser;
-import gr.grnet.pithos.web.client.foldertree.Resource;
-import gr.grnet.pithos.web.client.rest.resource.FolderResource;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-public class ContainerResource extends Resource {
-    /*
-     * The name of the container
-     */
-    private String name;
-
-    /*
-     * The number of objects inside the container
-     */
-    private long count;
-
-    /*
-     * The total size of the objects inside the container
-     */
-    private long bytes;
-
-    /*
-     * The last object modification date
-     */
-    private Date lastModified;
-
-    /*
-     * The date the container was created
-     */
-    private Date created;
-
-    private List<Folder> subfolders = new ArrayList<Folder>();
-
-    @Override
-    public String getLastModifiedSince() {
-        return "";
-    }
-
-    public String getName() {
-        return name;
-    }
-
-    public long getBytes() {
-        return bytes;
-    }
-
-    public long getCount() {
-        return count;
-    }
-
-    public Date getCreated() {
-        return created;
-    }
-
-    public Date getLastModified() {
-        return lastModified;
-    }
-
-    public void setBytes(long bytes) {
-        this.bytes = bytes;
-    }
-
-    public void setCount(long count) {
-        this.count = count;
-    }
-
-    public void setCreated(Date created) {
-        this.created = created;
-    }
-
-    public void setLastModified(Date lastModified) {
-        this.lastModified = lastModified;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    public void addSubfolder(Folder f) {
-        subfolders.add(f);
-    }
-
-    public boolean hasSubfolders() {
-        return !subfolders.isEmpty();
-    }
-
-    public List<Folder> getSubfolders() {
-        return subfolders;
-    }
-}
index d65a8c9..73224e2 100644 (file)
@@ -11,14 +11,15 @@ import com.google.gwt.json.client.JSONArray;
 import com.google.gwt.json.client.JSONObject;
 import com.google.gwt.json.client.JSONParser;
 import com.google.gwt.json.client.JSONValue;
-import java.util.ArrayList;
 import java.util.Date;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Set;
-import org.w3c.css.sac.ElementSelector;
 
 public class Folder extends Resource {
+    /*
+     * The name of the folder. If the folder is a container this is its name. If it is a virtual folder this is the
+     * last part of its path
+     */
     private String name = null;
 
     private Date lastModified = null;
@@ -26,8 +27,15 @@ public class Folder extends Resource {
     private long bytesUsed = 0;
 
     private Set<Folder> subfolders = new LinkedHashSet<Folder>();
+    /*
+     * The name of the container that this folder belongs to. If this folder is container, this field equals name
+     */
     private String container = null;
 
+    /*
+     * This is the full path of the folder (prefix is a misnomer but it was named so because this is used as a prefix=
+     * parameter in the request that fetches its children). If the folder is a cointainer this is empty string
+     */
     private String prefix = "";
 
     public Folder() {};
@@ -64,10 +72,6 @@ public class Folder extends Resource {
         return container;
     }
 
-    public void setContainer(String container) {
-        this.container = container;
-    }
-
     public String getPrefix() {
         return prefix;
     }
@@ -91,41 +95,43 @@ public class Folder extends Resource {
             for (int i=0; i<array.size(); i++) {
                 JSONObject o = array.get(i).isObject();
                 if (o != null) {
-                    if (o.containsKey("subdir")) {
+                    String contentType = unmarshallString(o, "content_type");
+                    if (o.containsKey("subdir") || (contentType != null && contentType.startsWith("application/directory"))) {
                         Folder f = new Folder();
-                        f.populate(o);
-                        f.setContainer(container == null ? name : container);
-                        f.setPrefix(container == null ? f.getName() : prefix + "/" + f.getName());
+                        f.populate(o, container);
                         subfolders.add(f);
                     }
                     else {
-                        String contentType = unmarshallString(o, "content_type");
-                        if (contentType != null && contentType.startsWith("application/directory")) {
-                            Folder f = new Folder();
-                            f.populate(o);
-                            f.setContainer(container == null ? name : container);
-                            f.setPrefix(container == null ? f.getName() : prefix + "/" + f.getName());
-                            subfolders.add(f);
-                        }
-                        else {
-                            // add file
-                        }
+                        // add file
                     }
                 }
             }
         }
     }
 
-    public void populate(JSONObject o) {
+    public void populate(JSONObject o, String aContainer) {
+        String path = null;
         if (o.containsKey("subdir")) {
-            name = unmarshallString(o, "subdir");
-            if (name.endsWith("/"))
-                name = name.substring(0, name.length() - 1);
+            path = unmarshallString(o, "subdir");
         }
         else {
-            name = unmarshallString(o, "name");
+            path = unmarshallString(o, "name");
             lastModified = unmarshallDate(o, "last_modified");
         }
+        if (path.endsWith("/"))
+            path = path.substring(0, path.length() - 1);
+        if (path.contains("/"))
+            name = path.substring(path.lastIndexOf("/") + 1, path.length()); //strip the prefix
+        else
+            name = path;
+        if (aContainer != null) {
+            container = aContainer;
+            prefix = path;
+        }
+        else {
+            container = name;
+            prefix = "";
+        }
     }
 
     @Override
@@ -148,7 +154,10 @@ public class Folder extends Resource {
     public boolean equals(Object other) {
         if (other instanceof Folder) {
             Folder o = (Folder) other;
-            return name.equals(o.getName()) && prefix.equals(o.getPrefix());
+            if (container != null)
+                return prefix.equals(o.getPrefix()) && container.equals(o.getContainer());
+            else
+                return o.getContainer() == null && name.equals(o.getName());
         }
         return false;
     }
index ff807c0..80eebca 100644 (file)
@@ -25,6 +25,7 @@ import com.google.gwt.view.client.TreeViewModel.NodeInfo;
 import gr.grnet.pithos.web.client.FolderContextMenu;
 import gr.grnet.pithos.web.client.GSS;
 import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTree;
+import java.util.Iterator;
 
 public class FolderTreeView extends Composite {
 
@@ -74,10 +75,11 @@ public class FolderTreeView extends Composite {
         }
     }
 
-    private SingleSelectionModel<Folder> selectionModel = new SingleSelectionModel<Folder>();
 
-    public FolderTreeView() {
-        final FolderTreeViewModel model = new FolderTreeViewModel(selectionModel);
+    private FolderTreeViewModel model;
+
+    public FolderTreeView(FolderTreeViewModel viewModel) {
+        this.model = viewModel;
         /*
          * Create the tree using the model. We use <code>null</code> as the default
          * value of the root node. The default value will be passed to
@@ -88,21 +90,6 @@ public class FolderTreeView extends Composite {
 
         tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
 
-        Handler selectionHandler = new SelectionChangeEvent.Handler() {
-            @Override
-            public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
-                NodeInfo<Folder> nodeInfo = (NodeInfo<Folder>) model.getNodeInfo(selectionModel.getSelectedObject());
-                if(nodeInfo == null || nodeInfo.getValueUpdater() == null) {
-                    //GSS.get().showFileList(selectionModel.getSelectedObject());
-                }
-                else
-                    nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
-                GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
-
-
-            }
-        };
-        selectionModel.addSelectionChangeHandler(selectionHandler);
         sinkEvents(Event.ONCONTEXTMENU);
         sinkEvents(Event.ONMOUSEUP);
         initWidget(tree);
index 402a653..4ce2356 100644 (file)
@@ -12,6 +12,8 @@ import com.google.gwt.core.client.Scheduler.ScheduledCommand;
 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
 import com.google.gwt.user.client.ui.AbstractImagePrototype;
 import com.google.gwt.view.client.ListDataProvider;
+import com.google.gwt.view.client.SelectionChangeEvent;
+import com.google.gwt.view.client.SelectionChangeEvent.Handler;
 import com.google.gwt.view.client.SingleSelectionModel;
 import com.google.gwt.view.client.TreeViewModel;
 import gr.grnet.pithos.web.client.GSS;
@@ -26,37 +28,42 @@ import java.util.Set;
 
 public class FolderTreeViewModel implements TreeViewModel {
 
-    private SingleSelectionModel<Folder> selectionModel;
+    private SingleSelectionModel<Folder> selectionModel = new SingleSelectionModel<Folder>();
 
-    public FolderTreeViewModel(SingleSelectionModel<Folder> selectionModel) {
-        this.selectionModel = selectionModel;
+    private ListDataProvider<Folder> rootDataProvider = new ListDataProvider<Folder>();
+
+    public FolderTreeViewModel() {
+        Handler selectionHandler = new SelectionChangeEvent.Handler() {
+            @Override
+            public void onSelectionChange(SelectionChangeEvent event) {
+                NodeInfo<Folder> nodeInfo = (NodeInfo<Folder>) getNodeInfo(selectionModel.getSelectedObject());
+                if(nodeInfo == null || nodeInfo.getValueUpdater() == null) {
+                    //GSS.get().showFileList(selectionModel.getSelectedObject());
+                }
+                else
+                    nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
+                GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
+            }
+        };
+        selectionModel.addSelectionChangeHandler(selectionHandler);
     }
-    
+
     @Override
     public <T> NodeInfo<?> getNodeInfo(T value) {
         if (value == null) {
-            final ListDataProvider<Folder> dataProvider = new ListDataProvider<Folder>();
             Folder f = new Folder("Loading ...");
-            dataProvider.getList().add(f);
-            Scheduler.get().scheduleDeferred(new ScheduledCommand() {
-                @Override
-                public void execute() {
-                    fetchAccount(dataProvider);
-                }
-            });
-            return new DragAndDropNodeInfo<Folder>(dataProvider, new FolderCell(), selectionModel, null);
+            rootDataProvider.getList().add(f);
+            return new DragAndDropNodeInfo<Folder>(rootDataProvider, new FolderCell(), selectionModel, null);
         }
         else {
             final Folder f = (Folder) value;
             final ListDataProvider<Folder> dataProvider = new ListDataProvider<Folder>();
-            dataProvider.getList().addAll(f.getSubfolders());
+            dataProvider.flush();
             Scheduler.get().scheduleDeferred(new ScheduledCommand() {
                 @Override
                 public void execute() {
                     final GSS app = GSS.get();
-                    String container = f.getContainer() == null ? f.getName() : f.getContainer();
-                    String prefix = f.getContainer() == null ? "" : f.getPrefix();
-                    String path = app.getApiPath() + app.getUsername() + "/" + container + "?format=json&delimiter=/&prefix=" + prefix;
+                    String path = app.getApiPath() + app.getUsername() + "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix();
                     GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, path, f) {
                         @Override
                         public void onSuccess(Folder result) {
@@ -89,39 +96,12 @@ public class FolderTreeViewModel implements TreeViewModel {
         return false;
     }
 
-    public void fetchAccount(final ListDataProvider<Folder> dataProvider) {
-        final GSS app = GSS.get();
-        String path = app.getApiPath() + app.getUsername() + "?format=json";
-
-        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
-            @Override
-            public void onSuccess(AccountResource result) {
-                app.setAccount(result);
-                Iterator<Folder> iter = result.getContainers().iterator();
-                fetchFolder(iter, dataProvider, result.getContainers());
-            }
-
-            @Override
-            public void onError(Throwable t) {
-                GWT.log("Error getting account", t);
-                if (t instanceof RestException)
-                    GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
-                else
-                    GSS.get().displayError("System error fetching user data: " + t.getMessage());
-            }
-        };
-
-        Scheduler.get().scheduleDeferred(getAccount);
-    }
-
     private void fetchFolder(final Iterator<Folder> iter, final ListDataProvider<Folder> dataProvider, final Set<Folder> folders) {
         if (iter.hasNext()) {
             final Folder f = iter.next();
 
             GSS app = GSS.get();
-            String container = f.getContainer() == null ? f.getName() : f.getContainer();
-            String prefix = f.getContainer() == null ? "" : f.getPrefix();
-            String path = app.getApiPath() + app.getUsername() + "/" + container + "?format=json&delimiter=/&prefix=" + prefix;
+            String path = app.getApiPath() + app.getUsername() + "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix();
             GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, path, f) {
                 @Override
                 public void onSuccess(Folder result) {
@@ -144,4 +124,9 @@ public class FolderTreeViewModel implements TreeViewModel {
             dataProvider.getList().addAll(folders);
         }
     }
+
+    public void initialize(AccountResource account) {
+        Iterator<Folder> iter = account.getContainers().iterator();
+        fetchFolder(iter, rootDataProvider, account.getContainers());
+    }
 }
index 0594301..479df02 100644 (file)
@@ -17,12 +17,6 @@ import java.util.Date;
 
 public abstract class Resource {
 
-    String uri;
-
-    public String getUri() {
-        return uri;
-    }
-
     protected static String unmarshallString(JSONObject obj, String key){
         if(obj.get(key) != null) {
             JSONString s = obj.get(key).isString();
index de5d2dd..4c0a7d1 100644 (file)
@@ -70,7 +70,7 @@ public abstract class GetRequest<T extends Resource> implements ScheduledCommand
                 public void onError(Request request, Throwable throwable) {
                     if (throwable instanceof RestException) {
                         if (((RestException) throwable).getHttpStatusCode() == 304 && cached != null){
-                            GWT.log("Using cache: " + cached.getUri(), null);
+                            GWT.log("Using cache: " + cached.toString(), null);
                             onSuccess(cached);
                             return;
                         }