early commit - first attemp, regarding giving a uri and fetching the proper directory
[pithos] / src / gr / ebs / gss / client / FilePropertiesDialog.java
1 /*\r
2  * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.\r
3  *\r
4  * This file is part of GSS.\r
5  *\r
6  * GSS is free software: you can redistribute it and/or modify\r
7  * it under the terms of the GNU General Public License as published by\r
8  * the Free Software Foundation, either version 3 of the License, or\r
9  * (at your option) any later version.\r
10  *\r
11  * GSS is distributed in the hope that it will be useful,\r
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14  * GNU General Public License for more details.\r
15  *\r
16  * You should have received a copy of the GNU General Public License\r
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.\r
18  */\r
19 package gr.ebs.gss.client;\r
20 \r
21 import gr.ebs.gss.client.rest.PostCommand;\r
22 import gr.ebs.gss.client.rest.RestException;\r
23 import gr.ebs.gss.client.rest.resource.FileResource;\r
24 import gr.ebs.gss.client.rest.resource.GroupResource;\r
25 import gr.ebs.gss.client.rest.resource.PermissionHolder;\r
26 \r
27 import java.util.Iterator;\r
28 import java.util.List;\r
29 import java.util.Set;\r
30 \r
31 import com.google.gwt.core.client.GWT;\r
32 import com.google.gwt.event.dom.client.ClickEvent;\r
33 import com.google.gwt.event.dom.client.ClickHandler;\r
34 import com.google.gwt.i18n.client.DateTimeFormat;\r
35 import com.google.gwt.json.client.JSONArray;\r
36 import com.google.gwt.json.client.JSONBoolean;\r
37 import com.google.gwt.json.client.JSONObject;\r
38 import com.google.gwt.json.client.JSONString;\r
39 import com.google.gwt.resources.client.ClientBundle;\r
40 import com.google.gwt.resources.client.ImageResource;\r
41 import com.google.gwt.user.client.Command;\r
42 import com.google.gwt.user.client.DeferredCommand;\r
43 import com.google.gwt.user.client.ui.AbstractImagePrototype;\r
44 import com.google.gwt.user.client.ui.Button;\r
45 import com.google.gwt.user.client.ui.CheckBox;\r
46 import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
47 import com.google.gwt.user.client.ui.DisclosurePanel;\r
48 import com.google.gwt.user.client.ui.FlexTable;\r
49 import com.google.gwt.user.client.ui.FlowPanel;\r
50 import com.google.gwt.user.client.ui.FocusPanel;\r
51 import com.google.gwt.user.client.ui.HTML;\r
52 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
53 import com.google.gwt.user.client.ui.HorizontalPanel;\r
54 import com.google.gwt.user.client.ui.Label;\r
55 import com.google.gwt.user.client.ui.TextBox;\r
56 import com.google.gwt.user.client.ui.VerticalPanel;\r
57 \r
58 /**\r
59  * The 'File properties' dialog box implementation.\r
60  *\r
61  * @author past\r
62  */\r
63 public class FilePropertiesDialog extends AbstractPropertiesDialog {\r
64 \r
65         final PermissionsList permList;\r
66 \r
67         private CheckBox readForAll;\r
68 \r
69         /**\r
70          * An image bundle for this widgets images.\r
71          */\r
72         public interface Images extends ClientBundle,MessagePanel.Images {\r
73 \r
74                 @Source("gr/ebs/gss/resources/edit_user.png")\r
75                 ImageResource permUser();\r
76 \r
77                 @Source("gr/ebs/gss/resources/groupevent.png")\r
78                 ImageResource permGroup();\r
79 \r
80                 @Source("gr/ebs/gss/resources/editdelete.png")\r
81                 ImageResource delete();\r
82 \r
83                 @Source("gr/ebs/gss/resources/db_update.png")\r
84                 ImageResource restore();\r
85 \r
86                 @Source("gr/ebs/gss/resources/folder_inbox.png")\r
87                 ImageResource download();\r
88         }\r
89 \r
90         /**\r
91          * The widget that holds the name of the file.\r
92          */\r
93         private TextBox name = new TextBox();\r
94 \r
95         private final CheckBox versioned = new CheckBox();\r
96 \r
97         final FileResource file;\r
98 \r
99         /**\r
100          * The widget's constructor.\r
101          *\r
102          * @param images the dialog's ImageBundle\r
103          * @param groups\r
104          * @param bodies\r
105          */\r
106         public FilePropertiesDialog(final Images images, final List<GroupResource> groups, List<FileResource> bodies) {\r
107 \r
108                 // Set the dialog's caption.\r
109                 setText("File properties");\r
110 \r
111                 file = (FileResource) GSS.get().getCurrentSelection();\r
112                 permList = new PermissionsList(images, file.getPermissions(), file.getOwner());\r
113 \r
114                 // Outer contains inner and buttons.\r
115                 final VerticalPanel outer = new VerticalPanel();\r
116                 final FocusPanel focusPanel = new FocusPanel(outer);\r
117                 // Inner contains generalPanel and permPanel.\r
118                 inner = new DecoratedTabPanel();\r
119                 inner.setAnimationEnabled(true);\r
120                 final VerticalPanel generalPanel = new VerticalPanel();\r
121                 final VerticalPanel permPanel = new VerticalPanel();\r
122                 final HorizontalPanel buttons = new HorizontalPanel();\r
123                 final HorizontalPanel permButtons = new HorizontalPanel();\r
124                 final HorizontalPanel permForAll = new HorizontalPanel();\r
125                 final HorizontalPanel pathPanel = new HorizontalPanel();\r
126                 final VerticalPanel verPanel = new VerticalPanel();\r
127                 final HorizontalPanel vPanel = new HorizontalPanel();\r
128                 final HorizontalPanel vPanel2 = new HorizontalPanel();\r
129 \r
130                 versioned.setValue(file.isVersioned());\r
131                 inner.add(generalPanel, "General");\r
132                 inner.add(permPanel, "Sharing");\r
133                 inner.add(verPanel, "Versions");\r
134                 inner.selectTab(0);\r
135 \r
136                 final FlexTable generalTable = new FlexTable();\r
137                 generalTable.setText(0, 0, "Name");\r
138                 generalTable.setText(1, 0, "Folder");\r
139                 generalTable.setText(2, 0, "Owner");\r
140                 generalTable.setText(3, 0, "Last modified");\r
141                 generalTable.setText(4, 0, "Tags");\r
142                 name.setText(file.getName());\r
143                 generalTable.setWidget(0, 1, name);\r
144                 if(file.getFolderName() != null)\r
145                         generalTable.setText(1, 1, file.getFolderName());\r
146                 else\r
147                         generalTable.setText(1, 1, "-");\r
148                 generalTable.setText(2, 1, file.getOwner());\r
149                 final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");\r
150                 generalTable.setText(3, 1, formatter.format(file.getModificationDate()));\r
151                 // Get the tags.\r
152                 StringBuffer tagsBuffer = new StringBuffer();\r
153                 Iterator i = file.getTags().iterator();\r
154                 while (i.hasNext()) {\r
155                         String tag = (String) i.next();\r
156                         tagsBuffer.append(tag).append(", ");\r
157                 }\r
158                 if (tagsBuffer.length() > 1)\r
159                         tagsBuffer.delete(tagsBuffer.length() - 2, tagsBuffer.length() - 1);\r
160                 initialTagText = tagsBuffer.toString();\r
161                 tags.setText(initialTagText);\r
162                 generalTable.setWidget(4, 1, tags);\r
163                 generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");\r
164                 generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");\r
165                 generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");\r
166                 generalTable.getFlexCellFormatter().setStyleName(3, 0, "props-labels");\r
167                 generalTable.getFlexCellFormatter().setStyleName(4, 0, "props-labels");\r
168                 generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");\r
169                 generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");\r
170                 generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");\r
171                 generalTable.getFlexCellFormatter().setStyleName(3, 1, "props-values");\r
172                 generalTable.getFlexCellFormatter().setStyleName(4, 1, "props-values");\r
173                 generalTable.setCellSpacing(4);\r
174 \r
175                 // Create the 'OK' button, along with a listener that hides the dialog\r
176                 // when the button is clicked.\r
177                 final Button ok = new Button("OK", new ClickHandler() {\r
178                         @Override\r
179                         public void onClick(ClickEvent event) {\r
180                                 accept();\r
181                                 closeDialog();\r
182                         }\r
183                 });\r
184                 buttons.add(ok);\r
185                 buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
186                 // Create the 'Cancel' button, along with a listener that hides the\r
187                 // dialog when the button is clicked.\r
188                 final Button cancel = new Button("Cancel", new ClickHandler() {\r
189                         @Override\r
190                         public void onClick(ClickEvent event) {\r
191                                 closeDialog();\r
192                         }\r
193                 });\r
194                 buttons.add(cancel);\r
195                 buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
196                 buttons.setSpacing(8);\r
197                 buttons.addStyleName("gss-TabPanelBottom");\r
198 \r
199                 generalPanel.add(generalTable);\r
200 \r
201                 // Asynchronously retrieve the tags defined by this user.\r
202                 DeferredCommand.addCommand(new Command() {\r
203 \r
204                         public void execute() {\r
205                                 updateTags();\r
206                         }\r
207                 });\r
208 \r
209                 DisclosurePanel allTags = new DisclosurePanel("All tags");\r
210                 allTagsContent = new FlowPanel();\r
211                 allTags.setContent(allTagsContent);\r
212                 generalPanel.add(allTags);\r
213                 generalPanel.setSpacing(4);\r
214 \r
215                 final Button add = new Button("Add Group", new ClickHandler() {\r
216                         @Override\r
217                         public void onClick(ClickEvent event) {\r
218                                 PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, false);\r
219                                 dlg.center();\r
220                         }\r
221                 });\r
222                 permButtons.add(add);\r
223                 permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);\r
224 \r
225                 final Button addUser = new Button("Add User", new ClickHandler() {\r
226                         @Override\r
227                         public void onClick(ClickEvent event) {\r
228                                 PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, true);\r
229                                 dlg.center();\r
230                         }\r
231                 });\r
232                 permButtons.add(addUser);\r
233                 permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);\r
234 \r
235                 permButtons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
236                 permButtons.setSpacing(8);\r
237                 permButtons.addStyleName("gss-TabPanelBottom");\r
238 \r
239                 final Label readForAllNote = new Label("When this option is enabled, the file will be readable" +\r
240                                         " by everyone. By checking this option, you are certifying that you have the right to " +\r
241                                         "distribute this file and that it does not violate the Terms of Use.", true);\r
242                 readForAllNote.setVisible(false);\r
243                 readForAllNote.setStylePrimaryName("gss-readForAllNote");\r
244 \r
245                 readForAll = new CheckBox();\r
246                 readForAll.setValue(file.isReadForAll());\r
247                 readForAll.addClickHandler(new ClickHandler() {\r
248                         @Override\r
249                         public void onClick(ClickEvent event) {\r
250                                 if (readForAll.getValue()) {\r
251                                         readForAllNote.setVisible(true);\r
252                                         pathPanel.setVisible(true);\r
253                                 }\r
254                                 else {\r
255                                         readForAllNote.setVisible(false);\r
256                                         pathPanel.setVisible(false);\r
257                                 }\r
258                         }\r
259 \r
260                 });\r
261 \r
262                 permPanel.add(permList);\r
263                 permPanel.add(permButtons);\r
264                 // Only show the read for all permission if the user is the owner.\r
265                 if (file.getOwner().equals(GSS.get().getCurrentUserResource().getUsername())) {\r
266                         permForAll.add(new Label("Make Public"));\r
267                         permForAll.add(readForAll);\r
268                         permForAll.setSpacing(8);\r
269                         permForAll.addStyleName("gss-TabPanelBottom");\r
270                         permForAll.add(readForAllNote);\r
271                         permPanel.add(permForAll);\r
272                 }\r
273 \r
274                 TextBox path = new TextBox();\r
275                 path.setWidth("100%");\r
276                 path.addClickHandler(new ClickHandler() {\r
277                         @Override\r
278                         public void onClick(ClickEvent event) {\r
279                                 GSS.enableIESelection();\r
280                                 ((TextBox) event.getSource()).selectAll();\r
281                                 GSS.preventIESelection();\r
282                         }\r
283 \r
284                 });\r
285                 path.setText(file.getUri());\r
286                 path.setTitle("Use this URI for sharing this file with the world (crtl-C/cmd-C to copy to system clipboard)");\r
287                 path.setWidth("100%");\r
288                 path.setReadOnly(true);\r
289                 pathPanel.setWidth("100%");\r
290                 pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);\r
291                 pathPanel.add(new Label("Sharing URI"));\r
292                 pathPanel.setSpacing(8);\r
293                 pathPanel.addStyleName("gss-TabPanelBottom");\r
294                 pathPanel.add(path);\r
295                 pathPanel.setVisible(file.isReadForAll());\r
296                 permPanel.add(pathPanel);\r
297 \r
298                 VersionsList verList = new VersionsList(this, images, bodies);\r
299                 verPanel.add(verList);\r
300 \r
301                 vPanel.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
302                 vPanel.setSpacing(8);\r
303                 vPanel.addStyleName("gss-TabPanelBottom");\r
304                 vPanel.add(new Label("Versioned"));\r
305 \r
306                 vPanel.add(versioned);\r
307                 verPanel.add(vPanel);\r
308                 vPanel2.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
309                 vPanel2.setSpacing(8);\r
310                 vPanel2.addStyleName("gss-TabPanelBottom");\r
311                 Button removeVersionsButton = new Button(AbstractImagePrototype.create(images.delete()).getHTML(), new ClickHandler() {\r
312                         @Override\r
313                         public void onClick(ClickEvent event) {\r
314                                 ConfirmationDialog confirm = new ConfirmationDialog("Really " +\r
315                                                 "remove all previous versions?", "Remove") {\r
316 \r
317                                         @Override\r
318                                         public void cancel() {\r
319                                         }\r
320 \r
321                                         @Override\r
322                                         public void confirm() {\r
323                                                 FilePropertiesDialog.this.closeDialog();\r
324                                                 removeAllOldVersions();\r
325                                         }\r
326 \r
327                                 };\r
328                                 confirm.center();\r
329                         }\r
330 \r
331                 });\r
332                 HTML removeAllVersion = new HTML("<span>Remove all previous versions?</span>");\r
333                 vPanel2.add(removeAllVersion);\r
334                 vPanel2.add(removeVersionsButton);\r
335                 verPanel.add(vPanel2);\r
336                 if(!file.isVersioned())\r
337                         vPanel2.setVisible(false);\r
338                 outer.add(inner);\r
339                 outer.add(buttons);\r
340                 outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
341                 outer.addStyleName("gss-TabPanelBottom");\r
342 \r
343                 focusPanel.setFocus(true);\r
344                 setWidget(outer);\r
345         }\r
346 \r
347 \r
348         /**\r
349          * Accepts any change and updates the file\r
350          *\r
351          */\r
352         @Override\r
353         protected void accept() {\r
354                 String newFilename = null;\r
355                 permList.updatePermissionsAccordingToInput();\r
356                 Set<PermissionHolder> perms = permList.getPermissions();\r
357                 JSONObject json = new JSONObject();\r
358                 if (!name.getText().equals(file.getName())) {\r
359                         newFilename = name.getText();\r
360                         json.put("name", new JSONString(newFilename));\r
361                 }\r
362                 if (versioned.getValue() != file.isVersioned())\r
363                         json.put("versioned", JSONBoolean.getInstance(versioned.getValue()));\r
364                 //only update the read for all perm if the user is the owner\r
365                 if (readForAll.getValue() != file.isReadForAll())\r
366                         if (file.getOwner().equals(GSS.get().getCurrentUserResource().getUsername()))\r
367                                 json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue()));\r
368                 int i = 0;\r
369                 if (permList.hasChanges()) {\r
370                         GWT.log("Permissions change", null);\r
371                         JSONArray perma = new JSONArray();\r
372 \r
373                         for (PermissionHolder p : perms) {\r
374                                 JSONObject po = new JSONObject();\r
375                                 if (p.getUser() != null)\r
376                                         po.put("user", new JSONString(p.getUser()));\r
377                                 if (p.getGroup() != null)\r
378                                         po.put("group", new JSONString(p.getGroup()));\r
379                                 po.put("read", JSONBoolean.getInstance(p.isRead()));\r
380                                 po.put("write", JSONBoolean.getInstance(p.isWrite()));\r
381                                 po.put("modifyACL", JSONBoolean.getInstance(p.isModifyACL()));\r
382                                 perma.set(i, po);\r
383                                 i++;\r
384                         }\r
385                         json.put("permissions", perma);\r
386                 }\r
387                 JSONArray taga = new JSONArray();\r
388                 i = 0;\r
389                 if (!tags.getText().equals(initialTagText)) {\r
390                         String[] tagset = tags.getText().split(",");\r
391                         for (String t : tagset) {\r
392                                 JSONString to = new JSONString(t);\r
393                                 taga.set(i, to);\r
394                                 i++;\r
395                         }\r
396                         json.put("tags", taga);\r
397                 }\r
398                 String jsonString = json.toString();\r
399                 if(jsonString.equals("{}")){\r
400                         GWT.log("NO CHANGES", null);\r
401                         return;\r
402                 }\r
403                 final String newFilenameFinal = newFilename;\r
404                 PostCommand cf = new PostCommand(file.getUri() + "?update=", jsonString, 200) {\r
405 \r
406                         @Override\r
407                         public void onComplete() {\r
408                                 GSS.get().getFileList().updateFileCache(true, false /* do not clear selected file*/, newFilenameFinal);\r
409                         }\r
410 \r
411                         @Override\r
412                         public void onError(Throwable t) {\r
413                                 GWT.log("", t);\r
414                                 if (t instanceof RestException) {\r
415                                         int statusCode = ((RestException) t).getHttpStatusCode();\r
416                                         if (statusCode == 405)\r
417                                                 GSS.get().displayError("You don't have the necessary permissions");\r
418                                         else if (statusCode == 404)\r
419                                                 GSS.get().displayError("User in permissions does not exist");\r
420                                         else if (statusCode == 409)\r
421                                                 GSS.get().displayError("A file with the same name already exists");\r
422                                         else if (statusCode == 413)\r
423                                                 GSS.get().displayError("Your quota has been exceeded");\r
424                                         else\r
425                                                 GSS.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
426                                 } else\r
427                                         GSS.get().displayError("System error modifying file:" + t.getMessage());\r
428                         }\r
429 \r
430                 };\r
431                 DeferredCommand.addCommand(cf);\r
432 \r
433         }\r
434 \r
435         private void removeAllOldVersions() {\r
436                 JSONObject json = new JSONObject();\r
437                 json.put("versioned", JSONBoolean.getInstance(false));\r
438                 GWT.log(json.toString(), null);\r
439                 PostCommand cf = new PostCommand(file.getUri() + "?update=", json.toString(), 200) {\r
440 \r
441                         @Override\r
442                         public void onComplete() {\r
443                                 toggleVersioned(true);\r
444                         }\r
445 \r
446                         @Override\r
447                         public void onError(Throwable t) {\r
448                                 GWT.log("", t);\r
449                                 if (t instanceof RestException) {\r
450                                         int statusCode = ((RestException) t).getHttpStatusCode();\r
451                                         if (statusCode == 405)\r
452                                                 GSS.get().displayError("You don't have the necessary permissions");\r
453                                         else if (statusCode == 404)\r
454                                                 GSS.get().displayError("User in permissions does not exist");\r
455                                         else if (statusCode == 409)\r
456                                                 GSS.get().displayError("A folder with the same name already exists");\r
457                                         else if (statusCode == 413)\r
458                                                 GSS.get().displayError("Your quota has been exceeded");\r
459                                         else\r
460                                                 GSS.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
461                                 } else\r
462                                         GSS.get().displayError("System error moifying file:" + t.getMessage());\r
463                         }\r
464                 };\r
465                 DeferredCommand.addCommand(cf);\r
466         }\r
467 \r
468         private void toggleVersioned(boolean versionedValue) {\r
469                 JSONObject json = new JSONObject();\r
470                 json.put("versioned", JSONBoolean.getInstance(versionedValue));\r
471                 GWT.log(json.toString(), null);\r
472                 PostCommand cf = new PostCommand(file.getUri() + "?update=", json.toString(), 200) {\r
473 \r
474                         @Override\r
475                         public void onComplete() {\r
476                                 GSS.get().getFileList().updateFileCache(true, false /* do not clear selected file*/);\r
477                         }\r
478 \r
479                         @Override\r
480                         public void onError(Throwable t) {\r
481                                 GWT.log("", t);\r
482                                 if (t instanceof RestException) {\r
483                                         int statusCode = ((RestException) t).getHttpStatusCode();\r
484                                         if (statusCode == 405)\r
485                                                 GSS.get().displayError("You don't have the necessary permissions");\r
486                                         else if (statusCode == 404)\r
487                                                 GSS.get().displayError("User in permissions does not exist");\r
488                                         else if (statusCode == 409)\r
489                                                 GSS.get().displayError("A folder with the same name already exists");\r
490                                         else if (statusCode == 413)\r
491                                                 GSS.get().displayError("Your quota has been exceeded");\r
492                                         else\r
493                                                 GSS.get().displayError("Unable to modify file:" + ((RestException) t).getHttpStatusText());\r
494                                 } else\r
495                                         GSS.get().displayError("System error moifying file:" + t.getMessage());\r
496                         }\r
497                 };\r
498                 DeferredCommand.addCommand(cf);\r
499         }\r
500 \r
501 \r
502 }\r