Merge branch 'develop' into debian-develop-wheezy
[pithos-web-client] / src / gr / grnet / pithos / web / client / FilePermissionsDialog.java
1 /*\r
2  * Copyright 2011-2013 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 com.google.gwt.core.client.GWT;\r
38 import com.google.gwt.core.client.Scheduler;\r
39 import com.google.gwt.dom.client.NativeEvent;\r
40 import com.google.gwt.event.dom.client.ClickEvent;\r
41 import com.google.gwt.event.dom.client.ClickHandler;\r
42 import com.google.gwt.event.dom.client.KeyCodes;\r
43 import com.google.gwt.http.client.Response;\r
44 import com.google.gwt.http.client.URL;\r
45 import com.google.gwt.http.client.UrlBuilder;\r
46 import com.google.gwt.resources.client.ImageResource;\r
47 import com.google.gwt.user.client.Command;\r
48 import com.google.gwt.user.client.Event.NativePreviewEvent;\r
49 import com.google.gwt.user.client.Window;\r
50 import com.google.gwt.user.client.ui.*;\r
51 import gr.grnet.pithos.web.client.foldertree.File;\r
52 import gr.grnet.pithos.web.client.rest.HeadRequest;\r
53 import gr.grnet.pithos.web.client.rest.PostRequest;\r
54 \r
55 import java.util.Map;\r
56 \r
57 /**\r
58  * The 'File properties' dialog box implementation.\r
59  *\r
60  */\r
61 public class FilePermissionsDialog extends AbstractPropertiesDialog {\r
62 \r
63         protected PermissionsList permList;\r
64 \r
65         private HorizontalPanel pathPanel;\r
66         \r
67         private TextBox path;\r
68         \r
69         /**\r
70          * An image bundle for this widgets images.\r
71          */\r
72         public interface Images extends MessagePanel.Images {\r
73 \r
74                 @Source("gr/grnet/pithos/resources/edit_user.png")\r
75                 ImageResource permUser();\r
76 \r
77                 @Source("gr/grnet/pithos/resources/groups22.png")\r
78                 ImageResource permGroup();\r
79 \r
80                 @Source("gr/grnet/pithos/resources/delete.gif")\r
81                 ImageResource delete();\r
82         }\r
83 \r
84         final File file;\r
85 \r
86     FileShareDialog.PrivateSharingImages images = GWT.create(FileShareDialog.PrivateSharingImages.class);\r
87 \r
88         /**\r
89          * The widget's constructor.\r
90          */\r
91         public FilePermissionsDialog(Pithos _app, File _file) {\r
92         super(_app);\r
93         file = _file;\r
94 \r
95                 Anchor close = new Anchor("close");\r
96                 close.addStyleName("close");\r
97                 close.addClickHandler(new ClickHandler() {\r
98                         \r
99                         @Override\r
100                         public void onClick(ClickEvent event) {\r
101                                 hide();\r
102                         }\r
103                 });\r
104                 // Set the dialog's caption.\r
105                 setText("File permissions");\r
106                 setGlassEnabled(true);\r
107                 setStyleName("pithos-DialogBox");\r
108 \r
109                 // Outer contains inner and buttons.\r
110                 final VerticalPanel outer = new VerticalPanel();\r
111                 outer.add(close);\r
112                 final FocusPanel focusPanel = new FocusPanel(outer);\r
113                 // Inner contains generalPanel and permPanel.\r
114                 inner = new VerticalPanel();\r
115                 inner.addStyleName("inner");\r
116 \r
117         inner.add(createSharingPanel());\r
118 \r
119         outer.add(inner);\r
120 \r
121                 final Button ok = new Button("OK", new ClickHandler() {\r
122                         @Override\r
123                         public void onClick(ClickEvent event) {\r
124                                 closeDialog();\r
125                         }\r
126                 });\r
127                 ok.addStyleName("button");\r
128 \r
129         outer.add(ok);\r
130         outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);\r
131 \r
132         focusPanel.setFocus(true);\r
133         setWidget(outer);\r
134         }\r
135 \r
136     private VerticalPanel createSharingPanel() {\r
137         VerticalPanel permPanel = new VerticalPanel();\r
138 \r
139         permList = new PermissionsList(app, images, file.getPermissions(), file.getOwnerID(), false, new Command() {\r
140                         \r
141                         @Override\r
142                         public void execute() {\r
143                                 accept();\r
144                         }\r
145                 });\r
146         permPanel.add(permList);\r
147 \r
148         HorizontalPanel permButtons = new HorizontalPanel();\r
149         final Button addUser = new Button("Add User", new ClickHandler() {\r
150             @Override\r
151             public void onClick(ClickEvent event) {\r
152                 PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true);\r
153                 dlg.center();\r
154                 permList.updatePermissionTable();\r
155             }\r
156         });\r
157         addUser.addStyleName("button");\r
158         permButtons.add(addUser);\r
159         permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
160 \r
161         Button add = new Button("Add Group", new ClickHandler() {\r
162             @Override\r
163             public void onClick(ClickEvent event) {\r
164                 if (app.getAccount().getGroups().isEmpty()) {\r
165                     new GroupCreateDialog(app, new Command() {\r
166                                                 \r
167                                                 @Override\r
168                                                 public void execute() {\r
169                                         if (app.getAccount().getGroups().isEmpty())\r
170                                                 return;\r
171                                         PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);\r
172                                         dlg.center();\r
173                                         permList.updatePermissionTable();\r
174                                                 }\r
175                                         }).center();\r
176                 }\r
177                 else {\r
178                         PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);\r
179                         dlg.center();\r
180                         permList.updatePermissionTable();\r
181                 }\r
182             }\r
183         });\r
184         add.addStyleName("button");\r
185         permButtons.add(add);\r
186         permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
187 \r
188         permButtons.setSpacing(8);\r
189         permButtons.addStyleName("pithos-TabPanelBottom");\r
190         permPanel.add(permButtons);\r
191 \r
192         final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
193                     " by everyone. By checking this option, you are certifying that you have the right to " +\r
194                     "distribute this file and that it does not violate the Terms of Use.", true);\r
195         readForAllNote.setStylePrimaryName("pithos-readForAllNote");\r
196 \r
197         pathPanel = new HorizontalPanel();\r
198         pathPanel.setVisible(false);\r
199         pathPanel.setWidth(Const.PERCENT_100);\r
200         pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
201         pathPanel.add(new Label("Link"));\r
202         pathPanel.setSpacing(8);\r
203         pathPanel.addStyleName("pithos-TabPanelBottom");\r
204 \r
205         path = new TextBox();\r
206         path.setWidth(Const.PERCENT_100);\r
207         path.addClickHandler(new ClickHandler() {\r
208             @Override\r
209             public void onClick(ClickEvent event) {\r
210                 Pithos.enableIESelection();\r
211                 ((TextBox) event.getSource()).selectAll();\r
212                 Pithos.preventIESelection();\r
213             }\r
214         });\r
215         path.setText(Window.Location.getHost() + file.getPublicUri());\r
216         path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
217         path.setWidth(Const.PERCENT_100);\r
218         path.setReadOnly(true);\r
219         pathPanel.add(path);\r
220         permPanel.add(pathPanel);\r
221 \r
222         Scheduler.get().scheduleDeferred(new Command() {\r
223                         \r
224                         @Override\r
225                         public void execute() {\r
226                                 showLinkIfShared();\r
227                         }\r
228                 });\r
229         return permPanel;\r
230     }\r
231 \r
232     void showLinkIfShared() {\r
233                 if (file.isShared()) {\r
234                         UrlBuilder b = Window.Location.createUrlBuilder();\r
235                         b.setPath(Pithos.getStorageAPIURL() + file.getOwnerID() + file.getUri());\r
236                         path.setText(b.buildString());\r
237                 pathPanel.setVisible(true);\r
238                 }\r
239                 else {\r
240                         pathPanel.setVisible(false);\r
241                 }\r
242     }\r
243         /**\r
244          * Accepts any change and updates the file\r
245          *\r
246          */\r
247         @Override\r
248         protected boolean accept() {\r
249         updateMetaData(\r
250             Pithos.getStorageAPIURL(),\r
251             app.getUserID(),\r
252             file.getUri() + Const.QUESTION_MARK_UPDATE_EQ,\r
253             permList.getPermissions()\r
254         );\r
255         return true;\r
256         }\r
257 \r
258         protected void updateMetaData(String api, String owner, final String path, final Map<String, Boolean[]> newPermissions) {\r
259         if (newPermissions != null) {\r
260             PostRequest updateFile = new PostRequest(api, owner, path) {\r
261                 @Override\r
262                 public void onSuccess(Resource result) {\r
263                         HeadRequest<File> headFile = new HeadRequest<File>(File.class, Pithos.getStorageAPIURL(), file.getOwnerID(), path, file) {\r
264 \r
265                                                 @Override\r
266                                                 public void onSuccess(File _result) {\r
267                                                         showLinkIfShared();\r
268                                                         if (!app.isMySharedSelected())\r
269                                             app.updateFolder(file.getParent(), true, new Command() {\r
270                                                                         \r
271                                                                         @Override\r
272                                                                         public void execute() {\r
273                                                                                 app.updateMySharedRoot();\r
274                                                                         }\r
275                                                                 }, true);\r
276                                                         else\r
277                                                                 app.updateSharedFolder(file.getParent(), true);\r
278                                                 }\r
279 \r
280                                                 @Override\r
281                                                 public void onError(Throwable t) {\r
282                                                         app.setError(t);\r
283                                     app.displayError("System error modifying file:" + t.getMessage());\r
284                                                 }\r
285 \r
286                                                 @Override\r
287                                                 protected void onUnauthorized(Response response) {\r
288                                                         app.sessionExpired();\r
289                                                 }\r
290                                         };\r
291                                         headFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());\r
292                                         Scheduler.get().scheduleDeferred(headFile);\r
293                 }\r
294 \r
295                 @Override\r
296                 public void onError(Throwable t) {\r
297                                         app.setError(t);\r
298                     app.displayError("System error modifying file:" + t.getMessage());\r
299                 }\r
300 \r
301                                 @Override\r
302                                 protected void onUnauthorized(Response response) {\r
303                                         app.sessionExpired();\r
304                                 }\r
305             };\r
306             updateFile.setHeader(Const.X_AUTH_TOKEN, app.getUserToken());\r
307             \r
308             String readPermHeader = Const.READ_EQ;\r
309             String writePermHeader = Const.WRITE_EQ;\r
310             for (String u : newPermissions.keySet()) {\r
311                 Boolean[] p = newPermissions.get(u);\r
312                 if (p[0] != null && p[0]) {\r
313                     readPermHeader += u + Const.COMMA;\r
314                 }\r
315                 if (p[1] != null && p[1]) {\r
316                     writePermHeader += u + Const.COMMA;\r
317                 }\r
318             }\r
319             if (readPermHeader.endsWith(Const.EQ)) {\r
320                 readPermHeader = "";\r
321             }\r
322             else if (readPermHeader.endsWith(Const.COMMA)) {\r
323                 readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);\r
324             }\r
325             if (writePermHeader.endsWith(Const.EQ)) {\r
326                 writePermHeader = "";\r
327             }\r
328             else if (writePermHeader.endsWith(Const.COMMA)) {\r
329                 writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);\r
330             }\r
331             String permHeader = readPermHeader +\r
332                 ((readPermHeader.length()  > 0 && writePermHeader.length() > 0) ?  Const.SEMI : "") + writePermHeader;\r
333             if (permHeader.length() == 0) {\r
334                 permHeader=Const.TILDE;\r
335             }\r
336             else {\r
337                 permHeader = URL.encodePathSegment(permHeader);\r
338             }\r
339             updateFile.setHeader(Const.X_OBJECT_SHARING, permHeader);\r
340             Scheduler.get().scheduleDeferred(updateFile);\r
341         }\r
342         else if (!app.isMySharedSelected()) {\r
343             app.updateFolder(file.getParent(), true, new Command() {\r
344                                 @Override\r
345                                 public void execute() {\r
346                                         if (file.isSharedOrPublished())\r
347                                                 app.updateMySharedRoot();\r
348                                 }\r
349                         }, true);\r
350         }\r
351         else {\r
352                 app.updateSharedFolder(file.getParent(), true);\r
353         }\r
354     }\r
355 \r
356         @Override\r
357         protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
358             super.onPreviewNativeEvent(preview);\r
359 \r
360             NativeEvent evt = preview.getNativeEvent();\r
361             if (evt.getType().equals(Const.EVENT_TYPE_KEYDOWN) &&\r
362             evt.getKeyCode() == KeyCodes.KEY_ENTER) {\r
363 \r
364             closeDialog();\r
365         }\r
366         }\r
367 }\r