/*
- * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
+ * Copyright 2011 GRNET S.A. All rights reserved.
*
- * This file is part of GSS.
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
*
- * GSS is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 1. Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer.
*
- * GSS is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * 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.
*
- * You should have received a copy of the GNU General Public License
- * along with GSS. If not, see <http://www.gnu.org/licenses/>.
+ * 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;
-import gr.grnet.pithos.web.client.rest.GetCommand;
-import gr.grnet.pithos.web.client.rest.PostCommand;
-import gr.grnet.pithos.web.client.rest.RestCommand;
-import gr.grnet.pithos.web.client.rest.RestException;
-import gr.grnet.pithos.web.client.rest.resource.FileResource;
-import gr.grnet.pithos.web.client.rest.resource.FolderResource;
-import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper;
-import gr.grnet.pithos.web.client.rest.resource.UploadStatusResource;
-
-import java.util.ArrayList;
-import java.util.List;
+import gr.grnet.pithos.web.client.foldertree.File;
+import gr.grnet.pithos.web.client.foldertree.Folder;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
-import com.google.gwt.http.client.URL;
-import com.google.gwt.json.client.JSONObject;
-import com.google.gwt.json.client.JSONString;
-import com.google.gwt.user.client.DeferredCommand;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.Event.NativePreviewEvent;
-import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel.SubmitEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitHandler;
import com.google.gwt.user.client.ui.Grid;
-import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.HorizontalPanel;
/**
* The 'File upload' dialog box implementation.
*/
-public class FileUploadDialog extends DialogBox implements Updateable {
-
- protected int prgBarInterval = 1500;
+public class FileUploadDialog extends DialogBox {
- private ProgressBar progressBar;
-
- protected RepeatingTimer repeater = new RepeatingTimer(this, prgBarInterval);
-
- public static final boolean DONE = true;
+ public static final boolean DONE = true;
/**
* The Form element that performs the file upload.
*/
- private final FormPanel form = new FormPanel();
+ protected final FormPanel form = new FormPanel();
private final FileUpload upload = new FileUpload();
- protected final Label filenameLabel = new Label("");
+ private final Label filenameLabel = new Label();
- protected List<FileResource> files;
+ private final Label foldernameLabel = new Label();
- protected boolean cancelEvent = false;
+ private Button submit;
- protected String fileNameToUse;
+ protected Folder folder;
- protected FolderResource folder;
+ protected Pithos app;
/**
* The widget's constructor.
*/
public FileUploadDialog() {
+ Anchor close = new Anchor();
+ close.addStyleName("close");
+ close.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
// Set the dialog's caption.
setText("File upload");
setAnimationEnabled(true);
+ setGlassEnabled(true);
+ setStyleName("pithos-DialogBox");
// Since we're going to add a FileUpload widget, we'll need to set the
// form to use the POST method, and multipart MIME encoding.
form.setEncoding(FormPanel.ENCODING_MULTIPART);
// Create a panel to hold all of the form widgets.
VerticalPanel panel = new VerticalPanel();
+ panel.add(close);
form.setWidget(panel);
- final HTML info = new HTML("You may select a file to upload. Install" +
- " <a href='http://gears.google.com/' target='_blank'>Google " +
- "Gears</a><br> for uploading multiple files simultaneously.");
- info.addStyleName("pithos-uploadNote");
- panel.add(info);
- final Hidden date = new Hidden("Date", "");
- panel.add(date);
- final Hidden auth = new Hidden("Authorization", "");
- panel.add(auth);
- // Add an informative label with the folder name.
- Object selection = GSS.get().getTreeView().getSelection();
- folder = ((RestResourceWrapper) selection).getResource();
- upload.setName("file");
+
+ VerticalPanel inner = new VerticalPanel();
+ inner.addStyleName("inner");
+
+ final Hidden auth = new Hidden("X-Auth-Token");
+ inner.add(auth);
+ upload.setName("X-Object-Data");
filenameLabel.setText("");
filenameLabel.setVisible(false);
filenameLabel.setStyleName("props-labels");
- HorizontalPanel fileUloadPanel = new HorizontalPanel();
- fileUloadPanel.add(filenameLabel);
- fileUloadPanel.add(upload);
- upload.getElement().setId("fileUploadDiallog.uploadPanel");
+ HorizontalPanel fileUploadPanel = new HorizontalPanel();
+ fileUploadPanel.add(filenameLabel);
+ fileUploadPanel.add(upload);
Grid generalTable = new Grid(2, 2);
generalTable.setText(0, 0, "Folder");
+ generalTable.setWidget(0, 1, foldernameLabel);
generalTable.setText(1, 0, "File");
- generalTable.setText(0, 1, folder.getName());
- generalTable.setWidget(1, 1, fileUloadPanel);
+ generalTable.setWidget(1, 1, fileUploadPanel);
generalTable.getCellFormatter().setStyleName(0, 0, "props-labels");
+ generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
generalTable.getCellFormatter().setStyleName(1, 0, "props-labels");
- generalTable.getCellFormatter().setStyleName(0, 1, "props-values");
generalTable.getCellFormatter().setStyleName(1, 1, "props-values");
generalTable.setCellSpacing(4);
- panel.add(generalTable);
-
- // Create a panel to hold the buttons.
- HorizontalPanel buttons = new HorizontalPanel();
+ inner.add(generalTable);
// Create the 'upload' button, along with a listener that submits the
// form.
- final Button submit = new Button("Upload", new ClickHandler() {
+ submit = new Button("Upload", new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
prepareAndSubmit();
}
});
- submit.getElement().setId("fileUploadDialog.button.upload");
- buttons.add(submit);
- buttons.setCellHorizontalAlignment(submit, HasHorizontalAlignment.ALIGN_CENTER);
- // Create the 'Cancel' button, along with a listener that hides the
- // dialog when the button is clicked.
- final Button cancel = new Button("Cancel", new ClickHandler() {
- @Override
- public void onClick(ClickEvent event) {
- repeater.finish();
- hide();
- }
- });
- cancel.getElement().setId("fileUploadDialog.button.cancel");
- buttons.add(cancel);
- buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
- buttons.setSpacing(8);
- buttons.addStyleName("pithos-DialogBox");
+ submit.addStyleName("button");
+ inner.add(submit);
// Add an event handler to the form.
form.addSubmitHandler(new SubmitHandler() {
@Override
public void onSubmit(SubmitEvent event) {
- GSS app = GSS.get();
- // This event is fired just before the form is submitted. We can
- // take this opportunity to perform validation.
- if (upload.getFilename().length() == 0) {
- app.displayError("You must select a file!");
- event.cancel();
- hide();
- } else {
-
- canContinue();
- GWT.log("Cancel:" + cancelEvent, null);
- if (cancelEvent) {
- cancelEvent = false;
- app.displayError("The specified file name already exists in this folder");
- event.cancel();
- hide();
- } else {
-
- fileNameToUse = getFilename(upload.getFilename());
- String apath;
- FileResource selectedFile = getFileForName(fileNameToUse);
- if (selectedFile == null ) {
- //we are going to create a file
- apath = folder.getUri();
- if (!apath.endsWith("/"))
- apath = apath + "/";
- apath = apath + encodeComponent(fileNameToUse);
- } else
- apath = selectedFile.getUri();
- form.setAction(apath);
- String dateString = RestCommand.getDate();
- String resource = apath.substring(app.getApiPath().length() - 1, apath.length());
- String sig = RestCommand.calculateSig("POST", dateString, resource, RestCommand.base64decode(app.getToken()));
- date.setValue(dateString);
- auth.setValue(app.getCurrentUserResource().getUsername() + " " + sig);
- GWT.log("FolderPATH:" + folder.getUri(), null);
- submit.setEnabled(false);
- upload.setVisible(false);
- filenameLabel.setText(fileNameToUse);
- filenameLabel.setVisible(true);
- repeater.start();
- progressBar.setVisible(true);
- }
- }
-
+ auth.setValue(app.getToken()); //This is done here because the app object is not available in the constructor
+ Cookies.setCookie("X-Auth-Token", app.getToken(), null, "", "/", false);
}
});
form.addSubmitCompleteHandler(new SubmitCompleteHandler() {
// Unfortunately the results are never empty, even in
// the absense of errors, so we have to check for '<pre></pre>'.
- if (!results.equalsIgnoreCase("<pre></pre>")) {
+ if (results != null && results.length() > 0 && !results.equalsIgnoreCase("<pre></pre>")) {
GWT.log(results, null);
- GSS.get().displayError(results);
+ app.displayError(results);
}
- progressBar.setProgress(100);
- cancelUpload();
- GSS.get().getTreeView().updateNode(GSS.get().getTreeView().getSelection());
- GSS.get().getStatusPanel().updateStats();
-
+ if (app.getSelectedTree().equals(app.getFolderTreeView()))
+ app.updateFolder(folder, true, new Command() {
+
+ @Override
+ public void execute() {
+ app.updateStatistics();
+ }
+ });
+ else
+ app.updateOtherSharedFolder(folder, true);
+ hide();
}
});
-
- panel.add(buttons);
- progressBar = new ProgressBar(50, ProgressBar.SHOW_TIME_REMAINING);
- panel.add(progressBar);
- progressBar.setVisible(false);
- panel.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
- panel.setCellHorizontalAlignment(progressBar, HasHorizontalAlignment.ALIGN_CENTER);
- panel.addStyleName("pithos-DialogBox");
- addStyleName("pithos-DialogBox");
+ panel.add(inner);
+ panel.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);
+
setWidget(form);
}
prepareAndSubmit();
break;
case KeyCodes.KEY_ESCAPE:
- cancelUpload();
+ hide();
break;
}
}
-
-
- /**
- * Cancels the file upload.
- */
- private void cancelUpload() {
- repeater.finish();
- hide();
- }
-
/**
* Make any last minute checks and start the upload.
*/
- public void prepareAndSubmit() {
- final String fname = getFilename(upload.getFilename());
+ protected void prepareAndSubmit() {
+ if (upload.getFilename().length() == 0) {
+ app.displayError("You must select a file!");
+ return;
+ }
+ final String fname = getFilename(upload.getFilename());
+ String apath = app.getApiPath() + folder.getOwner() + folder.getUri() + "/" + fname + "?X-Auth-Token=" + app.getToken();
+ form.setAction(apath);
+ submit.setEnabled(false);
+ upload.setVisible(false);
+ filenameLabel.setText(fname);
+ filenameLabel.setVisible(true);
+
if (getFileForName(fname) == null) {
- //we are going to create a file, so we check to see if there is a trashed file with the same name
- FileResource same = null;
- for (FileResource fres : folder.getFiles())
- if (fres.isDeleted() && fres.getName().equals(fname))
- same = fres;
- if (same == null)
- form.submit();
- else {
- final FileResource sameFile = same;
- GWT.log("Same deleted file", null);
- ConfirmationDialog confirm = new ConfirmationDialog("A file with " +
- "the same name exists in the trash. If you continue,<br/>the trashed " +
- "file '" + fname + "' will be renamed automatically for you.", "Continue") {
-
- @Override
- public void cancel() {
- FileUploadDialog.this.hide();
- }
-
- @Override
- public void confirm() {
- updateTrashedFile(getBackupFilename(fname), sameFile);
- }
-
- };
- confirm.center();
- }
+ form.submit();
}
else {
// We are going to update an existing file, so show a confirmation dialog.
}
}
- /**
+ /**
* Returns the file name from a potential full path argument. Apparently IE
* insists on sending the full path name of a file when uploading, forcing
* us to trim the extra path info. Since this is only observed on Windows we
return name.substring(pathSepIndex + 1);
}
- /**
- * Check whether the file name exists in selected folder.
- *
- * @return
- */
- private boolean canContinue() {
- if (files == null)
- return false;
- String fileName = getFilename(upload.getFilename());
- if (getFileForName(fileName) == null) {
- // For file creation, check to see if the file already exists.
- GWT.log("filename to upload:" + fileName, null);
- for (FileResource dto : files) {
- GWT.log("Check:" + dto.getName() + "/" + fileName, null);
- if (!dto.isDeleted() && dto.getName().equals(fileName)) {
- cancelEvent = true;
- return true;
- }
- }
- }
- return true;
- }
-
- class RepeatingTimer extends Timer {
-
- private Updateable updateable;
-
- private int interval = 1500;
-
- private boolean running = true;
-
- RepeatingTimer(Updateable _updateable, int _interval) {
- updateable = _updateable;
- interval = _interval;
- }
-
- @Override
- public void run() {
- updateable.update();
- }
-
- public void start() {
- running = true;
-
- scheduleRepeating(interval);
- }
-
- public void finish() {
- running = false;
- cancel();
- }
-
- public int getInterval() {
- return interval;
- }
-
- public void setInterval(int anInterval) {
- if (interval != anInterval) {
- interval = anInterval;
- if (running) {
- finish();
- start();
- }
- }
- }
- }
-
- @Override
- public void update() {
- String apath = folder.getUri();
- if (!apath.endsWith("/"))
- apath = apath + "/";
- apath = apath + encodeComponent(fileNameToUse) + "?progress=" + encodeComponent(fileNameToUse);
- GetCommand eg = new GetCommand<UploadStatusResource>(UploadStatusResource.class, apath, false, null) {
-
- @Override
- public void onComplete() {
- UploadStatusResource res = getResult();
- progressBar.setProgress(res.percent());
- }
-
- @Override
- public void onError(Throwable t) {
- GWT.log("", t);
- }
-
- };
- DeferredCommand.addCommand(eg);
- }
-
- protected String getBackupFilename(String filename) {
- List<FileResource> filesInSameFolder = new ArrayList<FileResource>();
- for (FileResource deleted : folder.getFiles())
- if (deleted.isDeleted())
- filesInSameFolder.add(deleted);
- int i = 1;
- for (FileResource same : filesInSameFolder)
- if (same.getName().startsWith(filename)) {
- String toCheck = same.getName().substring(filename.length(), same.getName().length());
- if (toCheck.startsWith(" ")) {
- int test = -1;
- try {
- test = Integer.valueOf(toCheck.replace(" ", ""));
- } catch (NumberFormatException e) {
- // Do nothing since string is not a number.
- }
- if (test >= i)
- i = test + 1;
- }
- }
-
- return filename + " " + i;
- }
-
- /**
- * Rename the conflicting trashed file with the supplied new name.
- */
- private void updateTrashedFile(String newName, FileResource trashedFile) {
- JSONObject json = new JSONObject();
- json.put("name", new JSONString(newName));
- PostCommand cf = new PostCommand(trashedFile.getUri() + "?update=", json.toString(), 200) {
-
- @Override
- public void onComplete() {
- form.submit();
- }
-
- @Override
- public void onError(Throwable t) {
- GSS app = GSS.get();
- GWT.log("", t);
- if (t instanceof RestException) {
- int statusCode = ((RestException) t).getHttpStatusCode();
- if (statusCode == 405)
- app.displayError("You don't have the necessary permissions");
- else if (statusCode == 404)
- app.displayError("User in permissions does not exist");
- else if (statusCode == 409)
- app.displayError("A file with the same name already exists");
- else if (statusCode == 413)
- app.displayError("Your quota has been exceeded");
- else
- app.displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());
- } else
- app.displayError("System error modifying file:" + t.getMessage());
- }
-
- };
- DeferredCommand.addCommand(cf);
- }
-
- protected FileResource getFileForName(String name){
- for (FileResource f : folder.getFiles())
- if (!f.isDeleted() && f.getName().equals(name))
+ protected File getFileForName(String name){
+ for (File f : folder.getFiles())
+ if (f.getName().equals(name))
return f;
return null;
}
+ public void setApp(Pithos app) {
+ this.app = app;
+ }
- /**
- * Same as URL.encodeComponent, but also
- * encode apostrophe since browsers aren't consistent about it
- * (FF encodes, IE does not).
- */
- private String encodeComponent(String decodedURLComponent) {
- String retv = URL.encodeComponent(decodedURLComponent);
- retv = retv.replaceAll("'", "%27");
- return retv;
- }
-
- /**
- * Modify the files.
- *
- * @param newFiles the files to set
- */
- public void setFiles(List<FileResource> newFiles) {
- files = newFiles;
- }
+ public void setFolder(Folder folder) {
+ this.folder = folder;
+ foldernameLabel.setText(folder.getName());
+ }
}