<property file="runtime.properties"/>
<property name="deps.dir" value="dependencies"/>
- <property name="gwt.workers" value="1"/>
+ <property name="gwt.workers" value="2"/>
<property name="gwt.version" value="2.4.0"/>
<property name="gwt.home" value="${deps.dir}/gwt-${gwt.version}"/>
* Gathers application-wide constants, like <code>X-Auth-Token</code>
*/
public final class Const {
+ public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String ACCEPT = "Accept";
+ public static final String CONTENT_LENGTH = "Content-Length";
+
public static final String X_AUTH_TOKEN = "X-Auth-Token";
+ public static final String X_OBJECT_SHARING = "X-Object-Sharing";
+ public static final String X_OBJECT_PUBLIC = "X-Object-Public";
+ public static final String X_COPY_FROM = "X-Copy-From";
+ public static final String X_SOURCE_ACCOUNT = "X-Source-Account";
+ public static final String X_MOVE_FROM = "X-Move-From";
+
+ public static final String X_ACCOUNT_GROUP_ = "X-Account-Group-";
+
public static final String OTHER_PROPERTIES = "otherProperties";
public static final String LOGIN_URL = "loginUrl";
- public static final String IF_MODIFIED_SINCE = "If-Modified-Since";
+
public static final String PERCENT_100 = "100%";
public static final String DATE_FORMAT_1 = "EEE, dd MMM yyyy HH:mm:ss";
public static final String AUTH_COOKIE = "authCookie";
- public static final String X_COPY_FROM = "X-Copy-From";
- public static final String X_SOURCE_ACCOUNT = "X-Source-Account";
- public static final String CONTENT_TYPE = "Content-Type";
- public static final String ACCEPT = "Accept";
- public static final String CONTENT_LENGTH = "Content-Length";
- public static final String X_MOVE_FROM = "X-Move-From";
+
+ public static final RegExp EMAIL_REGEX = RegExp.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+[.][A-Z]{2,4}$", "i");
+
public static final String HOME_CONTAINER = "pithos";
public static final String TRASH_CONTAINER = "trash";
- public static final RegExp EMAIL_REGEX = RegExp.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+[.][A-Z]{2,4}$", "i");
- public static final String X_ACCOUNT_GROUP_ = "X-Account-Group-";
+
+ public static final String EQ = "=";
+ public static final String COMMA = ",";
+ public static final String TILDE = "~";
+ public static final String SEMI = ";";
+ public static final String QUESTION_MARK = "?";
+ public static final String AMPERSAND = "&";
+
+ public static final String READ_EQ = "read=";
+ public static final String WRITE_EQ = "write=";
+ public static final String GOTO_EQ = "goto=";
+ public static final String UPDATE_EQ = "update=";
+ public static final String QUESTION_MARK_UPDATE_EQ = QUESTION_MARK + UPDATE_EQ;
+
+
public static final String NL = "\n";
+ public static final String EVENT_TYPE_KEYDOWN = "keydown";
+
private Const() {}
if (selectedFolder != null && !selectedFolder.isInTrash()) {
if ((isFolderTreeSelected || isMysharedSelected) && selectedFiles.size() == 1) {
contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " Properties</span>", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.PROPERTIES)));
- contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Sharing</span>", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.PERMISSIONS)));
- contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.internet()).getHTML() + " Publish</span>", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.PUBLISH)));
+ contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.sharing()).getHTML() + " Share</span>", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.PERMISSIONS)));
contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.versions()).getHTML() + " Versions</span>", true, new PropertiesCommand(app, this, selectedFiles, PropertiesCommand.VERSIONS)));
}
\r
final File file;\r
\r
- Images images = GWT.create(Images.class);\r
+ FileShareDialog.PrivateSharingImages images = GWT.create(FileShareDialog.PrivateSharingImages.class);\r
\r
/**\r
* The widget's constructor.\r
\r
pathPanel = new HorizontalPanel();\r
pathPanel.setVisible(false);\r
- pathPanel.setWidth("100%");\r
+ pathPanel.setWidth(Const.PERCENT_100);\r
pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
pathPanel.add(new Label("Link"));\r
pathPanel.setSpacing(8);\r
pathPanel.addStyleName("pithos-TabPanelBottom");\r
\r
path = new TextBox();\r
- path.setWidth("100%");\r
+ path.setWidth(Const.PERCENT_100);\r
path.addClickHandler(new ClickHandler() {\r
@Override\r
public void onClick(ClickEvent event) {\r
});\r
path.setText(Window.Location.getHost() + file.getPublicUri());\r
path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
- path.setWidth("100%");\r
+ path.setWidth(Const.PERCENT_100);\r
path.setReadOnly(true);\r
pathPanel.add(path);\r
permPanel.add(pathPanel);\r
UrlBuilder b = Window.Location.createUrlBuilder();\r
b.setPath(app.getApiPath() + file.getOwnerID() + file.getUri());\r
String href = Window.Location.getHref();\r
- boolean hasParameters = href.contains("?");\r
- path.setText(href + (hasParameters ? "&" : "?") + "goto=" + b.buildString());\r
+ boolean hasParameters = href.contains(Const.QUESTION_MARK);\r
+ path.setText(href + (hasParameters ? Const.AMPERSAND : Const.QUESTION_MARK) + Const.GOTO_EQ + b.buildString());\r
pathPanel.setVisible(true);\r
}\r
else {\r
*/\r
@Override\r
protected boolean accept() {\r
- updateMetaData(app.getApiPath(), app.getUserID(), file.getUri() + "?update=", permList.getPermissions());\r
+ updateMetaData(\r
+ app.getApiPath(),\r
+ app.getUserID(),\r
+ file.getUri() + Const.QUESTION_MARK_UPDATE_EQ,\r
+ permList.getPermissions()\r
+ );\r
return true;\r
}\r
\r
\r
@Override\r
public void onError(Throwable t) {\r
- GWT.log("", t);\r
app.setError(t);\r
app.displayError("System error modifying file:" + t.getMessage());\r
}\r
app.sessionExpired();\r
}\r
};\r
- headFile.setHeader("X-Auth-Token", app.getUserToken());\r
+ headFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());\r
Scheduler.get().scheduleDeferred(headFile);\r
}\r
\r
@Override\r
public void onError(Throwable t) {\r
- GWT.log("", t);\r
app.setError(t);\r
app.displayError("System error modifying file:" + t.getMessage());\r
}\r
app.sessionExpired();\r
}\r
};\r
- updateFile.setHeader("X-Auth-Token", app.getUserToken());\r
+ updateFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());\r
\r
- String readPermHeader = "read=";\r
- String writePermHeader = "write=";\r
+ String readPermHeader = Const.READ_EQ;\r
+ String writePermHeader = Const.WRITE_EQ;\r
for (String u : newPermissions.keySet()) {\r
Boolean[] p = newPermissions.get(u);\r
- if (p[0] != null && p[0])\r
- readPermHeader += u + ",";\r
- if (p[1] != null && p[1])\r
- writePermHeader += u + ",";\r
+ if (p[0] != null && p[0]) {\r
+ readPermHeader += u + Const.COMMA;\r
+ }\r
+ if (p[1] != null && p[1]) {\r
+ writePermHeader += u + Const.COMMA;\r
+ }\r
}\r
- if (readPermHeader.endsWith("="))\r
+ if (readPermHeader.endsWith(Const.EQ)) {\r
readPermHeader = "";\r
- else if (readPermHeader.endsWith(","))\r
+ }\r
+ else if (readPermHeader.endsWith(Const.COMMA)) {\r
readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);\r
- if (writePermHeader.endsWith("="))\r
+ }\r
+ if (writePermHeader.endsWith(Const.EQ)) {\r
writePermHeader = "";\r
- else if (writePermHeader.endsWith(","))\r
+ }\r
+ else if (writePermHeader.endsWith(Const.COMMA)) {\r
writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);\r
- String permHeader = readPermHeader + ((readPermHeader.length() > 0 && writePermHeader.length() > 0) ? ";" : "") + writePermHeader;\r
- if (permHeader.length() == 0)\r
- permHeader="~";\r
- else\r
+ }\r
+ String permHeader = readPermHeader +\r
+ ((readPermHeader.length() > 0 && writePermHeader.length() > 0) ? Const.SEMI : "") + writePermHeader;\r
+ if (permHeader.length() == 0) {\r
+ permHeader=Const.TILDE;\r
+ }\r
+ else {\r
permHeader = URL.encodePathSegment(permHeader);\r
- updateFile.setHeader("X-Object-Sharing", permHeader);\r
+ }\r
+ updateFile.setHeader(Const.X_OBJECT_SHARING, permHeader);\r
Scheduler.get().scheduleDeferred(updateFile);\r
}\r
- else if (!app.isMySharedSelected())\r
+ else if (!app.isMySharedSelected()) {\r
app.updateFolder(file.getParent(), true, new Command() {\r
- \r
@Override\r
public void execute() {\r
if (file.isSharedOrPublished())\r
app.updateMySharedRoot();\r
}\r
}, true);\r
- else\r
+ }\r
+ else {\r
app.updateSharedFolder(file.getParent(), true);\r
+ }\r
}\r
\r
@Override\r
super.onPreviewNativeEvent(preview);\r
\r
NativeEvent evt = preview.getNativeEvent();\r
- if (evt.getType().equals("keydown") && evt.getKeyCode() == KeyCodes.KEY_ENTER)\r
- closeDialog();\r
+ if (evt.getType().equals(Const.EVENT_TYPE_KEYDOWN) &&\r
+ evt.getKeyCode() == KeyCodes.KEY_ENTER) {\r
+\r
+ closeDialog();\r
+ }\r
}\r
}\r
+++ /dev/null
-/*\r
- * Copyright 2011-2013 GRNET S.A. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or\r
- * without modification, are permitted provided that the following\r
- * conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer.\r
- *\r
- * 2. Redistributions in binary form must reproduce the above\r
- * copyright notice, this list of conditions and the following\r
- * disclaimer in the documentation and/or other materials\r
- * provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- * The views and conclusions contained in the software and\r
- * documentation are those of the authors and should not be\r
- * interpreted as representing official policies, either expressed\r
- * or implied, of GRNET S.A.\r
- */\r
-package gr.grnet.pithos.web.client;\r
-\r
-import gr.grnet.pithos.web.client.foldertree.File;\r
-import gr.grnet.pithos.web.client.rest.HeadRequest;\r
-import gr.grnet.pithos.web.client.rest.PostRequest;\r
-\r
-import com.google.gwt.core.client.GWT;\r
-import com.google.gwt.core.client.Scheduler;\r
-import com.google.gwt.dom.client.NativeEvent;\r
-import com.google.gwt.event.dom.client.ClickEvent;\r
-import com.google.gwt.event.dom.client.ClickHandler;\r
-import com.google.gwt.event.dom.client.KeyCodes;\r
-import com.google.gwt.http.client.Response;\r
-import com.google.gwt.http.client.UrlBuilder;\r
-import com.google.gwt.resources.client.ImageResource;\r
-import com.google.gwt.user.client.Command;\r
-import com.google.gwt.user.client.Window;\r
-import com.google.gwt.user.client.Event.NativePreviewEvent;\r
-import com.google.gwt.user.client.ui.Anchor;\r
-import com.google.gwt.user.client.ui.Button;\r
-import com.google.gwt.user.client.ui.CheckBox;\r
-import com.google.gwt.user.client.ui.FocusPanel;\r
-import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
-import com.google.gwt.user.client.ui.HorizontalPanel;\r
-import com.google.gwt.user.client.ui.Label;\r
-import com.google.gwt.user.client.ui.TextBox;\r
-import com.google.gwt.user.client.ui.VerticalPanel;\r
-\r
-/**\r
- * The 'File properties' dialog box implementation.\r
- *\r
- */\r
-public class FilePublishDialog extends AbstractPropertiesDialog {\r
-\r
- protected CheckBox readForAll;\r
- \r
- private HorizontalPanel pathPanel;\r
- \r
- private TextBox path;\r
- \r
- /**\r
- * An image bundle for this widgets images.\r
- */\r
- public interface Images extends MessagePanel.Images {\r
-\r
- @Source("gr/grnet/pithos/resources/edit_user.png")\r
- ImageResource permUser();\r
-\r
- @Source("gr/grnet/pithos/resources/groups22.png")\r
- ImageResource permGroup();\r
-\r
- @Source("gr/grnet/pithos/resources/editdelete.png")\r
- ImageResource delete();\r
- }\r
-\r
- final File file;\r
-\r
- Images images = GWT.create(Images.class);\r
-\r
- /**\r
- * The widget's constructor.\r
- */\r
- public FilePublishDialog(Pithos _app, File _file) {\r
- super(_app);\r
- file = _file;\r
-\r
- Anchor close = new Anchor("close");\r
- close.addStyleName("close");\r
- close.addClickHandler(new ClickHandler() {\r
- \r
- @Override\r
- public void onClick(ClickEvent event) {\r
- hide();\r
- }\r
- });\r
- // Set the dialog's caption.\r
- setText("Publish/Un-publish");\r
- setGlassEnabled(true);\r
- setStyleName("pithos-DialogBox");\r
-\r
- // Outer contains inner and buttons.\r
- final VerticalPanel outer = new VerticalPanel();\r
- outer.add(close);\r
- final FocusPanel focusPanel = new FocusPanel(outer);\r
- // Inner contains generalPanel and permPanel.\r
- inner = new VerticalPanel();\r
- inner.addStyleName("inner");\r
-\r
- inner.add(createSharingPanel());\r
-\r
- outer.add(inner);\r
-\r
- final Button ok = new Button("OK", new ClickHandler() {\r
- @Override\r
- public void onClick(ClickEvent event) {\r
- closeDialog();\r
- }\r
- });\r
- ok.addStyleName("button");\r
-\r
- outer.add(ok);\r
- outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);\r
-\r
- focusPanel.setFocus(true);\r
- setWidget(outer);\r
- }\r
-\r
- private VerticalPanel createSharingPanel() {\r
- VerticalPanel permPanel = new VerticalPanel();\r
-\r
- final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
- " by everyone. By checking this option, you are certifying that you have the right to " +\r
- "distribute this file and that it does not violate the Terms of Use.", true);\r
- readForAllNote.setStylePrimaryName("pithos-readForAllNote");\r
-\r
- readForAll = new CheckBox();\r
- readForAll.setValue(file.isPublished());\r
- readForAll.addClickHandler(new ClickHandler() {\r
- @Override\r
- public void onClick(ClickEvent event) {\r
- accept();\r
- }\r
- });\r
-\r
- // Only show the read for all permission if the user is the owner.\r
- if (file.getOwnerID().equals(app.getUserID())) {\r
- final HorizontalPanel permForAll = new HorizontalPanel();\r
- permForAll.add(new Label("Public"));\r
- permForAll.add(readForAll);\r
- permForAll.setSpacing(8);\r
- permForAll.addStyleName("pithos-TabPanelBottom");\r
- permForAll.add(readForAllNote);\r
- permPanel.add(permForAll);\r
- }\r
-\r
- pathPanel = new HorizontalPanel();\r
- pathPanel.setVisible(false);\r
- pathPanel.setWidth("100%");\r
- pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
- pathPanel.add(new Label("Link"));\r
- pathPanel.setSpacing(8);\r
- pathPanel.addStyleName("pithos-TabPanelBottom");\r
-\r
- path = new TextBox();\r
- path.setWidth("100%");\r
- path.addClickHandler(new ClickHandler() {\r
- @Override\r
- public void onClick(ClickEvent event) {\r
- Pithos.enableIESelection();\r
- ((TextBox) event.getSource()).selectAll();\r
- Pithos.preventIESelection();\r
- }\r
- });\r
- path.setText(Window.Location.getHost() + file.getPublicUri());\r
- path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
- path.setWidth("100%");\r
- path.setReadOnly(true);\r
- pathPanel.add(path);\r
- permPanel.add(pathPanel);\r
-\r
- Scheduler.get().scheduleDeferred(new Command() {\r
- \r
- @Override\r
- public void execute() {\r
- showLinkIfPublished();\r
- }\r
- });\r
- return permPanel;\r
- }\r
-\r
- void showLinkIfPublished() {\r
- if (file.isPublished()) {\r
- UrlBuilder b = Window.Location.createUrlBuilder();\r
- b.setPath(file.getPublicUri());\r
- path.setText(b.buildString());\r
- pathPanel.setVisible(true);\r
- }\r
- else {\r
- pathPanel.setVisible(false);\r
- }\r
- }\r
- /**\r
- * Accepts any change and updates the file\r
- * @return \r
- *\r
- */\r
- @Override\r
- protected boolean accept() {\r
- Boolean published = null;\r
- if (readForAll.getValue() != file.isPublished())\r
- if (file.getOwnerID().equals(app.getUserID()))\r
- published = readForAll.getValue();\r
- updateMetaData(app.getApiPath(), app.getUserID(), file.getUri() + "?update=", published);\r
- return true;\r
- }\r
-\r
- protected void updateMetaData(String api, String owner, final String path, final Boolean published) {\r
- if (published != null) {\r
- PostRequest updateFile = new PostRequest(api, owner, path) {\r
- @Override\r
- public void onSuccess(Resource result) {\r
- HeadRequest<File> headFile = new HeadRequest<File>(File.class, app.getApiPath(), file.getOwnerID(), path, file) {\r
-\r
- @Override\r
- public void onSuccess(File _result) {\r
- showLinkIfPublished();\r
- if (!app.isMySharedSelected())\r
- app.updateFolder(file.getParent(), true, new Command() {\r
- \r
- @Override\r
- public void execute() {\r
- app.updateMySharedRoot();\r
- }\r
- }, true);\r
- else\r
- app.updateSharedFolder(file.getParent(), true);\r
- }\r
-\r
- @Override\r
- public void onError(Throwable t) {\r
- GWT.log("", t);\r
- app.setError(t);\r
- app.displayError("System error modifying file:" + t.getMessage());\r
- }\r
-\r
- @Override\r
- protected void onUnauthorized(Response response) {\r
- app.sessionExpired();\r
- }\r
- };\r
- headFile.setHeader("X-Auth-Token", app.getUserToken());\r
- Scheduler.get().scheduleDeferred(headFile);\r
- }\r
-\r
- @Override\r
- public void onError(Throwable t) {\r
- GWT.log("", t);\r
- app.setError(t);\r
- app.displayError("System error modifying file:" + t.getMessage());\r
- }\r
-\r
- @Override\r
- protected void onUnauthorized(Response response) {\r
- app.sessionExpired();\r
- }\r
- };\r
- updateFile.setHeader("X-Auth-Token", app.getUserToken());\r
- updateFile.setHeader("X-Object-Public", published.toString());\r
- Scheduler.get().scheduleDeferred(updateFile);\r
- }\r
- else if (!app.isMySharedSelected())\r
- app.updateFolder(file.getParent(), true, new Command() {\r
- \r
- @Override\r
- public void execute() {\r
- if (file.isSharedOrPublished())\r
- app.updateMySharedRoot();\r
- }\r
- }, true);\r
- else\r
- app.updateSharedFolder(file.getParent(), true);\r
- }\r
-\r
- @Override\r
- protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
- super.onPreviewNativeEvent(preview);\r
-\r
- NativeEvent evt = preview.getNativeEvent();\r
- if (evt.getType().equals("keydown") && evt.getKeyCode() == KeyCodes.KEY_ENTER)\r
- closeDialog();\r
- }\r
-}\r
--- /dev/null
+/*
+ * Copyright 2011-2013 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;
+
+import com.google.gwt.http.client.URL;
+import com.google.gwt.user.client.ui.*;
+import gr.grnet.pithos.web.client.foldertree.File;
+import gr.grnet.pithos.web.client.rest.HeadRequest;
+import gr.grnet.pithos.web.client.rest.PostRequest;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.Scheduler;
+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.Response;
+import com.google.gwt.http.client.UrlBuilder;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+
+import java.util.Map;
+
+/**
+ * UI for the "Share" command.
+ */
+public class FileShareDialog extends AbstractPropertiesDialog {
+ // For public sharing
+ private final HorizontalPanel publicPathPanel = new HorizontalPanel();
+ private final TextBox publicPathText = new TextBox();
+
+ // For private sharing
+ private final HorizontalPanel privatePathPanel = new HorizontalPanel();
+ private final TextBox privatePathText = new TextBox();
+ private final VerticalPanel privatePermSuperPanel = new VerticalPanel();
+ private PermissionsList permList;
+
+ /**
+ * An image bundle for this widgets images.
+ */
+ public interface PublicSharingImages extends MessagePanel.Images {
+
+ @Source("gr/grnet/pithos/resources/edit_user.png")
+ ImageResource permUser();
+
+ @Source("gr/grnet/pithos/resources/groups22.png")
+ ImageResource permGroup();
+
+ @Source("gr/grnet/pithos/resources/editdelete.png")
+ ImageResource delete();
+ }
+
+ public interface PrivateSharingImages extends MessagePanel.Images {
+
+ @Source("gr/grnet/pithos/resources/edit_user.png")
+ ImageResource permUser();
+
+ @Source("gr/grnet/pithos/resources/groups22.png")
+ ImageResource permGroup();
+
+ @Source("gr/grnet/pithos/resources/delete.gif")
+ ImageResource delete();
+ }
+
+ private final File file;
+
+ private final PublicSharingImages publicSharingImages = GWT.create(PublicSharingImages.class);
+ private final PrivateSharingImages privateSharingImages = GWT.create(PrivateSharingImages.class);
+
+ /**
+ * The widget's constructor.
+ */
+ public FileShareDialog(Pithos _app, File _file) {
+ super(_app);
+ file = _file;
+
+ Anchor close = new Anchor("close");
+ close.addStyleName("close");
+ close.addClickHandler(new ClickHandler() {
+
+ @Override
+ public void onClick(ClickEvent event) {
+ hide();
+ }
+ });
+ // Set the dialog's caption.
+ setText("Share");
+ setGlassEnabled(true);
+ setStyleName("pithos-DialogBox");
+
+ // Outer contains inner and buttons.
+ final VerticalPanel outer = new VerticalPanel();
+ outer.add(close);
+ final FocusPanel focusPanel = new FocusPanel(outer);
+ // Inner contains generalPanel and permPanel.
+ inner = new VerticalPanel();
+ inner.addStyleName("inner");
+
+ inner.add(createMainPanel());
+
+ outer.add(inner);
+
+ final Button ok = new Button("OK", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ closeDialog();
+ }
+ });
+ ok.addStyleName("button");
+
+ outer.add(ok);
+ outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);
+
+ focusPanel.setFocus(true);
+ setWidget(outer);
+ }
+
+ private boolean IamOwner() {
+ return file.getOwnerID().equals(app.getUserID());
+ }
+
+ private void populatePublicSharingPanel(VerticalPanel publicSharingPanel) {
+ if(IamOwner()) {
+ final HorizontalPanel publicCheckPanel = new HorizontalPanel();
+ publicCheckPanel.setSpacing(8);
+
+ // Check box header
+ final CheckBox publicCheckBox = new CheckBox();
+ Label publicCheckTitle = new InlineHTML("<b>Public on the Internet</b>");
+ Label publicCheckInfo = new Label("Anyone who has the public link can access. No sign-in required.", true);
+
+ publicCheckBox.setValue(isFilePubliclyShared());
+ publicCheckBox.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ final Boolean published;
+ if(publicCheckBox.getValue() != file.isPublished() && IamOwner()) {
+ published = publicCheckBox.getValue();
+ }
+ else {
+ published = Boolean.FALSE;
+ }
+
+ updateMetaDataForPublicSharing(published);
+ }
+ });
+
+ publicCheckPanel.add(publicCheckBox);
+ publicCheckPanel.add(publicCheckTitle);
+ publicCheckPanel.add(publicCheckInfo);
+
+ // Public Link
+ publicPathPanel.setVisible(false);
+ publicPathPanel.setWidth(Const.PERCENT_100);
+ publicPathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
+ publicPathPanel.add(new Label("Link"));
+ publicPathPanel.setSpacing(8);
+ publicPathPanel.addStyleName("pithos-TabPanelBottom");
+
+ publicPathText.setWidth(Const.PERCENT_100);
+ publicPathText.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ Pithos.enableIESelection();
+ ((TextBox) event.getSource()).selectAll();
+ Pithos.preventIESelection();
+ }
+ });
+ publicPathText.setText(Window.Location.getHost() + file.getPublicUri());
+ publicPathText.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");
+ publicPathText.setReadOnly(true);
+ publicPathPanel.add(publicPathText);
+
+ publicSharingPanel.add(publicCheckPanel);
+ publicSharingPanel.add(publicPathPanel);
+
+ Scheduler.get().scheduleDeferred(new Command() {
+ @Override
+ public void execute() {
+ showLinkForPublicSharing();
+ }
+ });
+ }
+ }
+
+ private void populatePrivateSharingPanel(VerticalPanel privateSharingPanel) {
+ final HorizontalPanel privateCheckPanel = new HorizontalPanel();
+ final VerticalPanel privatePermPanel = new VerticalPanel();
+ final HorizontalPanel permButtons = new HorizontalPanel();
+
+ privateCheckPanel.setSpacing(8);
+ privatePermPanel.setVisible(isFilePrivatelyShared());
+ permButtons.setSpacing(8);
+
+ // Check box header
+ final CheckBox privateCheckBox = new CheckBox();
+ final Label privateCheckTitle = new InlineHTML("<b>Private sharing</b>");
+ final Label privateCheckInfo = new Label("Only people explicitly granted permission can access. Sign-in required.", true);
+
+ privateCheckBox.setValue(isFilePrivatelyShared());
+ privateCheckBox.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ if(isFilePrivatelyShared()) {
+ // ignore the click, set it always to "checked"
+ privateCheckBox.setValue(true);
+ // show permissions
+ privatePermPanel.setVisible(true);
+ }
+ else {
+ // This is the value *after* the click is applied :)
+ boolean isChecked = privateCheckBox.getValue();
+ privatePermPanel.setVisible(isChecked);
+ }
+ }
+ });
+
+ privateCheckPanel.add(privateCheckBox);
+ privateCheckPanel.add(privateCheckTitle);
+ privateCheckPanel.add(privateCheckInfo);
+
+ // Permission list
+ permList = new PermissionsList(app, privateSharingImages, file.getPermissions(), file.getOwnerID(), false, new Command() {
+ @Override
+ public void execute() {
+ updateMetaDataForPrivateSharing();
+ }
+ });
+
+ // Permission Add buttons
+ Button addUser = new Button("Add User", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true);
+ dlg.center();
+ permList.updatePermissionTable();
+ }
+ });
+ addUser.addStyleName("button");
+ permButtons.add(addUser);
+ permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);
+
+ Button add = new Button("Add Group", new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ if (app.getAccount().getGroups().isEmpty()) {
+ new GroupCreateDialog(app, new Command() {
+
+ @Override
+ public void execute() {
+ if (app.getAccount().getGroups().isEmpty()) {
+ return;
+ }
+ PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);
+ dlg.center();
+ }
+ }).center();
+ }
+ else {
+ PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);
+ dlg.center();
+ }
+ }
+ });
+ add.addStyleName("button");
+ permButtons.add(add);
+ permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);
+
+ privatePermPanel.add(permList);
+ privatePermPanel.add(permButtons);
+
+ // Private Link
+ privatePathPanel.setVisible(false);
+ privatePathPanel.setWidth(Const.PERCENT_100);
+ privatePathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
+ privatePathPanel.add(new Label("Link"));
+ privatePathPanel.setSpacing(8);
+ privatePathPanel.addStyleName("pithos-TabPanelBottom");
+
+ privatePathText.setWidth(Const.PERCENT_100);
+ privatePathText.addClickHandler(new ClickHandler() {
+ @Override
+ public void onClick(ClickEvent event) {
+ Pithos.enableIESelection();
+ ((TextBox) event.getSource()).selectAll();
+ Pithos.preventIESelection();
+ }
+ });
+ privatePathText.setText(Window.Location.getHost() + file.getPublicUri());
+ privatePathText.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");
+ privatePathText.setWidth(Const.PERCENT_100);
+ privatePathText.setReadOnly(true);
+ privatePathPanel.add(privatePathText);
+
+ Scheduler.get().scheduleDeferred(new Command() {
+ @Override
+ public void execute() {
+ showLinkForPrivateSharing();
+ }
+ });
+
+ privateSharingPanel.add(privateCheckPanel);
+ privateSharingPanel.add(privatePermPanel);
+ privateSharingPanel.add(privatePathPanel);
+ }
+
+ private Panel createMainPanel() {
+ VerticalPanel panelAll = new VerticalPanel();
+ VerticalPanel panelPublic = new VerticalPanel();
+ VerticalPanel panelPrivate = new VerticalPanel();
+
+ populatePrivateSharingPanel(panelPrivate);
+ populatePublicSharingPanel(panelPublic);
+
+ panelAll.add(panelPrivate);
+ panelAll.add(panelPublic);
+
+ return panelAll;
+ }
+
+ private boolean isFilePubliclyShared() {
+ return file.isPublished();
+ }
+
+ private boolean isFilePrivatelyShared() {
+ return file.isShared();
+ }
+
+ private void showLinkForPublicSharing() {
+ if (isFilePubliclyShared()) {
+ UrlBuilder b = Window.Location.createUrlBuilder();
+ b.setPath(file.getPublicUri());
+ publicPathText.setText(b.buildString());
+ publicPathPanel.setVisible(true);
+ }
+ else {
+ publicPathPanel.setVisible(false);
+ }
+ }
+
+ private void showLinkForPrivateSharing() {
+ if (isFilePrivatelyShared()) {
+ UrlBuilder b = Window.Location.createUrlBuilder();
+ b.setPath(app.getApiPath() + file.getOwnerID() + file.getUri());
+ String href = Window.Location.getHref();
+ boolean hasParameters = href.contains(Const.QUESTION_MARK);
+ privatePathText.setText(href + (hasParameters ? Const.AMPERSAND : Const.QUESTION_MARK) + Const.GOTO_EQ + b.buildString());
+ privatePathPanel.setVisible(true);
+ }
+ else {
+ privatePathPanel.setVisible(false);
+ }
+ }
+
+ protected void updateMetaDataForPublicSharing(String api, String owner, final String path, final Boolean published) {
+ if (published != null) {
+ PostRequest updateFile = new PostRequest(api, owner, path) {
+ @Override
+ public void onSuccess(Resource result) {
+ HeadRequest<File> headFile = new HeadRequest<File>(File.class, app.getApiPath(), file.getOwnerID(), path, file) {
+
+ @Override
+ public void onSuccess(File _result) {
+ showLinkForPublicSharing();
+ if (!app.isMySharedSelected()) {
+ app.updateFolder(file.getParent(), true, new Command() {
+
+ @Override
+ public void execute() {
+ app.updateMySharedRoot();
+ }
+ }, true);
+ }
+ else {
+ app.updateSharedFolder(file.getParent(), true);
+ }
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ app.setError(t);
+ app.displayError("System error modifying file:" + t.getMessage());
+ }
+
+ @Override
+ protected void onUnauthorized(Response response) {
+ app.sessionExpired();
+ }
+ };
+ headFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());
+ Scheduler.get().scheduleDeferred(headFile);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ app.setError(t);
+ app.displayError("System error modifying file:" + t.getMessage());
+ }
+
+ @Override
+ protected void onUnauthorized(Response response) {
+ app.sessionExpired();
+ }
+ };
+ updateFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());
+ updateFile.setHeader(Const.X_OBJECT_PUBLIC, published.toString());
+ Scheduler.get().scheduleDeferred(updateFile);
+ }
+ else if (!app.isMySharedSelected())
+ app.updateFolder(file.getParent(), true, new Command() {
+ @Override
+ public void execute() {
+ if (file.isSharedOrPublished()) {
+ app.updateMySharedRoot();
+ }
+ }
+ }, true);
+ else
+ app.updateSharedFolder(file.getParent(), true);
+ }
+ protected void updateMetaDataForPublicSharing(Boolean published) {
+ updateMetaDataForPublicSharing(
+ app.getApiPath(),
+ app.getUserID(),
+ file.getUri() + Const.QUESTION_MARK_UPDATE_EQ,
+ published
+ );
+ }
+
+ protected void updateMetaDataForPrivateSharing(String api, String owner, final String path, final Map<String, Boolean[]> newPermissions) {
+ if (newPermissions != null) {
+ PostRequest updateFile = new PostRequest(api, owner, path) {
+ @Override
+ public void onSuccess(Resource result) {
+ HeadRequest<File> headFile = new HeadRequest<File>(File.class, app.getApiPath(), file.getOwnerID(), path, file) {
+
+ @Override
+ public void onSuccess(File _result) {
+ showLinkForPrivateSharing();
+ if (!app.isMySharedSelected())
+ app.updateFolder(file.getParent(), true, new Command() {
+
+ @Override
+ public void execute() {
+ app.updateMySharedRoot();
+ }
+ }, true);
+ else
+ app.updateSharedFolder(file.getParent(), true);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ app.setError(t);
+ app.displayError("System error modifying file:" + t.getMessage());
+ }
+
+ @Override
+ protected void onUnauthorized(Response response) {
+ app.sessionExpired();
+ }
+ };
+ headFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());
+ Scheduler.get().scheduleDeferred(headFile);
+ }
+
+ @Override
+ public void onError(Throwable t) {
+ app.setError(t);
+ app.displayError("System error modifying file:" + t.getMessage());
+ }
+
+ @Override
+ protected void onUnauthorized(Response response) {
+ app.sessionExpired();
+ }
+ };
+ updateFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());
+
+ String readPermHeader = Const.READ_EQ;
+ String writePermHeader = Const.WRITE_EQ;
+ for (String u : newPermissions.keySet()) {
+ Boolean[] p = newPermissions.get(u);
+ if (p[0] != null && p[0]) {
+ readPermHeader += u + Const.COMMA;
+ }
+ if (p[1] != null && p[1]) {
+ writePermHeader += u + Const.COMMA;
+ }
+ }
+ if (readPermHeader.endsWith(Const.EQ)) {
+ readPermHeader = "";
+ }
+ else if (readPermHeader.endsWith(Const.COMMA)) {
+ readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);
+ }
+ if (writePermHeader.endsWith(Const.EQ)) {
+ writePermHeader = "";
+ }
+ else if (writePermHeader.endsWith(Const.COMMA)) {
+ writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);
+ }
+ String permHeader = readPermHeader +
+ ((readPermHeader.length() > 0 && writePermHeader.length() > 0) ? Const.SEMI : "") + writePermHeader;
+ if (permHeader.length() == 0) {
+ permHeader=Const.TILDE;
+ }
+ else {
+ permHeader = URL.encodePathSegment(permHeader);
+ }
+ updateFile.setHeader(Const.X_OBJECT_SHARING, permHeader);
+ Scheduler.get().scheduleDeferred(updateFile);
+ }
+ else if (!app.isMySharedSelected()) {
+ app.updateFolder(file.getParent(), true, new Command() {
+ @Override
+ public void execute() {
+ if (file.isSharedOrPublished())
+ app.updateMySharedRoot();
+ }
+ }, true);
+ }
+ else {
+ app.updateSharedFolder(file.getParent(), true);
+ }
+ }
+ protected void updateMetaDataForPrivateSharing() {
+ updateMetaDataForPrivateSharing(
+ app.getApiPath(),
+ app.getUserID(),
+ file.getUri() + Const.QUESTION_MARK_UPDATE_EQ,
+ permList.getPermissions()
+ );
+ }
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent preview) {
+ super.onPreviewNativeEvent(preview);
+
+ NativeEvent evt = preview.getNativeEvent();
+ if (evt.getType().equals(Const.EVENT_TYPE_KEYDOWN) &&
+ evt.getKeyCode() == KeyCodes.KEY_ENTER) {
+
+ closeDialog();
+ }
+ }
+
+ @Override
+ protected boolean accept() {
+ return true;
+ }
+}
folderName.setText(folder.getName());\r
\r
VerticalPanel permPanel = new VerticalPanel();\r
- FilePermissionsDialog.Images images = GWT.create(FilePermissionsDialog.Images.class);\r
+ FileShareDialog.PrivateSharingImages images = GWT.create(FileShareDialog.PrivateSharingImages.class);\r
permList = new PermissionsList(app, images, folder.getPermissions(), folder.getOwnerID(), false, null);\r
permPanel.add(permList);\r
\r
*/
package gr.grnet.pithos.web.client;
-import gr.grnet.pithos.web.client.FilePermissionsDialog.Images;
-
import java.util.HashMap;
import java.util.Map;
Map<String, Boolean[]> permissions = null;
- final Images images;
+ final FileShareDialog.PrivateSharingImages images;
final VerticalPanel permPanel = new VerticalPanel();
private final Pithos app;
- public PermissionsList(Pithos app, final Images theImages, Map<String, Boolean[]> thePermissions, String theOwner, boolean inheritsPermissions, Command _changePermissionsCallback){
+ public PermissionsList(Pithos app, final FileShareDialog.PrivateSharingImages theImages, Map<String, Boolean[]> thePermissions, String theOwner, boolean inheritsPermissions, Command _changePermissionsCallback){
this.app = app;
changePermissionsCallback = _changePermissionsCallback;
images = theImages;
if (isFolderTreeSelected || isMysharedTreeSelected) {
if (files != null && files.size() == 1) {
contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.viewText()).getHTML() + " File properties</span>", true, new PropertiesCommand(app, this, files, PropertiesCommand.PROPERTIES)));
- contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.group()).getHTML() + " Sharing</span>", true, new PropertiesCommand(app, this, files, PropertiesCommand.PERMISSIONS)));
- contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.internet()).getHTML() + " Publish</span>", true, new PropertiesCommand(app, this, files, PropertiesCommand.PUBLISH)));
+ contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.group()).getHTML() + " Share</span>", true, new PropertiesCommand(app, this, files, PropertiesCommand.PERMISSIONS)));
contextMenu.addItem(new MenuItem("<span>" + AbstractImagePrototype.create(newImages.versions()).getHTML() + " Versions</span>", true, new PropertiesCommand(app, this, files, PropertiesCommand.VERSIONS)));
empty = false;
}
*/
package gr.grnet.pithos.web.client.commands;
-import gr.grnet.pithos.web.client.FilePermissionsDialog;
-import gr.grnet.pithos.web.client.FilePropertiesDialog;
-import gr.grnet.pithos.web.client.FilePublishDialog;
-import gr.grnet.pithos.web.client.FileVersionsDialog;
-import gr.grnet.pithos.web.client.FilesPropertiesDialog;
-import gr.grnet.pithos.web.client.FolderPermissionsDialog;
-import gr.grnet.pithos.web.client.FolderPropertiesDialog;
-import gr.grnet.pithos.web.client.Pithos;
+import gr.grnet.pithos.web.client.*;
+import gr.grnet.pithos.web.client.FileShareDialog;
import gr.grnet.pithos.web.client.foldertree.File;
import gr.grnet.pithos.web.client.foldertree.Folder;
if (containerPanel != null)
containerPanel.hide();
+ Pithos.LOG("PropertiesCommand::execute(), resource = ", resource);
if (resource instanceof Folder) {
final Folder folder = (Folder) resource;
switch (tabToShow) {
@Override
public void execute() {
- FilePermissionsDialog dlg = new FilePermissionsDialog(app, f);
+ FileShareDialog dlg = new FileShareDialog(app, f);
dlg.center();
}
});
FileVersionsDialog dlg2 = new FileVersionsDialog(app, files.get(0));
dlg2.center();
break;
- case PUBLISH:
- app.scheduleFileHeadCommand(f, new Command() {
-
- @Override
- public void execute() {
- FilePublishDialog dlg = new FilePublishDialog(app, f);
- dlg.center();
- }
- });
- break;
default:
break;
}