Implement the /user_catalogs API
[pithos-web-client] / src / gr / grnet / pithos / web / client / FilePublishDialog.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 com.google.gwt.core.client.GWT;\r
42 import com.google.gwt.core.client.Scheduler;\r
43 import com.google.gwt.dom.client.NativeEvent;\r
44 import com.google.gwt.event.dom.client.ClickEvent;\r
45 import com.google.gwt.event.dom.client.ClickHandler;\r
46 import com.google.gwt.event.dom.client.KeyCodes;\r
47 import com.google.gwt.http.client.Response;\r
48 import com.google.gwt.http.client.UrlBuilder;\r
49 import com.google.gwt.resources.client.ImageResource;\r
50 import com.google.gwt.user.client.Command;\r
51 import com.google.gwt.user.client.Window;\r
52 import com.google.gwt.user.client.Event.NativePreviewEvent;\r
53 import com.google.gwt.user.client.ui.Anchor;\r
54 import com.google.gwt.user.client.ui.Button;\r
55 import com.google.gwt.user.client.ui.CheckBox;\r
56 import com.google.gwt.user.client.ui.FocusPanel;\r
57 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
58 import com.google.gwt.user.client.ui.HorizontalPanel;\r
59 import com.google.gwt.user.client.ui.Label;\r
60 import com.google.gwt.user.client.ui.TextBox;\r
61 import com.google.gwt.user.client.ui.VerticalPanel;\r
62 \r
63 /**\r
64  * The 'File properties' dialog box implementation.\r
65  *\r
66  */\r
67 public class FilePublishDialog extends AbstractPropertiesDialog {\r
68 \r
69         protected CheckBox readForAll;\r
70         \r
71         private HorizontalPanel pathPanel;\r
72         \r
73         private TextBox path;\r
74         \r
75         /**\r
76          * An image bundle for this widgets images.\r
77          */\r
78         public interface Images extends MessagePanel.Images {\r
79 \r
80                 @Source("gr/grnet/pithos/resources/edit_user.png")\r
81                 ImageResource permUser();\r
82 \r
83                 @Source("gr/grnet/pithos/resources/groups22.png")\r
84                 ImageResource permGroup();\r
85 \r
86                 @Source("gr/grnet/pithos/resources/editdelete.png")\r
87                 ImageResource delete();\r
88         }\r
89 \r
90         final File file;\r
91 \r
92     Images images = GWT.create(Images.class);\r
93 \r
94         /**\r
95          * The widget's constructor.\r
96          */\r
97         public FilePublishDialog(Pithos _app, File _file) {\r
98         super(_app);\r
99         file = _file;\r
100 \r
101                 Anchor close = new Anchor("close");\r
102                 close.addStyleName("close");\r
103                 close.addClickHandler(new ClickHandler() {\r
104                         \r
105                         @Override\r
106                         public void onClick(ClickEvent event) {\r
107                                 hide();\r
108                         }\r
109                 });\r
110                 // Set the dialog's caption.\r
111                 setText("Publish/Un-publish");\r
112                 setGlassEnabled(true);\r
113                 setStyleName("pithos-DialogBox");\r
114 \r
115                 // Outer contains inner and buttons.\r
116                 final VerticalPanel outer = new VerticalPanel();\r
117                 outer.add(close);\r
118                 final FocusPanel focusPanel = new FocusPanel(outer);\r
119                 // Inner contains generalPanel and permPanel.\r
120                 inner = new VerticalPanel();\r
121                 inner.addStyleName("inner");\r
122 \r
123         inner.add(createSharingPanel());\r
124 \r
125         outer.add(inner);\r
126 \r
127                 final Button ok = new Button("OK", new ClickHandler() {\r
128                         @Override\r
129                         public void onClick(ClickEvent event) {\r
130                                 closeDialog();\r
131                         }\r
132                 });\r
133                 ok.addStyleName("button");\r
134 \r
135         outer.add(ok);\r
136         outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);\r
137 \r
138         focusPanel.setFocus(true);\r
139         setWidget(outer);\r
140         }\r
141 \r
142     private VerticalPanel createSharingPanel() {\r
143         VerticalPanel permPanel = new VerticalPanel();\r
144 \r
145         final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
146                     " by everyone. By checking this option, you are certifying that you have the right to " +\r
147                     "distribute this file and that it does not violate the Terms of Use.", true);\r
148         readForAllNote.setStylePrimaryName("pithos-readForAllNote");\r
149 \r
150         readForAll = new CheckBox();\r
151         readForAll.setValue(file.isPublished());\r
152         readForAll.addClickHandler(new ClickHandler() {\r
153             @Override\r
154             public void onClick(ClickEvent event) {\r
155                 accept();\r
156             }\r
157         });\r
158 \r
159         // Only show the read for all permission if the user is the owner.\r
160         if (file.getOwner().equals(app.getUserID())) {\r
161             final HorizontalPanel permForAll = new HorizontalPanel();\r
162             permForAll.add(new Label("Public"));\r
163             permForAll.add(readForAll);\r
164             permForAll.setSpacing(8);\r
165             permForAll.addStyleName("pithos-TabPanelBottom");\r
166             permForAll.add(readForAllNote);\r
167             permPanel.add(permForAll);\r
168         }\r
169 \r
170         pathPanel = new HorizontalPanel();\r
171         pathPanel.setVisible(false);\r
172         pathPanel.setWidth("100%");\r
173         pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
174         pathPanel.add(new Label("Link"));\r
175         pathPanel.setSpacing(8);\r
176         pathPanel.addStyleName("pithos-TabPanelBottom");\r
177 \r
178         path = new TextBox();\r
179         path.setWidth("100%");\r
180         path.addClickHandler(new ClickHandler() {\r
181             @Override\r
182             public void onClick(ClickEvent event) {\r
183                 Pithos.enableIESelection();\r
184                 ((TextBox) event.getSource()).selectAll();\r
185                 Pithos.preventIESelection();\r
186             }\r
187         });\r
188         path.setText(Window.Location.getHost() + file.getPublicUri());\r
189         path.setTitle("Use this link for sharing the file via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");\r
190         path.setWidth("100%");\r
191         path.setReadOnly(true);\r
192         pathPanel.add(path);\r
193         permPanel.add(pathPanel);\r
194 \r
195         Scheduler.get().scheduleDeferred(new Command() {\r
196                         \r
197                         @Override\r
198                         public void execute() {\r
199                                 showLinkIfPublished();\r
200                         }\r
201                 });\r
202         return permPanel;\r
203     }\r
204 \r
205     void showLinkIfPublished() {\r
206                 if (file.isPublished()) {\r
207                         UrlBuilder b = Window.Location.createUrlBuilder();\r
208                         b.setPath(file.getPublicUri());\r
209                         path.setText(b.buildString());\r
210                 pathPanel.setVisible(true);\r
211                 }\r
212                 else {\r
213                         pathPanel.setVisible(false);\r
214                 }\r
215     }\r
216         /**\r
217          * Accepts any change and updates the file\r
218          * @return \r
219          *\r
220          */\r
221         @Override\r
222         protected boolean accept() {\r
223         Boolean published = null;\r
224                 if (readForAll.getValue() != file.isPublished())\r
225                         if (file.getOwner().equals(app.getUserID()))\r
226                 published = readForAll.getValue();\r
227         updateMetaData(app.getApiPath(), app.getUserID(), file.getUri() + "?update=", published);\r
228         return true;\r
229         }\r
230 \r
231         protected void updateMetaData(String api, String owner, final String path, final Boolean published) {\r
232         if (published != null) {\r
233             PostRequest updateFile = new PostRequest(api, owner, path) {\r
234                 @Override\r
235                 public void onSuccess(Resource result) {\r
236                         HeadRequest<File> headFile = new HeadRequest<File>(File.class, app.getApiPath(), file.getOwner(), path, file) {\r
237 \r
238                                                 @Override\r
239                                                 public void onSuccess(File _result) {\r
240                                                         showLinkIfPublished();\r
241                                                         if (!app.isMySharedSelected())\r
242                                             app.updateFolder(file.getParent(), true, new Command() {\r
243                                                                         \r
244                                                                         @Override\r
245                                                                         public void execute() {\r
246                                                                                 app.updateMySharedRoot();\r
247                                                                         }\r
248                                                                 }, true);\r
249                                                         else\r
250                                                                 app.updateSharedFolder(file.getParent(), true);\r
251                                                 }\r
252 \r
253                                                 @Override\r
254                                                 public void onError(Throwable t) {\r
255                                     GWT.log("", t);\r
256                                                         app.setError(t);\r
257                                     app.displayError("System error modifying file:" + t.getMessage());\r
258                                                 }\r
259 \r
260                                                 @Override\r
261                                                 protected void onUnauthorized(Response response) {\r
262                                                         app.sessionExpired();\r
263                                                 }\r
264                                         };\r
265                                         headFile.setHeader("X-Auth-Token", app.getUserToken());\r
266                                         Scheduler.get().scheduleDeferred(headFile);\r
267                 }\r
268 \r
269                 @Override\r
270                 public void onError(Throwable t) {\r
271                     GWT.log("", t);\r
272                                         app.setError(t);\r
273                     app.displayError("System error modifying file:" + t.getMessage());\r
274                 }\r
275 \r
276                                 @Override\r
277                                 protected void onUnauthorized(Response response) {\r
278                                         app.sessionExpired();\r
279                                 }\r
280             };\r
281             updateFile.setHeader("X-Auth-Token", app.getUserToken());\r
282             updateFile.setHeader("X-Object-Public", published.toString());\r
283             Scheduler.get().scheduleDeferred(updateFile);\r
284         }\r
285         else if (!app.isMySharedSelected())\r
286             app.updateFolder(file.getParent(), true, new Command() {\r
287                                 \r
288                                 @Override\r
289                                 public void execute() {\r
290                                         if (file.isSharedOrPublished())\r
291                                                 app.updateMySharedRoot();\r
292                                 }\r
293                         }, true);\r
294         else\r
295                 app.updateSharedFolder(file.getParent(), true);\r
296     }\r
297 \r
298         @Override\r
299         protected void onPreviewNativeEvent(NativePreviewEvent preview) {\r
300             super.onPreviewNativeEvent(preview);\r
301 \r
302             NativeEvent evt = preview.getNativeEvent();\r
303             if (evt.getType().equals("keydown") && evt.getKeyCode() == KeyCodes.KEY_ENTER)\r
304                                 closeDialog();\r
305         }\r
306 }\r