X-Git-Url: https://code.grnet.gr/git/pithos/blobdiff_plain/eee732d59e907f24179c970b9148184b923825ac..603e82ce71e54fa0e7d5f66cdda073ec5f1c8de5:/web_client/src/gr/grnet/pithos/web/client/Pithos.java diff --git a/web_client/src/gr/grnet/pithos/web/client/Pithos.java b/web_client/src/gr/grnet/pithos/web/client/Pithos.java index daf4d09..24a39b6 100644 --- a/web_client/src/gr/grnet/pithos/web/client/Pithos.java +++ b/web_client/src/gr/grnet/pithos/web/client/Pithos.java @@ -34,33 +34,6 @@ */ package gr.grnet.pithos.web.client; -import com.google.gwt.core.client.Scheduler; -import com.google.gwt.core.client.Scheduler.ScheduledCommand; -import com.google.gwt.event.dom.client.ClickEvent; -import com.google.gwt.event.dom.client.ClickHandler; -import com.google.gwt.http.client.Request; -import com.google.gwt.http.client.RequestBuilder; -import com.google.gwt.http.client.RequestCallback; -import com.google.gwt.http.client.RequestException; -import com.google.gwt.http.client.Response; -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.JSONString; -import com.google.gwt.json.client.JSONValue; -import com.google.gwt.user.client.Command; -import com.google.gwt.user.client.ui.Button; -import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant; -import com.google.gwt.user.client.ui.HasVerticalAlignment; -import com.google.gwt.user.client.ui.HorizontalPanel; -import com.google.gwt.user.client.ui.Image; -import com.google.gwt.user.client.ui.PushButton; -import com.google.gwt.view.client.SelectionChangeEvent; -import com.google.gwt.view.client.SelectionChangeEvent.Handler; -import com.google.gwt.view.client.SelectionModel; -import com.google.gwt.view.client.SingleSelectionModel; -import com.google.gwt.view.client.TreeViewModel; import gr.grnet.pithos.web.client.commands.UploadFileCommand; import gr.grnet.pithos.web.client.foldertree.AccountResource; import gr.grnet.pithos.web.client.foldertree.File; @@ -68,46 +41,65 @@ 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.foldertree.Resource; +import gr.grnet.pithos.web.client.grouptree.Group; +import gr.grnet.pithos.web.client.grouptree.GroupTreeView; +import gr.grnet.pithos.web.client.grouptree.GroupTreeViewModel; import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeView; import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeViewModel; import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeView; import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeViewModel; import gr.grnet.pithos.web.client.rest.DeleteRequest; import gr.grnet.pithos.web.client.rest.GetRequest; +import gr.grnet.pithos.web.client.rest.HeadRequest; import gr.grnet.pithos.web.client.rest.PutRequest; import gr.grnet.pithos.web.client.rest.RestException; - import gr.grnet.pithos.web.client.tagtree.Tag; import gr.grnet.pithos.web.client.tagtree.TagTreeView; import gr.grnet.pithos.web.client.tagtree.TagTreeViewModel; + 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 java.util.Set; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; +import com.google.gwt.core.client.Scheduler; +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ResizeEvent; import com.google.gwt.event.logical.shared.ResizeHandler; -import com.google.gwt.event.logical.shared.SelectionEvent; -import com.google.gwt.event.logical.shared.SelectionHandler; -import com.google.gwt.i18n.client.DateTimeFormat; -import com.google.gwt.resources.client.ClientBundle; +import com.google.gwt.http.client.Request; +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestCallback; +import com.google.gwt.http.client.RequestException; +import com.google.gwt.http.client.Response; +import com.google.gwt.http.client.URL; +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.JSONString; +import com.google.gwt.json.client.JSONValue; import com.google.gwt.resources.client.ImageResource; +import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Cookies; import com.google.gwt.user.client.Event; import com.google.gwt.user.client.History; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.AbstractImagePrototype; -import com.google.gwt.user.client.ui.DecoratedTabPanel; +import com.google.gwt.user.client.ui.Button; +import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasHorizontalAlignment; +import com.google.gwt.user.client.ui.HasVerticalAlignment; +import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.HorizontalSplitPanel; import com.google.gwt.user.client.ui.RootPanel; -import com.google.gwt.user.client.ui.TabPanel; import com.google.gwt.user.client.ui.VerticalPanel; -import java.util.Set; +import com.google.gwt.view.client.SelectionChangeEvent; +import com.google.gwt.view.client.SelectionChangeEvent.Handler; +import com.google.gwt.view.client.SingleSelectionModel; /** * Entry point classes define onModuleLoad(). @@ -115,12 +107,14 @@ import java.util.Set; public class Pithos implements EntryPoint, ResizeHandler { public static final String HOME_CONTAINER = "pithos"; + + public static final String TRASH_CONTAINER = "trash"; /** * Instantiate an application-level image bundle. This object will provide * programmatic access to all the images needed by widgets. */ - private static Images images = (Images) GWT.create(Images.class); + static Images images = (Images) GWT.create(Images.class); public String getUsername() { return username; @@ -134,8 +128,12 @@ public class Pithos implements EntryPoint, ResizeHandler { return account; } - public void updateFolder(Folder f, boolean showfiles) { - folderTreeView.updateFolder(f, showfiles); + public void updateFolder(Folder f, boolean showfiles, Command callback) { + folderTreeView.updateFolder(f, showfiles, callback); + } + + public void updateGroupNode(Group group) { + groupTreeView.updateGroupNode(group); } public void updateSharedFolder(Folder f, boolean showfiles) { @@ -146,14 +144,6 @@ public class Pithos implements EntryPoint, ResizeHandler { otherSharedTreeView.updateFolder(f, showfiles); } - public void updateTag(Tag t) { - tagTreeView.updateTag(t); - } - - public void updateTags() { - tagTreeViewModel.initialize(getAllTags()); - } - public List getAllTags() { List tagList = new ArrayList(); for (Folder f : account.getContainers()) { @@ -172,16 +162,13 @@ public class Pithos implements EntryPoint, ResizeHandler { * An aggregate image bundle that pulls together all the images for this * application into a single bundle. */ - public interface Images extends ClientBundle, TopPanel.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images { + public interface Images extends TopPanel.Images, FileList.Images, ToolsMenu.Images { @Source("gr/grnet/pithos/resources/document.png") ImageResource folders(); - @Source("gr/grnet/pithos/resources/edit_group_22.png") - ImageResource groups(); - - @Source("gr/grnet/pithos/resources/search.png") - ImageResource search(); + @Source("gr/grnet/pithos/resources/advancedsettings.png") + ImageResource tools(); } /** @@ -226,12 +213,6 @@ public class Pithos implements EntryPoint, ResizeHandler { */ private Object currentSelection; - - /** - * The WebDAV password of the current user - */ - private String webDAVPassword; - public HashMap userFullNameMap = new HashMap(); private String username = null; @@ -241,25 +222,43 @@ public class Pithos implements EntryPoint, ResizeHandler { */ private String token; - private SingleSelectionModel folderTreeSelectionModel; - private FolderTreeViewModel folderTreeViewModel; - private FolderTreeView folderTreeView; + VerticalPanel trees; + + SingleSelectionModel folderTreeSelectionModel; + FolderTreeViewModel folderTreeViewModel; + FolderTreeView folderTreeView; - private SingleSelectionModel mysharedTreeSelectionModel; - private MysharedTreeViewModel mysharedTreeViewModel; - private MysharedTreeView mysharedTreeView; + SingleSelectionModel mysharedTreeSelectionModel; + MysharedTreeViewModel mysharedTreeViewModel; + MysharedTreeView mysharedTreeView = null;; - private SingleSelectionModel otherSharedTreeSelectionModel; - private OtherSharedTreeViewModel otherSharedTreeViewModel; - private OtherSharedTreeView otherSharedTreeView; + protected SingleSelectionModel otherSharedTreeSelectionModel; + OtherSharedTreeViewModel otherSharedTreeViewModel; + OtherSharedTreeView otherSharedTreeView = null; - private SingleSelectionModel tagTreeSelectionModel; - private TagTreeViewModel tagTreeViewModel; - private TagTreeView tagTreeView; + GroupTreeViewModel groupTreeViewModel; + private GroupTreeView groupTreeView; - private AccountResource account; + private TreeView selectedTree; + protected AccountResource account; + + Folder trash; - private List selectionModels = new ArrayList(); + @SuppressWarnings("rawtypes") List selectionModels = new ArrayList(); + + Button upload; + + private HTML totalFiles; + + private HTML usedBytes; + + private HTML totalBytes; + + private HTML usedPercent; + + private HTML numOfFiles; + + private Button toolsButton; @Override public void onModuleLoad() { @@ -289,31 +288,43 @@ public class Pithos implements EntryPoint, ResizeHandler { rightside.addStyleName("pithos-rightSide"); rightside.setSpacing(5); - PushButton parentButton = new PushButton(new Image(images.asc()), new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - - } - }); - parentButton.addStyleName("pithos-parentButton"); - rightside.add(parentButton); - - HTML folderStatistics = new HTML("5 Files (size: 1.1GB)"); + toolsButton = new Button(AbstractImagePrototype.create(images.tools()).getHTML()); + toolsButton.addClickHandler(new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + ToolsMenu menu = new ToolsMenu(Pithos.this, images, getSelectedTree(), getSelectedTree().getSelection(), getFileList().getSelectedFiles()); + if (!menu.isEmpty()) { + menu.setPopupPosition(event.getClientX(), event.getClientY()); + menu.show(); + } + } + }); + rightside.add(toolsButton); + rightside.setCellHorizontalAlignment(toolsButton, HasHorizontalAlignment.ALIGN_LEFT); + + HorizontalPanel folderStatistics = new HorizontalPanel(); folderStatistics.addStyleName("pithos-folderStatistics"); + numOfFiles = new HTML(); + folderStatistics.add(numOfFiles); + HTML numOfFilesLabel = new HTML(" Files"); + folderStatistics.add(numOfFilesLabel); rightside.add(folderStatistics); + rightside.setCellHorizontalAlignment(folderStatistics, HasHorizontalAlignment.ALIGN_RIGHT); + inner.add(rightside); - inner.setCellHorizontalAlignment(rightside, HasHorizontalAlignment.ALIGN_RIGHT); inner.setCellVerticalAlignment(rightside, HasVerticalAlignment.ALIGN_MIDDLE); inner.setCellHeight(rightside, "60px"); folderTreeSelectionModel = new SingleSelectionModel(); folderTreeSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() { @Override - public void onSelectionChange(SelectionChangeEvent event) { + public void onSelectionChange(@SuppressWarnings("unused") SelectionChangeEvent event) { if (folderTreeSelectionModel.getSelectedObject() != null) { - deselectOthers(folderTreeSelectionModel); + deselectOthers(folderTreeView, folderTreeSelectionModel); + applyPermissions(folderTreeSelectionModel.getSelectedObject()); Folder f = folderTreeSelectionModel.getSelectedObject(); - updateFolder(f, true); + updateFolder(f, true, null); } } }); @@ -325,55 +336,15 @@ public class Pithos implements EntryPoint, ResizeHandler { fileList = new FileList(this, images, folderTreeView); inner.add(fileList); - mysharedTreeSelectionModel = new SingleSelectionModel(); - mysharedTreeSelectionModel.addSelectionChangeHandler(new Handler() { - @Override - public void onSelectionChange(SelectionChangeEvent event) { - if (mysharedTreeSelectionModel.getSelectedObject() != null) { - deselectOthers(mysharedTreeSelectionModel); - updateSharedFolder(mysharedTreeSelectionModel.getSelectedObject(), true); - } - } - }); - selectionModels.add(mysharedTreeSelectionModel); - mysharedTreeViewModel = new MysharedTreeViewModel(this, mysharedTreeSelectionModel); - mysharedTreeView = new MysharedTreeView(mysharedTreeViewModel); + groupTreeViewModel = new GroupTreeViewModel(this); + groupTreeView = new GroupTreeView(groupTreeViewModel); - otherSharedTreeSelectionModel = new SingleSelectionModel(); - otherSharedTreeSelectionModel.addSelectionChangeHandler(new Handler() { - @Override - public void onSelectionChange(SelectionChangeEvent event) { - if (otherSharedTreeSelectionModel.getSelectedObject() != null) { - deselectOthers(otherSharedTreeSelectionModel); - updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true); - } - } - }); - selectionModels.add(otherSharedTreeSelectionModel); - otherSharedTreeViewModel = new OtherSharedTreeViewModel(this, otherSharedTreeSelectionModel); - otherSharedTreeView = new OtherSharedTreeView(otherSharedTreeViewModel); + trees = new VerticalPanel(); - tagTreeSelectionModel = new SingleSelectionModel(); - tagTreeSelectionModel.addSelectionChangeHandler(new Handler() { + upload = new Button("Upload File", new ClickHandler() { @Override - public void onSelectionChange(SelectionChangeEvent event) { - if (tagTreeSelectionModel.getSelectedObject() != null) { - deselectOthers(tagTreeSelectionModel); - Tag t = tagTreeSelectionModel.getSelectedObject(); - updateTag(t); - } - } - }); - selectionModels.add(tagTreeSelectionModel); - tagTreeViewModel = new TagTreeViewModel(this, tagTreeSelectionModel); - tagTreeView = new TagTreeView(tagTreeViewModel); - - VerticalPanel trees = new VerticalPanel(); - - Button upload = new Button("Upload File", new ClickHandler() { - @Override - public void onClick(ClickEvent event) { - new UploadFileCommand(Pithos.this, null, folderTreeView.getSelection()).execute(); + public void onClick(@SuppressWarnings("unused") ClickEvent event) { + new UploadFileCommand(Pithos.this, null, getSelection()).execute(); } }); upload.addStyleName("pithos-uploadButton"); @@ -381,13 +352,25 @@ public class Pithos implements EntryPoint, ResizeHandler { HorizontalPanel treeHeader = new HorizontalPanel(); treeHeader.addStyleName("pithos-treeHeader"); - treeHeader.add(new HTML("Total Files: 6 | Used: 2.1 of 50 GB (4.2%)")); + HorizontalPanel statistics = new HorizontalPanel(); + statistics.add(new HTML("Total Objects: ")); + totalFiles = new HTML(); + statistics.add(totalFiles); + statistics.add(new HTML(" | Used: ")); + usedBytes = new HTML(); + statistics.add(usedBytes); + statistics.add(new HTML(" of ")); + totalBytes = new HTML(); + statistics.add(totalBytes); + statistics.add(new HTML(" (")); + usedPercent = new HTML(); + statistics.add(usedPercent); + statistics.add(new HTML("%)")); + treeHeader.add(statistics); trees.add(treeHeader); trees.add(folderTreeView); - trees.add(mysharedTreeView); - trees.add(otherSharedTreeView); -// trees.add(tagTreeView); + trees.add(groupTreeView); // Add the left and right panels to the split panel. splitPanel.setLeftWidget(trees); splitPanel.setRightWidget(inner); @@ -422,12 +405,51 @@ public class Pithos implements EntryPoint, ResizeHandler { Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { - fetchAccount(); + fetchAccount(new Command() { + + @Override + public void execute() { + if (!account.hasHomeContainer()) + createHomeContainer(account, this); + else if (!account.hasTrashContainer()) + createTrashContainer(this); + else { + for (Folder f : account.getContainers()) + if (f.getName().equals(Pithos.TRASH_CONTAINER)) { + trash = f; + break; + } + folderTreeViewModel.initialize(account); + groupTreeViewModel.initialize(); + createMySharedTree(); + showStatistics(); + } + } + }); } }); } - public void deselectOthers(SingleSelectionModel model) { + public void applyPermissions(Folder f) { + if (f != null) { + if (f.isInTrash()) + upload.setEnabled(false); + else { + Boolean[] perms = f.getPermissions().get(username); + if (f.getOwner().equals(username) || (perms != null && perms[1] != null && perms[1])) { + upload.setEnabled(true); + } + else + upload.setEnabled(false); + } + } + else + upload.setEnabled(false); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public void deselectOthers(TreeView _selectedTree, SingleSelectionModel model) { + selectedTree = _selectedTree; for (SingleSelectionModel s : selectionModels) if (!s.equals(model)) s.setSelected(s.getSelectedObject(), false); @@ -444,13 +466,13 @@ public class Pithos implements EntryPoint, ResizeHandler { fileList.setFiles(new ArrayList(files)); } - private void fetchFile(final Iterator iter, final Set files) { + protected void fetchFile(final Iterator iter, final Set files) { if (iter.hasNext()) { File file = iter.next(); String path = file.getUri() + "?format=json"; GetRequest getFile = new GetRequest(File.class, getApiPath(), username, path, file) { @Override - public void onSuccess(File result) { + public void onSuccess(@SuppressWarnings("unused") File _result) { fetchFile(iter, files); } @@ -462,6 +484,11 @@ public class Pithos implements EntryPoint, ResizeHandler { else displayError("System error fetching file: " + t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; getFile.setHeader("X-Auth-Token", "0000"); Scheduler.get().scheduleDeferred(getFile); @@ -484,23 +511,17 @@ public class Pithos implements EntryPoint, ResizeHandler { authenticateUser(); return false; } - else { - String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2); - if (authSplit.length != 2) { - authenticateUser(); - return false; - } - else { - username = authSplit[0]; - token = authSplit[1]; - return true; - } - } - } - else { - Cookies.setCookie(conf.authCookie(), username + conf.cookieSeparator() + token); - return true; + String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2); + if (authSplit.length != 2) { + authenticateUser(); + return false; + } + username = authSplit[0]; + token = authSplit[1]; + return true; } + Cookies.setCookie(conf.authCookie(), username + conf.cookieSeparator() + token); + return true; } /** @@ -508,21 +529,18 @@ public class Pithos implements EntryPoint, ResizeHandler { */ protected void authenticateUser() { Configuration conf = (Configuration) GWT.create(Configuration.class); - Window.Location.assign(Window.Location.getHost() + conf.loginUrl() + "?next=" + Window.Location.getHref()); + Window.Location.assign(conf.loginUrl() + "?next=" + Window.Location.getHref()); } - private void fetchAccount() { + protected void fetchAccount(final Command callback) { String path = "?format=json"; GetRequest getAccount = new GetRequest(AccountResource.class, getApiPath(), username, path) { @Override - public void onSuccess(AccountResource result) { - account = result; - if (account.getContainers().isEmpty()) - createHomeContainers(); - else { - folderTreeViewModel.initialize(account); - } + public void onSuccess(AccountResource _result) { + account = _result; + if (callback != null) + callback.execute(); } @Override @@ -533,17 +551,58 @@ public class Pithos implements EntryPoint, ResizeHandler { else displayError("System error fetching user data: " + t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; getAccount.setHeader("X-Auth-Token", token); Scheduler.get().scheduleDeferred(getAccount); } - private void createHomeContainers() { - String path = "/pithos"; + public void updateStatistics() { + HeadRequest headAccount = new HeadRequest(AccountResource.class, getApiPath(), username, "", account) { + + @Override + public void onSuccess(@SuppressWarnings("unused") AccountResource _result) { + showStatistics(); + } + + @Override + public void onError(Throwable t) { + GWT.log("Error getting account", t); + if (t instanceof RestException) + displayError("Error getting account: " + ((RestException) t).getHttpStatusText()); + else + displayError("System error fetching user data: " + t.getMessage()); + } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } + }; + headAccount.setHeader("X-Auth-Token", token); + Scheduler.get().scheduleDeferred(headAccount); + } + + protected void showStatistics() { + totalFiles.setHTML(String.valueOf(account.getNumberOfObjects())); + usedBytes.setHTML(String.valueOf(account.getFileSizeAsString())); + totalBytes.setHTML(String.valueOf(account.getQuotaAsString())); + usedPercent.setHTML(String.valueOf(account.getUsedPercentage())); + } + + protected void createHomeContainer(final AccountResource _account, final Command callback) { + String path = "/" + Pithos.HOME_CONTAINER; PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) { @Override - public void onSuccess(Resource result) { - fetchAccount(); + public void onSuccess(@SuppressWarnings("unused") Resource result) { + if (!_account.hasTrashContainer()) + createTrashContainer(callback); + else + fetchAccount(callback); } @Override @@ -554,12 +613,43 @@ public class Pithos implements EntryPoint, ResizeHandler { else displayError("System error Error creating pithos: " + t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; createPithos.setHeader("X-Auth-Token", getToken()); Scheduler.get().scheduleDeferred(createPithos); } - /** + protected void createTrashContainer(final Command callback) { + String path = "/" + Pithos.TRASH_CONTAINER; + PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) { + @Override + public void onSuccess(@SuppressWarnings("unused") Resource result) { + fetchAccount(callback); + } + + @Override + public void onError(Throwable t) { + GWT.log("Error creating pithos", t); + if (t instanceof RestException) + displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText()); + else + displayError("System error Error creating pithos: " + t.getMessage()); + } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } + }; + createPithos.setHeader("X-Auth-Token", getToken()); + Scheduler.get().scheduleDeferred(createPithos); + } + + /** * Creates an HTML fragment that places an image & caption together, for use * in a group header. * @@ -575,7 +665,7 @@ public class Pithos implements EntryPoint, ResizeHandler { return captionHTML; } - private void onWindowResized(int height) { + protected void onWindowResized(int height) { // Adjust the split panel to take up the available room in the window. int newHeight = height - splitPanel.getAbsoluteTop() - 60; if (newHeight < 1) @@ -652,10 +742,6 @@ public class Pithos implements EntryPoint, ResizeHandler { return token; } - public String getWebDAVPassword() { - return webDAVPassword; - } - public static native void preventIESelection() /*-{ $doc.body.onselectstart = function () { return false; }; }-*/; @@ -688,14 +774,13 @@ public class Pithos implements EntryPoint, ResizeHandler { } public void deleteFolder(final Folder folder) { - String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + folder.getPrefix(); + String path = getApiPath() + folder.getOwner() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(folder.getPrefix()) + "&t=" + System.currentTimeMillis(); RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path); - builder.setHeader("If-Modified-Since", "0"); builder.setHeader("X-Auth-Token", getToken()); try { builder.sendRequest("", new RequestCallback() { @Override - public void onResponseReceived(Request request, Response response) { + public void onResponseReceived(@SuppressWarnings("unused") Request request, Response response) { if (response.getStatusCode() == Response.SC_OK) { JSONValue json = JSONParser.parseStrict(response.getText()); JSONArray array = json.isArray(); @@ -707,7 +792,7 @@ public class Pithos implements EntryPoint, ResizeHandler { } @Override - public void onError(Request request, Throwable exception) { + public void onError(@SuppressWarnings("unused") Request request, Throwable exception) { displayError("System error unable to delete folder: " + exception.getMessage()); } }); @@ -716,15 +801,15 @@ public class Pithos implements EntryPoint, ResizeHandler { } } - public void deleteObject(final Folder folder, final int i, final JSONArray array) { + void deleteObject(final Folder folder, final int i, final JSONArray array) { if (i < array.size()) { JSONObject o = array.get(i).isObject(); if (o != null && !o.containsKey("subdir")) { JSONString name = o.get("name").isString(); String path = "/" + folder.getContainer() + "/" + name.stringValue(); - DeleteRequest delete = new DeleteRequest(getApiPath(), getUsername(), path) { + DeleteRequest delete = new DeleteRequest(getApiPath(), folder.getOwner(), path) { @Override - public void onSuccess(Resource result) { + public void onSuccess(@SuppressWarnings("unused") Resource result) { deleteObject(folder, i + 1, array); } @@ -733,21 +818,25 @@ public class Pithos implements EntryPoint, ResizeHandler { GWT.log("", t); displayError("System error unable to delete folder: " + t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; delete.setHeader("X-Auth-Token", getToken()); Scheduler.get().scheduleDeferred(delete); } - else { + else if (o != null) { String subdir = o.get("subdir").isString().stringValue(); subdir = subdir.substring(0, subdir.length() - 1); - String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + subdir; + String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(subdir) + "&t=" + System.currentTimeMillis(); RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path); - builder.setHeader("If-Modified-Since", "0"); builder.setHeader("X-Auth-Token", getToken()); try { builder.sendRequest("", new RequestCallback() { @Override - public void onResponseReceived(Request request, Response response) { + public void onResponseReceived(@SuppressWarnings("unused") Request request, Response response) { if (response.getStatusCode() == Response.SC_OK) { JSONValue json = JSONParser.parseStrict(response.getText()); JSONArray array2 = json.isArray(); @@ -762,7 +851,7 @@ public class Pithos implements EntryPoint, ResizeHandler { } @Override - public void onError(Request request, Throwable exception) { + public void onError(@SuppressWarnings("unused") Request request, Throwable exception) { displayError("System error unable to delete folder: " + exception.getMessage()); } }); @@ -775,19 +864,33 @@ public class Pithos implements EntryPoint, ResizeHandler { String path = folder.getUri(); DeleteRequest deleteFolder = new DeleteRequest(getApiPath(), getUsername(), path) { @Override - public void onSuccess(Resource result) { - updateFolder(folder.getParent(), true); + public void onSuccess(@SuppressWarnings("unused") Resource result) { + updateFolder(folder.getParent(), true, new Command() { + + @Override + public void execute() { + updateStatistics(); + } + }); } @Override public void onError(Throwable t) { GWT.log("", t); if (t instanceof RestException) { - displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText()); + if (((RestException) t).getHttpStatusCode() != Response.SC_NOT_FOUND) + displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText()); + else + onSuccess(null); } else displayError("System error unable to delete folder: " + t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; deleteFolder.setHeader("X-Auth-Token", getToken()); Scheduler.get().scheduleDeferred(deleteFolder); @@ -798,14 +901,14 @@ public class Pithos implements EntryPoint, ResizeHandler { return folderTreeView; } - public void copyFiles(final Iterator iter, final String targetUri, final Command callback) { + public void copyFiles(final Iterator iter, final String targetUsername, final String targetUri, final Command callback) { if (iter.hasNext()) { File file = iter.next(); String path = targetUri + "/" + file.getName(); - PutRequest copyFile = new PutRequest(getApiPath(), getUsername(), path) { + PutRequest copyFile = new PutRequest(getApiPath(), targetUsername, path) { @Override - public void onSuccess(Resource result) { - copyFiles(iter, targetUri, callback); + public void onSuccess(@SuppressWarnings("unused") Resource result) { + copyFiles(iter, targetUsername, targetUri, callback); } @Override @@ -817,9 +920,16 @@ public class Pithos implements EntryPoint, ResizeHandler { else displayError("System error unable to copy file: "+t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; copyFile.setHeader("X-Auth-Token", getToken()); copyFile.setHeader("X-Copy-From", file.getUri()); + if (!file.getOwner().equals(targetUsername)) + copyFile.setHeader("X-Source-Account", file.getOwner()); Scheduler.get().scheduleDeferred(copyFile); } else if (callback != null) { @@ -827,45 +937,74 @@ public class Pithos implements EntryPoint, ResizeHandler { } } - public void copySubfolders(final Iterator iter, final String targetUri, final Command callback) { + public void copySubfolders(final Iterator iter, final String targetUsername, final String targetUri, final Command callback) { if (iter.hasNext()) { final Folder f = iter.next(); - copyFolder(f, targetUri, callback); + copyFolder(f, targetUsername, targetUri, new Command() { + + @Override + public void execute() { + copySubfolders(iter, targetUsername, targetUri, callback); + } + }); } else if (callback != null) { callback.execute(); } } - public void copyFolder(final Folder f, final String targetUri, final Command callback) { + public void copyFolder(final Folder f, final String targetUsername, final String targetUri, final Command callback) { String path = targetUri + "/" + f.getName(); - PutRequest createFolder = new PutRequest(getApiPath(), getUsername(), path) { + PutRequest createFolder = new PutRequest(getApiPath(), targetUsername, path) { @Override - public void onSuccess(Resource result) { - Iterator iter = f.getFiles().iterator(); - copyFiles(iter, targetUri + "/" + f.getName(), new Command() { - @Override - public void execute() { - Iterator iterf = f.getSubfolders().iterator(); - copySubfolders(iterf, targetUri + "/" + f.getName(), new Command() { - @Override - public void execute() { - callback.execute(); - } - }); - } - }); + public void onSuccess(@SuppressWarnings("unused") Resource result) { + GetRequest getFolder = new GetRequest(Folder.class, getApiPath(), f.getOwner(), "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix()), f) { + + @Override + public void onSuccess(final Folder _f) { + Iterator iter = _f.getFiles().iterator(); + copyFiles(iter, targetUsername, targetUri + "/" + _f.getName(), new Command() { + @Override + public void execute() { + Iterator iterf = _f.getSubfolders().iterator(); + copySubfolders(iterf, targetUsername, targetUri + "/" + _f.getName(), callback); + } + }); + } + + @Override + public void onError(Throwable t) { + GWT.log("", t); + if (t instanceof RestException) { + displayError("Unable to get folder: " + ((RestException) t).getHttpStatusText()); + } + else + displayError("System error getting folder: " + t.getMessage()); + } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } + }; + getFolder.setHeader("X-Auth-Token", getToken()); + Scheduler.get().scheduleDeferred(getFolder); } @Override public void onError(Throwable t) { GWT.log("", t); if (t instanceof RestException) { - displayError("Unable to create folder:" + ((RestException) t).getHttpStatusText()); + displayError("Unable to create folder: " + ((RestException) t).getHttpStatusText()); } else - displayError("System error creating folder:" + t.getMessage()); + displayError("System error creating folder: " + t.getMessage()); } + + @Override + protected void onUnauthorized(Response response) { + sessionExpired(); + } }; createFolder.setHeader("X-Auth-Token", getToken()); createFolder.setHeader("Accept", "*/*"); @@ -874,11 +1013,109 @@ public class Pithos implements EntryPoint, ResizeHandler { Scheduler.get().scheduleDeferred(createFolder); } - public void addSelectionModel(SingleSelectionModel model) { + public void addSelectionModel(@SuppressWarnings("rawtypes") SingleSelectionModel model) { selectionModels.add(model); } public OtherSharedTreeView getOtherSharedTreeView() { return otherSharedTreeView; } + + public void updateTrash(boolean showFiles, Command callback) { + updateFolder(trash, showFiles, callback); + } + + public void updateGroupsNode() { + groupTreeView.updateGroupNode(null); + } + + public void addGroup(String groupname) { + Group newGroup = new Group(groupname); + account.addGroup(newGroup); + groupTreeView.updateGroupNode(null); + } + + public void removeGroup(Group group) { + account.removeGroup(group); + updateGroupsNode(); + } + + public TreeView getSelectedTree() { + return selectedTree; + } + + public Folder getSelection() { + return selectedTree.getSelection(); + } + + public void showFolderStatistics(int folderFileCount) { + numOfFiles.setHTML(String.valueOf(folderFileCount)); + } + + public GroupTreeView getGroupTreeView() { + return groupTreeView; + } + + public void sessionExpired() { + new SessionExpiredDialog(this).center(); + } + + public void updateRootFolder(Command callback) { + updateFolder(account.getPithos(), false, callback); + } + + void createMySharedTree() { + mysharedTreeSelectionModel = new SingleSelectionModel(); + mysharedTreeSelectionModel.addSelectionChangeHandler(new Handler() { + @Override + public void onSelectionChange(@SuppressWarnings("unused") SelectionChangeEvent event) { + if (mysharedTreeSelectionModel.getSelectedObject() != null) { + deselectOthers(mysharedTreeView, mysharedTreeSelectionModel); + upload.setEnabled(false); + updateSharedFolder(mysharedTreeSelectionModel.getSelectedObject(), true); + } + } + }); + selectionModels.add(mysharedTreeSelectionModel); + mysharedTreeViewModel = new MysharedTreeViewModel(Pithos.this, mysharedTreeSelectionModel); + mysharedTreeViewModel.initialize(new Command() { + + @Override + public void execute() { + mysharedTreeView = new MysharedTreeView(mysharedTreeViewModel); + trees.insert(mysharedTreeView, 3); + createOtherSharedTree(); + } + }); + } + + void createOtherSharedTree() { + otherSharedTreeSelectionModel = new SingleSelectionModel(); + otherSharedTreeSelectionModel.addSelectionChangeHandler(new Handler() { + @Override + public void onSelectionChange(@SuppressWarnings("unused") SelectionChangeEvent event) { + if (otherSharedTreeSelectionModel.getSelectedObject() != null) { + deselectOthers(otherSharedTreeView, otherSharedTreeSelectionModel); + applyPermissions(otherSharedTreeSelectionModel.getSelectedObject()); + updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true); + } + } + }); + selectionModels.add(otherSharedTreeSelectionModel); + otherSharedTreeViewModel = new OtherSharedTreeViewModel(Pithos.this, otherSharedTreeSelectionModel); + otherSharedTreeViewModel.initialize(new Command() { + + @Override + public void execute() { + otherSharedTreeView = new OtherSharedTreeView(otherSharedTreeViewModel); + trees.insert(otherSharedTreeView, 4); + } + }); + } + + public void logoff() { + Configuration conf = (Configuration) GWT.create(Configuration.class); + Cookies.removeCookie(conf.authCookie()); + Window.Location.assign(Window.Location.getHost()); + } }