Revision 1ac430a1

b/web_client/src/gr/grnet/pithos/web/client/FileMenu.java
158 158
				preDownloadCheck();
159 159
			}
160 160
		};
161
		//
162
		RestResource selectedItem = GSS.get().getTreeView().getSelection();
161
        CellTreeView treeView = GSS.get().getTreeView();
162
        if (treeView == null)
163
            return contextMenu;
164
		RestResource selectedItem = treeView.getSelection();
163 165
		boolean downloadVisible = GSS.get().getCurrentSelection() != null && GSS.get().getCurrentSelection() instanceof FileResource;
164 166
		boolean propertiesVisible = !(selectedItem != null && (selectedItem instanceof TrashResource || selectedItem instanceof TrashFolderResource || selectedItem instanceof SharedResource || selectedItem instanceof OthersResource || selectedItem instanceof OtherUserResource 
165 167
					//|| folders.isOthersShared(selectedItem) || selectedItem.getUserObject() instanceof GroupUserResource 
b/web_client/src/gr/grnet/pithos/web/client/GSS.java
7 7
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
8 8
import com.google.gwt.user.client.ui.DockPanel;
9 9
import com.google.gwt.user.client.ui.HasVerticalAlignment;
10
import com.google.gwt.view.client.ListDataProvider;
10 11
import gr.grnet.pithos.web.client.clipboard.Clipboard;
11 12
import gr.grnet.pithos.web.client.commands.GetUserCommand;
12 13
import gr.grnet.pithos.web.client.foldertree.AccountResource;
14
import gr.grnet.pithos.web.client.foldertree.Folder;
13 15
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
16
import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
14 17
import gr.grnet.pithos.web.client.rest.GetRequest;
15 18
import gr.grnet.pithos.web.client.rest.RestException;
16 19
import gr.grnet.pithos.web.client.rest.resource.FileResource;
......
25 28
import java.util.Arrays;
26 29
import java.util.Date;
27 30
import java.util.HashMap;
31
import java.util.Iterator;
28 32
import java.util.List;
29 33

  
30 34
import com.google.gwt.core.client.EntryPoint;
......
191 195
     */
192 196
    private String token;
193 197

  
194
    private FolderTreeView folderTreeView = new FolderTreeView();
198
    private FolderTreeViewModel folderTreeViewModel = new FolderTreeViewModel();
199

  
200
    private FolderTreeView folderTreeView = new FolderTreeView(folderTreeViewModel);
195 201

  
196 202
    private AccountResource account;
197 203

  
......
268 274
        // Call the window resized handler to get the initial sizes setup. Doing
269 275
        // this in a deferred command causes it to occur after all widgets'
270 276
        // sizes have been computed by the browser.
271
        DeferredCommand.addCommand(new Command() {
277
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
272 278

  
273 279
            @Override
274 280
            public void execute() {
275 281
                onWindowResized(Window.getClientHeight());
276 282
            }
277 283
        });
284

  
285
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
286
            @Override
287
            public void execute() {
288
                fetchAccount();
289
            }
290
        });
278 291
    }
279 292

  
280 293
	/**
......
313 326
        Window.Location.assign(GWT.getModuleBaseURL() + "GSS.html");
314 327
	}
315 328

  
329
    private void fetchAccount() {
330
        String path = getApiPath() + username + "?format=json";
331

  
332
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
333
            @Override
334
            public void onSuccess(AccountResource result) {
335
                account = result;
336
                statusPanel.displayStats(account);
337
                folderTreeViewModel.initialize(account);
338
            }
339

  
340
            @Override
341
            public void onError(Throwable t) {
342
                GWT.log("Error getting account", t);
343
                if (t instanceof RestException)
344
                    GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
345
                else
346
                    GSS.get().displayError("System error fetching user data: " + t.getMessage());
347
            }
348
        };
349

  
350
        Scheduler.get().scheduleDeferred(getAccount);
351
    }
352

  
316 353
	/**
317 354
	 * Clear the cookie and redirect the user to the logout page.
318 355
	 */
b/web_client/src/gr/grnet/pithos/web/client/StatusPanel.java
21 21
import com.google.gwt.user.client.ui.HTML;
22 22
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
23 23
import com.google.gwt.user.client.ui.HorizontalPanel;
24
import java.util.Date;
24 25

  
25 26
/**
26 27
 * The panel that displays a status bar with quota information.
......
102 103
		outer.setCellHorizontalAlignment(right, HasHorizontalAlignment.ALIGN_RIGHT);
103 104

  
104 105
		initWidget(outer);
105

  
106
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
107
            @Override
108
            public void execute() {
109
                AccountResource account = GSS.get().getAccount();
110
                displayStats(account);
111
            }
112
        });
113 106
	}
114 107

  
115 108
	/**
116 109
	 * Refresh the widget with the provided statistics.
117 110
	 */
118
	private void displayStats(AccountResource account) {
111
	public void displayStats(AccountResource account) {
119 112
		if (account.getNumberOfObjects() == 1)
120 113
			fileCountLabel.setHTML("1 object");
121 114
		else
......
133 126
			quotaLabel.setHTML(account.getQuotaLeftAsString() +" free");
134 127
		}
135 128
		final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
136
		lastLoginLabel.setHTML(formatter.format(account.getLastLogin()));
137
		currentLoginLabel.setHTML(formatter.format(account.getCurrentLogin()));
129
        Date login = account.getLastLogin();
130
		lastLoginLabel.setHTML(login == null ? "" : formatter.format(login));
131

  
132
        login = account.getCurrentLogin();
133
		currentLoginLabel.setHTML(login == null ? "" : formatter.format(login));
138 134
	}
139 135

  
140 136
	/**
141 137
	 * Requests updated quota information from the server and refreshes
142 138
	 * the display.
143 139
	 */
140
    //TODO: This should not be done here
144 141
	public void updateStats() {
145 142
		final GSS app = GSS.get();
146 143
        String path = app.getApiPath() + app.getUsername();
b/web_client/src/gr/grnet/pithos/web/client/foldertree/AccountResource.java
140 140
                JSONObject o = array.get(i).isObject();
141 141
                if (o != null) {
142 142
                    Folder f = new Folder();
143
                    f.populate(o);
143
                    f.populate(o, null);
144 144
                    containers.add(f);
145 145
                }
146 146
            }
/dev/null
1
/*
2
 * Copyright (c) 2011 Greek Research and Technology Network
3
 */
4

  
5
package gr.grnet.pithos.web.client.foldertree;
6

  
7
import com.google.gwt.http.client.Header;
8
import com.google.gwt.json.client.JSONObject;
9
import com.google.gwt.json.client.JSONParser;
10
import gr.grnet.pithos.web.client.foldertree.Resource;
11
import gr.grnet.pithos.web.client.rest.resource.FolderResource;
12
import java.util.ArrayList;
13
import java.util.Date;
14
import java.util.List;
15

  
16
public class ContainerResource extends Resource {
17
    /*
18
     * The name of the container
19
     */
20
    private String name;
21

  
22
    /*
23
     * The number of objects inside the container
24
     */
25
    private long count;
26

  
27
    /*
28
     * The total size of the objects inside the container
29
     */
30
    private long bytes;
31

  
32
    /*
33
     * The last object modification date
34
     */
35
    private Date lastModified;
36

  
37
    /*
38
     * The date the container was created
39
     */
40
    private Date created;
41

  
42
    private List<Folder> subfolders = new ArrayList<Folder>();
43

  
44
    @Override
45
    public String getLastModifiedSince() {
46
        return "";
47
    }
48

  
49
    public String getName() {
50
        return name;
51
    }
52

  
53
    public long getBytes() {
54
        return bytes;
55
    }
56

  
57
    public long getCount() {
58
        return count;
59
    }
60

  
61
    public Date getCreated() {
62
        return created;
63
    }
64

  
65
    public Date getLastModified() {
66
        return lastModified;
67
    }
68

  
69
    public void setBytes(long bytes) {
70
        this.bytes = bytes;
71
    }
72

  
73
    public void setCount(long count) {
74
        this.count = count;
75
    }
76

  
77
    public void setCreated(Date created) {
78
        this.created = created;
79
    }
80

  
81
    public void setLastModified(Date lastModified) {
82
        this.lastModified = lastModified;
83
    }
84

  
85
    public void setName(String name) {
86
        this.name = name;
87
    }
88

  
89
    public void addSubfolder(Folder f) {
90
        subfolders.add(f);
91
    }
92

  
93
    public boolean hasSubfolders() {
94
        return !subfolders.isEmpty();
95
    }
96

  
97
    public List<Folder> getSubfolders() {
98
        return subfolders;
99
    }
100
}
b/web_client/src/gr/grnet/pithos/web/client/foldertree/Folder.java
11 11
import com.google.gwt.json.client.JSONObject;
12 12
import com.google.gwt.json.client.JSONParser;
13 13
import com.google.gwt.json.client.JSONValue;
14
import java.util.ArrayList;
15 14
import java.util.Date;
16 15
import java.util.LinkedHashSet;
17
import java.util.List;
18 16
import java.util.Set;
19
import org.w3c.css.sac.ElementSelector;
20 17

  
21 18
public class Folder extends Resource {
19
    /*
20
     * The name of the folder. If the folder is a container this is its name. If it is a virtual folder this is the
21
     * last part of its path
22
     */
22 23
    private String name = null;
23 24

  
24 25
    private Date lastModified = null;
......
26 27
    private long bytesUsed = 0;
27 28

  
28 29
    private Set<Folder> subfolders = new LinkedHashSet<Folder>();
30
    /*
31
     * The name of the container that this folder belongs to. If this folder is container, this field equals name
32
     */
29 33
    private String container = null;
30 34

  
35
    /*
36
     * This is the full path of the folder (prefix is a misnomer but it was named so because this is used as a prefix=
37
     * parameter in the request that fetches its children). If the folder is a cointainer this is empty string
38
     */
31 39
    private String prefix = "";
32 40

  
33 41
    public Folder() {};
......
64 72
        return container;
65 73
    }
66 74

  
67
    public void setContainer(String container) {
68
        this.container = container;
69
    }
70

  
71 75
    public String getPrefix() {
72 76
        return prefix;
73 77
    }
......
91 95
            for (int i=0; i<array.size(); i++) {
92 96
                JSONObject o = array.get(i).isObject();
93 97
                if (o != null) {
94
                    if (o.containsKey("subdir")) {
98
                    String contentType = unmarshallString(o, "content_type");
99
                    if (o.containsKey("subdir") || (contentType != null && contentType.startsWith("application/directory"))) {
95 100
                        Folder f = new Folder();
96
                        f.populate(o);
97
                        f.setContainer(container == null ? name : container);
98
                        f.setPrefix(container == null ? f.getName() : prefix + "/" + f.getName());
101
                        f.populate(o, container);
99 102
                        subfolders.add(f);
100 103
                    }
101 104
                    else {
102
                        String contentType = unmarshallString(o, "content_type");
103
                        if (contentType != null && contentType.startsWith("application/directory")) {
104
                            Folder f = new Folder();
105
                            f.populate(o);
106
                            f.setContainer(container == null ? name : container);
107
                            f.setPrefix(container == null ? f.getName() : prefix + "/" + f.getName());
108
                            subfolders.add(f);
109
                        }
110
                        else {
111
                            // add file
112
                        }
105
                        // add file
113 106
                    }
114 107
                }
115 108
            }
116 109
        }
117 110
    }
118 111

  
119
    public void populate(JSONObject o) {
112
    public void populate(JSONObject o, String aContainer) {
113
        String path = null;
120 114
        if (o.containsKey("subdir")) {
121
            name = unmarshallString(o, "subdir");
122
            if (name.endsWith("/"))
123
                name = name.substring(0, name.length() - 1);
115
            path = unmarshallString(o, "subdir");
124 116
        }
125 117
        else {
126
            name = unmarshallString(o, "name");
118
            path = unmarshallString(o, "name");
127 119
            lastModified = unmarshallDate(o, "last_modified");
128 120
        }
121
        if (path.endsWith("/"))
122
            path = path.substring(0, path.length() - 1);
123
        if (path.contains("/"))
124
            name = path.substring(path.lastIndexOf("/") + 1, path.length()); //strip the prefix
125
        else
126
            name = path;
127
        if (aContainer != null) {
128
            container = aContainer;
129
            prefix = path;
130
        }
131
        else {
132
            container = name;
133
            prefix = "";
134
        }
129 135
    }
130 136

  
131 137
    @Override
......
148 154
    public boolean equals(Object other) {
149 155
        if (other instanceof Folder) {
150 156
            Folder o = (Folder) other;
151
            return name.equals(o.getName()) && prefix.equals(o.getPrefix());
157
            if (container != null)
158
                return prefix.equals(o.getPrefix()) && container.equals(o.getContainer());
159
            else
160
                return o.getContainer() == null && name.equals(o.getName());
152 161
        }
153 162
        return false;
154 163
    }
b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java
25 25
import gr.grnet.pithos.web.client.FolderContextMenu;
26 26
import gr.grnet.pithos.web.client.GSS;
27 27
import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTree;
28
import java.util.Iterator;
28 29

  
29 30
public class FolderTreeView extends Composite {
30 31

  
......
74 75
        }
75 76
    }
76 77

  
77
    private SingleSelectionModel<Folder> selectionModel = new SingleSelectionModel<Folder>();
78 78

  
79
    public FolderTreeView() {
80
        final FolderTreeViewModel model = new FolderTreeViewModel(selectionModel);
79
    private FolderTreeViewModel model;
80

  
81
    public FolderTreeView(FolderTreeViewModel viewModel) {
82
        this.model = viewModel;
81 83
        /*
82 84
         * Create the tree using the model. We use <code>null</code> as the default
83 85
         * value of the root node. The default value will be passed to
......
88 90

  
89 91
        tree.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
90 92

  
91
        Handler selectionHandler = new SelectionChangeEvent.Handler() {
92
            @Override
93
            public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
94
                NodeInfo<Folder> nodeInfo = (NodeInfo<Folder>) model.getNodeInfo(selectionModel.getSelectedObject());
95
                if(nodeInfo == null || nodeInfo.getValueUpdater() == null) {
96
                    //GSS.get().showFileList(selectionModel.getSelectedObject());
97
                }
98
                else
99
                    nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
100
                GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
101

  
102

  
103
            }
104
        };
105
        selectionModel.addSelectionChangeHandler(selectionHandler);
106 93
        sinkEvents(Event.ONCONTEXTMENU);
107 94
        sinkEvents(Event.ONMOUSEUP);
108 95
        initWidget(tree);
b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java
12 12
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
13 13
import com.google.gwt.user.client.ui.AbstractImagePrototype;
14 14
import com.google.gwt.view.client.ListDataProvider;
15
import com.google.gwt.view.client.SelectionChangeEvent;
16
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
15 17
import com.google.gwt.view.client.SingleSelectionModel;
16 18
import com.google.gwt.view.client.TreeViewModel;
17 19
import gr.grnet.pithos.web.client.GSS;
......
26 28

  
27 29
public class FolderTreeViewModel implements TreeViewModel {
28 30

  
29
    private SingleSelectionModel<Folder> selectionModel;
31
    private SingleSelectionModel<Folder> selectionModel = new SingleSelectionModel<Folder>();
30 32

  
31
    public FolderTreeViewModel(SingleSelectionModel<Folder> selectionModel) {
32
        this.selectionModel = selectionModel;
33
    private ListDataProvider<Folder> rootDataProvider = new ListDataProvider<Folder>();
34

  
35
    public FolderTreeViewModel() {
36
        Handler selectionHandler = new SelectionChangeEvent.Handler() {
37
            @Override
38
            public void onSelectionChange(SelectionChangeEvent event) {
39
                NodeInfo<Folder> nodeInfo = (NodeInfo<Folder>) getNodeInfo(selectionModel.getSelectedObject());
40
                if(nodeInfo == null || nodeInfo.getValueUpdater() == null) {
41
                    //GSS.get().showFileList(selectionModel.getSelectedObject());
42
                }
43
                else
44
                    nodeInfo.getValueUpdater().update(selectionModel.getSelectedObject());
45
                GSS.get().setCurrentSelection(selectionModel.getSelectedObject());
46
            }
47
        };
48
        selectionModel.addSelectionChangeHandler(selectionHandler);
33 49
    }
34
    
50

  
35 51
    @Override
36 52
    public <T> NodeInfo<?> getNodeInfo(T value) {
37 53
        if (value == null) {
38
            final ListDataProvider<Folder> dataProvider = new ListDataProvider<Folder>();
39 54
            Folder f = new Folder("Loading ...");
40
            dataProvider.getList().add(f);
41
            Scheduler.get().scheduleDeferred(new ScheduledCommand() {
42
                @Override
43
                public void execute() {
44
                    fetchAccount(dataProvider);
45
                }
46
            });
47
            return new DragAndDropNodeInfo<Folder>(dataProvider, new FolderCell(), selectionModel, null);
55
            rootDataProvider.getList().add(f);
56
            return new DragAndDropNodeInfo<Folder>(rootDataProvider, new FolderCell(), selectionModel, null);
48 57
        }
49 58
        else {
50 59
            final Folder f = (Folder) value;
51 60
            final ListDataProvider<Folder> dataProvider = new ListDataProvider<Folder>();
52
            dataProvider.getList().addAll(f.getSubfolders());
61
            dataProvider.flush();
53 62
            Scheduler.get().scheduleDeferred(new ScheduledCommand() {
54 63
                @Override
55 64
                public void execute() {
56 65
                    final GSS app = GSS.get();
57
                    String container = f.getContainer() == null ? f.getName() : f.getContainer();
58
                    String prefix = f.getContainer() == null ? "" : f.getPrefix();
59
                    String path = app.getApiPath() + app.getUsername() + "/" + container + "?format=json&delimiter=/&prefix=" + prefix;
66
                    String path = app.getApiPath() + app.getUsername() + "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix();
60 67
                    GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, path, f) {
61 68
                        @Override
62 69
                        public void onSuccess(Folder result) {
......
89 96
        return false;
90 97
    }
91 98

  
92
    public void fetchAccount(final ListDataProvider<Folder> dataProvider) {
93
        final GSS app = GSS.get();
94
        String path = app.getApiPath() + app.getUsername() + "?format=json";
95

  
96
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
97
            @Override
98
            public void onSuccess(AccountResource result) {
99
                app.setAccount(result);
100
                Iterator<Folder> iter = result.getContainers().iterator();
101
                fetchFolder(iter, dataProvider, result.getContainers());
102
            }
103

  
104
            @Override
105
            public void onError(Throwable t) {
106
                GWT.log("Error getting account", t);
107
                if (t instanceof RestException)
108
                    GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
109
                else
110
                    GSS.get().displayError("System error fetching user data: " + t.getMessage());
111
            }
112
        };
113

  
114
        Scheduler.get().scheduleDeferred(getAccount);
115
    }
116

  
117 99
    private void fetchFolder(final Iterator<Folder> iter, final ListDataProvider<Folder> dataProvider, final Set<Folder> folders) {
118 100
        if (iter.hasNext()) {
119 101
            final Folder f = iter.next();
120 102

  
121 103
            GSS app = GSS.get();
122
            String container = f.getContainer() == null ? f.getName() : f.getContainer();
123
            String prefix = f.getContainer() == null ? "" : f.getPrefix();
124
            String path = app.getApiPath() + app.getUsername() + "/" + container + "?format=json&delimiter=/&prefix=" + prefix;
104
            String path = app.getApiPath() + app.getUsername() + "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix();
125 105
            GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, path, f) {
126 106
                @Override
127 107
                public void onSuccess(Folder result) {
......
144 124
            dataProvider.getList().addAll(folders);
145 125
        }
146 126
    }
127

  
128
    public void initialize(AccountResource account) {
129
        Iterator<Folder> iter = account.getContainers().iterator();
130
        fetchFolder(iter, rootDataProvider, account.getContainers());
131
    }
147 132
}
b/web_client/src/gr/grnet/pithos/web/client/foldertree/Resource.java
17 17

  
18 18
public abstract class Resource {
19 19

  
20
    String uri;
21

  
22
    public String getUri() {
23
        return uri;
24
    }
25

  
26 20
    protected static String unmarshallString(JSONObject obj, String key){
27 21
        if(obj.get(key) != null) {
28 22
            JSONString s = obj.get(key).isString();
b/web_client/src/gr/grnet/pithos/web/client/rest/GetRequest.java
70 70
                public void onError(Request request, Throwable throwable) {
71 71
                    if (throwable instanceof RestException) {
72 72
                        if (((RestException) throwable).getHttpStatusCode() == 304 && cached != null){
73
                            GWT.log("Using cache: " + cached.getUri(), null);
73
                            GWT.log("Using cache: " + cached.toString(), null);
74 74
                            onSuccess(cached);
75 75
                            return;
76 76
                        }

Also available in: Unified diff