Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / Pithos.java @ 3646552f

History | View | Annotate | Download (47.8 kB)

1
/*
2
 * Copyright 2011-2012 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.PithosDisclosurePanel.Style;
38
import gr.grnet.pithos.web.client.commands.UploadFileCommand;
39
import gr.grnet.pithos.web.client.foldertree.AccountResource;
40
import gr.grnet.pithos.web.client.foldertree.File;
41
import gr.grnet.pithos.web.client.foldertree.Folder;
42
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
43
import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
44
import gr.grnet.pithos.web.client.foldertree.Resource;
45
import gr.grnet.pithos.web.client.grouptree.Group;
46
import gr.grnet.pithos.web.client.grouptree.GroupTreeView;
47
import gr.grnet.pithos.web.client.grouptree.GroupTreeViewModel;
48
import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeView;
49
import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeViewModel;
50
import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeView;
51
import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeViewModel;
52
import gr.grnet.pithos.web.client.rest.DeleteRequest;
53
import gr.grnet.pithos.web.client.rest.GetRequest;
54
import gr.grnet.pithos.web.client.rest.HeadRequest;
55
import gr.grnet.pithos.web.client.rest.PutRequest;
56
import gr.grnet.pithos.web.client.rest.RestException;
57

    
58
import java.util.ArrayList;
59
import java.util.HashMap;
60
import java.util.Iterator;
61
import java.util.List;
62
import java.util.Set;
63

    
64
import com.google.gwt.core.client.EntryPoint;
65
import com.google.gwt.core.client.GWT;
66
import com.google.gwt.core.client.JavaScriptObject;
67
import com.google.gwt.core.client.JsArray;
68
import com.google.gwt.core.client.JsArrayString;
69
import com.google.gwt.core.client.Scheduler;
70
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
71
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
72
import com.google.gwt.event.dom.client.ClickEvent;
73
import com.google.gwt.event.dom.client.ClickHandler;
74
import com.google.gwt.event.logical.shared.ResizeEvent;
75
import com.google.gwt.event.logical.shared.ResizeHandler;
76
import com.google.gwt.http.client.Request;
77
import com.google.gwt.http.client.RequestBuilder;
78
import com.google.gwt.http.client.RequestCallback;
79
import com.google.gwt.http.client.RequestException;
80
import com.google.gwt.http.client.Response;
81
import com.google.gwt.http.client.URL;
82
import com.google.gwt.i18n.client.Dictionary;
83
import com.google.gwt.i18n.client.NumberFormat;
84
import com.google.gwt.json.client.JSONArray;
85
import com.google.gwt.json.client.JSONObject;
86
import com.google.gwt.json.client.JSONParser;
87
import com.google.gwt.json.client.JSONString;
88
import com.google.gwt.json.client.JSONValue;
89
import com.google.gwt.resources.client.ClientBundle;
90
import com.google.gwt.resources.client.CssResource;
91
import com.google.gwt.resources.client.ImageResource;
92
import com.google.gwt.resources.client.ClientBundle.Source;
93
import com.google.gwt.resources.client.ImageResource.ImageOptions;
94
import com.google.gwt.user.client.Command;
95
import com.google.gwt.user.client.Cookies;
96
import com.google.gwt.user.client.Event;
97
import com.google.gwt.user.client.History;
98
import com.google.gwt.user.client.Window;
99
import com.google.gwt.user.client.ui.AbstractImagePrototype;
100
import com.google.gwt.user.client.ui.Button;
101
import com.google.gwt.user.client.ui.Composite;
102
import com.google.gwt.user.client.ui.FlowPanel;
103
import com.google.gwt.user.client.ui.HTML;
104
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
105
import com.google.gwt.user.client.ui.HasVerticalAlignment;
106
import com.google.gwt.user.client.ui.HorizontalPanel;
107
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
108
import com.google.gwt.user.client.ui.PopupPanel;
109
import com.google.gwt.user.client.ui.RootPanel;
110
import com.google.gwt.user.client.ui.VerticalPanel;
111
import com.google.gwt.view.client.SelectionChangeEvent;
112
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
113
import com.google.gwt.view.client.SingleSelectionModel;
114

    
115
/**
116
 * Entry point classes define <code>onModuleLoad()</code>.
117
 */
118
public class Pithos implements EntryPoint, ResizeHandler {
119

    
120
        public static final String HOME_CONTAINER = "pithos";
121

    
122
        public static final String TRASH_CONTAINER = "trash";
123

    
124
        public static final Configuration config = GWT.create(Configuration.class);
125
        
126
        public interface Style extends CssResource {
127
                String commandAnchor();
128
                
129
                String statistics();
130
                
131
                @ClassName("gwt-HTML")
132
                String html();
133
                
134
                String uploadAlert();
135

    
136
                String uploadAlertLink();
137

    
138
                String uploadAlertClose();
139
        }
140
        
141
        public interface Resources extends ClientBundle {
142
                @Source("Pithos.css")
143
                Style pithosCss();
144
                
145
                @Source("gr/grnet/pithos/resources/close-popup.png")
146
                ImageResource closePopup();
147
        }
148

    
149
        public static Resources resources = GWT.create(Resources.class);
150
        
151
        /**
152
         * Instantiate an application-level image bundle. This object will provide
153
         * programmatic access to all the images needed by widgets.
154
         */
155
        static Images images = (Images) GWT.create(Images.class);
156

    
157
    public String getUsername() {
158
        return username;
159
    }
160

    
161
    public void setAccount(AccountResource acct) {
162
        account = acct;
163
    }
164

    
165
    public AccountResource getAccount() {
166
        return account;
167
    }
168

    
169
    public void updateFolder(Folder f, boolean showfiles, Command callback, final boolean openParent) {
170
        folderTreeView.updateFolder(f, showfiles, callback, openParent);
171
    }
172

    
173
    public void updateGroupNode(Group group) {
174
        groupTreeView.updateGroupNode(group);
175
    }
176

    
177
    public void updateMySharedRoot() {
178
            mysharedTreeView.updateRoot();
179
    }
180
    
181
    public void updateSharedFolder(Folder f, boolean showfiles, Command callback) {
182
            mysharedTreeView.updateFolder(f, showfiles, callback);
183
    }
184
    
185
    public void updateSharedFolder(Folder f, boolean showfiles) {
186
            updateSharedFolder(f, showfiles, null);
187
    }
188

    
189
    public void updateOtherSharedFolder(Folder f, boolean showfiles, Command callback) {
190
            otherSharedTreeView.updateFolder(f, showfiles, callback);
191
    }
192

    
193
    public MysharedTreeView getMySharedTreeView() {
194
        return mysharedTreeView;
195
    }
196

    
197
    /**
198
         * An aggregate image bundle that pulls together all the images for this
199
         * application into a single bundle.
200
         */
201
        public interface Images extends TopPanel.Images, FileList.Images, ToolsMenu.Images {
202

    
203
                @Source("gr/grnet/pithos/resources/document.png")
204
                ImageResource folders();
205

    
206
                @Source("gr/grnet/pithos/resources/advancedsettings.png")
207
                @ImageOptions(width=32, height=32)
208
                ImageResource tools();
209
        }
210

    
211
        private Throwable error;
212
        
213
        /**
214
         * The Application Clipboard implementation;
215
         */
216
        private Clipboard clipboard = new Clipboard();
217

    
218
        /**
219
         * The top panel that contains the menu bar.
220
         */
221
        private TopPanel topPanel;
222

    
223
        /**
224
         * The panel that contains the various system messages.
225
         */
226
        private MessagePanel messagePanel = new MessagePanel(this, Pithos.images);
227

    
228
        /**
229
         * The bottom panel that contains the status bar.
230
         */
231
        private StatusPanel statusPanel = null;
232

    
233
        /**
234
         * The file list widget.
235
         */
236
        private FileList fileList;
237

    
238
        /**
239
         * The tab panel that occupies the right side of the screen.
240
         */
241
        private VerticalPanel inner = new VerticalPanel();
242

    
243

    
244
        /**
245
         * The split panel that will contain the left and right panels.
246
         */
247
        private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
248

    
249
        /**
250
         * The currently selected item in the application, for use by the Edit menu
251
         * commands. Potential types are Folder, File, User and Group.
252
         */
253
        private Object currentSelection;
254

    
255
        public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
256

    
257
    private String username = null;
258

    
259
    /**
260
     * The authentication token of the current user.
261
     */
262
    private String token;
263

    
264
    VerticalPanel trees;
265
    
266
    SingleSelectionModel<Folder> folderTreeSelectionModel;
267
    FolderTreeViewModel folderTreeViewModel;
268
    FolderTreeView folderTreeView;
269

    
270
    SingleSelectionModel<Folder> mysharedTreeSelectionModel;
271
    MysharedTreeViewModel mysharedTreeViewModel;
272
    MysharedTreeView mysharedTreeView = null;;
273

    
274
    protected SingleSelectionModel<Folder> otherSharedTreeSelectionModel;
275
    OtherSharedTreeViewModel otherSharedTreeViewModel;
276
    OtherSharedTreeView otherSharedTreeView = null;
277

    
278
    GroupTreeViewModel groupTreeViewModel;
279
    GroupTreeView groupTreeView;
280

    
281
    TreeView selectedTree;
282
    protected AccountResource account;
283
    
284
    Folder trash;
285
    
286
    List<Composite> treeViews = new ArrayList<Composite>();
287

    
288
    @SuppressWarnings("rawtypes") List<SingleSelectionModel> selectionModels = new ArrayList<SingleSelectionModel>();
289
    
290
    public Button upload;
291
    
292
    private HTML numOfFiles;
293
    
294
    private Toolbar toolbar;
295
    
296
    private FileUploadDialog fileUploadDialog = new FileUploadDialog(this);
297

    
298
        UploadAlert uploadAlert;
299

    
300
        @Override
301
        public void onModuleLoad() {
302
                if (parseUserCredentials())
303
            initialize();
304
        }
305

    
306
    private void initialize() {
307
            resources.pithosCss().ensureInjected();
308
            boolean bareContent = Window.Location.getParameter("noframe") != null;
309
            String contentWidth = bareContent ? "100%" : "75%";
310

    
311
            VerticalPanel outer = new VerticalPanel();
312
        outer.setWidth("100%");
313
            if (!bareContent) {
314
                    outer.addStyleName("pithos-outer");
315
            }
316

    
317
        if (!bareContent) {
318
                topPanel = new TopPanel(this, Pithos.images);
319
                topPanel.setWidth("100%");
320
                outer.add(topPanel);
321
                outer.setCellHorizontalAlignment(topPanel, HasHorizontalAlignment.ALIGN_CENTER);
322
        }
323
        
324
        messagePanel.setVisible(false);
325
        outer.add(messagePanel);
326
        outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
327
        outer.setCellVerticalAlignment(messagePanel, HasVerticalAlignment.ALIGN_MIDDLE);
328

    
329
        HorizontalPanel header = new HorizontalPanel();
330
        header.addStyleName("pithos-header");
331
        header.setWidth(contentWidth);
332
        if (bareContent)
333
                header.addStyleName("pithos-header-noframe");
334
        upload = new Button("Upload", new ClickHandler() {
335
            @Override
336
            public void onClick(ClickEvent event) {
337
                    if (getSelection() != null)
338
                            new UploadFileCommand(Pithos.this, null, getSelection()).execute();
339
            }
340
        });
341
        upload.addStyleName("pithos-uploadButton");
342
        header.add(upload);
343
        header.setCellHorizontalAlignment(upload, HasHorizontalAlignment.ALIGN_LEFT);
344
        header.setCellVerticalAlignment(upload, HasVerticalAlignment.ALIGN_MIDDLE);
345

    
346
        toolbar = new Toolbar(this);
347
        header.add(toolbar);
348
        header.setCellHorizontalAlignment(toolbar, HasHorizontalAlignment.ALIGN_CENTER);
349
        header.setCellVerticalAlignment(toolbar, HasVerticalAlignment.ALIGN_MIDDLE);
350
        
351
        HorizontalPanel folderStatistics = new HorizontalPanel();
352
        folderStatistics.addStyleName("pithos-folderStatistics");
353
        numOfFiles = new HTML();
354
        folderStatistics.add(numOfFiles);
355
        folderStatistics.setCellVerticalAlignment(numOfFiles, HasVerticalAlignment.ALIGN_MIDDLE);
356
        HTML numOfFilesLabel = new HTML("&nbsp;Files");
357
        folderStatistics.add(numOfFilesLabel);
358
        folderStatistics.setCellVerticalAlignment(numOfFilesLabel, HasVerticalAlignment.ALIGN_MIDDLE);
359
        header.add(folderStatistics);
360
        header.setCellHorizontalAlignment(folderStatistics, HasHorizontalAlignment.ALIGN_RIGHT);
361
        header.setCellVerticalAlignment(folderStatistics, HasVerticalAlignment.ALIGN_MIDDLE);
362
        header.setCellWidth(folderStatistics, "40px");
363
        outer.add(header);
364
        outer.setCellHorizontalAlignment(header, HasHorizontalAlignment.ALIGN_CENTER);
365
        // Inner contains the various lists
366
        inner.sinkEvents(Event.ONCONTEXTMENU);
367
        inner.setWidth("100%");
368

    
369
        folderTreeSelectionModel = new SingleSelectionModel<Folder>();
370
        folderTreeSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
371
            @Override
372
            public void onSelectionChange(SelectionChangeEvent event) {
373
                if (folderTreeSelectionModel.getSelectedObject() != null) {
374
                    deselectOthers(folderTreeView, folderTreeSelectionModel);
375
                    applyPermissions(folderTreeSelectionModel.getSelectedObject());
376
                    Folder f = folderTreeSelectionModel.getSelectedObject();
377
                            updateFolder(f, true, new Command() {
378
                                    
379
                                    @Override
380
                                    public void execute() {
381
                                            updateStatistics();
382
                                    }
383
                            }, true);
384
                            showRelevantToolbarButtons();
385
                }
386
                                else {
387
                                        if (getSelectedTree().equals(folderTreeView))
388
                                                setSelectedTree(null);
389
                                        if (getSelectedTree() == null)
390
                                                showRelevantToolbarButtons();
391
                                }
392
            }
393
        });
394
        selectionModels.add(folderTreeSelectionModel);
395

    
396
        folderTreeViewModel = new FolderTreeViewModel(this, folderTreeSelectionModel);
397
        folderTreeView = new FolderTreeView(folderTreeViewModel);
398
        treeViews.add(folderTreeView);
399
        
400
        fileList = new FileList(this, images);
401
        inner.add(fileList);
402

    
403
        inner.add(createUploadArea());
404
        
405
        trees = new VerticalPanel();
406
        trees.setWidth("100%");
407
        
408
        // Add the left and right panels to the split panel.
409
        splitPanel.setLeftWidget(trees);
410
        FlowPanel right = new FlowPanel();
411
        right.getElement().setId("rightPanel");
412
        right.add(inner);
413
        splitPanel.setRightWidget(right);
414
        splitPanel.setSplitPosition("219px");
415
        splitPanel.setSize("100%", "100%");
416
        splitPanel.addStyleName("pithos-splitPanel");
417
        splitPanel.setWidth(contentWidth);
418
        outer.add(splitPanel);
419
        outer.setCellHorizontalAlignment(splitPanel, HasHorizontalAlignment.ALIGN_CENTER);
420

    
421
        if (!bareContent) {
422
                statusPanel = new StatusPanel();
423
                statusPanel.setWidth("100%");
424
                outer.add(statusPanel);
425
                outer.setCellHorizontalAlignment(statusPanel, HasHorizontalAlignment.ALIGN_CENTER);
426
        }
427
        else
428
                splitPanel.addStyleName("pithos-splitPanel-noframe");
429

    
430
        // Hook the window resize event, so that we can adjust the UI.
431
        Window.addResizeHandler(this);
432
        // Clear out the window's built-in margin, because we want to take
433
        // advantage of the entire client area.
434
        Window.setMargin("0px");
435
        // Finally, add the outer panel to the RootPanel, so that it will be
436
        // displayed.
437
        RootPanel.get().add(outer);
438
        // Call the window resized handler to get the initial sizes setup. Doing
439
        // this in a deferred command causes it to occur after all widgets'
440
        // sizes have been computed by the browser.
441
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
442

    
443
            @Override
444
            public void execute() {
445
                onWindowResized(Window.getClientHeight());
446
            }
447
        });
448

    
449
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
450
            @Override
451
            public void execute() {
452
                fetchAccount(new Command() {
453
                                        
454
                                        @Override
455
                                        public void execute() {
456
                                if (!account.hasHomeContainer())
457
                                    createHomeContainer(account, this);
458
                                else if (!account.hasTrashContainer())
459
                                        createTrashContainer(this);
460
                                else {
461
                                        for (Folder f : account.getContainers())
462
                                                if (f.getName().equals(Pithos.TRASH_CONTAINER)) {
463
                                                        trash = f;
464
                                                        break;
465
                                                }
466
                                    trees.add(folderTreeView);
467
                                    folderTreeViewModel.initialize(account, new Command() {
468
                                                                
469
                                                                @Override
470
                                                                public void execute() {
471
                                                    createMySharedTree();
472
                                                                }
473
                                                        });
474

    
475
                                    HorizontalPanel separator = new HorizontalPanel();
476
                                    separator.addStyleName("pithos-statisticsSeparator");
477
                                    separator.add(new HTML(""));
478
                                    trees.add(separator);
479

    
480
                                    groupTreeViewModel = new GroupTreeViewModel(Pithos.this);
481
                                    groupTreeView = new GroupTreeView(groupTreeViewModel);
482
                                    treeViews.add(groupTreeView);
483
                                    trees.add(groupTreeView);
484
                                    folderTreeView.showStatistics(account);
485
                                }
486
                                        }
487
                                });
488
            }
489
        });
490
        
491
        Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
492
                        
493
                        @Override
494
                        public boolean execute() {
495
                                Folder f = getSelection();
496
                                if (f != null) {
497
                                        if (getSelectedTree().equals(folderTreeView))
498
                                                updateFolder(f, true, null, false);
499
                                        else if (getSelectedTree().equals(mysharedTreeView))
500
                                                updateSharedFolder(f, true);
501
                                }
502
                                return true;
503
                        }
504
                }, 3000);
505
    }
506

    
507
    public void applyPermissions(Folder f) {
508
            if (f != null) {
509
                    if (f.isInTrash()) {
510
                            upload.setEnabled(false);
511
                            disableUploadArea();
512
                    }
513
                    else {
514
                            Boolean[] perms = f.getPermissions().get(username);
515
                            if (f.getOwner().equals(username) || (perms != null && perms[1] != null && perms[1])) {
516
                                    upload.setEnabled(true);
517
                                    enableUploadArea();
518
                            }
519
                            else {
520
                                    upload.setEnabled(false);
521
                                    disableUploadArea();
522
                            }
523
                    }
524
            }
525
            else {
526
                    upload.setEnabled(false);
527
                    disableUploadArea();
528
            }
529
        }
530

    
531
        @SuppressWarnings({ "rawtypes", "unchecked" })
532
        public void deselectOthers(TreeView _selectedTree, SingleSelectionModel model) {
533
            selectedTree = _selectedTree;
534
            
535
        for (SingleSelectionModel s : selectionModels)
536
            if (!s.equals(model) && s.getSelectedObject() != null)
537
                s.setSelected(s.getSelectedObject(), false);
538
    }
539

    
540
    public void showFiles(final Folder f) {
541
        Set<File> files = f.getFiles();
542
        showFiles(files);
543
    }
544

    
545
    public void showFiles(Set<File> files) {
546
        fileList.setFiles(new ArrayList<File>(files));
547
    }
548

    
549
    /**
550
         * Parse and store the user credentials to the appropriate fields.
551
         */
552
        private boolean parseUserCredentials() {
553
        Configuration conf = (Configuration) GWT.create(Configuration.class);
554
                Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
555
        String cookie = otherProperties.get("authCookie");
556
        String auth = Cookies.getCookie(cookie);
557
        if (auth == null) {
558
            authenticateUser();
559
            return false;
560
        }
561
        if (auth.startsWith("\""))
562
                auth = auth.substring(1);
563
        if (auth.endsWith("\""))
564
                auth = auth.substring(0, auth.length() - 1);
565
                String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2);
566
                if (authSplit.length != 2) {
567
                    authenticateUser();
568
                    return false;
569
                }
570
                username = authSplit[0];
571
                token = authSplit[1];
572

    
573
        String gotoUrl = Window.Location.getParameter("goto");
574
                if (gotoUrl != null && gotoUrl.length() > 0) {
575
                        Window.Location.assign(gotoUrl);
576
                        return false;
577
                }
578
                return true;
579
    }
580

    
581
    /**
582
         * Redirect the user to the login page for authentication.
583
         */
584
        protected void authenticateUser() {
585
                Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
586
        Window.Location.assign(otherProperties.get("loginUrl") + Window.Location.getHref());
587
        }
588

    
589
        protected void fetchAccount(final Command callback) {
590
        String path = "?format=json";
591

    
592
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, getApiPath(), username, path) {
593
            @Override
594
            public void onSuccess(AccountResource _result) {
595
                account = _result;
596
                if (callback != null)
597
                        callback.execute();
598
            }
599

    
600
            @Override
601
            public void onError(Throwable t) {
602
                GWT.log("Error getting account", t);
603
                                setError(t);
604
                if (t instanceof RestException)
605
                    displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
606
                else
607
                    displayError("System error fetching user data: " + t.getMessage());
608
            }
609

    
610
                        @Override
611
                        protected void onUnauthorized(Response response) {
612
                                sessionExpired();
613
                        }
614
        };
615
        getAccount.setHeader("X-Auth-Token", token);
616
        Scheduler.get().scheduleDeferred(getAccount);
617
    }
618

    
619
    public void updateStatistics() {
620
            HeadRequest<AccountResource> headAccount = new HeadRequest<AccountResource>(AccountResource.class, getApiPath(), username, "", account) {
621

    
622
                        @Override
623
                        public void onSuccess(AccountResource _result) {
624
                                folderTreeView.showStatistics(account);
625
                        }
626

    
627
                        @Override
628
                        public void onError(Throwable t) {
629
                GWT.log("Error getting account", t);
630
                                setError(t);
631
                if (t instanceof RestException)
632
                    displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
633
                else
634
                    displayError("System error fetching user data: " + t.getMessage());
635
                        }
636

    
637
                        @Override
638
                        protected void onUnauthorized(Response response) {
639
                                sessionExpired();
640
                        }
641
                };
642
                headAccount.setHeader("X-Auth-Token", token);
643
                Scheduler.get().scheduleDeferred(headAccount);
644
        }
645

    
646
        protected void createHomeContainer(final AccountResource _account, final Command callback) {
647
        String path = "/" + Pithos.HOME_CONTAINER;
648
        PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) {
649
            @Override
650
            public void onSuccess(Resource result) {
651
                    if (!_account.hasTrashContainer())
652
                            createTrashContainer(callback);
653
                    else
654
                            fetchAccount(callback);
655
            }
656

    
657
            @Override
658
            public void onError(Throwable t) {
659
                GWT.log("Error creating pithos", t);
660
                                setError(t);
661
                if (t instanceof RestException)
662
                    displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText());
663
                else
664
                    displayError("System error Error creating pithos: " + t.getMessage());
665
            }
666

    
667
                        @Override
668
                        protected void onUnauthorized(Response response) {
669
                                sessionExpired();
670
                        }
671
        };
672
        createPithos.setHeader("X-Auth-Token", getToken());
673
        Scheduler.get().scheduleDeferred(createPithos);
674
    }
675

    
676
    protected void createTrashContainer(final Command callback) {
677
        String path = "/" + Pithos.TRASH_CONTAINER;
678
        PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) {
679
            @Override
680
            public void onSuccess(Resource result) {
681
                           fetchAccount(callback);
682
            }
683

    
684
            @Override
685
            public void onError(Throwable t) {
686
                GWT.log("Error creating pithos", t);
687
                                setError(t);
688
                if (t instanceof RestException)
689
                    displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText());
690
                else
691
                    displayError("System error Error creating pithos: " + t.getMessage());
692
            }
693

    
694
                        @Override
695
                        protected void onUnauthorized(Response response) {
696
                                sessionExpired();
697
                        }
698
        };
699
        createPithos.setHeader("X-Auth-Token", getToken());
700
        Scheduler.get().scheduleDeferred(createPithos);
701
    }
702

    
703
    /**
704
         * Creates an HTML fragment that places an image & caption together, for use
705
         * in a group header.
706
         *
707
         * @param imageProto an image prototype for an image
708
         * @param caption the group caption
709
         * @return the header HTML fragment
710
         */
711
        private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
712
                String captionHTML = "<table class='caption' cellpadding='0' " 
713
                + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() 
714
                + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'>&nbsp;" 
715
                + caption + "</b></td></tr></table>";
716
                return captionHTML;
717
        }
718

    
719
        protected void onWindowResized(int height) {
720
                // Adjust the split panel to take up the available room in the window.
721
                int newHeight = height - splitPanel.getAbsoluteTop();
722
                if (newHeight < 1)
723
                        newHeight = 1;
724
                splitPanel.setHeight("" + newHeight);
725
                inner.setHeight("" + newHeight);
726
        }
727

    
728
        @Override
729
        public void onResize(ResizeEvent event) {
730
                int height = event.getHeight();
731
                onWindowResized(height);
732
        }
733

    
734
        /**
735
         * Display an error message.
736
         *
737
         * @param msg the message to display
738
         */
739
        public void displayError(String msg) {
740
                messagePanel.displayError(msg);
741
        }
742

    
743
        /**
744
         * Display a warning message.
745
         *
746
         * @param msg the message to display
747
         */
748
        public void displayWarning(String msg) {
749
                messagePanel.displayWarning(msg);
750
        }
751

    
752
        /**
753
         * Display an informational message.
754
         *
755
         * @param msg the message to display
756
         */
757
        public void displayInformation(String msg) {
758
                messagePanel.displayInformation(msg);
759
        }
760

    
761
        /**
762
         * Retrieve the fileList.
763
         *
764
         * @return the fileList
765
         */
766
        public FileList getFileList() {
767
                return fileList;
768
        }
769

    
770
        /**
771
         * Retrieve the topPanel.
772
         *
773
         * @return the topPanel
774
         */
775
        TopPanel getTopPanel() {
776
                return topPanel;
777
        }
778

    
779
        /**
780
         * Retrieve the clipboard.
781
         *
782
         * @return the clipboard
783
         */
784
        public Clipboard getClipboard() {
785
                return clipboard;
786
        }
787

    
788
        public StatusPanel getStatusPanel() {
789
                return statusPanel;
790
        }
791

    
792
        public String getToken() {
793
                return token;
794
        }
795

    
796
        public static native void preventIESelection() /*-{
797
                $doc.body.onselectstart = function () { return false; };
798
        }-*/;
799

    
800
        public static native void enableIESelection() /*-{
801
                if ($doc.body.onselectstart != null)
802
                $doc.body.onselectstart = null;
803
        }-*/;
804

    
805
        /**
806
         * @return the absolute path of the API root URL
807
         */
808
        public String getApiPath() {
809
                Configuration conf = (Configuration) GWT.create(Configuration.class);
810
                return conf.apiPath();
811
        }
812

    
813
        /**
814
         * History support for folder navigation
815
         * adds a new browser history entry
816
         *
817
         * @param key
818
         */
819
        public void updateHistory(String key){
820
//                Replace any whitespace of the initial string to "+"
821
//                String result = key.replaceAll("\\s","+");
822
//                Add a new browser history entry.
823
//                History.newItem(result);
824
                History.newItem(key);
825
        }
826

    
827
    public void deleteFolder(final Folder folder, final Command callback) {
828
        String path = getApiPath() + folder.getOwner() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(folder.getPrefix()) + "&t=" + System.currentTimeMillis();
829
        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
830
        builder.setHeader("X-Auth-Token", getToken());
831
        try {
832
            builder.sendRequest("", new RequestCallback() {
833
                @Override
834
                public void onResponseReceived(Request request, Response response) {
835
                    if (response.getStatusCode() == Response.SC_OK) {
836
                        JSONValue json = JSONParser.parseStrict(response.getText());
837
                        JSONArray array = json.isArray();
838
                        int i = 0;
839
                        if (array != null) {
840
                            deleteObject(folder, i, array, callback);
841
                        }
842
                    }
843
                }
844

    
845
                @Override
846
                public void onError(Request request, Throwable exception) {
847
                        setError(exception);
848
                    displayError("System error unable to delete folder: " + exception.getMessage());
849
                }
850
            });
851
        }
852
        catch (RequestException e) {
853
        }
854
    }
855

    
856
    void deleteObject(final Folder folder, final int i, final JSONArray array, final Command callback) {
857
        if (i < array.size()) {
858
            JSONObject o = array.get(i).isObject();
859
            if (o != null && !o.containsKey("subdir")) {
860
                JSONString name = o.get("name").isString();
861
                String path = "/" + folder.getContainer() + "/" + name.stringValue();
862
                DeleteRequest delete = new DeleteRequest(getApiPath(), folder.getOwner(), URL.encode(path)) {
863
                    @Override
864
                    public void onSuccess(Resource result) {
865
                        deleteObject(folder, i + 1, array, callback);
866
                    }
867

    
868
                    @Override
869
                    public void onError(Throwable t) {
870
                        GWT.log("", t);
871
                                                setError(t);
872
                        displayError("System error unable to delete folder: " + t.getMessage());
873
                    }
874

    
875
                                    @Override
876
                                    protected void onUnauthorized(Response response) {
877
                                            sessionExpired();
878
                                    }
879
                };
880
                delete.setHeader("X-Auth-Token", getToken());
881
                Scheduler.get().scheduleDeferred(delete);
882
            }
883
            else if (o != null) {
884
                String subdir = o.get("subdir").isString().stringValue();
885
                subdir = subdir.substring(0, subdir.length() - 1);
886
                String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(subdir) + "&t=" + System.currentTimeMillis();
887
                RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
888
                builder.setHeader("X-Auth-Token", getToken());
889
                try {
890
                    builder.sendRequest("", new RequestCallback() {
891
                        @Override
892
                        public void onResponseReceived(Request request, Response response) {
893
                            if (response.getStatusCode() == Response.SC_OK) {
894
                                JSONValue json = JSONParser.parseStrict(response.getText());
895
                                JSONArray array2 = json.isArray();
896
                                if (array2 != null) {
897
                                    int l = array.size();
898
                                    for (int j=0; j<array2.size(); j++) {
899
                                        array.set(l++, array2.get(j));
900
                                    }
901
                                }
902
                                deleteObject(folder, i + 1, array, callback);
903
                            }
904
                        }
905

    
906
                        @Override
907
                        public void onError(Request request, Throwable exception) {
908
                                setError(exception);
909
                            displayError("System error unable to delete folder: " + exception.getMessage());
910
                        }
911
                    });
912
                }
913
                catch (RequestException e) {
914
                }
915
            }
916
        }
917
        else {
918
            String path = folder.getUri();
919
            DeleteRequest deleteFolder = new DeleteRequest(getApiPath(), getUsername(), URL.encode(path)) {
920
                @Override
921
                public void onSuccess(Resource result) {
922
                    updateFolder(folder.getParent(), true, new Command() {
923
                                                
924
                                                @Override
925
                                                public void execute() {
926
                                                        folderTreeSelectionModel.setSelected(folder.getParent(), true);
927
                                                        updateStatistics();
928
                                                        if (callback != null)
929
                                                                callback.execute();
930
                                                }
931
                                        }, true);
932
                }
933

    
934
                @Override
935
                public void onError(Throwable t) {
936
                    GWT.log("", t);
937
                                        setError(t);
938
                    if (t instanceof RestException) {
939
                            if (((RestException) t).getHttpStatusCode() != Response.SC_NOT_FOUND)
940
                                    displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText());
941
                            else
942
                                    onSuccess(null);
943
                    }
944
                    else
945
                        displayError("System error unable to delete folder: " + t.getMessage());
946
                }
947

    
948
                                @Override
949
                                protected void onUnauthorized(Response response) {
950
                                        sessionExpired();
951
                                }
952
            };
953
            deleteFolder.setHeader("X-Auth-Token", getToken());
954
            Scheduler.get().scheduleDeferred(deleteFolder);
955
        }
956
    }
957

    
958
    public FolderTreeView getFolderTreeView() {
959
        return folderTreeView;
960
    }
961

    
962
    public void copyFiles(final Iterator<File> iter, final String targetUsername, final String targetUri, final Command callback) {
963
        if (iter.hasNext()) {
964
            File file = iter.next();
965
            String path = targetUri + "/" + file.getName();
966
            PutRequest copyFile = new PutRequest(getApiPath(), targetUsername, path) {
967
                @Override
968
                public void onSuccess(Resource result) {
969
                    copyFiles(iter, targetUsername, targetUri, callback);
970
                }
971

    
972
                @Override
973
                public void onError(Throwable t) {
974
                    GWT.log("", t);
975
                                        setError(t);
976
                    if (t instanceof RestException) {
977
                        displayError("Unable to copy file: " + ((RestException) t).getHttpStatusText());
978
                    }
979
                    else
980
                        displayError("System error unable to copy file: "+t.getMessage());
981
                }
982

    
983
                                @Override
984
                                protected void onUnauthorized(Response response) {
985
                                        sessionExpired();
986
                                }
987
            };
988
            copyFile.setHeader("X-Auth-Token", getToken());
989
            copyFile.setHeader("X-Copy-From", URL.encodePathSegment(file.getUri()));
990
            if (!file.getOwner().equals(targetUsername))
991
                    copyFile.setHeader("X-Source-Account", URL.encodePathSegment(file.getOwner()));
992
            copyFile.setHeader("Content-Type", file.getContentType());
993
            Scheduler.get().scheduleDeferred(copyFile);
994
        }
995
        else  if (callback != null) {
996
            callback.execute();
997
        }
998
    }
999

    
1000
    public void copySubfolders(final Iterator<Folder> iter, final String targetUsername, final String targetUri, final Command callback) {
1001
        if (iter.hasNext()) {
1002
            final Folder f = iter.next();
1003
            copyFolder(f, targetUsername, targetUri, new Command() {
1004
                                
1005
                                @Override
1006
                                public void execute() {
1007
                                        copySubfolders(iter, targetUsername, targetUri, callback);
1008
                                }
1009
                        });
1010
        }
1011
        else  if (callback != null) {
1012
            callback.execute();
1013
        }
1014
    }
1015

    
1016
    public void copyFolder(final Folder f, final String targetUsername, final String targetUri, final Command callback) {
1017
        String path = targetUri + "/" + f.getName();
1018
        PutRequest createFolder = new PutRequest(getApiPath(), targetUsername, path) {
1019
            @Override
1020
            public void onSuccess(Resource result) {
1021
                    GetRequest<Folder> getFolder = new GetRequest<Folder>(Folder.class, getApiPath(), f.getOwner(), "/" + f.getContainer() + "?format=json&delimiter=/&prefix=" + URL.encodeQueryString(f.getPrefix()), f) {
1022

    
1023
                                        @Override
1024
                                        public void onSuccess(final Folder _f) {
1025
                                Iterator<File> iter = _f.getFiles().iterator();
1026
                                copyFiles(iter, targetUsername, targetUri + "/" + _f.getName(), new Command() {
1027
                                    @Override
1028
                                    public void execute() {
1029
                                        Iterator<Folder> iterf = _f.getSubfolders().iterator();
1030
                                        copySubfolders(iterf, targetUsername, targetUri + "/" + _f.getName(), callback);
1031
                                    }
1032
                                });
1033
                                        }
1034

    
1035
                                        @Override
1036
                                        public void onError(Throwable t) {
1037
                                GWT.log("", t);
1038
                                                setError(t);
1039
                                if (t instanceof RestException) {
1040
                                    displayError("Unable to get folder: " + ((RestException) t).getHttpStatusText());
1041
                                }
1042
                                else
1043
                                    displayError("System error getting folder: " + t.getMessage());
1044
                                        }
1045

    
1046
                                        @Override
1047
                                        protected void onUnauthorized(Response response) {
1048
                                                sessionExpired();
1049
                                        }
1050
                                };
1051
                                getFolder.setHeader("X-Auth-Token", getToken());
1052
                                Scheduler.get().scheduleDeferred(getFolder);
1053
            }
1054

    
1055
            @Override
1056
            public void onError(Throwable t) {
1057
                GWT.log("", t);
1058
                                setError(t);
1059
               if (t instanceof RestException) {
1060
                    displayError("Unable to create folder: " + ((RestException) t).getHttpStatusText());
1061
                }
1062
                else
1063
                    displayError("System error creating folder: " + t.getMessage());
1064
            }
1065

    
1066
                        @Override
1067
                        protected void onUnauthorized(Response response) {
1068
                                sessionExpired();
1069
                        }
1070
        };
1071
        createFolder.setHeader("X-Auth-Token", getToken());
1072
        createFolder.setHeader("Accept", "*/*");
1073
        createFolder.setHeader("Content-Length", "0");
1074
        createFolder.setHeader("Content-Type", "application/folder");
1075
        Scheduler.get().scheduleDeferred(createFolder);
1076
    }
1077
    
1078
    public void addSelectionModel(@SuppressWarnings("rawtypes") SingleSelectionModel model) {
1079
            selectionModels.add(model);
1080
    }
1081

    
1082
        public OtherSharedTreeView getOtherSharedTreeView() {
1083
                return otherSharedTreeView;
1084
        }
1085

    
1086
        public void updateTrash(boolean showFiles, Command callback) {
1087
                updateFolder(trash, showFiles, callback, true);
1088
        }
1089

    
1090
        public void updateGroupsNode() {
1091
                groupTreeView.updateGroupNode(null);
1092
        }
1093

    
1094
        public Group addGroup(String groupname) {
1095
                Group newGroup = new Group(groupname);
1096
                account.addGroup(newGroup);
1097
                groupTreeView.updateGroupNode(null);
1098
                return newGroup;
1099
        }
1100

    
1101
        public void removeGroup(Group group) {
1102
                account.removeGroup(group);
1103
                updateGroupsNode();
1104
        }
1105

    
1106
        public TreeView getSelectedTree() {
1107
                return selectedTree;
1108
        }
1109
        
1110
        public void setSelectedTree(TreeView selected) {
1111
                selectedTree = selected;
1112
        }
1113

    
1114
        public Folder getSelection() {
1115
                if (selectedTree != null)
1116
                        return selectedTree.getSelection();
1117
                return null;
1118
        }
1119

    
1120
        public void showFolderStatistics(int folderFileCount) {
1121
                numOfFiles.setHTML(String.valueOf(folderFileCount));
1122
        }
1123

    
1124
        public GroupTreeView getGroupTreeView() {
1125
                return groupTreeView;
1126
        }
1127

    
1128
        public void sessionExpired() {
1129
                new SessionExpiredDialog(this).center();
1130
        }
1131

    
1132
        public void updateRootFolder(Command callback) {
1133
                updateFolder(account.getPithos(), false, callback, true);
1134
        }
1135

    
1136
        void createMySharedTree() {
1137
                mysharedTreeSelectionModel = new SingleSelectionModel<Folder>();
1138
                mysharedTreeSelectionModel.addSelectionChangeHandler(new Handler() {
1139
                    @Override
1140
                    public void onSelectionChange(SelectionChangeEvent event) {
1141
                        if (mysharedTreeSelectionModel.getSelectedObject() != null) {
1142
                            deselectOthers(mysharedTreeView, mysharedTreeSelectionModel);
1143
                            upload.setEnabled(false);
1144
                            disableUploadArea();
1145
                            updateSharedFolder(mysharedTreeSelectionModel.getSelectedObject(), true);
1146
                                        showRelevantToolbarButtons();
1147
                        }
1148
                                else {
1149
                                        if (getSelectedTree().equals(mysharedTreeView))
1150
                                                setSelectedTree(null);
1151
                                        if (getSelectedTree() == null)
1152
                                                showRelevantToolbarButtons();
1153
                                }
1154
                     }
1155
                });
1156
                selectionModels.add(mysharedTreeSelectionModel);
1157
                mysharedTreeViewModel = new MysharedTreeViewModel(Pithos.this, mysharedTreeSelectionModel);
1158
                mysharedTreeViewModel.initialize(new Command() {
1159
                        
1160
                        @Override
1161
                        public void execute() {
1162
                            mysharedTreeView = new MysharedTreeView(mysharedTreeViewModel);
1163
                                trees.insert(mysharedTreeView, 2);
1164
                                treeViews.add(mysharedTreeView);
1165
                                createOtherSharedTree();
1166
                        }
1167
                });
1168
        }
1169

    
1170
        void createOtherSharedTree() {
1171
                otherSharedTreeSelectionModel = new SingleSelectionModel<Folder>();
1172
                otherSharedTreeSelectionModel.addSelectionChangeHandler(new Handler() {
1173
                    @Override
1174
                    public void onSelectionChange(SelectionChangeEvent event) {
1175
                        if (otherSharedTreeSelectionModel.getSelectedObject() != null) {
1176
                            deselectOthers(otherSharedTreeView, otherSharedTreeSelectionModel);
1177
                            applyPermissions(otherSharedTreeSelectionModel.getSelectedObject());
1178
                            updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true, null);
1179
                                        showRelevantToolbarButtons();
1180
                        }
1181
                                else {
1182
                                        if (getSelectedTree().equals(otherSharedTreeView))
1183
                                                setSelectedTree(null);
1184
                                        if (getSelectedTree() == null)
1185
                                                showRelevantToolbarButtons();
1186
                                }
1187
                     }
1188
                });
1189
                selectionModels.add(otherSharedTreeSelectionModel);
1190
                otherSharedTreeViewModel = new OtherSharedTreeViewModel(Pithos.this, otherSharedTreeSelectionModel);
1191
                otherSharedTreeViewModel.initialize(new Command() {
1192
                        
1193
                        @Override
1194
                        public void execute() {
1195
                            otherSharedTreeView = new OtherSharedTreeView(otherSharedTreeViewModel);
1196
                                trees.insert(otherSharedTreeView, 1);
1197
                                treeViews.add(otherSharedTreeView);
1198
                        }
1199
                });
1200
        }
1201

    
1202
        public native void log1(String message)/*-{
1203
                $wnd.console.log(message);
1204
        }-*/;
1205

    
1206
        public String getErrorData() {
1207
                if (error != null)
1208
                        return error.toString();
1209
                return "";
1210
        }
1211
        
1212
        public void setError(Throwable t) {
1213
                error = t;
1214
        }
1215
        
1216
        public void showRelevantToolbarButtons() {
1217
                toolbar.showRelevantButtons();
1218
        }
1219

    
1220
        public FileUploadDialog getFileUploadDialog() {
1221
                if (fileUploadDialog == null)
1222
                        fileUploadDialog = new FileUploadDialog(this);
1223
                return fileUploadDialog;
1224
        }
1225

    
1226
        public void hideUploadIndicator() {
1227
                upload.removeStyleName("pithos-uploadButton-loading");
1228
                upload.setTitle("");
1229
        }
1230
        
1231
        public void showUploadIndicator() {
1232
                upload.addStyleName("pithos-uploadButton-loading");
1233
                upload.setTitle("Upload in progress. Click for details.");
1234
        }
1235

    
1236
        public void scheduleFolderHeadCommand(final Folder folder, final Command callback) {
1237
                if (folder == null) {
1238
                        if (callback != null)
1239
                                callback.execute();
1240
                }
1241
                else {
1242
                        HeadRequest<Folder> headFolder = new HeadRequest<Folder>(Folder.class, getApiPath(), folder.getOwner(), folder.getUri(), folder) {
1243
        
1244
                                @Override
1245
                                public void onSuccess(Folder _result) {
1246
                                        if (callback != null)
1247
                                                callback.execute();
1248
                                }
1249
        
1250
                                @Override
1251
                                public void onError(Throwable t) {
1252
                                if (t instanceof RestException) {
1253
                                        if (((RestException) t).getHttpStatusCode() == Response.SC_NOT_FOUND) {
1254
                                final String path = folder.getUri();
1255
                                PutRequest newFolder = new PutRequest(getApiPath(), folder.getOwner(), path) {
1256
                                    @Override
1257
                                    public void onSuccess(Resource _result) {
1258
                                            scheduleFolderHeadCommand(folder, callback);
1259
                                    }
1260
        
1261
                                    @Override
1262
                                    public void onError(Throwable _t) {
1263
                                        GWT.log("", _t);
1264
                                                                setError(_t);
1265
                                        if(_t instanceof RestException){
1266
                                            displayError("Unable to create folder: " + ((RestException) _t).getHttpStatusText());
1267
                                        }
1268
                                        else
1269
                                            displayError("System error creating folder: " + _t.getMessage());
1270
                                    }
1271
        
1272
                                                    @Override
1273
                                                    protected void onUnauthorized(Response response) {
1274
                                                            sessionExpired();
1275
                                                    }
1276
                                };
1277
                                newFolder.setHeader("X-Auth-Token", getToken());
1278
                                newFolder.setHeader("Content-Type", "application/folder");
1279
                                newFolder.setHeader("Accept", "*/*");
1280
                                newFolder.setHeader("Content-Length", "0");
1281
                                Scheduler.get().scheduleDeferred(newFolder);
1282
                                        }
1283
                                        else
1284
                                                displayError("Error heading folder: " + ((RestException) t).getHttpStatusText());
1285
                                }
1286
                                else
1287
                                    displayError("System error heading folder: " + t.getMessage());
1288
        
1289
                                GWT.log("Error heading folder", t);
1290
                                        setError(t);
1291
                                }
1292
        
1293
                                @Override
1294
                                protected void onUnauthorized(Response response) {
1295
                                        sessionExpired();
1296
                                }
1297
                        };
1298
                        headFolder.setHeader("X-Auth-Token", getToken());
1299
                        Scheduler.get().scheduleDeferred(headFolder);
1300
                }
1301
        }
1302

    
1303
        public void scheduleFileHeadCommand(File f, final Command callback) {
1304
                HeadRequest<File> headFile = new HeadRequest<File>(File.class, getApiPath(), f.getOwner(), f.getUri(), f) {
1305

    
1306
                        @Override
1307
                        public void onSuccess(File _result) {
1308
                                if (callback != null)
1309
                                        callback.execute();
1310
                        }
1311

    
1312
                        @Override
1313
                        public void onError(Throwable t) {
1314
                        GWT.log("Error heading file", t);
1315
                                setError(t);
1316
                        if (t instanceof RestException)
1317
                            displayError("Error heading file: " + ((RestException) t).getHttpStatusText());
1318
                        else
1319
                            displayError("System error heading file: " + t.getMessage());
1320
                        }
1321

    
1322
                        @Override
1323
                        protected void onUnauthorized(Response response) {
1324
                                sessionExpired();
1325
                        }
1326
                };
1327
                headFile.setHeader("X-Auth-Token", getToken());
1328
                Scheduler.get().scheduleDeferred(headFile);
1329
        }
1330

    
1331
        public boolean isMySharedSelected() {
1332
                return getSelectedTree().equals(getMySharedTreeView());
1333
        }
1334
        
1335
        private FlowPanel createUploadArea() {
1336
                FlowPanel area = new FlowPanel();
1337
                area.getElement().setId("container");
1338
                HTML list = new HTML();
1339
                list.getElement().setId("filelist");
1340
                area.add(list);
1341
                Scheduler.get().scheduleDeferred(new ScheduledCommand() {
1342
                        
1343
                        @Override
1344
                        public void execute() {
1345
//                                setupUploadArea(Pithos.this, getToken());
1346
                        }
1347
                });
1348
                
1349
                return area;
1350
        }
1351
        
1352
        private Folder getUploadFolder() {
1353
                if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
1354
                        return getSelection();
1355
                }
1356
                return null;
1357
        }
1358
        
1359
        private void updateUploadFolder() {
1360
                updateUploadFolder(null);
1361
        }
1362
        
1363
        private void updateUploadFolder(final JsArrayString urls) {
1364
                if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
1365
                        Folder f = getSelection();
1366
                        if (getSelectedTree().equals(getFolderTreeView()))
1367
                                updateFolder(f, true, new Command() {
1368
                                
1369
                                        @Override
1370
                                        public void execute() {
1371
                                                updateStatistics();
1372
                                                if (urls != null)
1373
                                                        selectUploadedFiles(urls);
1374
                                        }
1375
                                }, false);
1376
                        else
1377
                                updateOtherSharedFolder(f, true, null);
1378
                }
1379
        }
1380

    
1381
        public native void disableUploadArea() /*-{
1382
                var uploader = $wnd.$("#uploader").pluploadQueue();
1383
                var dropElm = $wnd.document.getElementById('rightPanel');
1384
                $wnd.plupload.removeAllEvents(dropElm, uploader.id);
1385
        }-*/;
1386

    
1387
        public native void enableUploadArea() /*-{
1388
                var uploader = $wnd.$("#uploader").pluploadQueue();
1389
                var dropElm = $wnd.document.getElementById('rightPanel');
1390
                $wnd.plupload.removeAllEvents(dropElm, uploader.id);
1391
                if (uploader.runtime == 'html5') {
1392
                        uploader.settings.drop_element = 'rightPanel';
1393
                        uploader.trigger('PostInit');
1394
                }
1395
        }-*/;
1396
        
1397
        public void showUploadAlert(int numOfFiles) {
1398
                uploadAlert = new UploadAlert(this, numOfFiles);
1399
                uploadAlert.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
1400
                        
1401
                        @Override
1402
                        public void setPosition(int offsetWidth, int offsetHeight) {
1403
                                uploadAlert.setPopupPosition((Window.getClientWidth() - offsetWidth)/2, Window.getClientHeight() - offsetHeight);
1404
                        }
1405
                });
1406
        }
1407
        
1408
        public void hideUploadAlert() {
1409
                uploadAlert.hide();
1410
        }
1411
        
1412
        public void selectUploadedFiles(JsArrayString urls) {
1413
                List<String> selectedUrls = new ArrayList<String>();
1414
                for (int i=0; i<urls.length(); i++)
1415
                        selectedUrls.add(urls.get(i));
1416
                fileList.selectByUrl(selectedUrls);
1417
        }
1418
}