Statistics
| Branch: | Tag: | Revision:

root / web_client / src / gr / grnet / pithos / web / client / FolderPropertiesDialog.java @ 58777026

History | View | Annotate | Download (18 kB)

1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35
package gr.grnet.pithos.web.client;
36

    
37
import gr.grnet.pithos.web.client.FilePropertiesDialog.Images;
38
import gr.grnet.pithos.web.client.rest.PostCommand;
39
import gr.grnet.pithos.web.client.rest.RestException;
40
import gr.grnet.pithos.web.client.rest.resource.FolderResource;
41
import gr.grnet.pithos.web.client.rest.resource.GroupResource;
42
import gr.grnet.pithos.web.client.rest.resource.PermissionHolder;
43
import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper;
44

    
45
import java.util.List;
46
import java.util.Set;
47

    
48
import com.google.gwt.core.client.GWT;
49
import com.google.gwt.dom.client.NativeEvent;
50
import com.google.gwt.event.dom.client.ChangeEvent;
51
import com.google.gwt.event.dom.client.ChangeHandler;
52
import com.google.gwt.event.dom.client.ClickEvent;
53
import com.google.gwt.event.dom.client.ClickHandler;
54
import com.google.gwt.event.dom.client.KeyCodes;
55
import com.google.gwt.http.client.URL;
56
import com.google.gwt.i18n.client.DateTimeFormat;
57
import com.google.gwt.json.client.JSONArray;
58
import com.google.gwt.json.client.JSONBoolean;
59
import com.google.gwt.json.client.JSONObject;
60
import com.google.gwt.json.client.JSONString;
61
import com.google.gwt.user.client.DeferredCommand;
62
import com.google.gwt.user.client.Event.NativePreviewEvent;
63
import com.google.gwt.user.client.ui.Button;
64
import com.google.gwt.user.client.ui.CheckBox;
65
import com.google.gwt.user.client.ui.DecoratedTabPanel;
66
import com.google.gwt.user.client.ui.DialogBox;
67
import com.google.gwt.user.client.ui.FlexTable;
68
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
69
import com.google.gwt.user.client.ui.HorizontalPanel;
70
import com.google.gwt.user.client.ui.Label;
71
import com.google.gwt.user.client.ui.TabPanel;
72
import com.google.gwt.user.client.ui.TextBox;
73
import com.google.gwt.user.client.ui.VerticalPanel;
74

    
75
/**
76
 * The 'Folder properties' dialog box implementation.
77
 */
78
public class FolderPropertiesDialog extends DialogBox {
79

    
80
        private List<GroupResource> groups = null;
81

    
82
        final PermissionsList permList;
83

    
84
        private CheckBox readForAll;
85

    
86
        /**
87
         * The widget that holds the folderName of the folder.
88
         */
89
        private TextBox folderName = new TextBox();
90

    
91
        /**
92
         * A flag that denotes whether the dialog will be used to create or modify a
93
         * folder.
94
         */
95
        private final boolean create;
96

    
97
        final FolderResource folder;
98

    
99
        final TabPanel inner;
100

    
101
        /**
102
         * The widget's constructor.
103
         *
104
         * @param images the image icons from the file properties dialog
105
         * @param _create true if the dialog is displayed for creating a new
106
         *            sub-folder of the selected folder, false if it is displayed
107
         *            for modifying the selected folder
108
         */
109
        public FolderPropertiesDialog(Images images, boolean _create,  final List<GroupResource> _groups) {
110
                setAnimationEnabled(true);
111

    
112
                // Enable IE selection for the dialog (must disable it upon closing it)
113
                GSS.enableIESelection();
114

    
115
                create = _create;
116
                
117
                folder = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();
118
                permList = new PermissionsList(images, folder.getPermissions(), folder.getOwner());
119
                groups = _groups;
120

    
121
                // Use this opportunity to set the dialog's caption.
122
                if (create)
123
                        setText("Create folder");
124
                else
125
                        setText("Folder properties");
126

    
127
                // Outer contains inner and buttons
128
                VerticalPanel outer = new VerticalPanel();
129
                // Inner contains generalPanel and permPanel
130
                inner = new DecoratedTabPanel();
131
                inner.setAnimationEnabled(true);
132
                VerticalPanel generalPanel = new VerticalPanel();
133
                VerticalPanel permPanel = new VerticalPanel();
134
                final HorizontalPanel permForAll = new HorizontalPanel();
135
                final HorizontalPanel pathPanel = new HorizontalPanel();
136
                HorizontalPanel buttons = new HorizontalPanel();
137
                HorizontalPanel permButtons = new HorizontalPanel();
138

    
139
                inner.add(generalPanel, "General");
140
                if (!create)
141
                        inner.add(permPanel, "Sharing");
142
                inner.selectTab(0);
143

    
144
                final Label folderNameNote = new Label("Please note that slashes ('/') are not allowed in folder names.", true);
145
                folderNameNote.setVisible(false);
146
                folderNameNote.setStylePrimaryName("pithos-readForAllNote");
147

    
148
                FlexTable generalTable = new FlexTable();
149
                generalTable.setText(0, 0, "Name");
150
                generalTable.setText(1, 0, "Parent");
151
                generalTable.setText(2, 0, "Creator");
152
                generalTable.setText(3, 0, "Last modified");
153
                folderName.setText(create ? "" : folder.getName());
154
                folderName.getElement().setId("folderPropertiesDialog.textBox.name");
155
                generalTable.setWidget(0, 1, folderName);
156
                folderName.addChangeHandler(new ChangeHandler() {
157
                        
158
                        @Override
159
                        public void onChange(ChangeEvent event) {
160
                                if(folderName.getText().contains("/"))
161
                                        folderNameNote.setVisible(true);
162
                                else
163
                                        folderNameNote.setVisible(false);                                
164
                                
165
                        }
166
                });
167

    
168

    
169
                if (create)
170
                        generalTable.setText(1, 1, folder.getName());
171
                else if(folder.getParentName() == null)
172
                        generalTable.setText(1, 1, "-");
173
                else
174
                        generalTable.setText(1, 1, folder.getParentName());
175
                generalTable.setWidget(0, 2, folderNameNote);
176
                generalTable.setText(2, 1, folder.getOwner());
177
                DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
178
                if(folder.getModificationDate() != null)
179
                        generalTable.setText(3, 1, formatter.format(folder.getModificationDate()));
180
                generalTable.getFlexCellFormatter().setStyleName(0, 0, "props-labels");
181
                generalTable.getFlexCellFormatter().setStyleName(1, 0, "props-labels");
182
                generalTable.getFlexCellFormatter().setStyleName(2, 0, "props-labels");
183
                generalTable.getFlexCellFormatter().setStyleName(3, 0, "props-labels");
184
                generalTable.getFlexCellFormatter().setStyleName(0, 1, "props-values");
185
                generalTable.getFlexCellFormatter().setStyleName(1, 1, "props-values");
186
                generalTable.getFlexCellFormatter().setStyleName(2, 1, "props-values");
187
                generalTable.getFlexCellFormatter().setStyleName(3, 1, "props-values");
188
                generalTable.setCellSpacing(4);
189

    
190
                // Create the 'Create/Update' button, along with a listener that hides the dialog
191
                // when the button is clicked and quits the application.
192
                String okLabel;
193
                if (create)
194
                        okLabel = "Create";
195
                else
196
                        okLabel = "Update";
197
                Button ok = new Button(okLabel, new ClickHandler() {
198
                        @Override
199
                        public void onClick(ClickEvent event) {                                
200
                                if(folderName.getText().contains("/"))
201
                                        folderNameNote.setVisible(true);
202
                                else {
203
                                        folderNameNote.setVisible(false);
204
                                        createOrUpdateFolder();
205
                                        closeDialog();
206
                                }
207

    
208
                        }
209
                });
210
                ok.getElement().setId("folderPropertiesDialog.button.ok");
211
                buttons.add(ok);
212
                buttons.setCellHorizontalAlignment(ok, HasHorizontalAlignment.ALIGN_CENTER);
213
                // Create the 'Cancel' button, along with a listener that hides the
214
                // dialog
215
                // when the button is clicked.
216
                Button cancel = new Button("Cancel", new ClickHandler() {
217
                        @Override
218
                        public void onClick(ClickEvent event) {
219
                                closeDialog();
220
                        }
221
                });
222
                cancel.getElement().setId("folderPropertiesDialog.button.cancel");
223
                buttons.add(cancel);
224
                buttons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
225
                buttons.setSpacing(8);
226
                buttons.addStyleName("pithos-TabPanelBottom");
227

    
228
                Button add = new Button("Add Group", new ClickHandler() {
229
                        @Override
230
                        public void onClick(ClickEvent event) {
231
                                PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, false);
232
                                dlg.center();
233
                        }
234
                });
235
                add.getElement().setId("folderPropertiesDialog.button.addGroup");
236
                permButtons.add(add);
237
                permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);
238

    
239
                Button addUser = new Button("Add User", new ClickHandler() {
240
                        @Override
241
                        public void onClick(ClickEvent event) {
242
                                PermissionsAddDialog dlg = new PermissionsAddDialog(groups, permList, true);
243
                                dlg.center();
244
                        }
245
                });
246
                addUser.getElement().setId("folderPropertiesDialog.button.addUser");
247
                permButtons.add(addUser);
248
                permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);
249

    
250
                permButtons.setCellHorizontalAlignment(cancel, HasHorizontalAlignment.ALIGN_CENTER);
251
                permButtons.setSpacing(8);
252
                permButtons.addStyleName("pithos-TabPanelBottom");
253

    
254
                final Label readForAllNote = new Label("When this option is enabled, the folder will be readable" +
255
                                        " by everyone. By checking this option, you are certifying that you have the right to " +
256
                                        "distribute this folder's contents and that it does not violate the Terms of Use.", true);
257
                readForAllNote.setVisible(false);
258
                readForAllNote.setStylePrimaryName("pithos-readForAllNote");
259

    
260
                readForAll = new CheckBox();
261
                readForAll.getElement().setId("folderPropertiesDialog.checkBox.public");
262
                readForAll.setValue(folder.isReadForAll());
263
                readForAll.addClickHandler(new ClickHandler() {
264
                        @Override
265
                        public void onClick(ClickEvent event) {
266
                                readForAllNote.setVisible(readForAll.getValue());
267
                        }
268

    
269
                });
270

    
271
                generalPanel.add(generalTable);
272
                permPanel.add(permList);
273
                permPanel.add(permButtons);
274

    
275
                // Only show the read for all permission if the user is the owner.
276
                if (folder.getOwner().equals(GSS.get().getCurrentUserResource().getUsername())) {
277
                        permForAll.add(new Label("Public"));
278
                        permForAll.add(readForAll);
279
                        permForAll.setSpacing(8);
280
                        permForAll.addStyleName("pithos-TabPanelBottom");
281
                        permForAll.add(readForAllNote);
282
                        permPanel.add(permForAll);
283
                }
284
                TextBox path = new TextBox();
285
                path.getElement().setId("folderPropertiesDialog.textBox.link");
286
                path.setWidth("100%");
287
                path.addClickHandler(new ClickHandler() {
288
                        @Override
289
                        public void onClick(ClickEvent event) {
290
                                GSS.enableIESelection();
291
                                ((TextBox) event.getSource()).selectAll();
292
                                GSS.preventIESelection();
293
                        }
294

    
295
                });
296
                path.setText(folder.getUri());
297
                path.setTitle("Use this link for sharing the folder via e-mail, IM, etc. (crtl-C/cmd-C to copy to system clipboard)");
298
                path.setWidth("100%");
299
                path.setReadOnly(true);
300
                pathPanel.setWidth("100%");
301
                pathPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
302
                pathPanel.add(new Label("Link"));
303
                pathPanel.setSpacing(8);
304
                pathPanel.addStyleName("pithos-TabPanelBottom");
305
                pathPanel.add(path);
306
                permPanel.add(pathPanel);
307

    
308
                outer.add(inner);
309
                outer.add(buttons);
310
                outer.setCellHorizontalAlignment(buttons, HasHorizontalAlignment.ALIGN_CENTER);
311
                outer.addStyleName("pithos-TabPanelBottom");
312

    
313
                setWidget(outer);
314

    
315
                /*if (create)
316
                        folderName.setFocus(true);
317
                else
318
                        ok.setFocus(true);*/
319
        }
320

    
321
        @Override
322
        public void center() {
323
                super.center();
324
                folderName.setFocus(true);
325
        }
326

    
327
        @Override
328
        protected void onPreviewNativeEvent(NativePreviewEvent preview) {
329
                super.onPreviewNativeEvent(preview);
330

    
331
                NativeEvent evt = preview.getNativeEvent();
332
                if (evt.getType().equals("keydown"))
333
                        // Use the popup's key preview hooks to close the dialog when either
334
                        // enter or escape is pressed.
335
                        switch (evt.getKeyCode()) {
336
                                case KeyCodes.KEY_ENTER:
337
                                        closeDialog();
338
                                        createOrUpdateFolder();
339
                                        break;
340
                                case KeyCodes.KEY_ESCAPE:
341
                                        closeDialog();
342
                                        break;
343
                        }
344
        }
345

    
346

    
347
        /**
348
         * Enables IE selection prevention and hides the dialog
349
         * (we disable the prevention on creation of the dialog)
350
         */
351
        public void closeDialog() {
352
                GSS.preventIESelection();
353
                hide();
354
        }
355

    
356
        /**
357
         * Generate an RPC request to create a new folder.
358
         *
359
         * @param userId the ID of the user whose namespace will be searched for
360
         *            folders
361
         * @param _folderName the name of the folder to create
362
         */
363
        private void createFolder() {
364
                String name = folderName.getText();
365
                if (!GSS.isValidResourceName(name)) {
366
                        GSS.get().displayError("The folder name '" + name + "' is invalid");
367
                        return;
368
                }
369
                PostCommand ep = new PostCommand(folder.getUri() + "?new=" +
370
                                URL.encodeComponent(name), "", 201) {
371

    
372
                        @Override
373
                        public void onComplete() {
374
                                //TODO:CELLTREE
375
                                if(folder.getUri().equals(GSS.get().getTreeView().getMyFolders().getUri())){
376
                                        GSS.get().getTreeView().updateRootNode();
377
                                }
378
                                else
379
                                        GSS.get().getTreeView().updateNodeChildren((RestResourceWrapper) GSS.get().getTreeView().getSelection());
380
                                //GSS.get().getFolders().updateFolder((DnDTreeItem) GSS.get().getFolders().getCurrent());
381
                        }
382

    
383
                        @Override
384
                        public void onError(Throwable t) {
385
                                GWT.log("", t);
386
                                if(t instanceof RestException){
387
                                        int statusCode = ((RestException)t).getHttpStatusCode();
388
                                        if(statusCode == 405)
389
                                                GSS.get().displayError("You don't have the necessary" +
390
                                                                " permissions or a folder with same name " +
391
                                                                "already exists");
392
                                        else if(statusCode == 404)
393
                                                GSS.get().displayError("Resource not found");
394
                                        else
395
                                                GSS.get().displayError("Unable to create folder:" +
396
                                                                ((RestException)t).getHttpStatusText());
397
                                }
398
                                else
399
                                        GSS.get().displayError("System error creating folder:" +
400
                                                        t.getMessage());
401
                        }
402
                };
403
                DeferredCommand.addCommand(ep);
404

    
405
        }
406

    
407
        /**
408
         * Upon closing the dialog by clicking OK or pressing ENTER this method does
409
         * the actual work of modifying folder properties or creating a new Folder
410
         * depending on the value of the create field
411
         *
412
         * @param userId
413
         */
414
        private void createOrUpdateFolder() {
415
                if (create)
416
                        createFolder();
417
                else
418
                        updateFolder();
419

    
420
        }
421

    
422
        private void updateFolder() {
423
                permList.updatePermissionsAccordingToInput();
424
                Set<PermissionHolder> perms = permList.getPermissions();
425
                JSONObject json = new JSONObject();
426
                if(!folder.getName().equals(folderName.getText()))
427
                        json.put("name", new JSONString(folderName.getText()));
428
                //only update the read for all perm if the user is the owner
429
                if (readForAll.getValue() != folder.isReadForAll())
430
                        if (folder.getOwner().equals(GSS.get().getCurrentUserResource().getUsername()))
431
                                json.put("readForAll", JSONBoolean.getInstance(readForAll.getValue()));
432
                if (permList.hasChanges()) {
433
                        JSONArray perma = new JSONArray();
434
                        int i=0;
435
                        for(PermissionHolder p : perms){
436
                                JSONObject po = new JSONObject();
437
                                if(p.getUser() != null)
438
                                        po.put("user", new JSONString(p.getUser()));
439
                                if(p.getGroup() != null)
440
                                        po.put("group", new JSONString(p.getGroup()));
441
                                po.put("read", JSONBoolean.getInstance(p.isRead()));
442
                                po.put("write", JSONBoolean.getInstance(p.isWrite()));
443
                                po.put("modifyACL", JSONBoolean.getInstance(p.isModifyACL()));
444
                                perma.set(i,po);
445
                                i++;
446
                        }
447
                        json.put("permissions", perma);
448
                        GWT.log(json.toString(), null);
449
                }
450
                PostCommand ep = new PostCommand(folder.getUri()+"?update=", json.toString(), 200){
451

    
452
                        @Override
453
                        public void onComplete() {
454
                                //TODO:CELLTREE
455
                                
456
                                if(getPostBody() != null && !"".equals(getPostBody().trim())){
457
                                        
458
                                        
459
                                        FolderResource fres = ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource();
460
                                        String initialPath = fres.getUri();
461
                                        String newPath =  getPostBody().trim();
462
                                        fres.setUri(newPath);
463
                                        ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).getResource().setUri(newPath);
464
                                        ((RestResourceWrapper) GSS.get().getTreeView().getSelection()).setUri(newPath);
465
                                        GSS.get().getTreeView().updateNodeChildren(fres.getParentURI());
466
                                        if (permList.hasChanges()) {
467
                                                GSS.get().getTreeView().updateMySharedNode();
468
                                        }
469
                                        /*
470
                                        if(folderItem.getParentItem() != null && ((DnDTreeItem)folderItem.getParentItem()).getFolderResource() != null){
471
                                                ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().removeSubfolderPath(initialPath);
472
                                                ((DnDTreeItem)folderItem.getParentItem()).getFolderResource().getSubfolderPaths().add(newPath);
473
                                        }*/
474
                                }
475
                                //GSS.get().getFolders().updateFolder( (DnDTreeItem) GSS.get().getFolders().getCurrent());
476
                                
477
                                GSS.get().showFileList(true);
478
                        }
479

    
480
                        @Override
481
                        public void onError(Throwable t) {
482
                                GWT.log("", t);
483
                                if(t instanceof RestException){
484
                                        int statusCode = ((RestException)t).getHttpStatusCode();
485
                                        if(statusCode == 405)
486
                                                GSS.get().displayError("You don't have the necessary permissions or" +
487
                                                                " a folder with same name already exists");
488
                                        else if(statusCode == 404)
489
                                                GSS.get().displayError("Resource not found, or user specified in sharing does not exist");
490
                                        else
491
                                                GSS.get().displayError("Unable to update folder: "+((RestException)t).getHttpStatusText());
492
                                }
493
                                else
494
                                        GSS.get().displayError("System error moifying file: "+t.getMessage());
495
                                //TODO:CELLTREE
496
                                //GSS.get().getFolders().updateFolder( (DnDTreeItem) GSS.get().getFolders().getCurrent());
497
                        }
498
                };
499
                DeferredCommand.addCommand(ep);
500
        }
501

    
502
        public void selectTab(int _tab) {
503
                inner.selectTab(_tab);
504
        }
505

    
506
}