Statistics
| Branch: | Tag: | Revision:

root / src / gr / grnet / pithos / web / client / GSS.java @ 1e413f9b

History | View | Annotate | Download (23.7 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.view.client.SelectionChangeEvent;
40
import com.google.gwt.view.client.SingleSelectionModel;
41
import gr.grnet.pithos.web.client.commands.GetUserCommand;
42
import gr.grnet.pithos.web.client.foldertree.AccountResource;
43
import gr.grnet.pithos.web.client.foldertree.File;
44
import gr.grnet.pithos.web.client.foldertree.Folder;
45
import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
46
import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
47
import gr.grnet.pithos.web.client.rest.GetRequest;
48
import gr.grnet.pithos.web.client.rest.RestException;
49
import gr.grnet.pithos.web.client.rest.resource.FileResource;
50
import gr.grnet.pithos.web.client.rest.resource.OtherUserResource;
51
import gr.grnet.pithos.web.client.rest.resource.RestResource;
52
import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper;
53
import gr.grnet.pithos.web.client.rest.resource.SharedResource;
54
import gr.grnet.pithos.web.client.rest.resource.TrashResource;
55
import gr.grnet.pithos.web.client.rest.resource.UserResource;
56

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

    
64
import com.google.gwt.core.client.EntryPoint;
65
import com.google.gwt.core.client.GWT;
66
import com.google.gwt.event.logical.shared.ResizeEvent;
67
import com.google.gwt.event.logical.shared.ResizeHandler;
68
import com.google.gwt.event.logical.shared.SelectionEvent;
69
import com.google.gwt.event.logical.shared.SelectionHandler;
70
import com.google.gwt.http.client.URL;
71
import com.google.gwt.i18n.client.DateTimeFormat;
72
import com.google.gwt.resources.client.ClientBundle;
73
import com.google.gwt.resources.client.ImageResource;
74
import com.google.gwt.user.client.Cookies;
75
import com.google.gwt.user.client.Event;
76
import com.google.gwt.user.client.History;
77
import com.google.gwt.user.client.Window;
78
import com.google.gwt.user.client.ui.AbstractImagePrototype;
79
import com.google.gwt.user.client.ui.DecoratedTabPanel;
80
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
81
import com.google.gwt.user.client.ui.HorizontalSplitPanel;
82
import com.google.gwt.user.client.ui.RootPanel;
83
import com.google.gwt.user.client.ui.TabPanel;
84
import com.google.gwt.user.client.ui.VerticalPanel;
85
import java.util.Set;
86

    
87
/**
88
 * Entry point classes define <code>onModuleLoad()</code>.
89
 */
90
public class GSS implements EntryPoint, ResizeHandler {
91

    
92
        /**
93
         * A constant that denotes the completion of an IncrementalCommand.
94
         */
95
        public static final boolean DONE = false;
96

    
97
        public static final int VISIBLE_FILE_COUNT = 25;
98

    
99
        /**
100
         * Instantiate an application-level image bundle. This object will provide
101
         * programmatic access to all the images needed by widgets.
102
         */
103
        private static Images images = (Images) GWT.create(Images.class);
104

    
105
    public String getUsername() {
106
        return username;
107
    }
108

    
109
    public void setAccount(AccountResource acct) {
110
        account = acct;
111
    }
112

    
113
    public AccountResource getAccount() {
114
        return account;
115
    }
116

    
117
    public void updateFolder(Folder f) {
118
        folderTreeView.updateFolder(f);
119
    }
120

    
121
    /**
122
         * An aggregate image bundle that pulls together all the images for this
123
         * application into a single bundle.
124
         */
125
        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 {
126

    
127
                @Source("gr/grnet/pithos/resources/document.png")
128
                ImageResource folders();
129

    
130
                @Source("gr/grnet/pithos/resources/edit_group_22.png")
131
                ImageResource groups();
132

    
133
                @Source("gr/grnet/pithos/resources/search.png")
134
                ImageResource search();
135
        }
136

    
137
        /**
138
         * The single GSS instance.
139
         */
140
        private static GSS singleton;
141

    
142
        /**
143
         * Gets the singleton GSS instance.
144
         *
145
         * @return the GSS object
146
         */
147
        public static GSS get() {
148
                if (GSS.singleton == null)
149
                        GSS.singleton = new GSS();
150
                return GSS.singleton;
151
        }
152

    
153
        /**
154
         * The Application Clipboard implementation;
155
         */
156
        private Clipboard clipboard = new Clipboard();
157

    
158
        private UserResource currentUserResource;
159

    
160
        /**
161
         * The top panel that contains the menu bar.
162
         */
163
        private TopPanel topPanel;
164

    
165
        /**
166
         * The panel that contains the various system messages.
167
         */
168
        private MessagePanel messagePanel = new MessagePanel(GSS.images);
169

    
170
        /**
171
         * The bottom panel that contains the status bar.
172
         */
173
        private StatusPanel statusPanel = null;
174

    
175
        /**
176
         * The top right panel that displays the logged in user details
177
         */
178
        private UserDetailsPanel userDetailsPanel = new UserDetailsPanel();
179

    
180
        /**
181
         * The file list widget.
182
         */
183
        private FileList fileList;
184

    
185
        /**
186
         * The tab panel that occupies the right side of the screen.
187
         */
188
        private TabPanel inner = new DecoratedTabPanel(){
189
                
190
//                public void onBrowserEvent(com.google.gwt.user.client.Event event) {
191
//                        if (DOM.eventGetType(event) == Event.ONCONTEXTMENU){
192
//                                if(isFileListShowing()){
193
//                                        getFileList().showContextMenu(event);
194
//                                }
195
//                        }
196
//                };
197
        };
198

    
199

    
200
        /**
201
         * The split panel that will contain the left and right panels.
202
         */
203
        private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
204

    
205
        /**
206
         * The widget that displays the tree of folders.
207
         */
208
        
209
        private CellTreeView treeView = null;
210
        /**
211
         * The currently selected item in the application, for use by the Edit menu
212
         * commands. Potential types are Folder, File, User and Group.
213
         */
214
        private Object currentSelection;
215

    
216

    
217
        /**
218
         * The WebDAV password of the current user
219
         */
220
        private String webDAVPassword;
221

    
222
        public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
223

    
224
    private String username = null;
225

    
226
    /**
227
     * The authentication token of the current user.
228
     */
229
    private String token;
230

    
231
    private SingleSelectionModel<Folder> folderTreeSelectionModel;
232
    private FolderTreeViewModel folderTreeViewModel;
233
    private FolderTreeView folderTreeView;
234

    
235
    private AccountResource account;
236

    
237
        @Override
238
        public void onModuleLoad() {
239
                // Initialize the singleton before calling the constructors of the
240
                // various widgets that might call GSS.get().
241
                singleton = this;
242
                if (parseUserCredentials())
243
            initialize();
244
        }
245

    
246
    private void initialize() {
247
        topPanel = new TopPanel(GSS.images);
248
        topPanel.setWidth("100%");
249

    
250
        messagePanel.setWidth("100%");
251
        messagePanel.setVisible(false);
252

    
253

    
254
        // Inner contains the various lists.
255
        inner.sinkEvents(Event.ONCONTEXTMENU);
256
        inner.setAnimationEnabled(true);
257
        inner.getTabBar().addStyleName("pithos-MainTabBar");
258
        inner.getDeckPanel().addStyleName("pithos-MainTabPanelBottom");
259

    
260
        inner.setWidth("100%");
261

    
262
        inner.addSelectionHandler(new SelectionHandler<Integer>() {
263

    
264
            @Override
265
            public void onSelection(SelectionEvent<Integer> event) {
266
                int tabIndex = event.getSelectedItem();
267
                switch (tabIndex) {
268
                    case 0:
269
                        fileList.updateCurrentlyShowingStats();
270
                        break;
271
                }
272
            }
273
        });
274

    
275
        folderTreeSelectionModel = new SingleSelectionModel<Folder>();
276
        folderTreeSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
277
            @Override
278
            public void onSelectionChange(SelectionChangeEvent event) {
279
                Folder f = folderTreeSelectionModel.getSelectedObject();
280
                updateFolder(f);
281
            }
282
        });
283

    
284
        folderTreeViewModel = new FolderTreeViewModel(folderTreeSelectionModel);
285
        folderTreeView = new FolderTreeView(folderTreeViewModel);
286

    
287
        fileList = new FileList(images, folderTreeView);
288
        inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true);
289

    
290
        // Add the left and right panels to the split panel.
291
        splitPanel.setLeftWidget(folderTreeView);
292
        splitPanel.setRightWidget(inner);
293
        splitPanel.setSplitPosition("25%");
294
        splitPanel.setSize("100%", "100%");
295
        splitPanel.addStyleName("pithos-splitPanel");
296

    
297
        // Create a dock panel that will contain the menu bar at the top,
298
        // the shortcuts to the left, the status bar at the bottom and the
299
        // right panel taking the rest.
300
        VerticalPanel outer = new VerticalPanel();
301
        outer.add(topPanel);
302
        outer.add(messagePanel);
303
        outer.add(splitPanel);
304
        statusPanel = new StatusPanel(GSS.images);
305
        outer.add(statusPanel);
306
        outer.setWidth("100%");
307
        outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
308

    
309
        outer.setSpacing(4);
310

    
311
        // Hook the window resize event, so that we can adjust the UI.
312
        Window.addResizeHandler(this);
313
        // Clear out the window's built-in margin, because we want to take
314
        // advantage of the entire client area.
315
        Window.setMargin("0px");
316
        // Finally, add the outer panel to the RootPanel, so that it will be
317
        // displayed.
318
        RootPanel.get().add(outer);
319
        // Call the window resized handler to get the initial sizes setup. Doing
320
        // this in a deferred command causes it to occur after all widgets'
321
        // sizes have been computed by the browser.
322
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
323

    
324
            @Override
325
            public void execute() {
326
                onWindowResized(Window.getClientHeight());
327
            }
328
        });
329

    
330
        Scheduler.get().scheduleDeferred(new ScheduledCommand() {
331
            @Override
332
            public void execute() {
333
                fetchAccount();
334
            }
335
        });
336
    }
337

    
338
    public void showFiles(Folder f) {
339
        inner.selectTab(0);
340
        Set<File> files = f.getFiles();
341
        Iterator<File> iter = files.iterator();
342
        fetchFile(iter, files);
343
    }
344

    
345
    private void fetchFile(final Iterator<File> iter, final Set<File> files) {
346
        if (iter.hasNext()) {
347
            File file = iter.next();
348
            String path = getApiPath() + username + "/" + file.getContainer() + "/" + file.getPath() + "?format=json";
349
            GetRequest<File> getFile = new GetRequest<File>(File.class, path, file) {
350
                @Override
351
                public void onSuccess(File result) {
352
                    fetchFile(iter, files);
353
                }
354

    
355
                @Override
356
                public void onError(Throwable t) {
357
                    GWT.log("Error getting file", t);
358
                    if (t instanceof RestException)
359
                        GSS.get().displayError("Error getting file: " + ((RestException) t).getHttpStatusText());
360
                    else
361
                        GSS.get().displayError("System error fetching file: " + t.getMessage());
362
                }
363
            };
364
            getFile.setHeader("X-Auth-Token", "0000");
365
            Scheduler.get().scheduleDeferred(getFile);
366
        }
367
        else
368
            fileList.setFiles(new ArrayList<File>(files));
369
    }
370

    
371
    /**
372
         * Parse and store the user credentials to the appropriate fields.
373
         */
374
        private boolean parseUserCredentials() {
375
                Configuration conf = (Configuration) GWT.create(Configuration.class);
376
                String cookie = conf.authCookie();
377
                String auth = Cookies.getCookie(cookie);
378
                if (auth == null) {
379
                        authenticateUser();
380
            return false;
381
        }
382
        else {
383
            String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2);
384
            if (authSplit.length != 2) {
385
                authenticateUser();
386
                return false;
387
            }
388
            else {
389
                username = authSplit[0];
390
                token = authSplit[1];
391
                return true;
392
            }
393
        }
394
        }
395

    
396
    /**
397
         * Redirect the user to the login page for authentication.
398
         */
399
        protected void authenticateUser() {
400
                Configuration conf = (Configuration) GWT.create(Configuration.class);
401

    
402
//        Window.Location.assign(GWT.getModuleBaseURL() + conf.loginUrl() + "?next=" + Window.Location.getHref());
403
        Cookies.setCookie(conf.authCookie(), "test" + conf.cookieSeparator() + "0000");
404
        Window.Location.assign(GWT.getModuleBaseURL() + "GSS.html");
405
        }
406

    
407
    private void fetchAccount() {
408
        String path = getApiPath() + username + "?format=json";
409

    
410
        GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
411
            @Override
412
            public void onSuccess(AccountResource result) {
413
                account = result;
414
                statusPanel.displayStats(account);
415
                folderTreeViewModel.initialize(account);
416
                inner.selectTab(0);
417
            }
418

    
419
            @Override
420
            public void onError(Throwable t) {
421
                GWT.log("Error getting account", t);
422
                if (t instanceof RestException)
423
                    GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
424
                else
425
                    GSS.get().displayError("System error fetching user data: " + t.getMessage());
426
            }
427
        };
428
        getAccount.setHeader("X-Auth-Token", token);
429
        Scheduler.get().scheduleDeferred(getAccount);
430
    }
431

    
432
        /**
433
         * Clear the cookie and redirect the user to the logout page.
434
         */
435
        void logout() {
436
                Configuration conf = (Configuration) GWT.create(Configuration.class);
437
                String cookie = conf.authCookie();
438
                String domain = Window.Location.getHostName();
439
                String path = Window.Location.getPath();
440
                Cookies.setCookie(cookie, "", null, domain, path, false);
441
        String baseUrl = GWT.getModuleBaseURL();
442
        String homeUrl = baseUrl.substring(0, baseUrl.indexOf(path));
443
                Window.Location.assign(homeUrl + conf.logoutUrl());
444
        }
445

    
446
        /**
447
         * Creates an HTML fragment that places an image & caption together, for use
448
         * in a group header.
449
         *
450
         * @param imageProto an image prototype for an image
451
         * @param caption the group caption
452
         * @return the header HTML fragment
453
         */
454
        private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
455
                String captionHTML = "<table class='caption' cellpadding='0' " 
456
                + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() 
457
                + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'>&nbsp;" 
458
                + caption + "</b></td></tr></table>";
459
                return captionHTML;
460
        }
461

    
462
        private void onWindowResized(int height) {
463
                // Adjust the split panel to take up the available room in the window.
464
                int newHeight = height - splitPanel.getAbsoluteTop() - 44;
465
                if (newHeight < 1)
466
                        newHeight = 1;
467
                splitPanel.setHeight("" + newHeight);
468
                inner.setHeight("" + newHeight);
469
        }
470

    
471
        @Override
472
        public void onResize(ResizeEvent event) {
473
                int height = event.getHeight();
474
                onWindowResized(height);
475
        }
476

    
477
        public boolean isFileListShowing() {
478
                int tab = inner.getTabBar().getSelectedTab();
479
                if (tab == 0)
480
                        return true;
481
                return false;
482
        }
483

    
484
        public boolean isSearchResultsShowing() {
485
                int tab = inner.getTabBar().getSelectedTab();
486
                if (tab == 2)
487
                        return true;
488
                return false;
489
        }
490

    
491
        /**
492
         * Make the file list visible.
493
         *
494
         * @param update
495
         */
496
        public void showFileList(boolean update) {
497
                if(update){
498
                        getTreeView().refreshCurrentNode(true);
499
                }
500
                else{
501
                        RestResource currentFolder = getTreeView().getSelection();
502
                        if(currentFolder!=null){
503
                                showFileList(currentFolder);
504
                }
505
                }
506

    
507
        }
508
        
509
        public void showFileList(RestResource r) {
510
                showFileList(r,true);
511
        }
512
        
513
        public void showFileList(RestResource r, boolean clearSelection) {
514
                RestResource currentFolder = r;
515
                if(currentFolder!=null){
516
                        List<FileResource> files = null;
517
                        if (currentFolder instanceof RestResourceWrapper) {
518
                                RestResourceWrapper folder = (RestResourceWrapper) currentFolder;
519
                                files = folder.getResource().getFiles();
520
                        }
521
                }
522
                inner.selectTab(0);
523
        }
524

    
525
        /**
526
         * Display the 'loading' indicator.
527
         */
528
        public void showLoadingIndicator(String message, String path) {
529
                if(path!=null){
530
                        String[] split = path.split("/");
531
                        message = message +" "+URL.decode(split[split.length-1]);
532
                }
533
                topPanel.getLoading().show(message);
534
        }
535

    
536
        /**
537
         * Hide the 'loading' indicator.
538
         */
539
        public void hideLoadingIndicator() {
540
                topPanel.getLoading().hide();
541
        }
542

    
543
        /**
544
         * A native JavaScript method to reach out to the browser's window and
545
         * invoke its resizeTo() method.
546
         *
547
         * @param x the new width
548
         * @param y the new height
549
         */
550
        public static native void resizeTo(int x, int y) /*-{
551
                $wnd.resizeTo(x,y);
552
        }-*/;
553

    
554
        /**
555
         * A helper method that returns true if the user's list is currently visible
556
         * and false if it is hidden.
557
         *
558
         * @return true if the user list is visible
559
         */
560
        public boolean isUserListVisible() {
561
                return inner.getTabBar().getSelectedTab() == 1;
562
        }
563

    
564
        /**
565
         * Display an error message.
566
         *
567
         * @param msg the message to display
568
         */
569
        public void displayError(String msg) {
570
                messagePanel.displayError(msg);
571
        }
572

    
573
        /**
574
         * Display a warning message.
575
         *
576
         * @param msg the message to display
577
         */
578
        public void displayWarning(String msg) {
579
                messagePanel.displayWarning(msg);
580
        }
581

    
582
        /**
583
         * Display an informational message.
584
         *
585
         * @param msg the message to display
586
         */
587
        public void displayInformation(String msg) {
588
                messagePanel.displayInformation(msg);
589
        }
590

    
591
        /**
592
         * Retrieve the folders.
593
         *
594
         * @return the folders
595
         
596
        public Folders getFolders() {
597
                return folders;
598
        }*/
599

    
600
        /**
601
         * Retrieve the currentSelection.
602
         *
603
         * @return the currentSelection
604
         */
605
        public Object getCurrentSelection() {
606
                return currentSelection;
607
        }
608

    
609
        /**
610
         * Modify the currentSelection.
611
         *
612
         * @param newCurrentSelection the currentSelection to set
613
         */
614
        public void setCurrentSelection(Object newCurrentSelection) {
615
                currentSelection = newCurrentSelection;
616
        }
617

    
618
        /**
619
         * Retrieve the fileList.
620
         *
621
         * @return the fileList
622
         */
623
        public FileList getFileList() {
624
                return fileList;
625
        }
626

    
627
        /**
628
         * Retrieve the topPanel.
629
         *
630
         * @return the topPanel
631
         */
632
        TopPanel getTopPanel() {
633
                return topPanel;
634
        }
635

    
636
        /**
637
         * Retrieve the clipboard.
638
         *
639
         * @return the clipboard
640
         */
641
        public Clipboard getClipboard() {
642
                return clipboard;
643
        }
644

    
645
        public StatusPanel getStatusPanel() {
646
                return statusPanel;
647
        }
648

    
649
        /**
650
         * Retrieve the userDetailsPanel.
651
         *
652
         * @return the userDetailsPanel
653
         */
654
        public UserDetailsPanel getUserDetailsPanel() {
655
                return userDetailsPanel;
656
        }
657

    
658
        
659

    
660
        public String getToken() {
661
                return token;
662
        }
663

    
664
        public String getWebDAVPassword() {
665
                return webDAVPassword;
666
        }
667

    
668
        /**
669
         * Retrieve the currentUserResource.
670
         *
671
         * @return the currentUserResource
672
         */
673
        public UserResource getCurrentUserResource() {
674
                return currentUserResource;
675
        }
676

    
677
        /**
678
         * Modify the currentUserResource.
679
         *
680
         * @param newUser the new currentUserResource
681
         */
682
        public void setCurrentUserResource(UserResource newUser) {
683
                currentUserResource = newUser;
684
        }
685

    
686
        public static native void preventIESelection() /*-{
687
                $doc.body.onselectstart = function () { return false; };
688
        }-*/;
689

    
690
        public static native void enableIESelection() /*-{
691
                if ($doc.body.onselectstart != null)
692
                $doc.body.onselectstart = null;
693
        }-*/;
694

    
695
        /**
696
         * @return the absolute path of the API root URL
697
         */
698
        public String getApiPath() {
699
                Configuration conf = (Configuration) GWT.create(Configuration.class);
700
                return conf.apiPath();
701
        }
702

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

    
736
        /**
737
         * This method examines the token input and add a "/" at the end in case it's omitted.
738
         * This happens only in Files/trash/, Files/shared/, Files/others.
739
         *
740
         * @param tokenInput
741
         * @return the formated token with a "/" at the end or the same tokenInput parameter
742
         */
743

    
744
        private String handleSpecialFolderNames(String tokenInput){
745
                List<String> pathsToCheck = Arrays.asList("Files/trash", "Files/shared", "Files/others");
746
                if(pathsToCheck.contains(tokenInput))
747
                        return tokenInput + "/";
748
                return tokenInput;
749

    
750
        }
751

    
752
        /**
753
         * Reject illegal resource names, like '.' or '..' or slashes '/'.
754
         */
755
        static boolean isValidResourceName(String name) {
756
                if (".".equals(name) ||        "..".equals(name) || name.contains("/"))
757
                        return false;
758
                return true;
759
        }
760

    
761
        public void putUserToMap(String _userName, String _userFullName){
762
                userFullNameMap.put(_userName, _userFullName);
763
        }
764

    
765
        public String findUserFullName(String _userName){
766
                return userFullNameMap.get(_userName);
767
        }
768
        public String getUserFullName(String _userName) {
769
                
770
        if (GSS.get().findUserFullName(_userName) == null)
771
                //if there is no userFullName found then the map fills with the given _userName,
772
                //so userFullName = _userName
773
                GSS.get().putUserToMap(_userName, _userName);
774
        else if(GSS.get().findUserFullName(_userName).indexOf('@') != -1){
775
                //if the userFullName = _userName the GetUserCommand updates the userFullName in the map
776
                GetUserCommand guc = new GetUserCommand(_userName);
777
                guc.execute();
778
        }
779
        return GSS.get().findUserFullName(_userName);
780
        }
781
        /**
782
         * Retrieve the treeView.
783
         *
784
         * @return the treeView
785
         */
786
        public CellTreeView getTreeView() {
787
                return treeView;
788
        }
789
        
790
        public void onResourceUpdate(RestResource resource,boolean clearSelection){
791
                if(resource instanceof RestResourceWrapper || resource instanceof OtherUserResource || resource instanceof TrashResource || resource instanceof SharedResource){
792
                        if(getTreeView().getSelection()!=null&&getTreeView().getSelection().getUri().equals(resource.getUri()))
793
                                showFileList(resource,clearSelection);
794
                }
795
                
796
        }
797
}