Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / Pithos.java @ 39a92f5c

History | View | Annotate | Download (47.9 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 uploadAlertProgress();
139
                
140
                String uploadAlertPercent();
141
                
142
                String uploadAlertClose();
143
        }
144
        
145
        public interface Resources extends ClientBundle {
146
                @Source("Pithos.css")
147
                Style pithosCss();
148
                
149
                @Source("gr/grnet/pithos/resources/close-popup.png")
150
                ImageResource closePopup();
151
        }
152

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

    
161
    public String getUsername() {
162
        return username;
163
    }
164

    
165
    public void setAccount(AccountResource acct) {
166
        account = acct;
167
    }
168

    
169
    public AccountResource getAccount() {
170
        return account;
171
    }
172

    
173
    public void updateFolder(Folder f, boolean showfiles, Command callback, final boolean openParent) {
174
        folderTreeView.updateFolder(f, showfiles, callback, openParent);
175
    }
176

    
177
    public void updateGroupNode(Group group) {
178
        groupTreeView.updateGroupNode(group);
179
    }
180

    
181
    public void updateMySharedRoot() {
182
            mysharedTreeView.updateRoot();
183
    }
184
    
185
    public void updateSharedFolder(Folder f, boolean showfiles, Command callback) {
186
            mysharedTreeView.updateFolder(f, showfiles, callback);
187
    }
188
    
189
    public void updateSharedFolder(Folder f, boolean showfiles) {
190
            updateSharedFolder(f, showfiles, null);
191
    }
192

    
193
    public void updateOtherSharedFolder(Folder f, boolean showfiles, Command callback) {
194
            otherSharedTreeView.updateFolder(f, showfiles, callback);
195
    }
196

    
197
    public MysharedTreeView getMySharedTreeView() {
198
        return mysharedTreeView;
199
    }
200

    
201
    /**
202
         * An aggregate image bundle that pulls together all the images for this
203
         * application into a single bundle.
204
         */
205
        public interface Images extends TopPanel.Images, FileList.Images, ToolsMenu.Images {
206

    
207
                @Source("gr/grnet/pithos/resources/document.png")
208
                ImageResource folders();
209

    
210
                @Source("gr/grnet/pithos/resources/advancedsettings.png")
211
                @ImageOptions(width=32, height=32)
212
                ImageResource tools();
213
        }
214

    
215
        private Throwable error;
216
        
217
        /**
218
         * The Application Clipboard implementation;
219
         */
220
        private Clipboard clipboard = new Clipboard();
221

    
222
        /**
223
         * The top panel that contains the menu bar.
224
         */
225
        private TopPanel topPanel;
226

    
227
        /**
228
         * The panel that contains the various system messages.
229
         */
230
        private MessagePanel messagePanel = new MessagePanel(this, Pithos.images);
231

    
232
        /**
233
         * The bottom panel that contains the status bar.
234
         */
235
        private StatusPanel statusPanel = null;
236

    
237
        /**
238
         * The file list widget.
239
         */
240
        private FileList fileList;
241

    
242
        /**
243
         * The tab panel that occupies the right side of the screen.
244
         */
245
        private VerticalPanel inner = new VerticalPanel();
246

    
247

    
248
        /**
249
         * The split panel that will contain the left and right panels.
250
         */
251
        private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
252

    
253
        /**
254
         * The currently selected item in the application, for use by the Edit menu
255
         * commands. Potential types are Folder, File, User and Group.
256
         */
257
        private Object currentSelection;
258

    
259
        public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
260

    
261
    private String username = null;
262

    
263
    /**
264
     * The authentication token of the current user.
265
     */
266
    private String token;
267

    
268
    VerticalPanel trees;
269
    
270
    SingleSelectionModel<Folder> folderTreeSelectionModel;
271
    FolderTreeViewModel folderTreeViewModel;
272
    FolderTreeView folderTreeView;
273

    
274
    SingleSelectionModel<Folder> mysharedTreeSelectionModel;
275
    MysharedTreeViewModel mysharedTreeViewModel;
276
    MysharedTreeView mysharedTreeView = null;;
277

    
278
    protected SingleSelectionModel<Folder> otherSharedTreeSelectionModel;
279
    OtherSharedTreeViewModel otherSharedTreeViewModel;
280
    OtherSharedTreeView otherSharedTreeView = null;
281

    
282
    GroupTreeViewModel groupTreeViewModel;
283
    GroupTreeView groupTreeView;
284

    
285
    TreeView selectedTree;
286
    protected AccountResource account;
287
    
288
    Folder trash;
289
    
290
    List<Composite> treeViews = new ArrayList<Composite>();
291

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

    
302
        UploadAlert uploadAlert;
303

    
304
        @Override
305
        public void onModuleLoad() {
306
                if (parseUserCredentials())
307
            initialize();
308
        }
309

    
310
    private void initialize() {
311
            resources.pithosCss().ensureInjected();
312
            boolean bareContent = Window.Location.getParameter("noframe") != null;
313
            String contentWidth = bareContent ? "100%" : "75%";
314

    
315
            VerticalPanel outer = new VerticalPanel();
316
        outer.setWidth("100%");
317
            if (!bareContent) {
318
                    outer.addStyleName("pithos-outer");
319
            }
320

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

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

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

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

    
400
        folderTreeViewModel = new FolderTreeViewModel(this, folderTreeSelectionModel);
401
        folderTreeView = new FolderTreeView(folderTreeViewModel);
402
        treeViews.add(folderTreeView);
403
        
404
        fileList = new FileList(this, images);
405
        inner.add(fileList);
406

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

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

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

    
447
            @Override
448
            public void execute() {
449
                onWindowResized(Window.getClientHeight());
450
            }
451
        });
452

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

    
479
                                    HorizontalPanel separator = new HorizontalPanel();
480
                                    separator.addStyleName("pithos-statisticsSeparator");
481
                                    separator.add(new HTML(""));
482
                                    trees.add(separator);
483

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

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

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

    
544
    public void showFiles(final Folder f) {
545
        Set<File> files = f.getFiles();
546
        showFiles(files);
547
    }
548

    
549
    public void showFiles(Set<File> files) {
550
        fileList.setFiles(new ArrayList<File>(files));
551
    }
552

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

    
577
        String gotoUrl = Window.Location.getParameter("goto");
578
                if (gotoUrl != null && gotoUrl.length() > 0) {
579
                        Window.Location.assign(gotoUrl);
580
                        return false;
581
                }
582
                return true;
583
    }
584

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

    
593
        public void fetchAccount(final Command callback) {
594
        String path = "?format=json";
595

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

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

    
614
                        @Override
615
                        protected void onUnauthorized(Response response) {
616
                                sessionExpired();
617
                        }
618
        };
619
        getAccount.setHeader("X-Auth-Token", token);
620
        Scheduler.get().scheduleDeferred(getAccount);
621
    }
622

    
623
    public void updateStatistics() {
624
            HeadRequest<AccountResource> headAccount = new HeadRequest<AccountResource>(AccountResource.class, getApiPath(), username, "", account) {
625

    
626
                        @Override
627
                        public void onSuccess(AccountResource _result) {
628
                                folderTreeView.showStatistics(account);
629
                        }
630

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

    
641
                        @Override
642
                        protected void onUnauthorized(Response response) {
643
                                sessionExpired();
644
                        }
645
                };
646
                headAccount.setHeader("X-Auth-Token", token);
647
                Scheduler.get().scheduleDeferred(headAccount);
648
        }
649

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

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

    
671
                        @Override
672
                        protected void onUnauthorized(Response response) {
673
                                sessionExpired();
674
                        }
675
        };
676
        createPithos.setHeader("X-Auth-Token", getToken());
677
        Scheduler.get().scheduleDeferred(createPithos);
678
    }
679

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

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

    
698
                        @Override
699
                        protected void onUnauthorized(Response response) {
700
                                sessionExpired();
701
                        }
702
        };
703
        createPithos.setHeader("X-Auth-Token", getToken());
704
        Scheduler.get().scheduleDeferred(createPithos);
705
    }
706

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

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

    
732
        @Override
733
        public void onResize(ResizeEvent event) {
734
                int height = event.getHeight();
735
                onWindowResized(height);
736
        }
737

    
738
        /**
739
         * Display an error message.
740
         *
741
         * @param msg the message to display
742
         */
743
        public void displayError(String msg) {
744
                messagePanel.displayError(msg);
745
        }
746

    
747
        /**
748
         * Display a warning message.
749
         *
750
         * @param msg the message to display
751
         */
752
        public void displayWarning(String msg) {
753
                messagePanel.displayWarning(msg);
754
        }
755

    
756
        /**
757
         * Display an informational message.
758
         *
759
         * @param msg the message to display
760
         */
761
        public void displayInformation(String msg) {
762
                messagePanel.displayInformation(msg);
763
        }
764

    
765
        /**
766
         * Retrieve the fileList.
767
         *
768
         * @return the fileList
769
         */
770
        public FileList getFileList() {
771
                return fileList;
772
        }
773

    
774
        /**
775
         * Retrieve the topPanel.
776
         *
777
         * @return the topPanel
778
         */
779
        TopPanel getTopPanel() {
780
                return topPanel;
781
        }
782

    
783
        /**
784
         * Retrieve the clipboard.
785
         *
786
         * @return the clipboard
787
         */
788
        public Clipboard getClipboard() {
789
                return clipboard;
790
        }
791

    
792
        public StatusPanel getStatusPanel() {
793
                return statusPanel;
794
        }
795

    
796
        public String getToken() {
797
                return token;
798
        }
799

    
800
        public static native void preventIESelection() /*-{
801
                $doc.body.onselectstart = function () { return false; };
802
        }-*/;
803

    
804
        public static native void enableIESelection() /*-{
805
                if ($doc.body.onselectstart != null)
806
                $doc.body.onselectstart = null;
807
        }-*/;
808

    
809
        /**
810
         * @return the absolute path of the API root URL
811
         */
812
        public String getApiPath() {
813
                Configuration conf = (Configuration) GWT.create(Configuration.class);
814
                return conf.apiPath();
815
        }
816

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

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

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

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

    
872
                    @Override
873
                    public void onError(Throwable t) {
874
                        GWT.log("", t);
875
                                                setError(t);
876
                        displayError("System error unable to delete folder: " + t.getMessage());
877
                    }
878

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

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

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

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

    
962
    public FolderTreeView getFolderTreeView() {
963
        return folderTreeView;
964
    }
965

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

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

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

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

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

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

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

    
1050
                                        @Override
1051
                                        protected void onUnauthorized(Response response) {
1052
                                                sessionExpired();
1053
                                        }
1054
                                };
1055
                                getFolder.setHeader("X-Auth-Token", getToken());
1056
                                Scheduler.get().scheduleDeferred(getFolder);
1057
            }
1058

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

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

    
1086
        public OtherSharedTreeView getOtherSharedTreeView() {
1087
                return otherSharedTreeView;
1088
        }
1089

    
1090
        public void updateTrash(boolean showFiles, Command callback) {
1091
                updateFolder(trash, showFiles, callback, true);
1092
        }
1093

    
1094
        public void updateGroupsNode() {
1095
                groupTreeView.updateGroupNode(null);
1096
        }
1097

    
1098
        public Group addGroup(String groupname) {
1099
                Group newGroup = new Group(groupname);
1100
                account.addGroup(newGroup);
1101
                groupTreeView.updateGroupNode(null);
1102
                return newGroup;
1103
        }
1104

    
1105
        public void removeGroup(Group group) {
1106
                account.removeGroup(group);
1107
                updateGroupsNode();
1108
        }
1109

    
1110
        public TreeView getSelectedTree() {
1111
                return selectedTree;
1112
        }
1113
        
1114
        public void setSelectedTree(TreeView selected) {
1115
                selectedTree = selected;
1116
        }
1117

    
1118
        public Folder getSelection() {
1119
                if (selectedTree != null)
1120
                        return selectedTree.getSelection();
1121
                return null;
1122
        }
1123

    
1124
        public void showFolderStatistics(int folderFileCount) {
1125
                numOfFiles.setHTML(String.valueOf(folderFileCount));
1126
        }
1127

    
1128
        public GroupTreeView getGroupTreeView() {
1129
                return groupTreeView;
1130
        }
1131

    
1132
        public void sessionExpired() {
1133
                new SessionExpiredDialog(this).center();
1134
        }
1135

    
1136
        public void updateRootFolder(Command callback) {
1137
                updateFolder(account.getPithos(), false, callback, true);
1138
        }
1139

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

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

    
1206
        public native void log1(String message)/*-{
1207
                $wnd.console.log(message);
1208
        }-*/;
1209

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

    
1224
        public FileUploadDialog getFileUploadDialog() {
1225
                if (fileUploadDialog == null)
1226
                        fileUploadDialog = new FileUploadDialog(this);
1227
                return fileUploadDialog;
1228
        }
1229

    
1230
        public void hideUploadIndicator() {
1231
                upload.removeStyleName("pithos-uploadButton-loading");
1232
                upload.setTitle("");
1233
        }
1234
        
1235
        public void showUploadIndicator() {
1236
                upload.addStyleName("pithos-uploadButton-loading");
1237
                upload.setTitle("Upload in progress. Click for details.");
1238
        }
1239

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

    
1307
        public void scheduleFileHeadCommand(File f, final Command callback) {
1308
                HeadRequest<File> headFile = new HeadRequest<File>(File.class, getApiPath(), f.getOwner(), f.getUri(), f) {
1309

    
1310
                        @Override
1311
                        public void onSuccess(File _result) {
1312
                                if (callback != null)
1313
                                        callback.execute();
1314
                        }
1315

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

    
1326
                        @Override
1327
                        protected void onUnauthorized(Response response) {
1328
                                sessionExpired();
1329
                        }
1330
                };
1331
                headFile.setHeader("X-Auth-Token", getToken());
1332
                Scheduler.get().scheduleDeferred(headFile);
1333
        }
1334

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

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

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