Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / Pithos.java @ 9c198917

History | View | Annotate | Download (44.6 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.commands.UploadFileCommand;
38
import gr.grnet.pithos.web.client.foldertree.AccountResource;
39
import gr.grnet.pithos.web.client.foldertree.File;
40
import gr.grnet.pithos.web.client.foldertree.Folder;
41
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
42
import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
43
import gr.grnet.pithos.web.client.foldertree.Resource;
44
import gr.grnet.pithos.web.client.grouptree.Group;
45
import gr.grnet.pithos.web.client.grouptree.GroupTreeView;
46
import gr.grnet.pithos.web.client.grouptree.GroupTreeViewModel;
47
import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeView;
48
import gr.grnet.pithos.web.client.mysharedtree.MysharedTreeViewModel;
49
import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeView;
50
import gr.grnet.pithos.web.client.othersharedtree.OtherSharedTreeViewModel;
51
import gr.grnet.pithos.web.client.rest.DeleteRequest;
52
import gr.grnet.pithos.web.client.rest.GetRequest;
53
import gr.grnet.pithos.web.client.rest.HeadRequest;
54
import gr.grnet.pithos.web.client.rest.PutRequest;
55
import gr.grnet.pithos.web.client.rest.RestException;
56

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

    
64
import org.apache.http.HttpStatus;
65

    
66
import com.google.gwt.core.client.EntryPoint;
67
import com.google.gwt.core.client.GWT;
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.Response;
77
import com.google.gwt.http.client.URL;
78
import com.google.gwt.i18n.client.DateTimeFormat;
79
import com.google.gwt.i18n.client.Dictionary;
80
import com.google.gwt.i18n.client.TimeZone;
81
import com.google.gwt.resources.client.ClientBundle;
82
import com.google.gwt.resources.client.CssResource;
83
import com.google.gwt.resources.client.ImageResource;
84
import com.google.gwt.resources.client.ImageResource.ImageOptions;
85
import com.google.gwt.user.client.Command;
86
import com.google.gwt.user.client.Cookies;
87
import com.google.gwt.user.client.Event;
88
import com.google.gwt.user.client.History;
89
import com.google.gwt.user.client.Window;
90
import com.google.gwt.user.client.ui.AbstractImagePrototype;
91
import com.google.gwt.user.client.ui.Button;
92
import com.google.gwt.user.client.ui.Composite;
93
import com.google.gwt.user.client.ui.FlowPanel;
94
import com.google.gwt.user.client.ui.HTML;
95
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
96
import com.google.gwt.user.client.ui.HasVerticalAlignment;
97
import com.google.gwt.user.client.ui.HorizontalPanel;
98
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
99
import com.google.gwt.user.client.ui.PopupPanel;
100
import com.google.gwt.user.client.ui.RootPanel;
101
import com.google.gwt.user.client.ui.VerticalPanel;
102
import com.google.gwt.view.client.SelectionChangeEvent;
103
import com.google.gwt.view.client.SelectionChangeEvent.Handler;
104
import com.google.gwt.view.client.SingleSelectionModel;
105

    
106
/**
107
 * Entry point classes define <code>onModuleLoad()</code>.
108
 */
109
public class Pithos implements EntryPoint, ResizeHandler {
110

    
111
        public static final String HOME_CONTAINER = "pithos";
112

    
113
        public static final String TRASH_CONTAINER = "trash";
114

    
115
        public static final Configuration config = GWT.create(Configuration.class);
116
        
117
        public interface Style extends CssResource {
118
                String commandAnchor();
119
                
120
                String statistics();
121
                
122
                @ClassName("gwt-HTML")
123
                String html();
124
                
125
                String uploadAlert();
126

    
127
                String uploadAlertLink();
128

    
129
                String uploadAlertProgress();
130
                
131
                String uploadAlertPercent();
132
                
133
                String uploadAlertClose();
134
        }
135
        
136
        public interface Resources extends ClientBundle {
137
                @Source("Pithos.css")
138
                Style pithosCss();
139
                
140
                @Source("gr/grnet/pithos/resources/close-popup.png")
141
                ImageResource closePopup();
142
        }
143

    
144
        public static Resources resources = GWT.create(Resources.class);
145
        
146
        /**
147
         * Instantiate an application-level image bundle. This object will provide
148
         * programmatic access to all the images needed by widgets.
149
         */
150
        static Images images = (Images) GWT.create(Images.class);
151

    
152
    public String getUsername() {
153
        return username;
154
    }
155

    
156
    public void setAccount(AccountResource acct) {
157
        account = acct;
158
    }
159

    
160
    public AccountResource getAccount() {
161
        return account;
162
    }
163

    
164
    public void updateFolder(Folder f, boolean showfiles, Command callback, final boolean openParent) {
165
        folderTreeView.updateFolder(f, showfiles, callback, openParent);
166
    }
167

    
168
    public void updateGroupNode(Group group) {
169
        groupTreeView.updateGroupNode(group);
170
    }
171

    
172
    public void updateMySharedRoot() {
173
            mysharedTreeView.updateRoot();
174
    }
175
    
176
    public void updateSharedFolder(Folder f, boolean showfiles, Command callback) {
177
            mysharedTreeView.updateFolder(f, showfiles, callback);
178
    }
179
    
180
    public void updateSharedFolder(Folder f, boolean showfiles) {
181
            updateSharedFolder(f, showfiles, null);
182
    }
183

    
184
    public void updateOtherSharedFolder(Folder f, boolean showfiles, Command callback) {
185
            otherSharedTreeView.updateFolder(f, showfiles, callback);
186
    }
187

    
188
    public MysharedTreeView getMySharedTreeView() {
189
        return mysharedTreeView;
190
    }
191

    
192
    /**
193
         * An aggregate image bundle that pulls together all the images for this
194
         * application into a single bundle.
195
         */
196
        public interface Images extends TopPanel.Images, FileList.Images, ToolsMenu.Images {
197

    
198
                @Source("gr/grnet/pithos/resources/document.png")
199
                ImageResource folders();
200

    
201
                @Source("gr/grnet/pithos/resources/advancedsettings.png")
202
                @ImageOptions(width=32, height=32)
203
                ImageResource tools();
204
        }
205

    
206
        private Throwable error;
207
        
208
        /**
209
         * The Application Clipboard implementation;
210
         */
211
        private Clipboard clipboard = new Clipboard();
212

    
213
        /**
214
         * The top panel that contains the menu bar.
215
         */
216
        private TopPanel topPanel;
217

    
218
        /**
219
         * The panel that contains the various system messages.
220
         */
221
        private MessagePanel messagePanel = new MessagePanel(this, Pithos.images);
222

    
223
        /**
224
         * The bottom panel that contains the status bar.
225
         */
226
        StatusPanel statusPanel = null;
227

    
228
        /**
229
         * The file list widget.
230
         */
231
        private FileList fileList;
232

    
233
        /**
234
         * The tab panel that occupies the right side of the screen.
235
         */
236
        private VerticalPanel inner = new VerticalPanel();
237

    
238

    
239
        /**
240
         * The split panel that will contain the left and right panels.
241
         */
242
        private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
243

    
244
        /**
245
         * The currently selected item in the application, for use by the Edit menu
246
         * commands. Potential types are Folder, File, User and Group.
247
         */
248
        private Object currentSelection;
249

    
250
        public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
251

    
252
    private String username = null;
253

    
254
    /**
255
     * The authentication token of the current user.
256
     */
257
    private String token;
258

    
259
    VerticalPanel trees;
260
    
261
    SingleSelectionModel<Folder> folderTreeSelectionModel;
262
    FolderTreeViewModel folderTreeViewModel;
263
    FolderTreeView folderTreeView;
264

    
265
    SingleSelectionModel<Folder> mysharedTreeSelectionModel;
266
    MysharedTreeViewModel mysharedTreeViewModel;
267
    MysharedTreeView mysharedTreeView = null;;
268

    
269
    protected SingleSelectionModel<Folder> otherSharedTreeSelectionModel;
270
    OtherSharedTreeViewModel otherSharedTreeViewModel;
271
    OtherSharedTreeView otherSharedTreeView = null;
272

    
273
    GroupTreeViewModel groupTreeViewModel;
274
    GroupTreeView groupTreeView;
275

    
276
    TreeView selectedTree;
277
    protected AccountResource account;
278
    
279
    Folder trash;
280
    
281
    List<Composite> treeViews = new ArrayList<Composite>();
282

    
283
    @SuppressWarnings("rawtypes") List<SingleSelectionModel> selectionModels = new ArrayList<SingleSelectionModel>();
284
    
285
    public Button upload;
286
    
287
    private HTML numOfFiles;
288
    
289
    private Toolbar toolbar;
290
    
291
    private FileUploadDialog fileUploadDialog = new FileUploadDialog(this);
292

    
293
        UploadAlert uploadAlert;
294
        
295
        Date lastModified;
296

    
297
        @Override
298
        public void onModuleLoad() {
299
                if (parseUserCredentials())
300
            initialize();
301
        }
302

    
303
    private void initialize() {
304
            lastModified = new Date(); //Initialize if-modified-since value with now.
305
            resources.pithosCss().ensureInjected();
306
            boolean bareContent = Window.Location.getParameter("noframe") != null;
307
            String contentWidth = bareContent ? "100%" : "75%";
308

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

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

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

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

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

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

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

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

    
426
        // Hook the window resize event, so that we can adjust the UI.
427
        Window.addResizeHandler(this);
428
        // Clear out the window's built-in margin, because we want to take
429
        // advantage of the entire client area.
430
        Window.setMargin("0px");
431
        // Finally, add the outer panel to the RootPanel, so that it will be
432
        // displayed.
433
        RootPanel.get().add(outer);
434
        // Call the window resized handler to get the initial sizes setup. Doing
435
        // this in a deferred command causes it to occur after all widgets'
436
        // sizes have been computed by the browser.
437
        Scheduler.get().scheduleIncremental(new RepeatingCommand() {
438
                        
439
                        @Override
440
                        public boolean execute() {
441
                                if (!isCloudbarReady())
442
                                        return true;
443
                onWindowResized(Window.getClientHeight());
444
                                return false;
445
                        }
446
                });
447
        
448
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
449
            @Override
450
            public void execute() {
451
                fetchAccount(new Command() {
452
                                        
453
                                        @Override
454
                                        public void execute() {
455
                                if (!account.hasHomeContainer())
456
                                    createHomeContainer(account, this);
457
                                else if (!account.hasTrashContainer())
458
                                        createTrashContainer(this);
459
                                else {
460
                                        for (Folder f : account.getContainers())
461
                                                if (f.getName().equals(Pithos.TRASH_CONTAINER)) {
462
                                                        trash = f;
463
                                                        break;
464
                                                }
465
                                    trees.add(folderTreeView);
466
                                    folderTreeViewModel.initialize(account, new Command() {
467
                                                                
468
                                                                @Override
469
                                                                public void execute() {
470
                                                    createMySharedTree();
471
                                                                }
472
                                                        });
473

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

    
479
                                    groupTreeViewModel = new GroupTreeViewModel(Pithos.this);
480
                                    groupTreeView = new GroupTreeView(groupTreeViewModel);
481
                                    treeViews.add(groupTreeView);
482
                                    trees.add(groupTreeView);
483
                                    folderTreeView.showStatistics(account);
484
                                }
485
                                        }
486
                                });
487
            }
488
        });
489
    }
490
    
491
    public void scheduleResfresh() {
492
                Scheduler.get().scheduleFixedDelay(new RepeatingCommand() {
493
                        
494
                        @Override
495
                        public boolean execute() {
496
                                final Folder f = getSelection();
497
                                if (f == null)
498
                                        return true;
499
                                
500
                            HeadRequest<Folder> head = new HeadRequest<Folder>(Folder.class, getApiPath(), f.getOwner(), "/" + f.getContainer()) {
501

    
502
                                        @Override
503
                                        public void onSuccess(Folder _result) {
504
                                                lastModified = new Date();
505
                                                if (getSelectedTree().equals(folderTreeView))
506
                                                        updateFolder(f, true, new Command() {
507
        
508
                                                                @Override
509
                                                                public void execute() {
510
                                                                        scheduleResfresh();
511
                                                                }
512
                                                                
513
                                                        }, false);
514
                                                else if (getSelectedTree().equals(mysharedTreeView))
515
                                                        updateSharedFolder(f, true, new Command() {
516
        
517
                                                                @Override
518
                                                                public void execute() {
519
                                                                        scheduleResfresh();
520
                                                                }
521
                                                        });
522
                                                else
523
                                                        scheduleResfresh();
524
                                        }
525

    
526
                                        @Override
527
                                        public void onError(Throwable t) {
528
                                                if (t instanceof RestException && ((RestException) t).getHttpStatusCode() == HttpStatus.SC_NOT_MODIFIED)
529
                                                        scheduleResfresh();
530
                                                else if (retries >= MAX_RETRIES) {
531
                                        GWT.log("Error heading folder", t);
532
                                                        setError(t);
533
                                        if (t instanceof RestException)
534
                                            displayError("Error heading folder: " + ((RestException) t).getHttpStatusText());
535
                                        else
536
                                            displayError("System error heading folder: " + t.getMessage());
537
                                    }
538
                                    else {//retry
539
                                            GWT.log("Retry " + retries);
540
                                            Scheduler.get().scheduleDeferred(this);
541
                                    }
542
                                        }
543

    
544
                                        @Override
545
                                        protected void onUnauthorized(Response response) {
546
                                                if (retries >= MAX_RETRIES)
547
                                                        sessionExpired();
548
                                    else //retry
549
                                            Scheduler.get().scheduleDeferred(this);
550
                                        }
551
                                };
552
                                head.setHeader("X-Auth-Token", getToken());
553
                                head.setHeader("If-Modified-Since", DateTimeFormat.getFormat("EEE, dd MMM yyyy HH:mm:ss").format(lastModified, TimeZone.createTimeZone(0)) + " GMT");
554
                                Scheduler.get().scheduleDeferred(head);
555
                                
556
                                return false;
557
                        }
558
                }, 3000);
559
    }
560

    
561
    public void applyPermissions(Folder f) {
562
            if (f != null) {
563
                    if (f.isInTrash()) {
564
                            upload.setEnabled(false);
565
                            disableUploadArea();
566
                    }
567
                    else {
568
                            Boolean[] perms = f.getPermissions().get(username);
569
                            if (f.getOwner().equals(username) || (perms != null && perms[1] != null && perms[1])) {
570
                                    upload.setEnabled(true);
571
                                    enableUploadArea();
572
                            }
573
                            else {
574
                                    upload.setEnabled(false);
575
                                    disableUploadArea();
576
                            }
577
                    }
578
            }
579
            else {
580
                    upload.setEnabled(false);
581
                    disableUploadArea();
582
            }
583
        }
584

    
585
        @SuppressWarnings({ "rawtypes", "unchecked" })
586
        public void deselectOthers(TreeView _selectedTree, SingleSelectionModel model) {
587
            selectedTree = _selectedTree;
588
            
589
        for (SingleSelectionModel s : selectionModels)
590
            if (!s.equals(model) && s.getSelectedObject() != null)
591
                s.setSelected(s.getSelectedObject(), false);
592
    }
593

    
594
    public void showFiles(final Folder f) {
595
        Set<File> files = f.getFiles();
596
        showFiles(files);
597
    }
598

    
599
    public void showFiles(Set<File> files) {
600
        fileList.setFiles(new ArrayList<File>(files));
601
    }
602

    
603
    /**
604
         * Parse and store the user credentials to the appropriate fields.
605
         */
606
        private boolean parseUserCredentials() {
607
        Configuration conf = (Configuration) GWT.create(Configuration.class);
608
                Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
609
        String cookie = otherProperties.get("authCookie");
610
        String auth = Cookies.getCookie(cookie);
611
        if (auth == null) {
612
            authenticateUser();
613
            return false;
614
        }
615
        if (auth.startsWith("\""))
616
                auth = auth.substring(1);
617
        if (auth.endsWith("\""))
618
                auth = auth.substring(0, auth.length() - 1);
619
                String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2);
620
                if (authSplit.length != 2) {
621
                    authenticateUser();
622
                    return false;
623
                }
624
                username = authSplit[0];
625
                token = authSplit[1];
626

    
627
        String gotoUrl = Window.Location.getParameter("goto");
628
                if (gotoUrl != null && gotoUrl.length() > 0) {
629
                        Window.Location.assign(gotoUrl);
630
                        return false;
631
                }
632
                return true;
633
    }
634

    
635
    /**
636
         * Redirect the user to the login page for authentication.
637
         */
638
        protected void authenticateUser() {
639
                Dictionary otherProperties = Dictionary.getDictionary("otherProperties");
640
        Window.Location.assign(otherProperties.get("loginUrl") + Window.Location.getHref());
641
        }
642

    
643
        public void fetchAccount(final Command callback) {
644
        String path = "?format=json";
645

    
646
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, getApiPath(), username, path) {
647
            @Override
648
            public void onSuccess(AccountResource _result) {
649
                account = _result;
650
                if (callback != null)
651
                        callback.execute();
652
            }
653

    
654
            @Override
655
            public void onError(Throwable t) {
656
                GWT.log("Error getting account", t);
657
                                setError(t);
658
                if (t instanceof RestException)
659
                    displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
660
                else
661
                    displayError("System error fetching user data: " + t.getMessage());
662
            }
663

    
664
                        @Override
665
                        protected void onUnauthorized(Response response) {
666
                                sessionExpired();
667
                        }
668
        };
669
        getAccount.setHeader("X-Auth-Token", token);
670
        Scheduler.get().scheduleDeferred(getAccount);
671
    }
672

    
673
    public void updateStatistics() {
674
            HeadRequest<AccountResource> headAccount = new HeadRequest<AccountResource>(AccountResource.class, getApiPath(), username, "", account) {
675

    
676
                        @Override
677
                        public void onSuccess(AccountResource _result) {
678
                                folderTreeView.showStatistics(account);
679
                        }
680

    
681
                        @Override
682
                        public void onError(Throwable t) {
683
                GWT.log("Error getting account", t);
684
                                setError(t);
685
                if (t instanceof RestException)
686
                    displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
687
                else
688
                    displayError("System error fetching user data: " + t.getMessage());
689
                        }
690

    
691
                        @Override
692
                        protected void onUnauthorized(Response response) {
693
                                sessionExpired();
694
                        }
695
                };
696
                headAccount.setHeader("X-Auth-Token", token);
697
                Scheduler.get().scheduleDeferred(headAccount);
698
        }
699

    
700
        protected void createHomeContainer(final AccountResource _account, final Command callback) {
701
        String path = "/" + Pithos.HOME_CONTAINER;
702
        PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) {
703
            @Override
704
            public void onSuccess(Resource result) {
705
                    if (!_account.hasTrashContainer())
706
                            createTrashContainer(callback);
707
                    else
708
                            fetchAccount(callback);
709
            }
710

    
711
            @Override
712
            public void onError(Throwable t) {
713
                GWT.log("Error creating pithos", t);
714
                                setError(t);
715
                if (t instanceof RestException)
716
                    displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText());
717
                else
718
                    displayError("System error Error creating pithos: " + t.getMessage());
719
            }
720

    
721
                        @Override
722
                        protected void onUnauthorized(Response response) {
723
                                sessionExpired();
724
                        }
725
        };
726
        createPithos.setHeader("X-Auth-Token", getToken());
727
        Scheduler.get().scheduleDeferred(createPithos);
728
    }
729

    
730
    protected void createTrashContainer(final Command callback) {
731
        String path = "/" + Pithos.TRASH_CONTAINER;
732
        PutRequest createPithos = new PutRequest(getApiPath(), getUsername(), path) {
733
            @Override
734
            public void onSuccess(Resource result) {
735
                           fetchAccount(callback);
736
            }
737

    
738
            @Override
739
            public void onError(Throwable t) {
740
                GWT.log("Error creating pithos", t);
741
                                setError(t);
742
                if (t instanceof RestException)
743
                    displayError("Error creating pithos: " + ((RestException) t).getHttpStatusText());
744
                else
745
                    displayError("System error Error creating pithos: " + t.getMessage());
746
            }
747

    
748
                        @Override
749
                        protected void onUnauthorized(Response response) {
750
                                sessionExpired();
751
                        }
752
        };
753
        createPithos.setHeader("X-Auth-Token", getToken());
754
        Scheduler.get().scheduleDeferred(createPithos);
755
    }
756

    
757
    /**
758
         * Creates an HTML fragment that places an image & caption together, for use
759
         * in a group header.
760
         *
761
         * @param imageProto an image prototype for an image
762
         * @param caption the group caption
763
         * @return the header HTML fragment
764
         */
765
        private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
766
                String captionHTML = "<table class='caption' cellpadding='0' " 
767
                + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() 
768
                + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'>&nbsp;" 
769
                + caption + "</b></td></tr></table>";
770
                return captionHTML;
771
        }
772

    
773
        protected void onWindowResized(int height) {
774
                // Adjust the split panel to take up the available room in the window.
775
                int newHeight = height - splitPanel.getAbsoluteTop() - 153;
776
                if (newHeight < 1)
777
                        newHeight = 1;
778
                splitPanel.setHeight("" + newHeight);
779
                inner.setHeight("" + newHeight);
780
        }
781
        
782
        native boolean isCloudbarReady()/*-{
783
                if ($wnd.$("div.cloudbar") && $wnd.$("div.cloudbar").height() > 0)
784
                        return true;
785
                return false;
786
        }-*/;
787
        
788
        @Override
789
        public void onResize(ResizeEvent event) {
790
                int height = event.getHeight();
791
                onWindowResized(height);
792
        }
793

    
794
        /**
795
         * Display an error message.
796
         *
797
         * @param msg the message to display
798
         */
799
        public void displayError(String msg) {
800
                messagePanel.displayError(msg);
801
                onWindowResized(Window.getClientHeight());
802
        }
803

    
804
        /**
805
         * Display a warning message.
806
         *
807
         * @param msg the message to display
808
         */
809
        public void displayWarning(String msg) {
810
                messagePanel.displayWarning(msg);
811
                onWindowResized(Window.getClientHeight());
812
        }
813

    
814
        /**
815
         * Display an informational message.
816
         *
817
         * @param msg the message to display
818
         */
819
        public void displayInformation(String msg) {
820
                messagePanel.displayInformation(msg);
821
                onWindowResized(Window.getClientHeight());
822
        }
823

    
824
        /**
825
         * Retrieve the fileList.
826
         *
827
         * @return the fileList
828
         */
829
        public FileList getFileList() {
830
                return fileList;
831
        }
832

    
833
        /**
834
         * Retrieve the topPanel.
835
         *
836
         * @return the topPanel
837
         */
838
        TopPanel getTopPanel() {
839
                return topPanel;
840
        }
841

    
842
        /**
843
         * Retrieve the clipboard.
844
         *
845
         * @return the clipboard
846
         */
847
        public Clipboard getClipboard() {
848
                return clipboard;
849
        }
850

    
851
        public StatusPanel getStatusPanel() {
852
                return statusPanel;
853
        }
854

    
855
        public String getToken() {
856
                return token;
857
        }
858

    
859
        public static native void preventIESelection() /*-{
860
                $doc.body.onselectstart = function() {
861
                        return false;
862
                };
863
        }-*/;
864

    
865
        public static native void enableIESelection() /*-{
866
                if ($doc.body.onselectstart != null)
867
                        $doc.body.onselectstart = null;
868
        }-*/;
869

    
870
        /**
871
         * @return the absolute path of the API root URL
872
         */
873
        public String getApiPath() {
874
                Configuration conf = (Configuration) GWT.create(Configuration.class);
875
                return conf.apiPath();
876
        }
877

    
878
        /**
879
         * History support for folder navigation
880
         * adds a new browser history entry
881
         *
882
         * @param key
883
         */
884
        public void updateHistory(String key){
885
//                Replace any whitespace of the initial string to "+"
886
//                String result = key.replaceAll("\\s","+");
887
//                Add a new browser history entry.
888
//                History.newItem(result);
889
                History.newItem(key);
890
        }
891

    
892
    public void deleteFolder(final Folder folder, final Command callback) {
893
            final PleaseWaitPopup pwp = new PleaseWaitPopup();
894
            pwp.center();
895
        String path = "/" + folder.getContainer() + "/" + folder.getPrefix() + "?delimiter=/" + "&t=" + System.currentTimeMillis();
896
        DeleteRequest deleteFolder = new DeleteRequest(getApiPath(), folder.getOwner(), path) {
897
                        
898
                        @Override
899
                        protected void onUnauthorized(Response response) {
900
                                pwp.hide();
901
                                sessionExpired();
902
                        }
903
                        
904
                        @Override
905
                        public void onSuccess(Resource result) {
906
                updateFolder(folder.getParent(), true, new Command() {
907
                                        
908
                                        @Override
909
                                        public void execute() {
910
                                                folderTreeSelectionModel.setSelected(folder.getParent(), true);
911
                                                updateStatistics();
912
                                                if (callback != null)
913
                                                        callback.execute();
914
                                                pwp.hide();
915
                                        }
916
                                }, true);
917
                        }
918
                        
919
                        @Override
920
                        public void onError(Throwable t) {
921
                GWT.log("", t);
922
                                setError(t);
923
                if (t instanceof RestException) {
924
                        if (((RestException) t).getHttpStatusCode() != Response.SC_NOT_FOUND)
925
                                displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText());
926
                        else
927
                                onSuccess(null);
928
                }
929
                else
930
                    displayError("System error unable to delete folder: " + t.getMessage());
931
                                pwp.hide();
932
                        }
933
                };
934
                deleteFolder.setHeader("X-Auth-Token", getToken());
935
                Scheduler.get().scheduleDeferred(deleteFolder);
936
    }
937

    
938
    public FolderTreeView getFolderTreeView() {
939
        return folderTreeView;
940
    }
941

    
942
    public void copyFiles(final Iterator<File> iter, final String targetUsername, final String targetUri, final Command callback) {
943
        if (iter.hasNext()) {
944
            File file = iter.next();
945
            String path = targetUri + "/" + file.getName();
946
            PutRequest copyFile = new PutRequest(getApiPath(), targetUsername, path) {
947
                @Override
948
                public void onSuccess(Resource result) {
949
                    copyFiles(iter, targetUsername, targetUri, callback);
950
                }
951

    
952
                @Override
953
                public void onError(Throwable t) {
954
                    GWT.log("", t);
955
                                        setError(t);
956
                    if (t instanceof RestException) {
957
                        displayError("Unable to copy file: " + ((RestException) t).getHttpStatusText());
958
                    }
959
                    else
960
                        displayError("System error unable to copy file: "+t.getMessage());
961
                }
962

    
963
                                @Override
964
                                protected void onUnauthorized(Response response) {
965
                                        sessionExpired();
966
                                }
967
            };
968
            copyFile.setHeader("X-Auth-Token", getToken());
969
            copyFile.setHeader("X-Copy-From", URL.encodePathSegment(file.getUri()));
970
            if (!file.getOwner().equals(targetUsername))
971
                    copyFile.setHeader("X-Source-Account", URL.encodePathSegment(file.getOwner()));
972
            copyFile.setHeader("Content-Type", file.getContentType());
973
            Scheduler.get().scheduleDeferred(copyFile);
974
        }
975
        else  if (callback != null) {
976
            callback.execute();
977
        }
978
    }
979

    
980
    public void copyFolder(final Folder f, final String targetUsername, final String targetUri, boolean move, final Command callback) {
981
        String path = targetUri + "?delimiter=/";
982
        PutRequest copyFolder = new PutRequest(getApiPath(), targetUsername, path) {
983
            @Override
984
            public void onSuccess(Resource result) {
985
                    if (callback != null)
986
                            callback.execute();
987
            }
988

    
989
            @Override
990
            public void onError(Throwable t) {
991
                GWT.log("", t);
992
                                setError(t);
993
               if (t instanceof RestException) {
994
                    displayError("Unable to copy folder: " + ((RestException) t).getHttpStatusText());
995
                }
996
                else
997
                    displayError("System error copying folder: " + t.getMessage());
998
            }
999

    
1000
                        @Override
1001
                        protected void onUnauthorized(Response response) {
1002
                                sessionExpired();
1003
                        }
1004
        };
1005
        copyFolder.setHeader("X-Auth-Token", getToken());
1006
        copyFolder.setHeader("Accept", "*/*");
1007
        copyFolder.setHeader("Content-Length", "0");
1008
        copyFolder.setHeader("Content-Type", "application/directory");
1009
        if (!f.getOwner().equals(targetUsername))
1010
                copyFolder.setHeader("X-Source-Account", f.getOwner());
1011
        if (move)
1012
            copyFolder.setHeader("X-Move-From", URL.encodePathSegment(f.getUri()));
1013
        else
1014
                copyFolder.setHeader("X-Copy-From", URL.encodePathSegment(f.getUri()));
1015
        Scheduler.get().scheduleDeferred(copyFolder);
1016
    }
1017
    
1018
    public void addSelectionModel(@SuppressWarnings("rawtypes") SingleSelectionModel model) {
1019
            selectionModels.add(model);
1020
    }
1021

    
1022
        public OtherSharedTreeView getOtherSharedTreeView() {
1023
                return otherSharedTreeView;
1024
        }
1025

    
1026
        public void updateTrash(boolean showFiles, Command callback) {
1027
                updateFolder(trash, showFiles, callback, true);
1028
        }
1029

    
1030
        public void updateGroupsNode() {
1031
                groupTreeView.updateGroupNode(null);
1032
        }
1033

    
1034
        public Group addGroup(String groupname) {
1035
                Group newGroup = new Group(groupname);
1036
                account.addGroup(newGroup);
1037
                groupTreeView.updateGroupNode(null);
1038
                return newGroup;
1039
        }
1040

    
1041
        public void removeGroup(Group group) {
1042
                account.removeGroup(group);
1043
                updateGroupsNode();
1044
        }
1045

    
1046
        public TreeView getSelectedTree() {
1047
                return selectedTree;
1048
        }
1049
        
1050
        public void setSelectedTree(TreeView selected) {
1051
                selectedTree = selected;
1052
        }
1053

    
1054
        public Folder getSelection() {
1055
                if (selectedTree != null)
1056
                        return selectedTree.getSelection();
1057
                return null;
1058
        }
1059

    
1060
        public void showFolderStatistics(int folderFileCount) {
1061
                numOfFiles.setHTML(String.valueOf(folderFileCount));
1062
        }
1063

    
1064
        public GroupTreeView getGroupTreeView() {
1065
                return groupTreeView;
1066
        }
1067

    
1068
        public void sessionExpired() {
1069
                new SessionExpiredDialog(this).center();
1070
        }
1071

    
1072
        public void updateRootFolder(Command callback) {
1073
                updateFolder(account.getPithos(), false, callback, true);
1074
        }
1075

    
1076
        void createMySharedTree() {
1077
                mysharedTreeSelectionModel = new SingleSelectionModel<Folder>();
1078
                mysharedTreeSelectionModel.addSelectionChangeHandler(new Handler() {
1079
                    @Override
1080
                    public void onSelectionChange(SelectionChangeEvent event) {
1081
                        if (mysharedTreeSelectionModel.getSelectedObject() != null) {
1082
                            deselectOthers(mysharedTreeView, mysharedTreeSelectionModel);
1083
                            upload.setEnabled(false);
1084
                            disableUploadArea();
1085
                            updateSharedFolder(mysharedTreeSelectionModel.getSelectedObject(), true);
1086
                                        showRelevantToolbarButtons();
1087
                        }
1088
                                else {
1089
                                        if (getSelectedTree().equals(mysharedTreeView))
1090
                                                setSelectedTree(null);
1091
                                        if (getSelectedTree() == null)
1092
                                                showRelevantToolbarButtons();
1093
                                }
1094
                     }
1095
                });
1096
                selectionModels.add(mysharedTreeSelectionModel);
1097
                mysharedTreeViewModel = new MysharedTreeViewModel(Pithos.this, mysharedTreeSelectionModel);
1098
                mysharedTreeViewModel.initialize(new Command() {
1099
                        
1100
                        @Override
1101
                        public void execute() {
1102
                            mysharedTreeView = new MysharedTreeView(mysharedTreeViewModel);
1103
                                trees.insert(mysharedTreeView, 2);
1104
                                treeViews.add(mysharedTreeView);
1105
                                createOtherSharedTree();
1106
                        }
1107
                });
1108
        }
1109

    
1110
        void createOtherSharedTree() {
1111
                otherSharedTreeSelectionModel = new SingleSelectionModel<Folder>();
1112
                otherSharedTreeSelectionModel.addSelectionChangeHandler(new Handler() {
1113
                    @Override
1114
                    public void onSelectionChange(SelectionChangeEvent event) {
1115
                        if (otherSharedTreeSelectionModel.getSelectedObject() != null) {
1116
                            deselectOthers(otherSharedTreeView, otherSharedTreeSelectionModel);
1117
                            applyPermissions(otherSharedTreeSelectionModel.getSelectedObject());
1118
                            updateOtherSharedFolder(otherSharedTreeSelectionModel.getSelectedObject(), true, null);
1119
                                        showRelevantToolbarButtons();
1120
                        }
1121
                                else {
1122
                                        if (getSelectedTree().equals(otherSharedTreeView))
1123
                                                setSelectedTree(null);
1124
                                        if (getSelectedTree() == null)
1125
                                                showRelevantToolbarButtons();
1126
                                }
1127
                     }
1128
                });
1129
                selectionModels.add(otherSharedTreeSelectionModel);
1130
                otherSharedTreeViewModel = new OtherSharedTreeViewModel(Pithos.this, otherSharedTreeSelectionModel);
1131
                otherSharedTreeViewModel.initialize(new Command() {
1132
                        
1133
                        @Override
1134
                        public void execute() {
1135
                            otherSharedTreeView = new OtherSharedTreeView(otherSharedTreeViewModel);
1136
                                trees.insert(otherSharedTreeView, 1);
1137
                                treeViews.add(otherSharedTreeView);
1138
                                scheduleResfresh();
1139
                        }
1140
                });
1141
        }
1142

    
1143
        public native void log1(String message)/*-{
1144
                $wnd.console.log(message);
1145
        }-*/;
1146

    
1147
        public String getErrorData() {
1148
                if (error != null)
1149
                        return error.toString();
1150
                return "";
1151
        }
1152
        
1153
        public void setError(Throwable t) {
1154
                error = t;
1155
        }
1156
        
1157
        public void showRelevantToolbarButtons() {
1158
                toolbar.showRelevantButtons();
1159
        }
1160

    
1161
        public FileUploadDialog getFileUploadDialog() {
1162
                if (fileUploadDialog == null)
1163
                        fileUploadDialog = new FileUploadDialog(this);
1164
                return fileUploadDialog;
1165
        }
1166

    
1167
        public void hideUploadIndicator() {
1168
                upload.removeStyleName("pithos-uploadButton-loading");
1169
                upload.setTitle("");
1170
        }
1171
        
1172
        public void showUploadIndicator() {
1173
                upload.addStyleName("pithos-uploadButton-loading");
1174
                upload.setTitle("Upload in progress. Click for details.");
1175
        }
1176

    
1177
        public void scheduleFolderHeadCommand(final Folder folder, final Command callback) {
1178
                if (folder == null) {
1179
                        if (callback != null)
1180
                                callback.execute();
1181
                }
1182
                else {
1183
                        HeadRequest<Folder> headFolder = new HeadRequest<Folder>(Folder.class, getApiPath(), folder.getOwner(), folder.getUri(), folder) {
1184
        
1185
                                @Override
1186
                                public void onSuccess(Folder _result) {
1187
                                        if (callback != null)
1188
                                                callback.execute();
1189
                                }
1190
        
1191
                                @Override
1192
                                public void onError(Throwable t) {
1193
                                if (t instanceof RestException) {
1194
                                        if (((RestException) t).getHttpStatusCode() == Response.SC_NOT_FOUND) {
1195
                                final String path = folder.getUri();
1196
                                PutRequest newFolder = new PutRequest(getApiPath(), folder.getOwner(), path) {
1197
                                    @Override
1198
                                    public void onSuccess(Resource _result) {
1199
                                            scheduleFolderHeadCommand(folder, callback);
1200
                                    }
1201
        
1202
                                    @Override
1203
                                    public void onError(Throwable _t) {
1204
                                        GWT.log("", _t);
1205
                                                                setError(_t);
1206
                                        if(_t instanceof RestException){
1207
                                            displayError("Unable to create folder: " + ((RestException) _t).getHttpStatusText());
1208
                                        }
1209
                                        else
1210
                                            displayError("System error creating folder: " + _t.getMessage());
1211
                                    }
1212
        
1213
                                                    @Override
1214
                                                    protected void onUnauthorized(Response response) {
1215
                                                            sessionExpired();
1216
                                                    }
1217
                                };
1218
                                newFolder.setHeader("X-Auth-Token", getToken());
1219
                                newFolder.setHeader("Content-Type", "application/folder");
1220
                                newFolder.setHeader("Accept", "*/*");
1221
                                newFolder.setHeader("Content-Length", "0");
1222
                                Scheduler.get().scheduleDeferred(newFolder);
1223
                                        }
1224
                                        else if (((RestException) t).getHttpStatusCode() == Response.SC_FORBIDDEN) {
1225
                                                onSuccess(folder);
1226
                                        }
1227
                                        else
1228
                                                displayError("Error heading folder: " + ((RestException) t).getHttpStatusText());
1229
                                }
1230
                                else
1231
                                    displayError("System error heading folder: " + t.getMessage());
1232
        
1233
                                GWT.log("Error heading folder", t);
1234
                                        setError(t);
1235
                                }
1236
        
1237
                                @Override
1238
                                protected void onUnauthorized(Response response) {
1239
                                        sessionExpired();
1240
                                }
1241
                        };
1242
                        headFolder.setHeader("X-Auth-Token", getToken());
1243
                        Scheduler.get().scheduleDeferred(headFolder);
1244
                }
1245
        }
1246

    
1247
        public void scheduleFileHeadCommand(File f, final Command callback) {
1248
                HeadRequest<File> headFile = new HeadRequest<File>(File.class, getApiPath(), f.getOwner(), f.getUri(), f) {
1249

    
1250
                        @Override
1251
                        public void onSuccess(File _result) {
1252
                                if (callback != null)
1253
                                        callback.execute();
1254
                        }
1255

    
1256
                        @Override
1257
                        public void onError(Throwable t) {
1258
                        GWT.log("Error heading file", t);
1259
                                setError(t);
1260
                        if (t instanceof RestException)
1261
                            displayError("Error heading file: " + ((RestException) t).getHttpStatusText());
1262
                        else
1263
                            displayError("System error heading file: " + t.getMessage());
1264
                        }
1265

    
1266
                        @Override
1267
                        protected void onUnauthorized(Response response) {
1268
                                sessionExpired();
1269
                        }
1270
                };
1271
                headFile.setHeader("X-Auth-Token", getToken());
1272
                Scheduler.get().scheduleDeferred(headFile);
1273
        }
1274

    
1275
        public boolean isMySharedSelected() {
1276
                return getSelectedTree().equals(getMySharedTreeView());
1277
        }
1278
        
1279
        private Folder getUploadFolder() {
1280
                if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
1281
                        return getSelection();
1282
                }
1283
                return null;
1284
        }
1285
        
1286
        private void updateUploadFolder() {
1287
                updateUploadFolder(null);
1288
        }
1289
        
1290
        private void updateUploadFolder(final JsArrayString urls) {
1291
                if (folderTreeView.equals(getSelectedTree()) || otherSharedTreeView.equals(getSelectedTree())) {
1292
                        Folder f = getSelection();
1293
                        if (getSelectedTree().equals(getFolderTreeView()))
1294
                                updateFolder(f, true, new Command() {
1295
                                
1296
                                        @Override
1297
                                        public void execute() {
1298
                                                updateStatistics();
1299
                                                if (urls != null)
1300
                                                        selectUploadedFiles(urls);
1301
                                        }
1302
                                }, false);
1303
                        else
1304
                                updateOtherSharedFolder(f, true, null);
1305
                }
1306
        }
1307

    
1308
        public native void disableUploadArea() /*-{
1309
                var uploader = $wnd.$("#uploader").pluploadQueue();
1310
                var dropElm = $wnd.document.getElementById('rightPanel');
1311
                $wnd.plupload.removeAllEvents(dropElm, uploader.id);
1312
        }-*/;
1313

    
1314
        public native void enableUploadArea() /*-{
1315
                var uploader = $wnd.$("#uploader").pluploadQueue();
1316
                var dropElm = $wnd.document.getElementById('rightPanel');
1317
                $wnd.plupload.removeAllEvents(dropElm, uploader.id);
1318
                if (uploader.runtime == 'html5') {
1319
                        uploader.settings.drop_element = 'rightPanel';
1320
                        uploader.trigger('PostInit');
1321
                }
1322
        }-*/;
1323
        
1324
        public void showUploadAlert(int nOfFiles) {
1325
                if (uploadAlert == null)
1326
                        uploadAlert = new UploadAlert(this, nOfFiles);
1327
                if (!uploadAlert.isShowing())
1328
                        uploadAlert.setPopupPositionAndShow(new PopupPanel.PositionCallback() {
1329
                                
1330
                                @Override
1331
                                public void setPosition(int offsetWidth, int offsetHeight) {
1332
                                        uploadAlert.setPopupPosition((Window.getClientWidth() - offsetWidth)/2, statusPanel.getAbsoluteTop() - offsetHeight);
1333
                                }
1334
                        });
1335
                uploadAlert.setNumOfFiles(nOfFiles);
1336
        }
1337
        
1338
        public void hideUploadAlert() {
1339
                if (uploadAlert != null && uploadAlert.isShowing())
1340
                        uploadAlert.hide();
1341
        }
1342
        
1343
        public void selectUploadedFiles(JsArrayString urls) {
1344
                List<String> selectedUrls = new ArrayList<String>();
1345
                for (int i=0; i<urls.length(); i++)
1346
                        selectedUrls.add(urls.get(i));
1347
                fileList.selectByUrl(selectedUrls);
1348
        }
1349
        
1350
        public void emptyContainer(final Folder container) {
1351
                String path = "/" + container.getName() + "?delimiter=/";
1352
                DeleteRequest delete = new DeleteRequest(getApiPath(), getUsername(), path) {
1353
                        
1354
                        @Override
1355
                        protected void onUnauthorized(Response response) {
1356
                                sessionExpired();
1357
                        }
1358
                        
1359
                        @Override
1360
                        public void onSuccess(Resource result) {
1361
                                updateFolder(container, true, null, true);
1362
                        }
1363
                        
1364
                        @Override
1365
                        public void onError(Throwable t) {
1366
                GWT.log("Error deleting trash", t);
1367
                                setError(t);
1368
                if (t instanceof RestException)
1369
                    displayError("Error deleting trash: " + ((RestException) t).getHttpStatusText());
1370
                else
1371
                    displayError("System error deleting trash: " + t.getMessage());
1372
                        }
1373
                };
1374
                delete.setHeader("X-Auth-Token", getToken());
1375
                Scheduler.get().scheduleDeferred(delete);
1376
        }
1377
}