From: Christos Stathis Date: Tue, 5 Jul 2011 14:13:12 +0000 (+0300) Subject: Implemented virtual folder creation X-Git-Tag: pithos/v0.7.8~232 X-Git-Url: https://code.grnet.gr/git/pithos/commitdiff_plain/fa5600f71da38787cb0ffa595529960f82569b29 Implemented virtual folder creation --- diff --git a/web_client/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java b/web_client/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java index c1112f6..63d24d2 100644 --- a/web_client/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java +++ b/web_client/src/gr/grnet/pithos/web/client/FolderPropertiesDialog.java @@ -34,10 +34,13 @@ */ package gr.grnet.pithos.web.client; +import com.google.gwt.core.client.Scheduler; import com.google.gwt.event.dom.client.KeyDownEvent; import com.google.gwt.user.client.Event; import gr.grnet.pithos.web.client.foldertree.Folder; +import gr.grnet.pithos.web.client.foldertree.Resource; import gr.grnet.pithos.web.client.rest.PostCommand; +import gr.grnet.pithos.web.client.rest.PutRequest; import gr.grnet.pithos.web.client.rest.RestException; import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper; @@ -67,6 +70,8 @@ import com.google.gwt.user.client.ui.VerticalPanel; */ public class FolderPropertiesDialog extends DialogBox { + private GSS app; + private CheckBox readForAll; /** @@ -86,16 +91,13 @@ public class FolderPropertiesDialog extends DialogBox { /** * The widget's constructor. - * - * @param _create true if the dialog is displayed for creating a new - * sub-folder of the selected folder, false if it is displayed - * for modifying the selected folder */ - public FolderPropertiesDialog(boolean _create, Folder selected) { + public FolderPropertiesDialog(GSS app, boolean _create, Folder selected) { + this.app = app; setAnimationEnabled(true); // Enable IE selection for the dialog (must disable it upon closing it) - GSS.enableIESelection(); + app.enableIESelection(); create = _create; @@ -227,7 +229,7 @@ public class FolderPropertiesDialog extends DialogBox { * (we disable the prevention on creation of the dialog) */ public void closeDialog() { - GSS.preventIESelection(); + app.preventIESelection(); hide(); } @@ -236,43 +238,29 @@ public class FolderPropertiesDialog extends DialogBox { */ private void createFolder() { String name = folderName.getText(); - -// PostCommand ep = new PostCommand(folder.getUri() + "?new=" + -// URL.encodeComponent(name), "", 201) { -// -// @Override -// public void onComplete() { -// //TODO:CELLTREE -// if(folder.getUri().equals(GSS.get().getTreeView().getMyFolders().getUri())){ -// GSS.get().getTreeView().updateRootNode(); -// } -// else -// GSS.get().getTreeView().updateNodeChildren((RestResourceWrapper) GSS.get().getTreeView().getSelection()); -// //GSS.get().getFolders().updateFolder((DnDTreeItem) GSS.get().getFolders().getCurrent()); -// } -// -// @Override -// public void onError(Throwable t) { -// GWT.log("", t); -// if(t instanceof RestException){ -// int statusCode = ((RestException)t).getHttpStatusCode(); -// if(statusCode == 405) -// GSS.get().displayError("You don't have the necessary" + -// " permissions or a folder with same name " + -// "already exists"); -// else if(statusCode == 404) -// GSS.get().displayError("Resource not found"); -// else -// GSS.get().displayError("Unable to create folder:" + -// ((RestException)t).getHttpStatusText()); -// } -// else -// GSS.get().displayError("System error creating folder:" + -// t.getMessage()); -// } -// }; -// DeferredCommand.addCommand(ep); - + String prefix = folder.getPrefix(); + String path = app.getApiPath() + app.getUsername() + "/" + folder.getContainer() + "/" + (prefix.length() == 0 ? "" : prefix + "/") + name; + PutRequest createFolder = new PutRequest(path) { + @Override + public void onSuccess(Resource result) { + app.updateFolder(folder); + } + + @Override + public void onError(Throwable t) { + GWT.log("", t); + if (t instanceof RestException) { + app.displayError("Unable to create folder:" + ((RestException) t).getHttpStatusText()); + } + else + app.displayError("System error creating folder:" + t.getMessage()); + } + }; + createFolder.setHeader("X-Auth-Token", "0000"); + createFolder.setHeader("Accept", "*/*"); + createFolder.setHeader("Content-Length", "0"); + createFolder.setHeader("Content-Type", "application/folder"); + Scheduler.get().scheduleDeferred(createFolder); } /** @@ -296,7 +284,7 @@ public class FolderPropertiesDialog extends DialogBox { // json.put("name", new JSONString(folderName.getText())); // //only update the read for all perm if the user is the owner // if (readForAll.getValue() != folder.isReadForAll()) -// if (folder.getOwner().equals(GSS.get().getCurrentUserResource().getUsername())) +// if (folder.getOwner().equals(app.getCurrentUserResource().getUsername())) // json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue())); // if (permList.hasChanges()) { // JSONArray perma = new JSONArray(); @@ -325,15 +313,15 @@ public class FolderPropertiesDialog extends DialogBox { // if(getPostBody() != null && !"".equals(getPostBody().trim())){ // // -// FolderResource fres = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource(); +// FolderResource fres = ((RestResourceWrapper) app.getTreeView().getSelection()).getResource(); // String initialPath = fres.getUri(); // String newPath = getPostBody().trim(); // fres.setUri(newPath); -// ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource().setUri(newPath); -// ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).setUri(newPath); -// GSS.get().getTreeView().updateNodeChildren(fres.getParentURI()); +// ((RestResourceWrapper) app.getTreeView().getSelection()).getResource().setUri(newPath); +// ((RestResourceWrapper) app.getTreeView().getSelection()).setUri(newPath); +// app.getTreeView().updateNodeChildren(fres.getParentURI()); // if (permList.hasChanges()) { -// GSS.get().getTreeView().updateMySharedNode(); +// app.getTreeView().updateMySharedNode(); // } // /* // if(folderItem.getParentItem() != null && ((DnDTreeItem)folderItem.getParentItem()).getFolderResource() != null){ @@ -341,9 +329,9 @@ public class FolderPropertiesDialog extends DialogBox { // ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().getSubfolderPaths().add(newPath); // }*/ // } -// //GSS.get().getFolders().updateFolder( (DnDTreeItem) GSS.get().getFolders().getCurrent()); +// //app.getFolders().updateFolder( (DnDTreeItem) app.getFolders().getCurrent()); // -// GSS.get().showFileList(true); +// app.get().showFileList(true); // } // // @Override @@ -352,17 +340,17 @@ public class FolderPropertiesDialog extends DialogBox { // if(t instanceof RestException){ // int statusCode = ((RestException)t).getHttpStatusCode(); // if(statusCode == 405) -// GSS.get().displayError("You don't have the necessary permissions or" + +// app.displayError("You don't have the necessary permissions or" + // " a folder with same name already exists"); // else if(statusCode == 404) -// GSS.get().displayError("Resource not found, or user specified in sharing does not exist"); +// app.displayError("Resource not found, or user specified in sharing does not exist"); // else -// GSS.get().displayError("Unable to update folder: "+((RestException)t).getHttpStatusText()); +// app.displayError("Unable to update folder: "+((RestException)t).getHttpStatusText()); // } // else -// GSS.get().displayError("System error moifying file: "+t.getMessage()); +// app.displayError("System error moifying file: "+t.getMessage()); // //TODO:CELLTREE -// //GSS.get().getFolders().updateFolder( (DnDTreeItem) GSS.get().getFolders().getCurrent()); +// //app.getFolders().updateFolder( (DnDTreeItem) app.getFolders().getCurrent()); // } // }; // DeferredCommand.addCommand(ep); @@ -371,5 +359,4 @@ public class FolderPropertiesDialog extends DialogBox { public void selectTab(int _tab) { inner.selectTab(_tab); } - } diff --git a/web_client/src/gr/grnet/pithos/web/client/GSS.java b/web_client/src/gr/grnet/pithos/web/client/GSS.java index 762d99f..f8781da 100644 --- a/web_client/src/gr/grnet/pithos/web/client/GSS.java +++ b/web_client/src/gr/grnet/pithos/web/client/GSS.java @@ -120,6 +120,10 @@ public class GSS implements EntryPoint, ResizeHandler { return account; } + public void updateFolder(Folder f) { + folderTreeView.updateFolder(f); + } + /** * An aggregate image bundle that pulls together all the images for this * application into a single bundle. diff --git a/web_client/src/gr/grnet/pithos/web/client/commands/NewFolderCommand.java b/web_client/src/gr/grnet/pithos/web/client/commands/NewFolderCommand.java index be21779..0a8a7c3 100644 --- a/web_client/src/gr/grnet/pithos/web/client/commands/NewFolderCommand.java +++ b/web_client/src/gr/grnet/pithos/web/client/commands/NewFolderCommand.java @@ -86,7 +86,7 @@ public class NewFolderCommand implements Command{ void displayNewFolderDialog() { if (folder != null) { - FolderPropertiesDialog dlg = new FolderPropertiesDialog(true, folder); + FolderPropertiesDialog dlg = new FolderPropertiesDialog(GSS.get(), true, folder); dlg.center(); } } diff --git a/web_client/src/gr/grnet/pithos/web/client/foldertree/Folder.java b/web_client/src/gr/grnet/pithos/web/client/foldertree/Folder.java index 25c38d0..ec6f0e0 100644 --- a/web_client/src/gr/grnet/pithos/web/client/foldertree/Folder.java +++ b/web_client/src/gr/grnet/pithos/web/client/foldertree/Folder.java @@ -191,17 +191,14 @@ public class Folder extends Resource { public boolean equals(Object other) { if (other instanceof Folder) { Folder o = (Folder) other; - if (container != null) - return prefix.equals(o.getPrefix()) && container.equals(o.getContainer()); - else - return o.getContainer() == null && name.equals(o.getName()); + return (container + prefix).equals(o.getContainer() + o.getPrefix()); } return false; } @Override public int hashCode() { - return prefix.hashCode() + name.hashCode(); + return (container + prefix).hashCode(); } public Set getFiles() { diff --git a/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java index a70a4a1..099fa3e 100644 --- a/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java +++ b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeView.java @@ -106,4 +106,8 @@ public class FolderTreeView extends Composite { public Folder getSelection() { return model.getSelection(); } + + public void updateFolder(Folder folder) { + model.updateFolder(folder); + } } diff --git a/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java index 53320f3..faffec7 100644 --- a/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java +++ b/web_client/src/gr/grnet/pithos/web/client/foldertree/FolderTreeViewModel.java @@ -51,7 +51,9 @@ import gr.grnet.pithos.web.client.GSS; import gr.grnet.pithos.web.client.foldertree.FolderTreeView.Templates; import gr.grnet.pithos.web.client.rest.GetRequest; import gr.grnet.pithos.web.client.rest.RestException; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; import java.util.Set; public class FolderTreeViewModel implements TreeViewModel { @@ -68,9 +70,8 @@ public class FolderTreeViewModel implements TreeViewModel { @Override public void onBrowserEvent(Cell.Context context, com.google.gwt.dom.client.Element parent, Folder folder, com.google.gwt.dom.client.NativeEvent event, com.google.gwt.cell.client.ValueUpdater valueUpdater) { if (event.getType().equals(ContextMenuEvent.getType().getName())) { - Folder target = (Folder) context.getKey(); - FolderTreeViewModel.this.selectionModel.setSelected(target, true); - FolderContextMenu menu = new FolderContextMenu(FolderTreeView.images, target); + FolderTreeViewModel.this.selectionModel.setSelected(folder, true); + FolderContextMenu menu = new FolderContextMenu(FolderTreeView.images, folder); menu.setPopupPosition(event.getClientX(), event.getClientY()); menu.show(); } @@ -79,6 +80,8 @@ public class FolderTreeViewModel implements TreeViewModel { private ListDataProvider rootDataProvider = new ListDataProvider(); + private Map> dataProviderMap = new HashMap>(); + private SingleSelectionModel selectionModel; public FolderTreeViewModel(SingleSelectionModel selectionModel) { @@ -94,33 +97,11 @@ public class FolderTreeViewModel implements TreeViewModel { } else { final Folder f = (Folder) value; - final ListDataProvider dataProvider = new ListDataProvider(); - dataProvider.flush(); - Scheduler.get().scheduleDeferred(new ScheduledCommand() { - @Override - public void execute() { - final GSS app = GSS.get(); - String path = app.getApiPath() + app.getUsername() + "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix(); - GetRequest getFolder = new GetRequest(Folder.class, path, f) { - @Override - public void onSuccess(Folder result) { - Iterator iter = result.getSubfolders().iterator(); - fetchFolder(iter, dataProvider, result.getSubfolders()); - } - - @Override - public void onError(Throwable t) { - GWT.log("Error getting folder", t); - if (t instanceof RestException) - GSS.get().displayError("Error getting folder: " + ((RestException) t).getHttpStatusText()); - else - GSS.get().displayError("System error fetching folder: " + t.getMessage()); - } - }; - getFolder.setHeader("X-Auth-Token", app.getToken()); - Scheduler.get().scheduleDeferred(getFolder); - } - }); + if (dataProviderMap.get(f) == null) { + dataProviderMap.put(f, new ListDataProvider()); + } + final ListDataProvider dataProvider = dataProviderMap.get(f); + fetchFolder(f, dataProvider); return new DefaultNodeInfo(dataProvider, folderCell, selectionModel, null); } } @@ -174,4 +155,41 @@ public class FolderTreeViewModel implements TreeViewModel { public Folder getSelection() { return selectionModel.getSelectedObject(); } + + public void updateFolder(Folder folder) { + if (dataProviderMap.get(folder) == null) { + dataProviderMap.put(folder, new ListDataProvider()); + } + final ListDataProvider dataProvider = dataProviderMap.get(folder); + fetchFolder(folder, dataProvider); + } + + public void fetchFolder(final Folder f, final ListDataProvider dataProvider) { + dataProvider.flush(); + Scheduler.get().scheduleDeferred(new ScheduledCommand() { + @Override + public void execute() { + final GSS app = GSS.get(); + String path = app.getApiPath() + app.getUsername() + "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + f.getPrefix(); + GetRequest getFolder = new GetRequest(Folder.class, path, f) { + @Override + public void onSuccess(Folder result) { + Iterator iter = result.getSubfolders().iterator(); + fetchFolder(iter, dataProvider, result.getSubfolders()); + } + + @Override + public void onError(Throwable t) { + GWT.log("Error getting folder", t); + if (t instanceof RestException) + GSS.get().displayError("Error getting folder: " + ((RestException) t).getHttpStatusText()); + else + GSS.get().displayError("System error fetching folder: " + t.getMessage()); + } + }; + getFolder.setHeader("X-Auth-Token", app.getToken()); + Scheduler.get().scheduleDeferred(getFolder); + } + }); + } } diff --git a/web_client/src/gr/grnet/pithos/web/client/rest/GetRequest.java b/web_client/src/gr/grnet/pithos/web/client/rest/GetRequest.java index d1cac74..7a3c077 100644 --- a/web_client/src/gr/grnet/pithos/web/client/rest/GetRequest.java +++ b/web_client/src/gr/grnet/pithos/web/client/rest/GetRequest.java @@ -53,8 +53,6 @@ public abstract class GetRequest implements ScheduledCommand private int okCode; - private String username; - private T cached; private T result; @@ -83,8 +81,8 @@ public abstract class GetRequest implements ScheduledCommand @Override public void execute() { RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path); + builder.setHeader("If-Modified-Since", "0"); for (String header : headers.keySet()) { - builder.setHeader("If-Modified-Since", "0"); builder.setHeader(header, headers.get(header)); } try { diff --git a/web_client/src/gr/grnet/pithos/web/client/rest/PutRequest.java b/web_client/src/gr/grnet/pithos/web/client/rest/PutRequest.java new file mode 100644 index 0000000..b7ceb3a --- /dev/null +++ b/web_client/src/gr/grnet/pithos/web/client/rest/PutRequest.java @@ -0,0 +1,129 @@ +/* + * Copyright 2011 GRNET S.A. All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and + * documentation are those of the authors and should not be + * interpreted as representing official policies, either expressed + * or implied, of GRNET S.A. + */ + +/* + * Copyright 2011 GRNET S.A. All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and + * documentation are those of the authors and should not be + * interpreted as representing official policies, either expressed + * or implied, of GRNET S.A. + */ + +package gr.grnet.pithos.web.client.rest; + +import com.google.gwt.core.client.Scheduler.ScheduledCommand; +import com.google.gwt.http.client.Request; +import com.google.gwt.http.client.RequestBuilder; +import com.google.gwt.http.client.RequestException; +import com.google.gwt.http.client.Response; +import gr.grnet.pithos.web.client.foldertree.Resource; +import java.util.HashMap; +import java.util.Map; + +public abstract class PutRequest implements ScheduledCommand { + + private String path; + + private String username; + + private Map headers = new HashMap(); + + public abstract void onSuccess(Resource result); + + public abstract void onError(Throwable t); + + public PutRequest(String path) { + this.path = path; + } + + @Override + public void execute() { + RequestBuilder builder = new RequestBuilder(RequestBuilder.PUT, path); + for (String header : headers.keySet()) { + builder.setHeader(header, headers.get(header)); + } + try { + builder.sendRequest("", new RestRequestCallback(path, Response.SC_CREATED) { + @Override + public void onSuccess(Resource object) { + PutRequest.this.onSuccess(object); + } + + @Override + public Resource deserialize(Response response) { + return Resource.createFromResponse(Resource.class, response, null); + } + + @Override + public void onError(Request request, Throwable throwable) { + PutRequest.this.onError(throwable); + } + }); + } + catch (RequestException e) { + } + } + + public void setHeader(String header, String value) { + headers.put(header, value); + } +}