Show display name in FilePropertiesDialog
[pithos-web-client] / src / gr / grnet / pithos / web / client / FilePermissionsDialog.java
1 /*\r
2  * Copyright 2011-2012 GRNET S.A. All rights reserved.\r
3  *\r
4  * Redistribution and use in source and binary forms, with or\r
5  * without modification, are permitted provided that the following\r
6  * conditions are met:\r
7  *\r
8  *   1. Redistributions of source code must retain the above\r
9  *      copyright notice, this list of conditions and the following\r
10  *      disclaimer.\r
11  *\r
12  *   2. Redistributions in binary form must reproduce the above\r
13  *      copyright notice, this list of conditions and the following\r
14  *      disclaimer in the documentation and/or other materials\r
15  *      provided with the distribution.\r
16  *\r
17  * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS\r
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
20  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR\r
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
24  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED\r
25  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  *\r
30  * The views and conclusions contained in the software and\r
31  * documentation are those of the authors and should not be\r
32  * interpreted as representing official policies, either expressed\r
33  * or implied, of GRNET S.A.\r
34  */\r
35 package gr.grnet.pithos.web.client;\r
36 \r
37 import gr.grnet.pithos.web.client.foldertree.File;\r
38 import gr.grnet.pithos.web.client.rest.HeadRequest;\r
39 import gr.grnet.pithos.web.client.rest.PostRequest;\r
40 \r
41 import java.util.Map;\r
42 \r
43 import com.google.gwt.core.client.GWT;\r
44 import com.google.gwt.core.client.Scheduler;\r
45 import com.google.gwt.dom.client.NativeEvent;\r
46 import com.google.gwt.event.dom.client.ClickEvent;\r
47 import com.google.gwt.event.dom.client.ClickHandler;\r
48 import com.google.gwt.event.dom.client.KeyCodes;\r
49 import com.google.gwt.http.client.Response;\r
50 import com.google.gwt.http.client.URL;\r
51 import com.google.gwt.http.client.UrlBuilder;\r
52 import com.google.gwt.resources.client.ImageResource;\r
53 import com.google.gwt.user.client.Command;\r
54 import com.google.gwt.user.client.Window;\r
55 import com.google.gwt.user.client.Event.NativePreviewEvent;\r
56 import com.google.gwt.user.client.ui.Anchor;\r
57 import com.google.gwt.user.client.ui.Button;\r
58 import com.google.gwt.user.client.ui.FocusPanel;\r
59 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
60 import com.google.gwt.user.client.ui.HorizontalPanel;\r
61 import com.google.gwt.user.client.ui.Label;\r
62 import com.google.gwt.user.client.ui.TextBox;\r
63 import com.google.gwt.user.client.ui.VerticalPanel;\r
64 \r
65 /**\r
66  * The 'File properties' dialog box implementation.\r
67  *\r
68  */\r
69 public class FilePermissionsDialog extends AbstractPropertiesDialog {\r
70 \r
71         protected PermissionsList permList;\r
72 \r
73         private HorizontalPanel pathPanel;\r
74         \r
75         private TextBox path;\r
76         \r
77         /**\r
78          * An image bundle for this widgets images.\r
79          */\r
80         public interface Images extends MessagePanel.Images {\r
81 \r
82                 @Source("gr/grnet/pithos/resources/edit_user.png")\r
83                 ImageResource permUser();\r
84 \r
85                 @Source("gr/grnet/pithos/resources/groups22.png")\r
86                 ImageResource permGroup();\r
87 \r
88                 @Source("gr/grnet/pithos/resources/delete.gif")\r
89                 ImageResource delete();\r
90         }\r
91 \r
92         final File file;\r
93 \r
94     Images images = GWT.create(Images.class);\r
95 \r
96         /**\r
97          * The widget's constructor.\r
98          */\r
99         public FilePermissionsDialog(Pithos _app, File _file) {\r
100         super(_app);\r
101         file = _file;\r
102 \r
103                 Anchor close = new Anchor("close");\r
104                 close.addStyleName("close");\r
105                 close.addClickHandler(new ClickHandler() {\r
106                         \r
107                         @Override\r
108                         public void onClick(ClickEvent event) {\r
109                                 hide();\r
110                         }\r
111                 });\r
112                 // Set the dialog's caption.\r
113                 setText("File permissions");\r
114                 setGlassEnabled(true);\r
115                 setStyleName("pithos-DialogBox");\r
116 \r
117                 // Outer contains inner and buttons.\r
118                 final VerticalPanel outer = new VerticalPanel();\r
119                 outer.add(close);\r
120                 final FocusPanel focusPanel = new FocusPanel(outer);\r
121                 // Inner contains generalPanel and permPanel.\r
122                 inner = new VerticalPanel();\r
123                 inner.addStyleName("inner");\r
124 \r
125         inner.add(createSharingPanel());\r
126 \r
127         outer.add(inner);\r
128 \r
129                 final Button ok = new Button("OK", new ClickHandler() {\r
130                         @Override\r
131                         public void onClick(ClickEvent event) {\r
132                                 closeDialog();\r
133                         }\r
134                 });\r
135                 ok.addStyleName("button");\r
136 \r
137         outer.add(ok);\r
138         outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);\r
139 \r
140         focusPanel.setFocus(true);\r
141         setWidget(outer);\r
142         }\r
143 \r
144     private VerticalPanel createSharingPanel() {\r
145         VerticalPanel permPanel = new VerticalPanel();\r
146 \r
147         permList = new PermissionsList(images, file.getPermissions(), file.getOwnerID(), false, new Command() {\r
148                         \r
149                         @Override\r
150                         public void execute() {\r
151                                 accept();\r
152                         }\r
153                 });\r
154         permPanel.add(permList);\r
155 \r
156         HorizontalPanel permButtons = new HorizontalPanel();\r
157         final Button addUser = new Button("Add User", new ClickHandler() {\r
158             @Override\r
159             public void onClick(ClickEvent event) {\r
160                 PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true);\r
161                 dlg.center();\r
162                 permList.updatePermissionTable();\r
163             }\r
164         });\r
165         addUser.addStyleName("button");\r
166         permButtons.add(addUser);\r
167         permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
168 \r
169         Button add = new Button("Add Group", new ClickHandler() {\r
170             @Override\r
171             public void onClick(ClickEvent event) {\r
172                 if (app.getAccount().getGroups().isEmpty()) {\r
173                     new GroupCreateDialog(app, new Command() {\r
174                                                 \r
175                                                 @Override\r
176                                                 public void execute() {\r
177                                         if (app.getAccount().getGroups().isEmpty())\r
178                                                 return;\r
179                                         PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);\r
180                                         dlg.center();\r
181                                         permList.updatePermissionTable();\r
182                                                 }\r
183                                         }).center();\r
184                 }\r
185                 else {\r
186                         PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);\r
187                         dlg.center();\r
188                         permList.updatePermissionTable();\r
189                 }\r
190             }\r
191         });\r
192         add.addStyleName("button");\r
193         permButtons.add(add);\r
194         permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
195 \r
196         permButtons.setSpacing(8);\r
197         permButtons.addStyleName("pithos-TabPanelBottom");\r
198         permPanel.add(permButtons);\r
199 \r
200         final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
201                     " by everyone. By checking this option, you are certifying that you have the right to " +\r
202                     "distribute this file and that it does not violate the Terms of Use.", true);\r
203         readForAllNote.setStylePrimaryName("pithos-readForAllNote");\r
204 \r
205         pathPanel = new HorizontalPanel();\r
206         pathPanel.setVisible(false);\r
207         pathPanel.setWidth("100%");\r
208         pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
209         pathPanel.add(new Label("Link"));\r
210         pathPanel.setSpacing(8);\r
211         pathPanel.addStyleName("pithos-TabPanelBottom");\r
212 \r
213         path = new TextBox();\r
214         path.setWidth("100%");\r
215         path.addClickHandler(new ClickHandler() {\r
216             @Override\r
217             public void onClick(ClickEvent event) {\r
218                 Pithos.enableIESelection();\r
219                 ((TextBox) event.getSource()).selectAll();\r
220                 Pithos.preventIESelection();\r
221             }\r
222         });\r
223         path.setText(Window.Location.getHost() + file.getPublicUri());\r
224         path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
225         path.setWidth("100%");\r
226         path.setReadOnly(true);\r
227         pathPanel.add(path);\r
228         permPanel.add(pathPanel);\r
229 \r
230         Scheduler.get().scheduleDeferred(new Command() {\r
231                         \r
232                         @Override\r
233                         public void execute() {\r
234                                 showLinkIfShared();\r
235                         }\r
236                 });\r
237         return permPanel;\r
238     }\r
239 \r
240     void showLinkIfShared() {\r
241                 if (file.isShared()) {\r
242                         UrlBuilder b = Window.Location.createUrlBuilder();\r
243                         b.setPath(app.getApiPath() + file.getOwnerID() + file.getUri());\r
244                         String href = Window.Location.getHref();\r
245                         boolean hasParameters = href.contains("?");\r
246                         path.setText(href + (hasParameters ? "&" : "?") + "goto=" + b.buildString());\r
247                 pathPanel.setVisible(true);\r
248                 }\r
249                 else {\r
250                         pathPanel.setVisible(false);\r
251                 }\r
252     }\r
253         /**\r
254          * Accepts any change and updates the file\r
255          *\r
256          */\r
257         @Override\r
258         protected boolean accept() {\r
259         updateMetaData(app.getApiPath(), app.getUserID(), file.getUri() + "?update=", permList.getPermissions());\r
260         return true;\r
261         }\r
262 \r
263         protected void updateMetaData(String api, String owner, final String path, final Map<String, Boolean[]> newPermissions) {\r
264         if (newPermissions != null) {\r
265             PostRequest updateFile = new PostRequest(api, owner, path) {\r
266                 @Override\r
267                 public void onSuccess(Resource result) {\r
268                         HeadRequest<File> headFile = new HeadRequest<File>(File.class, app.getApiPath(), file.getOwnerID(), path, file) {\r
269 \r
270                                                 @Override\r
271                                                 public void onSuccess(File _result) {\r
272                                                         showLinkIfShared();\r
273                                                         if (!app.isMySharedSelected())\r
274                                             app.updateFolder(file.getParent(), true, new Command() {\r
275                                                                         \r
276                                                                         @Override\r
277                                                                         public void execute() {\r
278                                                                                 app.updateMySharedRoot();\r
279                                                                         }\r
280                                                                 }, true);\r
281                                                         else\r
282                                                                 app.updateSharedFolder(file.getParent(), true);\r
283                                                 }\r
284 \r
285                                                 @Override\r
286                                                 public void onError(Throwable t) {\r
287                                     GWT.log("", t);\r
288                                                         app.setError(t);\r
289                                     app.displayError("System error modifying file:" + t.getMessage());\r
290                                                 }\r
291 \r
292                                                 @Override\r
293                                                 protected void onUnauthorized(Response response) {\r
294                                                         app.sessionExpired();\r
295                                                 }\r
296                                         };\r
297                                         headFile.setHeader("X-Auth-Token", app.getUserToken());\r
298                                         Scheduler.get().scheduleDeferred(headFile);\r
299                 }\r
300 \r
301                 @Override\r
302                 public void onError(Throwable t) {\r
303                     GWT.log("", t);\r
304                                         app.setError(t);\r
305                     app.displayError("System error modifying file:" + t.getMessage());\r
306                 }\r
307 \r
308                                 @Override\r
309                                 protected void onUnauthorized(Response response) {\r
310                                         app.sessionExpired();\r
311                                 }\r
312             };\r
313             updateFile.setHeader("X-Auth-Token", app.getUserToken());\r
314             \r
315             String readPermHeader = "read=";\r
316             String writePermHeader = "write=";\r
317             for (String u : newPermissions.keySet()) {\r
318                 Boolean[] p = newPermissions.get(u);\r
319                 if (p[0] != null && p[0])\r
320                     readPermHeader += u + ",";\r
321                 if (p[1] != null && p[1])\r
322                     writePermHeader += u + ",";\r
323             }\r
324             if (readPermHeader.endsWith("="))\r
325                 readPermHeader = "";\r
326             else if (readPermHeader.endsWith(","))\r
327                 readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);\r
328             if (writePermHeader.endsWith("="))\r
329                 writePermHeader = "";\r
330             else if (writePermHeader.endsWith(","))\r
331                 writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);\r
332             String permHeader = readPermHeader +  ((readPermHeader.length()  > 0 && writePermHeader.length() > 0) ?  ";" : "") + writePermHeader;\r
333             if (permHeader.length() == 0)\r
334                 permHeader="~";\r
335             else\r
336                 permHeader = URL.encodePathSegment(permHeader);\r
337             updateFile.setHeader("X-Object-Sharing", permHeader);\r
338             Scheduler.get().scheduleDeferred(updateFile);\r
339         }\r
340         else if (!app.isMySharedSelected())\r
341             app.updateFolder(file.getParent(), true, new Command() {\r
342                                 \r
343                                 @Override\r
344                                 public void execute() {\r
345                                         if (file.isSharedOrPublished())\r
346                                                 app.updateMySharedRoot();\r
347                                 }\r
348                         }, true);\r
349         else\r
350                 app.updateSharedFolder(file.getParent(), true);\r
351     }\r
352 \r
353         @Override\r
354         protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
355             super.onPreviewNativeEvent(preview);\r
356 \r
357             NativeEvent evt = preview.getNativeEvent();\r
358             if (evt.getType().equals("keydown") && evt.getKeyCode() == KeyCodes.KEY_ENTER)\r
359                                 closeDialog();\r
360         }\r
361 }\r