74c421e16d3e7b54b0b747de80f5ee465cf93dea
[pithos] / web_client / src / gr / grnet / pithos / web / client / FilesPropertiesDialog.java
1 /*\r
2  * Copyright 2011 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.components.TristateCheckBox;\r
38 import gr.grnet.pithos.web.client.rest.MultiplePostCommand;\r
39 import gr.grnet.pithos.web.client.rest.RestException;\r
40 import gr.grnet.pithos.web.client.rest.resource.FileResource;\r
41 \r
42 import java.util.ArrayList;\r
43 import java.util.Iterator;\r
44 import java.util.List;\r
45 \r
46 import com.google.gwt.core.client.GWT;\r
47 import com.google.gwt.event.dom.client.ClickEvent;\r
48 import com.google.gwt.event.dom.client.ClickHandler;\r
49 import com.google.gwt.event.dom.client.FocusEvent;\r
50 import com.google.gwt.event.dom.client.FocusHandler;\r
51 import com.google.gwt.json.client.JSONArray;\r
52 import com.google.gwt.json.client.JSONBoolean;\r
53 import com.google.gwt.json.client.JSONObject;\r
54 import com.google.gwt.json.client.JSONString;\r
55 import com.google.gwt.user.client.Command;\r
56 import com.google.gwt.user.client.DeferredCommand;\r
57 import com.google.gwt.user.client.ui.Button;\r
58 import com.google.gwt.user.client.ui.DecoratedTabPanel;\r
59 import com.google.gwt.user.client.ui.DisclosurePanel;\r
60 import com.google.gwt.user.client.ui.FlexTable;\r
61 import com.google.gwt.user.client.ui.FlowPanel;\r
62 import com.google.gwt.user.client.ui.FocusPanel;\r
63 import com.google.gwt.user.client.ui.HasHorizontalAlignment;\r
64 import com.google.gwt.user.client.ui.HorizontalPanel;\r
65 import com.google.gwt.user.client.ui.Label;\r
66 import com.google.gwt.user.client.ui.VerticalPanel;\r
67 \r
68 /**\r
69  * The 'Multiple file properties' dialog box implementation.\r
70  *\r
71  */\r
72 public class FilesPropertiesDialog extends AbstractPropertiesDialog {\r
73 \r
74         private final TristateCheckBox versionedCheck;\r
75 \r
76         private final List<FileResource> files;\r
77 \r
78         private Boolean initialVersioned;\r
79 \r
80 \r
81         /**\r
82          * The widget's constructor.\r
83          *\r
84          * @param _files\r
85          */\r
86         public FilesPropertiesDialog(final List<FileResource> _files) {\r
87                 super();\r
88 \r
89                 files = _files;\r
90                 int versionedNum = 0;\r
91                 for (FileResource fr : files)\r
92                         if (fr.isVersioned()) versionedNum++;\r
93                 Boolean versioned = null;\r
94                 if (versionedNum==0) versioned = false;\r
95                 if (versionedNum==files.size()) versioned = true;\r
96                 initialVersioned = versioned;\r
97                 versionedCheck = new TristateCheckBox(versioned);\r
98 \r
99                 // Set the dialog's caption.\r
100                 setText("Files properties");\r
101 \r
102                 // Outer contains inner and buttons.\r
103                 final VerticalPanel outer = new VerticalPanel();\r
104                 final FocusPanel focusPanel = new FocusPanel(outer);\r
105                 // Inner contains generalPanel and permPanel.\r
106                 inner = new DecoratedTabPanel();\r
107                 inner.setAnimationEnabled(true);\r
108                 final VerticalPanel generalPanel = new VerticalPanel();\r
109                 final HorizontalPanel buttons = new HorizontalPanel();\r
110                 final VerticalPanel verPanel = new VerticalPanel();\r
111                 final HorizontalPanel vPanel = new HorizontalPanel();\r
112 \r
113                 inner.add(generalPanel, "General");\r
114                 inner.add(verPanel, "Versions");\r
115                 inner.selectTab(0);\r
116 \r
117                 final FlexTable generalTable = new FlexTable();\r
118                 generalTable.setText(0, 0, String.valueOf(files.size())+" files selected");\r
119                 generalTable.setText(1, 0, "Folder");\r
120                 generalTable.setText(2, 0, "Tags");\r
121                 FileResource firstFile = files.get(0);\r
122                 if(firstFile.getFolderName() != null)\r
123                         generalTable.setText(1, 1, firstFile.getFolderName());\r
124                 else\r
125                         generalTable.setText(1, 1, "-");\r
126 \r
127                 // Find if tags are identical\r
128                 List<String> tagsList = files.get(0).getTags();\r
129                 List<String> tagss;\r
130                 for (int i=1; i<files.size(); i++) {\r
131                         tagss = files.get(i).getTags();\r
132                         if (tagsList.size() != tagss.size() || !tagsList.containsAll(tagss)) {\r
133                                 tagsList = null;\r
134                                 break;\r
135                         }\r
136                 }\r
137                 // Get the tags.\r
138                 StringBuffer tagsBuffer = new StringBuffer();\r
139                 if (tagsList==null)\r
140                         tagsBuffer.append(MULTIPLE_VALUES_TEXT);\r
141                 else {\r
142                         Iterator i = tagsList.iterator();\r
143                         while (i.hasNext()) {\r
144                                 String tag = (String) i.next();\r
145                                 tagsBuffer.append(tag).append(", ");\r
146                         }\r
147                         if (tagsBuffer.length() > 1)\r
148                                 tagsBuffer.delete(tagsBuffer.length() - 2, tagsBuffer.length() - 1);\r
149                 }\r
150                 initialTagText = tagsBuffer.toString();\r
151                 tags.setText(initialTagText);\r
152                 tags.addFocusHandler(new FocusHandler() {\r
153                         @Override\r
154                         public void onFocus(FocusEvent event) {\r
155                                 if (MULTIPLE_VALUES_TEXT.equals(tags.getText()))\r
156                                         tags.setText("");\r
157                         }\r
158                 }\r
159                 );\r
160 \r
161                 generalTable.setWidget(2, 1, tags);\r
162                 generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");\r
163                 generalTable.getFlexCellFormatter().setColSpan(0, 0, 2);\r
164                 generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");\r
165                 generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");\r
166                 generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");\r
167                 generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");\r
168                 generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");\r
169                 generalTable.setCellSpacing(4);\r
170 \r
171                 // Create the 'OK' button, along with a listener that hides the dialog\r
172                 // when the button is clicked.\r
173                 final Button ok = new Button("OK", new ClickHandler() {\r
174                         @Override\r
175                         public void onClick(ClickEvent event) {\r
176                                 accept();\r
177                                 closeDialog();\r
178                         }\r
179                 });\r
180                 buttons.add(ok);\r
181                 buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);\r
182                 // Create the 'Cancel' button, along with a listener that hides the\r
183                 // dialog when the button is clicked.\r
184                 final Button cancel = new Button("Cancel", new ClickHandler() {\r
185                         @Override\r
186                         public void onClick(ClickEvent event) {\r
187                                 closeDialog();\r
188                         }\r
189                 });\r
190                 buttons.add(cancel);\r
191                 buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
192                 buttons.setSpacing(8);\r
193                 buttons.addStyleName("pithos-TabPanelBottom");\r
194 \r
195                 generalPanel.add(generalTable);\r
196 \r
197                 // Asynchronously retrieve the tags defined by this user.\r
198                 DeferredCommand.addCommand(new Command() {\r
199 \r
200                         @Override\r
201                         public void execute() {\r
202                                 updateTags();\r
203                         }\r
204                 });\r
205 \r
206                 DisclosurePanel allTags = new DisclosurePanel("All tags");\r
207                 allTagsContent = new FlowPanel();\r
208                 allTags.setContent(allTagsContent);\r
209                 generalPanel.add(allTags);\r
210                 generalPanel.setSpacing(4);\r
211 \r
212 \r
213                 vPanel.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);\r
214                 vPanel.setSpacing(8);\r
215                 vPanel.addStyleName("pithos-TabPanelBottom");\r
216                 vPanel.add(new Label("Versioned"));\r
217 \r
218                 vPanel.add(versionedCheck);\r
219                 verPanel.add(vPanel);\r
220                 outer.add(inner);\r
221                 outer.add(buttons);\r
222                 outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);\r
223                 outer.addStyleName("pithos-TabPanelBottom");\r
224 \r
225                 focusPanel.setFocus(true);\r
226                 setWidget(outer);\r
227         }\r
228 \r
229 \r
230         /**\r
231          * Accepts any change and updates the file\r
232          *\r
233          */\r
234         @Override\r
235         protected void accept() {\r
236                 JSONObject json = new JSONObject();\r
237                 if ( versionedCheck.getState()!=null && !versionedCheck.getState().equals(initialVersioned) )\r
238                                 json.put("versioned", JSONBoolean.getInstance(versionedCheck.getState()));\r
239 \r
240                 JSONArray taga = new JSONArray();\r
241                 int i = 0;\r
242                 String tagText = tags.getText();\r
243                 if (!MULTIPLE_VALUES_TEXT.equals(tagText) && !initialTagText.equals(tagText)) {\r
244                         String[] tagset = tagText.split(",");\r
245                         for (String t : tagset) {\r
246                                 JSONString to = new JSONString(t);\r
247                                 taga.set(i, to);\r
248                                 i++;\r
249                         }\r
250                         json.put("tags", taga);\r
251                 }\r
252                 String jsonString = json.toString();\r
253                 if(jsonString.equals("{}")){\r
254                         GWT.log("NO CHANGES", null);\r
255                         return;\r
256                 }\r
257                 final List<String> fileIds = new ArrayList<String>();\r
258                 for(FileResource f : files)\r
259                         fileIds.add(f.getUri()+"?update=");\r
260                 MultiplePostCommand rt = new MultiplePostCommand(fileIds.toArray(new String[0]), jsonString, 200){\r
261 \r
262                         @Override\r
263                         public void onComplete() {\r
264                                 GSS.get().getTreeView().refreshCurrentNode(false);\r
265                         }\r
266 \r
267                         @Override\r
268                         public void onError(String p, Throwable t) {\r
269                                 GWT.log("", t);\r
270                                 if(t instanceof RestException){\r
271                                         int statusCode = ((RestException)t).getHttpStatusCode();\r
272                                         if(statusCode == 405)\r
273                                                 GSS.get().displayError("You don't have the necessary permissions");\r
274                                         else if(statusCode == 404)\r
275                                                 GSS.get().displayError("File does not exist");\r
276                                         else if(statusCode == 409)\r
277                                                 GSS.get().displayError("A file with the same name already exists");\r
278                                         else if(statusCode == 413)\r
279                                                 GSS.get().displayError("Your quota has been exceeded");\r
280                                         else\r
281                                                 GSS.get().displayError("Unable to modify file::"+((RestException)t).getHttpStatusText());\r
282                                 }\r
283                                 else\r
284                                         GSS.get().displayError("System error modifying file:"+t.getMessage());\r
285                         }\r
286                 };\r
287                 DeferredCommand.addCommand(rt);\r
288         }\r
289 \r
290 \r
291 }\r