Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / FolderPermissionsDialog.java @ 87487bbf

History | View | Annotate | Download (13.3 kB)

1
/*
2
 * Copyright 2011-2013 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 com.google.gwt.core.client.GWT;
38
import com.google.gwt.core.client.Scheduler;
39
import com.google.gwt.dom.client.NativeEvent;
40
import com.google.gwt.event.dom.client.ClickEvent;
41
import com.google.gwt.event.dom.client.ClickHandler;
42
import com.google.gwt.event.dom.client.KeyCodes;
43
import com.google.gwt.event.dom.client.KeyDownEvent;
44
import com.google.gwt.http.client.Response;
45
import com.google.gwt.http.client.URL;
46
import com.google.gwt.user.client.Command;
47
import com.google.gwt.user.client.Event.NativePreviewEvent;
48
import com.google.gwt.user.client.ui.*;
49
import gr.grnet.pithos.web.client.foldertree.Folder;
50
import gr.grnet.pithos.web.client.rest.PostRequest;
51
import gr.grnet.pithos.web.client.rest.PutRequest;
52
import gr.grnet.pithos.web.client.rest.RestException;
53

    
54
import java.util.Map;
55

    
56
/**
57
 * The 'Folder properties' dialog box implementation.
58
 */
59
public class FolderPermissionsDialog extends DialogBox {
60

    
61
    protected Pithos app;
62

    
63
    /**
64
     * The widget that holds the folderName of the folder.
65
     */
66
    Label folderName = new Label();
67

    
68
    protected PermissionsList permList;
69

    
70
    final Folder folder;
71

    
72
    final VerticalPanel inner;
73

    
74
    final Button updateButton;
75

    
76
    private boolean _initialPermissionCheck = true;
77

    
78
    /**
79
     * The widget's constructor.
80
     */
81
    public FolderPermissionsDialog(final Pithos app, Folder selected) {
82
        this.app = app;
83
        Anchor close = new Anchor("close");
84
        close.addStyleName("close");
85
        close.addClickHandler(new ClickHandler() {
86

    
87
            @Override
88
            public void onClick(ClickEvent event) {
89
                hide();
90
            }
91
        });
92

    
93
        setGlassEnabled(true);
94
        setStyleName("pithos-DialogBox");
95

    
96
        // Enable IE selection for the dialog (must disable it upon closing it)
97
        Pithos.enableIESelection();
98

    
99
        folder = selected;
100

    
101
        setText("Folder permissions");
102

    
103
        // Outer contains inner and buttons
104
        VerticalPanel outer = new VerticalPanel();
105
        outer.add(close);
106
        // Inner contains generalPanel and permPanel
107
        inner = new VerticalPanel();
108
        inner.addStyleName("inner");
109

    
110

    
111
        folderName.setText(folder.getName());
112

    
113
        VerticalPanel permPanel = new VerticalPanel();
114
        FileShareDialog.PrivateSharingImages images = GWT.create(FileShareDialog.PrivateSharingImages.class);
115
        permList = new PermissionsList(app, images, folder.getPermissions(), folder.getOwnerID(), false, null);
116
        permPanel.add(permList);
117

    
118
        HorizontalPanel permButtons = new HorizontalPanel();
119
        Button addUser = new Button("Add User", new ClickHandler() {
120
            @Override
121
            public void onClick(ClickEvent event) {
122
                PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, true);
123
                dlg.center();
124
                checkUpdateButtonVisibility();
125
            }
126
        });
127
        addUser.addStyleName("button");
128
        permButtons.add(addUser);
129
        permButtons.setCellHorizontalAlignment(addUser, HasHorizontalAlignment.ALIGN_CENTER);
130

    
131
        Button add = new Button("Add Group", new ClickHandler() {
132
            @Override
133
            public void onClick(ClickEvent event) {
134
                if(app.getAccount().getGroups().isEmpty()) {
135
                    new GroupCreateDialog(app, new Command() {
136
                        @Override
137
                        public void execute() {
138
                            if(app.getAccount().getGroups().isEmpty()) {
139
                                return;
140
                            }
141
                            PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);
142
                            dlg.center();
143
                            checkUpdateButtonVisibility();
144
                        }
145
                    }).center();
146
                }
147
                else {
148
                    PermissionsAddDialog dlg = new PermissionsAddDialog(app, app.getAccount().getGroups(), permList, false);
149
                    dlg.center();
150
                    checkUpdateButtonVisibility();
151
                }
152
            }
153
        });
154
        add.addStyleName("button");
155
        permButtons.add(add);
156
        permButtons.setCellHorizontalAlignment(add, HasHorizontalAlignment.ALIGN_CENTER);
157

    
158
        permButtons.setSpacing(8);
159
        permPanel.add(permButtons);
160

    
161
        inner.add(permPanel);
162

    
163
        outer.add(inner);
164

    
165
        // Create the 'Create/Update' button, along with a listener that hides the dialog
166
        // when the button is clicked and quits the application.
167
        final String okLabel = "Update";
168
        updateButton = new Button(okLabel, new ClickHandler() {
169
            @Override
170
            public void onClick(ClickEvent event) {
171
                updateFolder();
172
                closeDialog();
173
            }
174
        });
175
        updateButton.addStyleName("button");
176
        checkUpdateButtonVisibility();
177
        outer.add(updateButton);
178
        outer.setCellHorizontalAlignment(inner, HasHorizontalAlignment.ALIGN_CENTER);
179

    
180
        setWidget(outer);
181
    }
182

    
183
    private void checkUpdateButtonVisibility() {
184
        if(!this._initialPermissionCheck) {
185
            updateButton.setVisible(true);
186
            return;
187
        }
188

    
189
        updateButton.setVisible(permList.hasPermissions());
190

    
191
        this._initialPermissionCheck = false;
192
    }
193

    
194
    @Override
195
    protected void onPreviewNativeEvent(NativePreviewEvent preview) {
196
        super.onPreviewNativeEvent(preview);
197

    
198
        NativeEvent evt = preview.getNativeEvent();
199
        if(evt.getType().equals(KeyDownEvent.getType().getName()))
200
        // Use the popup's key preview hooks to close the dialog when either
201
        // enter or escape is pressed.
202
        {
203
            switch(evt.getKeyCode()) {
204
                case KeyCodes.KEY_ENTER:
205
                    updateFolder();
206
                    closeDialog();
207
                    break;
208
                case KeyCodes.KEY_ESCAPE:
209
                    closeDialog();
210
                    break;
211
            }
212
        }
213
    }
214

    
215
    /**
216
     * Enables IE selection prevention and hides the dialog
217
     * (we disable the prevention on creation of the dialog)
218
     */
219
    public void closeDialog() {
220
        Pithos.preventIESelection();
221
        hide();
222
    }
223

    
224
    void updateFolder() {
225
        final Map<String, Boolean[]> perms = (permList.hasChanges() ? permList.getPermissions() : null);
226
        updateMetadata(
227
            folder.getUri() + Const.QUESTION_MARK_UPDATE_EQ,
228
            perms
229
        );
230
    }
231

    
232
    protected void updateMetadata(final String path, final Map<String, Boolean[]> newPermissions) {
233
        if(newPermissions != null) {
234
            PostRequest updateFolder = new PostRequest(app.getApiPath(), folder.getOwnerID(), path) {
235
                @Override
236
                public void onSuccess(Resource result) {
237
                    app.updateFolder(folder.getParent(), false, new Command() {
238
                        @Override
239
                        public void execute() {
240
                            app.updateMySharedRoot();
241
                        }
242
                    }, true);
243
                }
244

    
245
                @Override
246
                public void onError(Throwable t) {
247
                    app.setError(t);
248
                    if(t instanceof RestException) {
249
                        if(((RestException) t).getHttpStatusCode() == Response.SC_NOT_FOUND) { //Probably a virtual folder
250
                            final String path1 = folder.getUri();
251
                            PutRequest newFolder = new PutRequest(app.getApiPath(), folder.getOwnerID(), path1) {
252
                                @Override
253
                                public void onSuccess(Resource result) {
254
                                    updateMetadata(path, newPermissions);
255
                                }
256

    
257
                                @Override
258
                                public void onError(Throwable _t) {
259
                                    app.setError(_t);
260
                                    if(_t instanceof RestException) {
261
                                        app.displayError("Unable to update folder: " + ((RestException) _t).getHttpStatusText());
262
                                    }
263
                                    else {
264
                                        app.displayError("System error modifying folder: " + _t.getMessage());
265
                                    }
266
                                }
267

    
268
                                @Override
269
                                protected void onUnauthorized(Response response) {
270
                                    app.sessionExpired();
271
                                }
272
                            };
273
                            newFolder.setHeader("X-Auth-Token", app.getUserToken());
274
                            newFolder.setHeader("Content-Type", "application/folder");
275
                            newFolder.setHeader("Accept", "*/*");
276
                            newFolder.setHeader("Content-Length", "0");
277
                            Scheduler.get().scheduleDeferred(newFolder);
278
                        }
279
                        else if(((RestException) t).getHttpStatusCode() == Response.SC_CONFLICT) {
280
                            app.displayError("Cannot set permissions. Probably subfolders or files already have permissions set");
281
                        }
282
                        else {
283
                            app.displayError("Εrror modifying folder: " + t.getMessage());
284
                        }
285
                    }
286
                    else {
287
                        app.displayError("System error modifying folder: " + t.getMessage());
288
                    }
289
                }
290

    
291
                @Override
292
                protected void onUnauthorized(Response response) {
293
                    app.sessionExpired();
294
                }
295
            };
296
            updateFolder.setHeader("X-Auth-Token", app.getUserToken());
297
            String readPermHeader = "read=";
298
            String writePermHeader = "write=";
299
            for(String u : newPermissions.keySet()) {
300
                Boolean[] p = newPermissions.get(u);
301
                if(p[0] != null && p[0]) {
302
                    readPermHeader += u + ",";
303
                }
304
                if(p[1] != null && p[1]) {
305
                    writePermHeader += u + ",";
306
                }
307
            }
308
            if(readPermHeader.endsWith("=")) {
309
                readPermHeader = "";
310
            }
311
            else if(readPermHeader.endsWith(",")) {
312
                readPermHeader = readPermHeader.substring(0, readPermHeader.length() - 1);
313
            }
314
            if(writePermHeader.endsWith("=")) {
315
                writePermHeader = "";
316
            }
317
            else if(writePermHeader.endsWith(",")) {
318
                writePermHeader = writePermHeader.substring(0, writePermHeader.length() - 1);
319
            }
320
            String permHeader = readPermHeader + ((readPermHeader.length() > 0 && writePermHeader.length() > 0) ? ";" : "") + writePermHeader;
321
            if(permHeader.length() == 0) {
322
                permHeader = "~";
323
            }
324
            else {
325
                permHeader = URL.encodePathSegment(permHeader);
326
            }
327
            updateFolder.setHeader("X-Object-Sharing", permHeader);
328
            Scheduler.get().scheduleDeferred(updateFolder);
329
        }
330
        else {
331
            app.updateFolder(folder.getParent(), false, new Command() {
332
                @Override
333
                public void execute() {
334
                    app.updateMySharedRoot();
335
                }
336
            }, true);
337
        }
338
    }
339
}