2 * Copyright 2011-2012 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.
36 package gr.grnet.pithos.web.client.othersharedtree;
38 import gr.grnet.pithos.web.client.FolderContextMenu;
39 import gr.grnet.pithos.web.client.Pithos;
40 import gr.grnet.pithos.web.client.SharingUsers;
41 import gr.grnet.pithos.web.client.foldertree.AccountResource;
42 import gr.grnet.pithos.web.client.foldertree.File;
43 import gr.grnet.pithos.web.client.foldertree.Folder;
44 import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeView;
45 import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeView.Templates;
46 import gr.grnet.pithos.web.client.rest.GetRequest;
47 import gr.grnet.pithos.web.client.rest.RestException;
49 import java.util.HashMap;
50 import java.util.HashSet;
51 import java.util.Iterator;
55 import com.google.gwt.cell.client.AbstractCell;
56 import com.google.gwt.cell.client.Cell;
57 import com.google.gwt.cell.client.TextCell;
58 import com.google.gwt.cell.client.ValueUpdater;
59 import com.google.gwt.core.client.GWT;
60 import com.google.gwt.core.client.Scheduler;
61 import com.google.gwt.event.dom.client.ContextMenuEvent;
62 import com.google.gwt.http.client.Response;
63 import com.google.gwt.http.client.URL;
64 import com.google.gwt.safehtml.shared.SafeHtml;
65 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
66 import com.google.gwt.text.shared.SafeHtmlRenderer;
67 import com.google.gwt.user.client.Command;
68 import com.google.gwt.user.client.ui.AbstractImagePrototype;
69 import com.google.gwt.view.client.ListDataProvider;
70 import com.google.gwt.view.client.SelectionChangeEvent;
71 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
72 import com.google.gwt.view.client.SingleSelectionModel;
73 import com.google.gwt.view.client.TreeViewModel;
75 public class OtherSharedTreeViewModel implements TreeViewModel {
79 String dummy = "No shares by others yet";
81 private Cell<Folder> folderCell = new AbstractCell<Folder>(ContextMenuEvent.getType().getName()) {
84 public void render(Context context, Folder folder, SafeHtmlBuilder safeHtmlBuilder) {
85 String html = AbstractImagePrototype.create(OtherSharedTreeView.images.folderYellow()).getHTML();
86 safeHtmlBuilder.appendHtmlConstant(html).appendHtmlConstant(" ");
87 safeHtmlBuilder.append(Templates.INSTANCE.nameSpan(folder.getName()));
91 public void onBrowserEvent(Context context, com.google.gwt.dom.client.Element parent, final Folder folder, com.google.gwt.dom.client.NativeEvent event, ValueUpdater<Folder> valueUpdater) {
92 if (event.getType().equals(ContextMenuEvent.getType().getName())) {
93 final int x = event.getClientX();
94 final int y = event.getClientY();
95 OtherSharedTreeViewModel.this.selectionModel.setSelected(folder, true);
96 app.scheduleFolderHeadCommand(folder, new Command() {
99 public void execute() {
100 FolderContextMenu menu = new FolderContextMenu(app, OtherSharedTreeView.images, app.getSelectedTree(), folder);
101 menu.setPopupPosition(x, y);
109 private ListDataProvider<String> rootDataProvider = new ListDataProvider<String>();
110 protected ListDataProvider<String> userLevelDataProvider = new ListDataProvider<String>();
112 protected Map<String, ListDataProvider<Folder>> userDataProviderMap = new HashMap<String, ListDataProvider<Folder>>();
113 private Map<Folder, ListDataProvider<Folder>> dataProviderMap = new HashMap<Folder, ListDataProvider<Folder>>();
115 protected SingleSelectionModel<Folder> selectionModel;
117 public OtherSharedTreeViewModel(Pithos _app, SingleSelectionModel<Folder> selectionModel) {
119 this.selectionModel = selectionModel;
123 public <T> NodeInfo<?> getNodeInfo(T value) {
125 fetchSharingUsers(null);
126 return new DefaultNodeInfo<String>(userLevelDataProvider, new TextCell(new SafeHtmlRenderer<String>() {
129 public SafeHtml render(String object) {
130 SafeHtmlBuilder builder = new SafeHtmlBuilder();
131 render(object, builder);
132 return builder.toSafeHtml();
136 public void render(String object, SafeHtmlBuilder builder) {
137 if (!object.equals(dummy)) {
138 String html = AbstractImagePrototype.create(OtherSharedTreeView.images.myShared()).getHTML();
139 builder.appendHtmlConstant(html).appendHtmlConstant(" ");
141 builder.append(OtherSharedTreeView.Templates.INSTANCE.nameSpan(object));
145 else if (value instanceof String) {
146 String username = (String) value;
147 if (userDataProviderMap.get(username) == null) {
148 userDataProviderMap.put(username, new ListDataProvider<Folder>());
150 final ListDataProvider<Folder> dataProvider = userDataProviderMap.get(username);
151 fetchSharedContainers(username, dataProvider, null);
152 return new DefaultNodeInfo<Folder>(dataProvider, folderCell, selectionModel, null);
155 final Folder f = (Folder) value;
156 if (dataProviderMap.get(f) == null) {
157 dataProviderMap.put(f, new ListDataProvider<Folder>());
159 final ListDataProvider<Folder> dataProvider = dataProviderMap.get(f);
160 fetchFolder(f, dataProvider, false);
161 return new DefaultNodeInfo<Folder>(dataProvider, folderCell, selectionModel, null);
165 private void fetchSharingUsers(final Command callback) {
166 GetRequest<SharingUsers> getSharingUsers = new GetRequest<SharingUsers>(SharingUsers.class, app.getApiPath(), "", "?format=json") {
168 public void onSuccess(final SharingUsers _result) {
169 userLevelDataProvider.getList().clear();
170 userLevelDataProvider.getList().addAll(_result.getUsers());
171 if (userLevelDataProvider.getList().isEmpty())
172 userLevelDataProvider.getList().add(dummy);
173 Iterator<String> iter = _result.getUsers().iterator();
174 fetchSharedContainers(iter, callback);
178 public void onError(Throwable t) {
179 GWT.log("Error getting folder", t);
181 if (t instanceof RestException)
182 app.displayError("Error getting folder: " + ((RestException) t).getHttpStatusText());
184 app.displayError("System error fetching folder: " + t.getMessage());
188 protected void onUnauthorized(Response response) {
189 app.sessionExpired();
192 getSharingUsers.setHeader("X-Auth-Token", app.getToken());
193 Scheduler.get().scheduleDeferred(getSharingUsers);
196 protected void fetchSharedContainers(final Iterator<String> iter, final Command callback) {
197 if (iter.hasNext()) {
198 String username = iter.next();
199 if (userDataProviderMap.get(username) == null) {
200 userDataProviderMap.put(username, new ListDataProvider<Folder>());
202 final ListDataProvider<Folder> dataProvider = userDataProviderMap.get(username);
203 fetchSharedContainers(username, dataProvider, new Command() {
206 public void execute() {
207 fetchSharedContainers(iter, callback);
213 if (callback != null)
218 public boolean isLeaf(Object o) {
220 return userLevelDataProvider.getList().isEmpty();
221 else if (o instanceof Folder) {
222 Folder f = (Folder) o;
223 return f.getSubfolders().isEmpty();
226 ListDataProvider<Folder> dp = userDataProviderMap.get(o);
228 return dp.getList().isEmpty();
233 private void fetchSharedContainers(final String username, final ListDataProvider<Folder> dataProvider, final Command callback) {
234 GetRequest<AccountResource> getUserSharedContainers = new GetRequest<AccountResource>(AccountResource.class, app.getApiPath(), username, "?format=json") {
237 public void onSuccess(AccountResource _result) {
238 final ListDataProvider<Folder> tempProvider = new ListDataProvider<Folder>();
239 Iterator<Folder> iter = _result.getContainers().iterator();
240 fetchFolder(username, iter, tempProvider, new Command() {
243 public void execute() {
244 dataProvider.getList().clear();
245 dataProvider.getList().addAll(tempProvider.getList());
246 if (callback != null)
253 public void onError(Throwable t) {
254 GWT.log("Error getting account", t);
256 if (t instanceof RestException)
257 app.displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
259 app.displayError("System error fetching user data: " + t.getMessage());
263 protected void onUnauthorized(Response response) {
264 app.sessionExpired();
267 getUserSharedContainers.setHeader("X-Auth-Token", app.getToken());
268 Scheduler.get().scheduleDeferred(getUserSharedContainers);
271 protected void fetchFolder(final String username, final Iterator<Folder> iter, final ListDataProvider<Folder> dataProvider, final Command callback) {
272 if (iter.hasNext()) {
273 final Folder f = iter.next();
275 String path = "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
276 GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), username, path, f) {
278 public void onSuccess(Folder _result) {
279 dataProvider.getList().add(_result);
280 fetchFolder(username, iter, dataProvider, callback);
284 public void onError(Throwable t) {
285 GWT.log("Error getting folder", t);
287 if (t instanceof RestException)
288 app.displayError("Error getting folder: " + ((RestException) t).getHttpStatusText());
290 app.displayError("System error fetching folder: " + t.getMessage());
294 protected void onUnauthorized(Response response) {
295 app.sessionExpired();
298 getFolder.setHeader("X-Auth-Token", app.getToken());
299 Scheduler.get().scheduleDeferred(getFolder);
301 else if (callback != null)
305 public Folder getSelection() {
306 return selectionModel.getSelectedObject();
309 public void updateFolder(Folder folder, boolean showfiles) {
310 if (dataProviderMap.get(folder) == null) {
311 dataProviderMap.put(folder, new ListDataProvider<Folder>());
313 final ListDataProvider<Folder> dataProvider = dataProviderMap.get(folder);
314 fetchFolder(folder, dataProvider, showfiles);
317 public void fetchFolder(final Folder f, final ListDataProvider<Folder> dataProvider, final boolean showfiles) {
318 String path = "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix());
319 GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, app.getApiPath(), f.getOwner(), path, f) {
321 public void onSuccess(final Folder _result) {
323 app.showFiles(_result);
324 Iterator<Folder> iter = _result.getSubfolders().iterator();
325 fetchFolder(_result.getOwner(), iter, dataProvider, new Command() {
327 public void execute() {
328 dataProvider.getList().clear();
329 dataProvider.getList().addAll(_result.getSubfolders());
330 app.getOtherSharedTreeView().updateChildren(f);
336 public void onError(Throwable t) {
337 GWT.log("Error getting folder", t);
339 if (t instanceof RestException)
340 app.displayError("Error getting folder: " + ((RestException) t).getHttpStatusText());
342 app.displayError("System error fetching folder: " + t.getMessage());
346 protected void onUnauthorized(Response response) {
347 app.sessionExpired();
350 getFolder.setHeader("X-Auth-Token", app.getToken());
351 Scheduler.get().scheduleDeferred(getFolder);
354 public void initialize(Command callback) {
355 fetchSharingUsers(callback);