Partially implemented file upload. It only creates a 0 sized object
[pithos] / web_client / src / gr / grnet / pithos / web / client / GSS.java
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.event.dom.client.ContextMenuEvent;
40 import com.google.gwt.event.dom.client.ContextMenuHandler;
41 import com.google.gwt.event.shared.GwtEvent;
42 import com.google.gwt.event.shared.GwtEvent.Type;
43 import com.google.gwt.view.client.SelectionChangeEvent;
44 import com.google.gwt.view.client.SingleSelectionModel;
45 import gr.grnet.pithos.web.client.clipboard.Clipboard;
46 import gr.grnet.pithos.web.client.commands.GetUserCommand;
47 import gr.grnet.pithos.web.client.foldertree.AccountResource;
48 import gr.grnet.pithos.web.client.foldertree.File;
49 import gr.grnet.pithos.web.client.foldertree.Folder;
50 import gr.grnet.pithos.web.client.foldertree.FolderTreeView;
51 import gr.grnet.pithos.web.client.foldertree.FolderTreeViewModel;
52 import gr.grnet.pithos.web.client.rest.GetRequest;
53 import gr.grnet.pithos.web.client.rest.RestException;
54 import gr.grnet.pithos.web.client.rest.resource.FileResource;
55 import gr.grnet.pithos.web.client.rest.resource.OtherUserResource;
56 import gr.grnet.pithos.web.client.rest.resource.RestResource;
57 import gr.grnet.pithos.web.client.rest.resource.RestResourceWrapper;
58 import gr.grnet.pithos.web.client.rest.resource.SharedResource;
59 import gr.grnet.pithos.web.client.rest.resource.TrashResource;
60 import gr.grnet.pithos.web.client.rest.resource.UserResource;
61
62 import java.util.ArrayList;
63 import java.util.Arrays;
64 import java.util.Date;
65 import java.util.HashMap;
66 import java.util.Iterator;
67 import java.util.List;
68
69 import com.google.gwt.core.client.EntryPoint;
70 import com.google.gwt.core.client.GWT;
71 import com.google.gwt.event.logical.shared.ResizeEvent;
72 import com.google.gwt.event.logical.shared.ResizeHandler;
73 import com.google.gwt.event.logical.shared.SelectionEvent;
74 import com.google.gwt.event.logical.shared.SelectionHandler;
75 import com.google.gwt.http.client.URL;
76 import com.google.gwt.i18n.client.DateTimeFormat;
77 import com.google.gwt.resources.client.ClientBundle;
78 import com.google.gwt.resources.client.ImageResource;
79 import com.google.gwt.user.client.Cookies;
80 import com.google.gwt.user.client.DOM;
81 import com.google.gwt.user.client.Event;
82 import com.google.gwt.user.client.History;
83 import com.google.gwt.user.client.Window;
84 import com.google.gwt.user.client.ui.AbstractImagePrototype;
85 import com.google.gwt.user.client.ui.DecoratedTabPanel;
86 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
87 import com.google.gwt.user.client.ui.HorizontalSplitPanel;
88 import com.google.gwt.user.client.ui.RootPanel;
89 import com.google.gwt.user.client.ui.TabPanel;
90 import com.google.gwt.user.client.ui.VerticalPanel;
91 import java.util.Set;
92
93 /**
94  * Entry point classes define <code>onModuleLoad()</code>.
95  */
96 public class GSS implements EntryPoint, ResizeHandler {
97
98         /**
99          * A constant that denotes the completion of an IncrementalCommand.
100          */
101         public static final boolean DONE = false;
102
103         public static final int VISIBLE_FILE_COUNT = 25;
104
105         /**
106          * Instantiate an application-level image bundle. This object will provide
107          * programmatic access to all the images needed by widgets.
108          */
109         private static Images images = (Images) GWT.create(Images.class);
110
111     public String getUsername() {
112         return username;
113     }
114
115     public void setAccount(AccountResource acct) {
116         account = acct;
117     }
118
119     public AccountResource getAccount() {
120         return account;
121     }
122
123     public void updateFolder(Folder f) {
124         folderTreeView.updateFolder(f);
125     }
126
127     /**
128          * An aggregate image bundle that pulls together all the images for this
129          * application into a single bundle.
130          */
131         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 {
132
133                 @Source("gr/grnet/pithos/resources/document.png")
134                 ImageResource folders();
135
136                 @Source("gr/grnet/pithos/resources/edit_group_22.png")
137                 ImageResource groups();
138
139                 @Source("gr/grnet/pithos/resources/search.png")
140                 ImageResource search();
141         }
142
143         /**
144          * The single GSS instance.
145          */
146         private static GSS singleton;
147
148         /**
149          * Gets the singleton GSS instance.
150          *
151          * @return the GSS object
152          */
153         public static GSS get() {
154                 if (GSS.singleton == null)
155                         GSS.singleton = new GSS();
156                 return GSS.singleton;
157         }
158
159         /**
160          * The Application Clipboard implementation;
161          */
162         private Clipboard clipboard = new Clipboard();
163
164         private UserResource currentUserResource;
165
166         /**
167          * The top panel that contains the menu bar.
168          */
169         private TopPanel topPanel;
170
171         /**
172          * The panel that contains the various system messages.
173          */
174         private MessagePanel messagePanel = new MessagePanel(GSS.images);
175
176         /**
177          * The bottom panel that contains the status bar.
178          */
179         private StatusPanel statusPanel = null;
180
181         /**
182          * The top right panel that displays the logged in user details
183          */
184         private UserDetailsPanel userDetailsPanel = new UserDetailsPanel();
185
186         /**
187          * The file list widget.
188          */
189         private FileList fileList;
190
191         /**
192          * The tab panel that occupies the right side of the screen.
193          */
194         private TabPanel inner = new DecoratedTabPanel(){
195                 
196 //              public void onBrowserEvent(com.google.gwt.user.client.Event event) {
197 //                      if (DOM.eventGetType(event) == Event.ONCONTEXTMENU){
198 //                              if(isFileListShowing()){
199 //                                      getFileList().showContextMenu(event);
200 //                              }
201 //                      }
202 //              };
203         };
204
205
206         /**
207          * The split panel that will contain the left and right panels.
208          */
209         private HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
210
211         /**
212          * The widget that displays the tree of folders.
213          */
214         
215         private CellTreeView treeView = null;
216         /**
217          * The currently selected item in the application, for use by the Edit menu
218          * commands. Potential types are Folder, File, User and Group.
219          */
220         private Object currentSelection;
221
222
223         /**
224          * The WebDAV password of the current user
225          */
226         private String webDAVPassword;
227
228         public HashMap<String, String> userFullNameMap = new HashMap<String, String>();
229
230     private String username = null;
231
232     /**
233      * The authentication token of the current user.
234      */
235     private String token;
236
237     private SingleSelectionModel<Folder> folderTreeSelectionModel;
238     private FolderTreeViewModel folderTreeViewModel;
239     private FolderTreeView folderTreeView;
240
241     private AccountResource account;
242
243         @Override
244         public void onModuleLoad() {
245                 // Initialize the singleton before calling the constructors of the
246                 // various widgets that might call GSS.get().
247                 singleton = this;
248                 if (parseUserCredentials())
249             initialize();
250         }
251
252     private void initialize() {
253         topPanel = new TopPanel(GSS.images);
254         topPanel.setWidth("100%");
255
256         messagePanel.setWidth("100%");
257         messagePanel.setVisible(false);
258
259
260         // Inner contains the various lists.
261         inner.sinkEvents(Event.ONCONTEXTMENU);
262         inner.setAnimationEnabled(true);
263         inner.getTabBar().addStyleName("pithos-MainTabBar");
264         inner.getDeckPanel().addStyleName("pithos-MainTabPanelBottom");
265
266         inner.setWidth("100%");
267
268         inner.addSelectionHandler(new SelectionHandler<Integer>() {
269
270             @Override
271             public void onSelection(SelectionEvent<Integer> event) {
272                 int tabIndex = event.getSelectedItem();
273                 switch (tabIndex) {
274                     case 0:
275                         fileList.updateCurrentlyShowingStats();
276                         break;
277                 }
278             }
279         });
280
281         folderTreeSelectionModel = new SingleSelectionModel<Folder>();
282         folderTreeSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
283             @Override
284             public void onSelectionChange(SelectionChangeEvent event) {
285                 Folder f = folderTreeSelectionModel.getSelectedObject();
286                 updateFolder(f);
287             }
288         });
289
290         folderTreeViewModel = new FolderTreeViewModel(folderTreeSelectionModel);
291         folderTreeView = new FolderTreeView(folderTreeViewModel);
292
293         fileList = new FileList(images, folderTreeView);
294         inner.add(fileList, createHeaderHTML(AbstractImagePrototype.create(images.folders()), "Files"), true);
295
296         // Add the left and right panels to the split panel.
297         splitPanel.setLeftWidget(folderTreeView);
298         splitPanel.setRightWidget(inner);
299         splitPanel.setSplitPosition("25%");
300         splitPanel.setSize("100%", "100%");
301         splitPanel.addStyleName("pithos-splitPanel");
302
303         // Create a dock panel that will contain the menu bar at the top,
304         // the shortcuts to the left, the status bar at the bottom and the
305         // right panel taking the rest.
306         VerticalPanel outer = new VerticalPanel();
307         outer.add(topPanel);
308         outer.add(messagePanel);
309         outer.add(splitPanel);
310         statusPanel = new StatusPanel(GSS.images);
311         outer.add(statusPanel);
312         outer.setWidth("100%");
313         outer.setCellHorizontalAlignment(messagePanel, HasHorizontalAlignment.ALIGN_CENTER);
314
315         outer.setSpacing(4);
316
317         // Hook the window resize event, so that we can adjust the UI.
318         Window.addResizeHandler(this);
319         // Clear out the window's built-in margin, because we want to take
320         // advantage of the entire client area.
321         Window.setMargin("0px");
322         // Finally, add the outer panel to the RootPanel, so that it will be
323         // displayed.
324         RootPanel.get().add(outer);
325         // Call the window resized handler to get the initial sizes setup. Doing
326         // this in a deferred command causes it to occur after all widgets'
327         // sizes have been computed by the browser.
328         Scheduler.get().scheduleDeferred(new ScheduledCommand() {
329
330             @Override
331             public void execute() {
332                 onWindowResized(Window.getClientHeight());
333             }
334         });
335
336         Scheduler.get().scheduleDeferred(new ScheduledCommand() {
337             @Override
338             public void execute() {
339                 fetchAccount();
340             }
341         });
342     }
343
344     public void showFiles(Folder f) {
345         inner.selectTab(0);
346         Set<File> files = f.getFiles();
347         Iterator<File> iter = files.iterator();
348         fetchFile(iter, files);
349     }
350
351     private void fetchFile(final Iterator<File> iter, final Set<File> files) {
352         if (iter.hasNext()) {
353             File file = iter.next();
354             String path = getApiPath() + username + "/" + file.getContainer() + "/" + file.getPath() + "?format=json";
355             GetRequest<File> getFile = new GetRequest<File>(File.class, path, file) {
356                 @Override
357                 public void onSuccess(File result) {
358                     fetchFile(iter, files);
359                 }
360
361                 @Override
362                 public void onError(Throwable t) {
363                     GWT.log("Error getting file", t);
364                     if (t instanceof RestException)
365                         GSS.get().displayError("Error getting file: " + ((RestException) t).getHttpStatusText());
366                     else
367                         GSS.get().displayError("System error fetching file: " + t.getMessage());
368                 }
369             };
370             getFile.setHeader("X-Auth-Token", "0000");
371             Scheduler.get().scheduleDeferred(getFile);
372         }
373         else
374             fileList.setFiles(new ArrayList<File>(files));
375     }
376
377     /**
378          * Parse and store the user credentials to the appropriate fields.
379          */
380         private boolean parseUserCredentials() {
381                 Configuration conf = (Configuration) GWT.create(Configuration.class);
382                 String cookie = conf.authCookie();
383                 String auth = Cookies.getCookie(cookie);
384                 if (auth == null) {
385                         authenticateUser();
386             return false;
387         }
388         else {
389             String[] authSplit = auth.split("\\" + conf.cookieSeparator(), 2);
390             if (authSplit.length != 2) {
391                 authenticateUser();
392                 return false;
393             }
394             else {
395                 username = authSplit[0];
396                 token = authSplit[1];
397                 return true;
398             }
399         }
400         }
401
402     /**
403          * Redirect the user to the login page for authentication.
404          */
405         protected void authenticateUser() {
406                 Configuration conf = (Configuration) GWT.create(Configuration.class);
407
408 //        Window.Location.assign(GWT.getModuleBaseURL() + conf.loginUrl() + "?next=" + Window.Location.getHref());
409         Cookies.setCookie(conf.authCookie(), "test" + conf.cookieSeparator() + "0000");
410         Window.Location.assign(GWT.getModuleBaseURL() + "GSS.html");
411         }
412
413     private void fetchAccount() {
414         String path = getApiPath() + username + "?format=json";
415
416         GetRequest<AccountResource> getAccount = new GetRequest<AccountResource>(AccountResource.class, path) {
417             @Override
418             public void onSuccess(AccountResource result) {
419                 account = result;
420                 statusPanel.displayStats(account);
421                 folderTreeViewModel.initialize(account);
422                 inner.selectTab(0);
423             }
424
425             @Override
426             public void onError(Throwable t) {
427                 GWT.log("Error getting account", t);
428                 if (t instanceof RestException)
429                     GSS.get().displayError("Error getting account: " + ((RestException) t).getHttpStatusText());
430                 else
431                     GSS.get().displayError("System error fetching user data: " + t.getMessage());
432             }
433         };
434         getAccount.setHeader("X-Auth-Token", token);
435         Scheduler.get().scheduleDeferred(getAccount);
436     }
437
438         /**
439          * Clear the cookie and redirect the user to the logout page.
440          */
441         void logout() {
442                 Configuration conf = (Configuration) GWT.create(Configuration.class);
443                 String cookie = conf.authCookie();
444                 String domain = Window.Location.getHostName();
445                 String path = Window.Location.getPath();
446                 Cookies.setCookie(cookie, "", null, domain, path, false);
447         String baseUrl = GWT.getModuleBaseURL();
448         String homeUrl = baseUrl.substring(0, baseUrl.indexOf(path));
449                 Window.Location.assign(homeUrl + conf.logoutUrl());
450         }
451
452         /**
453          * Creates an HTML fragment that places an image & caption together, for use
454          * in a group header.
455          *
456          * @param imageProto an image prototype for an image
457          * @param caption the group caption
458          * @return the header HTML fragment
459          */
460         private String createHeaderHTML(AbstractImagePrototype imageProto, String caption) {
461                 String captionHTML = "<table class='caption' cellpadding='0' " 
462                 + "cellspacing='0'>" + "<tr><td class='lcaption'>" + imageProto.getHTML() 
463                 + "</td><td id =" + caption +" class='rcaption'><b style='white-space:nowrap'>&nbsp;" 
464                 + caption + "</b></td></tr></table>";
465                 return captionHTML;
466         }
467
468         private void onWindowResized(int height) {
469                 // Adjust the split panel to take up the available room in the window.
470                 int newHeight = height - splitPanel.getAbsoluteTop() - 44;
471                 if (newHeight < 1)
472                         newHeight = 1;
473                 splitPanel.setHeight("" + newHeight);
474                 inner.setHeight("" + newHeight);
475         }
476
477         @Override
478         public void onResize(ResizeEvent event) {
479                 int height = event.getHeight();
480                 onWindowResized(height);
481         }
482
483         public boolean isFileListShowing() {
484                 int tab = inner.getTabBar().getSelectedTab();
485                 if (tab == 0)
486                         return true;
487                 return false;
488         }
489
490         public boolean isSearchResultsShowing() {
491                 int tab = inner.getTabBar().getSelectedTab();
492                 if (tab == 2)
493                         return true;
494                 return false;
495         }
496
497         /**
498          * Make the file list visible.
499          *
500          * @param update
501          */
502         public void showFileList(boolean update) {
503                 if(update){
504                         getTreeView().refreshCurrentNode(true);
505                 }
506                 else{
507                         RestResource currentFolder = getTreeView().getSelection();
508                         if(currentFolder!=null){
509                                 showFileList(currentFolder);
510                 }
511                 }
512
513         }
514         
515         public void showFileList(RestResource r) {
516                 showFileList(r,true);
517         }
518         
519         public void showFileList(RestResource r, boolean clearSelection) {
520                 RestResource currentFolder = r;
521                 if(currentFolder!=null){
522                         List<FileResource> files = null;
523                         if (currentFolder instanceof RestResourceWrapper) {
524                                 RestResourceWrapper folder = (RestResourceWrapper) currentFolder;
525                                 files = folder.getResource().getFiles();
526                         }
527                 }
528                 inner.selectTab(0);
529         }
530
531         /**
532          * Display the 'loading' indicator.
533          */
534         public void showLoadingIndicator(String message, String path) {
535                 if(path!=null){
536                         String[] split = path.split("/");
537                         message = message +" "+URL.decode(split[split.length-1]);
538                 }
539                 topPanel.getLoading().show(message);
540         }
541
542         /**
543          * Hide the 'loading' indicator.
544          */
545         public void hideLoadingIndicator() {
546                 topPanel.getLoading().hide();
547         }
548
549         /**
550          * A native JavaScript method to reach out to the browser's window and
551          * invoke its resizeTo() method.
552          *
553          * @param x the new width
554          * @param y the new height
555          */
556         public static native void resizeTo(int x, int y) /*-{
557                 $wnd.resizeTo(x,y);
558         }-*/;
559
560         /**
561          * A helper method that returns true if the user's list is currently visible
562          * and false if it is hidden.
563          *
564          * @return true if the user list is visible
565          */
566         public boolean isUserListVisible() {
567                 return inner.getTabBar().getSelectedTab() == 1;
568         }
569
570         /**
571          * Display an error message.
572          *
573          * @param msg the message to display
574          */
575         public void displayError(String msg) {
576                 messagePanel.displayError(msg);
577         }
578
579         /**
580          * Display a warning message.
581          *
582          * @param msg the message to display
583          */
584         public void displayWarning(String msg) {
585                 messagePanel.displayWarning(msg);
586         }
587
588         /**
589          * Display an informational message.
590          *
591          * @param msg the message to display
592          */
593         public void displayInformation(String msg) {
594                 messagePanel.displayInformation(msg);
595         }
596
597         /**
598          * Retrieve the folders.
599          *
600          * @return the folders
601          
602         public Folders getFolders() {
603                 return folders;
604         }*/
605
606         /**
607          * Retrieve the currentSelection.
608          *
609          * @return the currentSelection
610          */
611         public Object getCurrentSelection() {
612                 return currentSelection;
613         }
614
615         /**
616          * Modify the currentSelection.
617          *
618          * @param newCurrentSelection the currentSelection to set
619          */
620         public void setCurrentSelection(Object newCurrentSelection) {
621                 currentSelection = newCurrentSelection;
622         }
623
624         /**
625          * Retrieve the fileList.
626          *
627          * @return the fileList
628          */
629         public FileList getFileList() {
630                 return fileList;
631         }
632
633         /**
634          * Retrieve the topPanel.
635          *
636          * @return the topPanel
637          */
638         TopPanel getTopPanel() {
639                 return topPanel;
640         }
641
642         /**
643          * Retrieve the clipboard.
644          *
645          * @return the clipboard
646          */
647         public Clipboard getClipboard() {
648                 return clipboard;
649         }
650
651         public StatusPanel getStatusPanel() {
652                 return statusPanel;
653         }
654
655         /**
656          * Retrieve the userDetailsPanel.
657          *
658          * @return the userDetailsPanel
659          */
660         public UserDetailsPanel getUserDetailsPanel() {
661                 return userDetailsPanel;
662         }
663
664         
665
666         public String getToken() {
667                 return token;
668         }
669
670         public String getWebDAVPassword() {
671                 return webDAVPassword;
672         }
673
674         /**
675          * Retrieve the currentUserResource.
676          *
677          * @return the currentUserResource
678          */
679         public UserResource getCurrentUserResource() {
680                 return currentUserResource;
681         }
682
683         /**
684          * Modify the currentUserResource.
685          *
686          * @param newUser the new currentUserResource
687          */
688         public void setCurrentUserResource(UserResource newUser) {
689                 currentUserResource = newUser;
690         }
691
692         public static native void preventIESelection() /*-{
693                 $doc.body.onselectstart = function () { return false; };
694         }-*/;
695
696         public static native void enableIESelection() /*-{
697                 if ($doc.body.onselectstart != null)
698                 $doc.body.onselectstart = null;
699         }-*/;
700
701         /**
702          * @return the absolute path of the API root URL
703          */
704         public String getApiPath() {
705                 Configuration conf = (Configuration) GWT.create(Configuration.class);
706                 return conf.apiPath();
707         }
708
709         /**
710          * Convert server date to local time according to browser timezone
711          * and format it according to localized pattern.
712          * Time is always formatted to 24hr format.
713          * NB: This assumes that server runs in UTC timezone. Otherwise
714          * we would need to adjust for server time offset as well.
715          *
716          * @param date
717          * @return String
718          */
719         public static String formatLocalDateTime(Date date) {
720                 Date convertedDate = new Date(date.getTime() - date.getTimezoneOffset());
721                 final DateTimeFormat dateFormatter = DateTimeFormat.getShortDateFormat();
722                 final DateTimeFormat timeFormatter = DateTimeFormat.getFormat("HH:mm");
723                 String datePart = dateFormatter.format(convertedDate);
724                 String timePart = timeFormatter.format(convertedDate);
725                 return datePart + " " + timePart;
726         }
727         
728         /**
729          * History support for folder navigation
730          * adds a new browser history entry
731          *
732          * @param key
733          */
734         public void updateHistory(String key){
735 //              Replace any whitespace of the initial string to "+"
736 //              String result = key.replaceAll("\\s","+");
737 //              Add a new browser history entry.
738 //              History.newItem(result);
739                 History.newItem(key);
740         }
741
742         /**
743          * This method examines the token input and add a "/" at the end in case it's omitted.
744          * This happens only in Files/trash/, Files/shared/, Files/others.
745          *
746          * @param tokenInput
747          * @return the formated token with a "/" at the end or the same tokenInput parameter
748          */
749
750         private String handleSpecialFolderNames(String tokenInput){
751                 List<String> pathsToCheck = Arrays.asList("Files/trash", "Files/shared", "Files/others");
752                 if(pathsToCheck.contains(tokenInput))
753                         return tokenInput + "/";
754                 return tokenInput;
755
756         }
757
758         /**
759          * Reject illegal resource names, like '.' or '..' or slashes '/'.
760          */
761         static boolean isValidResourceName(String name) {
762                 if (".".equals(name) || "..".equals(name) || name.contains("/"))
763                         return false;
764                 return true;
765         }
766
767         public void putUserToMap(String _userName, String _userFullName){
768                 userFullNameMap.put(_userName, _userFullName);
769         }
770
771         public String findUserFullName(String _userName){
772                 return userFullNameMap.get(_userName);
773         }
774         public String getUserFullName(String _userName) {
775                 
776         if (GSS.get().findUserFullName(_userName) == null)
777                 //if there is no userFullName found then the map fills with the given _userName,
778                 //so userFullName = _userName
779                 GSS.get().putUserToMap(_userName, _userName);
780         else if(GSS.get().findUserFullName(_userName).indexOf('@') != -1){
781                 //if the userFullName = _userName the GetUserCommand updates the userFullName in the map
782                 GetUserCommand guc = new GetUserCommand(_userName);
783                 guc.execute();
784         }
785         return GSS.get().findUserFullName(_userName);
786         }
787         /**
788          * Retrieve the treeView.
789          *
790          * @return the treeView
791          */
792         public CellTreeView getTreeView() {
793                 return treeView;
794         }
795         
796         public void onResourceUpdate(RestResource resource,boolean clearSelection){
797                 if(resource instanceof RestResourceWrapper || resource instanceof OtherUserResource || resource instanceof TrashResource || resource instanceof SharedResource){
798                         if(getTreeView().getSelection()!=null&&getTreeView().getSelection().getUri().equals(resource.getUri()))
799                                 showFileList(resource,clearSelection);
800                 }
801                 
802         }
803 }