Statistics
| Branch: | Tag: | Revision:

root / web_client / src / gr / grnet / pithos / web / client / GSS.java @ 3d01deba

History | View | Annotate | Download (29.4 kB)

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

    
37
import com.google.gwt.core.client.Scheduler;
38
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
39
import com.google.gwt.http.client.Request;
40
import com.google.gwt.http.client.RequestBuilder;
41
import com.google.gwt.http.client.RequestCallback;
42
import com.google.gwt.http.client.RequestException;
43
import com.google.gwt.http.client.Response;
44
import com.google.gwt.json.client.JSONArray;
45
import com.google.gwt.json.client.JSONObject;
46
import com.google.gwt.json.client.JSONParser;
47
import com.google.gwt.json.client.JSONString;
48
import com.google.gwt.json.client.JSONValue;
49
import com.google.gwt.view.client.SelectionChangeEvent;
50
import com.google.gwt.view.client.SingleSelectionModel;
51
import gr.grnet.pithos.web.client.commands.GetUserCommand;
52
import gr.grnet.pithos.web.client.foldertree.AccountResource;
53
import gr.grnet.pithos.web.client.foldertree.File;
54
import gr.grnet.pithos.web.client.foldertree.Folder;
55
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
56
import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
57
import gr.grnet.pithos.web.client.foldertree.Resource;
58
import gr.grnet.pithos.web.client.rest.DeleteRequest;
59
import gr.grnet.pithos.web.client.rest.GetRequest;
60
import gr.grnet.pithos.web.client.rest.RestException;
61
import gr.grnet.pithos.web.client.rest.resource.FileResource;
62
import gr.grnet.pithos.web.client.rest.resource.OtherUserResource;
63
import gr.grnet.pithos.web.client.rest.resource.RestResource;
64
import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper;
65
import gr.grnet.pithos.web.client.rest.resource.SharedResource;
66
import gr.grnet.pithos.web.client.rest.resource.TrashResource;
67
import gr.grnet.pithos.web.client.rest.resource.UserResource;
68

    
69
import java.util.ArrayList;
70
import java.util.Arrays;
71
import java.util.Date;
72
import java.util.HashMap;
73
import java.util.Iterator;
74
import java.util.List;
75

    
76
import com.google.gwt.core.client.EntryPoint;
77
import com.google.gwt.core.client.GWT;
78
import com.google.gwt.event.logical.shared.ResizeEvent;
79
import com.google.gwt.event.logical.shared.ResizeHandler;
80
import com.google.gwt.event.logical.shared.SelectionEvent;
81
import com.google.gwt.event.logical.shared.SelectionHandler;
82
import com.google.gwt.http.client.URL;
83
import com.google.gwt.i18n.client.DateTimeFormat;
84
import com.google.gwt.resources.client.ClientBundle;
85
import com.google.gwt.resources.client.ImageResource;
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.DecoratedTabPanel;
92
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
93
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
94
import com.google.gwt.user.client.ui.RootPanel;
95
import com.google.gwt.user.client.ui.TabPanel;
96
import com.google.gwt.user.client.ui.VerticalPanel;
97
import java.util.Set;
98

    
99
/**
100
 * Entry point classes define <code>onModuleLoad()</code>.
101
 */
102
public class GSS implements EntryPoint, ResizeHandler {
103

    
104
        /**
105
         * A constant that denotes the completion of an IncrementalCommand.
106
         */
107
        public static final boolean DONE = false;
108

    
109
        public static final int VISIBLE_FILE_COUNT = 25;
110

    
111
        /**
112
         * Instantiate an application-level image bundle. This object will provide
113
         * programmatic access to all the images needed by widgets.
114
         */
115
        private static Images images = (Images) GWT.create(Images.class);
116

    
117
    public String getUsername() {
118
        return username;
119
    }
120

    
121
    public void setAccount(AccountResource acct) {
122
        account = acct;
123
    }
124

    
125
    public AccountResource getAccount() {
126
        return account;
127
    }
128

    
129
    public void updateFolder(Folder f) {
130
        folderTreeView.updateFolder(f);
131
    }
132

    
133
    /**
134
         * An aggregate image bundle that pulls together all the images for this
135
         * application into a single bundle.
136
         */
137
        public interface Images extends ClientBundle, TopPanel.Images, StatusPanel.Images, FileMenu.Images, EditMenu.Images, SettingsMenu.Images, FilePropertiesDialog.Images, MessagePanel.Images, FileList.Images, Search.Images, CellTreeView.Images {
138

    
139
                @Source("gr/grnet/pithos/resources/document.png")
140
                ImageResource folders();
141

    
142
                @Source("gr/grnet/pithos/resources/edit_group_22.png")
143
                ImageResource groups();
144

    
145
                @Source("gr/grnet/pithos/resources/search.png")
146
                ImageResource search();
147
        }
148

    
149
        /**
150
         * The single GSS instance.
151
         */
152
        private static GSS singleton;
153

    
154
        /**
155
         * Gets the singleton GSS instance.
156
         *
157
         * @return the GSS object
158
         */
159
        public static GSS get() {
160
                if (GSS.singleton == null)
161
                        GSS.singleton = new GSS();
162
                return GSS.singleton;
163
        }
164

    
165
        /**
166
         * The Application Clipboard implementation;
167
         */
168
        private Clipboard clipboard = new Clipboard();
169

    
170
        private UserResource currentUserResource;
171

    
172
        /**
173
         * The top panel that contains the menu bar.
174
         */
175
        private TopPanel topPanel;
176

    
177
        /**
178
         * The panel that contains the various system messages.
179
         */
180
        private MessagePanel messagePanel = new MessagePanel(GSS.images);
181

    
182
        /**
183
         * The bottom panel that contains the status bar.
184
         */
185
        private StatusPanel statusPanel = null;
186

    
187
        /**
188
         * The top right panel that displays the logged in user details
189
         */
190
        private UserDetailsPanel userDetailsPanel = new UserDetailsPanel();
191

    
192
        /**
193
         * The file list widget.
194
         */
195
        private FileList fileList;
196

    
197
        /**
198
         * The tab panel that occupies the right side of the screen.
199
         */
200
        private TabPanel inner = new DecoratedTabPanel(){
201
                
202
//                public void onBrowserEvent(com.google.gwt.user.client.Event event) {
203
//                        if (DOM.eventGetType(event) == Event.ONCONTEXTMENU){
204
//                                if(isFileListShowing()){
205
//                                        getFileList().showContextMenu(event);
206
//                                }
207
//                        }
208
//                };
209
        };
210

    
211

    
212
        /**
213
         * The split panel that will contain the left and right panels.
214
         */
215
        private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
216

    
217
        /**
218
         * The widget that displays the tree of folders.
219
         */
220
        
221
        private CellTreeView treeView = null;
222
        /**
223
         * The currently selected item in the application, for use by the Edit menu
224
         * commands. Potential types are Folder, File, User and Group.
225
         */
226
        private Object currentSelection;
227

    
228

    
229
        /**
230
         * The WebDAV password of the current user
231
         */
232
        private String webDAVPassword;
233

    
234
        public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
235

    
236
    private String username = null;
237

    
238
    /**
239
     * The authentication token of the current user.
240
     */
241
    private String token;
242

    
243
    private SingleSelectionModel<Folder> folderTreeSelectionModel;
244
    private FolderTreeViewModel folderTreeViewModel;
245
    private FolderTreeView folderTreeView;
246

    
247
    private AccountResource account;
248

    
249
        @Override
250
        public void onModuleLoad() {
251
                // Initialize the singleton before calling the constructors of the
252
                // various widgets that might call GSS.get().
253
                singleton = this;
254
                if (parseUserCredentials())
255
            initialize();
256
        }
257

    
258
    private void initialize() {
259
        topPanel = new TopPanel(GSS.images);
260
        topPanel.setWidth("100%");
261

    
262
        messagePanel.setWidth("100%");
263
        messagePanel.setVisible(false);
264

    
265

    
266
        // Inner contains the various lists.
267
        inner.sinkEvents(Event.ONCONTEXTMENU);
268
        inner.setAnimationEnabled(true);
269
        inner.getTabBar().addStyleName("pithos-MainTabBar");
270
        inner.getDeckPanel().addStyleName("pithos-MainTabPanelBottom");
271

    
272
        inner.setWidth("100%");
273

    
274
        inner.addSelectionHandler(new SelectionHandler<Integer>() {
275

    
276
            @Override
277
            public void onSelection(SelectionEvent<Integer> event) {
278
                int tabIndex = event.getSelectedItem();
279
                switch (tabIndex) {
280
                    case 0:
281
                        fileList.updateCurrentlyShowingStats();
282
                        break;
283
                }
284
            }
285
        });
286

    
287
        folderTreeSelectionModel = new SingleSelectionModel<Folder>();
288
        folderTreeSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
289
            @Override
290
            public void onSelectionChange(SelectionChangeEvent event) {
291
                Folder f = folderTreeSelectionModel.getSelectedObject();
292
                updateFolder(f);
293
            }
294
        });
295

    
296
        folderTreeViewModel = new FolderTreeViewModel(folderTreeSelectionModel);
297
        folderTreeView = new FolderTreeView(folderTreeViewModel);
298

    
299
        fileList = new FileList(images, folderTreeView);
300
        inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true);
301

    
302
        // Add the left and right panels to the split panel.
303
        splitPanel.setLeftWidget(folderTreeView);
304
        splitPanel.setRightWidget(inner);
305
        splitPanel.setSplitPosition("25%");
306
        splitPanel.setSize("100%", "100%");
307
        splitPanel.addStyleName("pithos-splitPanel");
308

    
309
        // Create a dock panel that will contain the menu bar at the top,
310
        // the shortcuts to the left, the status bar at the bottom and the
311
        // right panel taking the rest.
312
        VerticalPanel outer = new VerticalPanel();
313
        outer.add(topPanel);
314
        outer.add(messagePanel);
315
        outer.add(splitPanel);
316
        statusPanel = new StatusPanel(GSS.images);
317
        outer.add(statusPanel);
318
        outer.setWidth("100%");
319
        outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
320

    
321
        outer.setSpacing(4);
322

    
323
        // Hook the window resize event, so that we can adjust the UI.
324
        Window.addResizeHandler(this);
325
        // Clear out the window's built-in margin, because we want to take
326
        // advantage of the entire client area.
327
        Window.setMargin("0px");
328
        // Finally, add the outer panel to the RootPanel, so that it will be
329
        // displayed.
330
        RootPanel.get().add(outer);
331
        // Call the window resized handler to get the initial sizes setup. Doing
332
        // this in a deferred command causes it to occur after all widgets'
333
        // sizes have been computed by the browser.
334
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
335

    
336
            @Override
337
            public void execute() {
338
                onWindowResized(Window.getClientHeight());
339
            }
340
        });
341

    
342
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
343
            @Override
344
            public void execute() {
345
                fetchAccount();
346
            }
347
        });
348
    }
349

    
350
    public void showFiles(Folder f) {
351
        inner.selectTab(0);
352
        Set<File> files = f.getFiles();
353
        Iterator<File> iter = files.iterator();
354
        fetchFile(iter, files);
355
    }
356

    
357
    private void fetchFile(final Iterator<File> iter, final Set<File> files) {
358
        if (iter.hasNext()) {
359
            File file = iter.next();
360
            String path = getApiPath() + username + "/" + file.getContainer() + "/" + file.getPath() + "?format=json";
361
            GetRequest<File> getFile = new GetRequest<File>(File.class, path, file) {
362
                @Override
363
                public void onSuccess(File result) {
364
                    fetchFile(iter, files);
365
                }
366

    
367
                @Override
368
                public void onError(Throwable t) {
369
                    GWT.log("Error getting file", t);
370
                    if (t instanceof RestException)
371
                        GSS.get().displayError("Error getting file: " + ((RestException) t).getHttpStatusText());
372
                    else
373
                        GSS.get().displayError("System error fetching file: " + t.getMessage());
374
                }
375
            };
376
            getFile.setHeader("X-Auth-Token", "0000");
377
            Scheduler.get().scheduleDeferred(getFile);
378
        }
379
        else
380
            fileList.setFiles(new ArrayList<File>(files));
381
    }
382

    
383
    /**
384
         * Parse and store the user credentials to the appropriate fields.
385
         */
386
        private boolean parseUserCredentials() {
387
                Configuration conf = (Configuration) GWT.create(Configuration.class);
388
                String cookie = conf.authCookie();
389
                String auth = Cookies.getCookie(cookie);
390
                if (auth == null) {
391
                        authenticateUser();
392
            return false;
393
        }
394
        else {
395
            String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2);
396
            if (authSplit.length != 2) {
397
                authenticateUser();
398
                return false;
399
            }
400
            else {
401
                username = authSplit[0];
402
                token = authSplit[1];
403
                return true;
404
            }
405
        }
406
        }
407

    
408
    /**
409
         * Redirect the user to the login page for authentication.
410
         */
411
        protected void authenticateUser() {
412
                Configuration conf = (Configuration) GWT.create(Configuration.class);
413

    
414
//        Window.Location.assign(GWT.getModuleBaseURL() + conf.loginUrl() + "?next=" + Window.Location.getHref());
415
        Cookies.setCookie(conf.authCookie(), "test" + conf.cookieSeparator() + "0000");
416
        Window.Location.assign(GWT.getModuleBaseURL() + "GSS.html");
417
        }
418

    
419
    private void fetchAccount() {
420
        String path = getApiPath() + username + "?format=json";
421

    
422
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
423
            @Override
424
            public void onSuccess(AccountResource result) {
425
                account = result;
426
                statusPanel.displayStats(account);
427
                folderTreeViewModel.initialize(account);
428
                inner.selectTab(0);
429
            }
430

    
431
            @Override
432
            public void onError(Throwable t) {
433
                GWT.log("Error getting account", t);
434
                if (t instanceof RestException)
435
                    GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
436
                else
437
                    GSS.get().displayError("System error fetching user data: " + t.getMessage());
438
            }
439
        };
440
        getAccount.setHeader("X-Auth-Token", token);
441
        Scheduler.get().scheduleDeferred(getAccount);
442
    }
443

    
444
        /**
445
         * Clear the cookie and redirect the user to the logout page.
446
         */
447
        void logout() {
448
                Configuration conf = (Configuration) GWT.create(Configuration.class);
449
                String cookie = conf.authCookie();
450
                String domain = Window.Location.getHostName();
451
                String path = Window.Location.getPath();
452
                Cookies.setCookie(cookie, "", null, domain, path, false);
453
        String baseUrl = GWT.getModuleBaseURL();
454
        String homeUrl = baseUrl.substring(0, baseUrl.indexOf(path));
455
                Window.Location.assign(homeUrl + conf.logoutUrl());
456
        }
457

    
458
        /**
459
         * Creates an HTML fragment that places an image & caption together, for use
460
         * in a group header.
461
         *
462
         * @param imageProto an image prototype for an image
463
         * @param caption the group caption
464
         * @return the header HTML fragment
465
         */
466
        private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
467
                String captionHTML = "<table class='caption' cellpadding='0' " 
468
                + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() 
469
                + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'>&nbsp;" 
470
                + caption + "</b></td></tr></table>";
471
                return captionHTML;
472
        }
473

    
474
        private void onWindowResized(int height) {
475
                // Adjust the split panel to take up the available room in the window.
476
                int newHeight = height - splitPanel.getAbsoluteTop() - 44;
477
                if (newHeight < 1)
478
                        newHeight = 1;
479
                splitPanel.setHeight("" + newHeight);
480
                inner.setHeight("" + newHeight);
481
        }
482

    
483
        @Override
484
        public void onResize(ResizeEvent event) {
485
                int height = event.getHeight();
486
                onWindowResized(height);
487
        }
488

    
489
        public boolean isFileListShowing() {
490
                int tab = inner.getTabBar().getSelectedTab();
491
                if (tab == 0)
492
                        return true;
493
                return false;
494
        }
495

    
496
        public boolean isSearchResultsShowing() {
497
                int tab = inner.getTabBar().getSelectedTab();
498
                if (tab == 2)
499
                        return true;
500
                return false;
501
        }
502

    
503
        /**
504
         * Make the file list visible.
505
         *
506
         * @param update
507
         */
508
        public void showFileList(boolean update) {
509
                if(update){
510
                        getTreeView().refreshCurrentNode(true);
511
                }
512
                else{
513
                        RestResource currentFolder = getTreeView().getSelection();
514
                        if(currentFolder!=null){
515
                                showFileList(currentFolder);
516
                }
517
                }
518

    
519
        }
520
        
521
        public void showFileList(RestResource r) {
522
                showFileList(r,true);
523
        }
524
        
525
        public void showFileList(RestResource r, boolean clearSelection) {
526
                RestResource currentFolder = r;
527
                if(currentFolder!=null){
528
                        List<FileResource> files = null;
529
                        if (currentFolder instanceof RestResourceWrapper) {
530
                                RestResourceWrapper folder = (RestResourceWrapper) currentFolder;
531
                                files = folder.getResource().getFiles();
532
                        }
533
                }
534
                inner.selectTab(0);
535
        }
536

    
537
        /**
538
         * Display the 'loading' indicator.
539
         */
540
        public void showLoadingIndicator(String message, String path) {
541
                if(path!=null){
542
                        String[] split = path.split("/");
543
                        message = message +" "+URL.decode(split[split.length-1]);
544
                }
545
                topPanel.getLoading().show(message);
546
        }
547

    
548
        /**
549
         * Hide the 'loading' indicator.
550
         */
551
        public void hideLoadingIndicator() {
552
                topPanel.getLoading().hide();
553
        }
554

    
555
        /**
556
         * A native JavaScript method to reach out to the browser's window and
557
         * invoke its resizeTo() method.
558
         *
559
         * @param x the new width
560
         * @param y the new height
561
         */
562
        public static native void resizeTo(int x, int y) /*-{
563
                $wnd.resizeTo(x,y);
564
        }-*/;
565

    
566
        /**
567
         * A helper method that returns true if the user's list is currently visible
568
         * and false if it is hidden.
569
         *
570
         * @return true if the user list is visible
571
         */
572
        public boolean isUserListVisible() {
573
                return inner.getTabBar().getSelectedTab() == 1;
574
        }
575

    
576
        /**
577
         * Display an error message.
578
         *
579
         * @param msg the message to display
580
         */
581
        public void displayError(String msg) {
582
                messagePanel.displayError(msg);
583
        }
584

    
585
        /**
586
         * Display a warning message.
587
         *
588
         * @param msg the message to display
589
         */
590
        public void displayWarning(String msg) {
591
                messagePanel.displayWarning(msg);
592
        }
593

    
594
        /**
595
         * Display an informational message.
596
         *
597
         * @param msg the message to display
598
         */
599
        public void displayInformation(String msg) {
600
                messagePanel.displayInformation(msg);
601
        }
602

    
603
        /**
604
         * Retrieve the folders.
605
         *
606
         * @return the folders
607
         
608
        public Folders getFolders() {
609
                return folders;
610
        }*/
611

    
612
        /**
613
         * Retrieve the currentSelection.
614
         *
615
         * @return the currentSelection
616
         */
617
        public Object getCurrentSelection() {
618
                return currentSelection;
619
        }
620

    
621
        /**
622
         * Modify the currentSelection.
623
         *
624
         * @param newCurrentSelection the currentSelection to set
625
         */
626
        public void setCurrentSelection(Object newCurrentSelection) {
627
                currentSelection = newCurrentSelection;
628
        }
629

    
630
        /**
631
         * Retrieve the fileList.
632
         *
633
         * @return the fileList
634
         */
635
        public FileList getFileList() {
636
                return fileList;
637
        }
638

    
639
        /**
640
         * Retrieve the topPanel.
641
         *
642
         * @return the topPanel
643
         */
644
        TopPanel getTopPanel() {
645
                return topPanel;
646
        }
647

    
648
        /**
649
         * Retrieve the clipboard.
650
         *
651
         * @return the clipboard
652
         */
653
        public Clipboard getClipboard() {
654
                return clipboard;
655
        }
656

    
657
        public StatusPanel getStatusPanel() {
658
                return statusPanel;
659
        }
660

    
661
        /**
662
         * Retrieve the userDetailsPanel.
663
         *
664
         * @return the userDetailsPanel
665
         */
666
        public UserDetailsPanel getUserDetailsPanel() {
667
                return userDetailsPanel;
668
        }
669

    
670
        
671

    
672
        public String getToken() {
673
                return token;
674
        }
675

    
676
        public String getWebDAVPassword() {
677
                return webDAVPassword;
678
        }
679

    
680
        /**
681
         * Retrieve the currentUserResource.
682
         *
683
         * @return the currentUserResource
684
         */
685
        public UserResource getCurrentUserResource() {
686
                return currentUserResource;
687
        }
688

    
689
        /**
690
         * Modify the currentUserResource.
691
         *
692
         * @param newUser the new currentUserResource
693
         */
694
        public void setCurrentUserResource(UserResource newUser) {
695
                currentUserResource = newUser;
696
        }
697

    
698
        public static native void preventIESelection() /*-{
699
                $doc.body.onselectstart = function () { return false; };
700
        }-*/;
701

    
702
        public static native void enableIESelection() /*-{
703
                if ($doc.body.onselectstart != null)
704
                $doc.body.onselectstart = null;
705
        }-*/;
706

    
707
        /**
708
         * @return the absolute path of the API root URL
709
         */
710
        public String getApiPath() {
711
                Configuration conf = (Configuration) GWT.create(Configuration.class);
712
                return conf.apiPath();
713
        }
714

    
715
        /**
716
         * Convert server date to local time according to browser timezone
717
         * and format it according to localized pattern.
718
         * Time is always formatted to 24hr format.
719
         * NB: This assumes that server runs in UTC timezone. Otherwise
720
         * we would need to adjust for server time offset as well.
721
         *
722
         * @param date
723
         * @return String
724
         */
725
        public static String formatLocalDateTime(Date date) {
726
                Date convertedDate = new Date(date.getTime() - date.getTimezoneOffset());
727
                final DateTimeFormat dateFormatter = DateTimeFormat.getShortDateFormat();
728
                final DateTimeFormat timeFormatter = DateTimeFormat.getFormat("HH:mm");
729
                String datePart = dateFormatter.format(convertedDate);
730
                String timePart = timeFormatter.format(convertedDate);
731
                return datePart + " " + timePart;
732
        }
733
        
734
        /**
735
         * History support for folder navigation
736
         * adds a new browser history entry
737
         *
738
         * @param key
739
         */
740
        public void updateHistory(String key){
741
//                Replace any whitespace of the initial string to "+"
742
//                String result = key.replaceAll("\\s","+");
743
//                Add a new browser history entry.
744
//                History.newItem(result);
745
                History.newItem(key);
746
        }
747

    
748
        /**
749
         * This method examines the token input and add a "/" at the end in case it's omitted.
750
         * This happens only in Files/trash/, Files/shared/, Files/others.
751
         *
752
         * @param tokenInput
753
         * @return the formated token with a "/" at the end or the same tokenInput parameter
754
         */
755

    
756
        private String handleSpecialFolderNames(String tokenInput){
757
                List<String> pathsToCheck = Arrays.asList("Files/trash", "Files/shared", "Files/others");
758
                if(pathsToCheck.contains(tokenInput))
759
                        return tokenInput + "/";
760
                return tokenInput;
761

    
762
        }
763

    
764
        /**
765
         * Reject illegal resource names, like '.' or '..' or slashes '/'.
766
         */
767
        static boolean isValidResourceName(String name) {
768
                if (".".equals(name) ||        "..".equals(name) || name.contains("/"))
769
                        return false;
770
                return true;
771
        }
772

    
773
        public void putUserToMap(String _userName, String _userFullName){
774
                userFullNameMap.put(_userName, _userFullName);
775
        }
776

    
777
        public String findUserFullName(String _userName){
778
                return userFullNameMap.get(_userName);
779
        }
780
        public String getUserFullName(String _userName) {
781
                
782
        if (GSS.get().findUserFullName(_userName) == null)
783
                //if there is no userFullName found then the map fills with the given _userName,
784
                //so userFullName = _userName
785
                GSS.get().putUserToMap(_userName, _userName);
786
        else if(GSS.get().findUserFullName(_userName).indexOf('@') != -1){
787
                //if the userFullName = _userName the GetUserCommand updates the userFullName in the map
788
                GetUserCommand guc = new GetUserCommand(_userName);
789
                guc.execute();
790
        }
791
        return GSS.get().findUserFullName(_userName);
792
        }
793
        /**
794
         * Retrieve the treeView.
795
         *
796
         * @return the treeView
797
         */
798
        public CellTreeView getTreeView() {
799
                return treeView;
800
        }
801
        
802
        public void onResourceUpdate(RestResource resource,boolean clearSelection){
803
                if(resource instanceof RestResourceWrapper || resource instanceof OtherUserResource || resource instanceof TrashResource || resource instanceof SharedResource){
804
                        if(getTreeView().getSelection()!=null&&getTreeView().getSelection().getUri().equals(resource.getUri()))
805
                                showFileList(resource,clearSelection);
806
                }
807
                
808
        }
809

    
810
    public void deleteFolder(final Folder folder) {
811
        String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + folder.getPrefix();
812
        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
813
        builder.setHeader("If-Modified-Since", "0");
814
        builder.setHeader("X-Auth-Token", getToken());
815
        try {
816
            builder.sendRequest("", new RequestCallback() {
817
                @Override
818
                public void onResponseReceived(Request request, Response response) {
819
                    if (response.getStatusCode() == Response.SC_OK) {
820
                        JSONValue json = JSONParser.parseStrict(response.getText());
821
                        JSONArray array = json.isArray();
822
                        int i = 0;
823
                        if (array != null) {
824
                            deleteObject(folder, i, array);
825
                        }
826
                    }
827
                }
828

    
829
                @Override
830
                public void onError(Request request, Throwable exception) {
831
                    GSS.get().displayError("System error unable to delete folder: " + exception.getMessage());
832
                }
833
            });
834
        }
835
        catch (RequestException e) {
836
        }
837
    }
838

    
839
    public void deleteObject(final Folder folder, final int i, final JSONArray array) {
840
        if (i < array.size()) {
841
            JSONObject o = array.get(i).isObject();
842
            if (o != null && !o.containsKey("subdir")) {
843
                JSONString name = o.get("name").isString();
844
                String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "/" + name.stringValue();
845
                DeleteRequest delete = new DeleteRequest(path) {
846
                    @Override
847
                    public void onSuccess(Resource result) {
848
                        deleteObject(folder, i + 1, array);
849
                    }
850

    
851
                    @Override
852
                    public void onError(Throwable t) {
853
                        GWT.log("", t);
854
                        GSS.get().displayError("System error unable to delete folder: " + t.getMessage());
855
                    }
856
                };
857
                delete.setHeader("X-Auth-Token", getToken());
858
                Scheduler.get().scheduleDeferred(delete);
859
            }
860
            else {
861
                String subdir = o.get("subdir").isString().stringValue();
862
                subdir = subdir.substring(0, subdir.length() - 1);
863
                String path = getApiPath() + getUsername() + "/" + folder.getContainer() + "?format=json&delimiter=/&prefix=" + subdir;
864
                RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, path);
865
                builder.setHeader("If-Modified-Since", "0");
866
                builder.setHeader("X-Auth-Token", getToken());
867
                try {
868
                    builder.sendRequest("", new RequestCallback() {
869
                        @Override
870
                        public void onResponseReceived(Request request, Response response) {
871
                            if (response.getStatusCode() == Response.SC_OK) {
872
                                JSONValue json = JSONParser.parseStrict(response.getText());
873
                                JSONArray array2 = json.isArray();
874
                                if (array2 != null) {
875
                                    int l = array.size();
876
                                    for (int j=0; j<array2.size(); j++) {
877
                                        array.set(l++, array2.get(j));
878
                                    }
879
                                }
880
                                deleteObject(folder, i + 1, array);
881
                            }
882
                        }
883

    
884
                        @Override
885
                        public void onError(Request request, Throwable exception) {
886
                            GSS.get().displayError("System error unable to delete folder: " + exception.getMessage());
887
                        }
888
                    });
889
                }
890
                catch (RequestException e) {
891
                }
892
            }
893
        }
894
        else {
895
            String prefix = folder.getPrefix();
896
            String path = getApiPath() + getUsername() + "/" + folder.getContainer() + (prefix.length() == 0 ? "" : "/" + prefix);
897
            DeleteRequest deleteFolder = new DeleteRequest(path) {
898
                @Override
899
                public void onSuccess(Resource result) {
900
                    updateFolder(folder.getParent());
901
                }
902

    
903
                @Override
904
                public void onError(Throwable t) {
905
                    GWT.log("", t);
906
                    if (t instanceof RestException) {
907
                        displayError("Unable to delete folder: "+((RestException) t).getHttpStatusText());
908
                    }
909
                    else
910
                        GSS.get().displayError("System error unable to delete folder: " + t.getMessage());
911
                }
912
            };
913
            deleteFolder.setHeader("X-Auth-Token", getToken());
914
            Scheduler.get().scheduleDeferred(deleteFolder);
915
        }
916
    }
917

    
918
    public FolderTreeView getFolderTreeView() {
919
        return folderTreeView;
920
    }
921
}