Each need for displaying the resource's user full name is fulfilled whether by asking...
[pithos] / src / gr / ebs / gss / client / FileList.java
1 /*
2  * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
3  *
4  * This file is part of GSS.
5  *
6  * GSS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GSS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 package gr.ebs.gss.client;
20
21 import gr.ebs.gss.client.dnd.DnDSimpleFocusPanel;
22 import gr.ebs.gss.client.dnd.DnDTreeItem;
23 import gr.ebs.gss.client.rest.GetCommand;
24 import gr.ebs.gss.client.rest.MultipleHeadCommand;
25 import gr.ebs.gss.client.rest.RestCommand;
26 import gr.ebs.gss.client.rest.RestException;
27 import gr.ebs.gss.client.rest.resource.FileResource;
28 import gr.ebs.gss.client.rest.resource.FolderResource;
29 import gr.ebs.gss.client.rest.resource.OtherUserResource;
30 import gr.ebs.gss.client.rest.resource.SharedResource;
31 import gr.ebs.gss.client.rest.resource.TrashResource;
32 import gr.ebs.gss.client.rest.resource.UserResource;
33 import gr.ebs.gss.client.rest.resource.UserSearchResource;
34
35 import java.util.ArrayList;
36 import java.util.Collections;
37 import java.util.Comparator;
38 import java.util.Iterator;
39 import java.util.List;
40
41 import com.google.gwt.cell.client.ImageResourceCell;
42 import com.google.gwt.cell.client.ValueUpdater;
43 import com.google.gwt.core.client.GWT;
44 import com.google.gwt.core.client.Scheduler;
45 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
46 import com.google.gwt.dom.client.Element;
47 import com.google.gwt.dom.client.NativeEvent;
48 import com.google.gwt.http.client.URL;
49 import com.google.gwt.i18n.client.DateTimeFormat;
50 import com.google.gwt.resources.client.ClientBundle;
51 import com.google.gwt.resources.client.ImageResource;
52 import com.google.gwt.user.cellview.client.CellTable;
53 import com.google.gwt.user.cellview.client.Column;
54 import com.google.gwt.user.cellview.client.TextColumn;
55 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
56 import com.google.gwt.user.client.DOM;
57 import com.google.gwt.user.client.DeferredCommand;
58 import com.google.gwt.user.client.Event;
59 import com.google.gwt.user.client.Window;
60 import com.google.gwt.user.client.ui.AbstractImagePrototype;
61 import com.google.gwt.user.client.ui.Composite;
62 import com.google.gwt.user.client.ui.Grid;
63 import com.google.gwt.user.client.ui.HTML;
64 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
65 import com.google.gwt.user.client.ui.HorizontalPanel;
66 import com.google.gwt.user.client.ui.TreeItem;
67 import com.google.gwt.user.client.ui.Widget;
68 import com.google.gwt.view.client.DefaultSelectionEventManager;
69 import com.google.gwt.view.client.MultiSelectionModel;
70 import com.google.gwt.view.client.ProvidesKey;
71 import com.google.gwt.view.client.SelectionChangeEvent;
72 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
73
74 /**
75  * A composite that displays the list of files in a particular folder.
76  */
77 public class FileList extends Composite {
78
79         interface TableResources extends CellTable.Resources {
80             @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
81             TableStyle cellTableStyle();
82           }
83         
84         /**
85            * The styles applied to the table.
86            */
87           interface TableStyle extends CellTable.Style {
88           }
89
90         private String showingStats = "";
91
92         private int startIndex = 0;
93
94         /**
95          * A constant that denotes the completion of an IncrementalCommand.
96          */
97         public static final boolean DONE = false;
98
99         /**
100          * The context menu for the selected file.
101          */
102         final DnDSimpleFocusPanel contextMenu;
103         
104         private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
105
106         /**
107          * Specifies that the images available for this composite will be the ones
108          * available in FileContextMenu.
109          */
110         public interface Images extends ClientBundle,FileContextMenu.Images, Folders.Images {
111
112                 @Source("gr/ebs/gss/resources/blank.gif")
113                 ImageResource blank();
114
115                 @Source("gr/ebs/gss/resources/asc.png")
116                 ImageResource asc();
117
118                 @Source("gr/ebs/gss/resources/desc.png")
119                 ImageResource desc();
120
121                 @Source("gr/ebs/gss/resources/mimetypes/document_shared.png")
122                 ImageResource documentShared();
123
124                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst.png")
125                 ImageResource wordprocessor();
126
127                 @Source("gr/ebs/gss/resources/mimetypes/log.png")
128                 ImageResource spreadsheet();
129
130                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr.png")
131                 ImageResource presentation();
132
133                 @Source("gr/ebs/gss/resources/mimetypes/acroread.png")
134                 ImageResource pdf();
135
136                 @Source("gr/ebs/gss/resources/mimetypes/image.png")
137                 ImageResource image();
138
139                 @Source("gr/ebs/gss/resources/mimetypes/video2.png")
140                 ImageResource video();
141
142                 @Source("gr/ebs/gss/resources/mimetypes/knotify.png")
143                 ImageResource audio();
144
145                 @Source("gr/ebs/gss/resources/mimetypes/html.png")
146                 ImageResource html();
147
148                 @Source("gr/ebs/gss/resources/mimetypes/txt.png")
149                 ImageResource txt();
150
151                 @Source("gr/ebs/gss/resources/mimetypes/ark2.png")
152                 ImageResource zip();
153
154                 @Source("gr/ebs/gss/resources/mimetypes/kcmfontinst_shared.png")
155                 ImageResource wordprocessorShared();
156
157                 @Source("gr/ebs/gss/resources/mimetypes/log_shared.png")
158                 ImageResource spreadsheetShared();
159
160                 @Source("gr/ebs/gss/resources/mimetypes/kpresenter_kpr_shared.png")
161                 ImageResource presentationShared();
162
163                 @Source("gr/ebs/gss/resources/mimetypes/acroread_shared.png")
164                 ImageResource pdfShared();
165
166                 @Source("gr/ebs/gss/resources/mimetypes/image_shared.png")
167                 ImageResource imageShared();
168
169                 @Source("gr/ebs/gss/resources/mimetypes/video2_shared.png")
170                 ImageResource videoShared();
171
172                 @Source("gr/ebs/gss/resources/mimetypes/knotify_shared.png")
173                 ImageResource audioShared();
174
175                 @Source("gr/ebs/gss/resources/mimetypes/html_shared.png")
176                 ImageResource htmlShared();
177
178                 @Source("gr/ebs/gss/resources/mimetypes/txt_shared.png")
179                 ImageResource txtShared();
180
181                 @Source("gr/ebs/gss/resources/mimetypes/ark2_shared.png")
182                 ImageResource zipShared();
183
184         }
185
186         /**
187          * A label with the number of files in this folder.
188          */
189         private HTML countLabel = new HTML();
190
191         /**
192          * The table widget with the file list.
193          */
194         //private FileTable table = new FileTable(GSS.VISIBLE_FILE_COUNT + 1, 8);
195
196         /**
197          * The navigation bar for paginating the results.
198          */
199         private HorizontalPanel navBar = new HorizontalPanel();
200
201         /**
202          * The number of files in this folder.
203          */
204         int folderFileCount;
205
206         /**
207          * Total folder size
208          */
209         long folderTotalSize;
210
211         /**
212          * A cache of the files in the list.
213          */
214         private List<FileResource> files;
215
216         /**
217          * The widget's image bundle.
218          */
219         private final Images images;
220
221         
222         private FileContextMenu menuShowing;
223         private CellTable<FileResource> celltable;
224         private final MultiSelectionModel<FileResource> selectionModel;
225         private final List<SortableHeader> allHeaders = new ArrayList<SortableHeader>();
226         SortableHeader nameHeader;
227         /**
228          * Construct the file list widget. This entails setting up the widget
229          * layout, fetching the number of files in the current folder from the
230          * server and filling the local file cache of displayed files with data from
231          * the server, as well.
232          *
233          * @param _images
234          */
235         public FileList(Images _images) {
236                 images = _images;
237                 CellTable.Resources resources = GWT.create(TableResources.class);
238                 
239                 contextMenu = new DnDSimpleFocusPanel(new HTML(AbstractImagePrototype.create(images.fileContextMenu()).getHTML()));
240                 GSS.get().getDragController().makeDraggable(contextMenu);
241
242                 // Setup the table.
243                 
244
245                 // Create the 'navigation' bar at the upper-right.
246                 HorizontalPanel innerNavBar = new HorizontalPanel();
247                 innerNavBar.setStyleName("gss-ListNavBar");
248                 innerNavBar.setSpacing(8);
249                 innerNavBar.add(countLabel);
250                 navBar.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
251                 navBar.add(innerNavBar);
252                 navBar.setWidth("100%");
253                 ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
254
255                         @Override
256                         public Object getKey(FileResource item) {
257                                 return item.getUri();
258                         }
259                         
260                 };
261                 final TextColumn<FileResource> nameColumn = new TextColumn<FileResource>() {
262
263                         @Override
264                         public String getValue(FileResource object) {
265                                 // TODO Auto-generated method stub
266                                 return object.getName();
267                         }
268                         
269                         
270                 };
271                 celltable = new CellTable<FileResource>(100,resources,keyProvider){
272                         @Override
273                         protected void onBrowserEvent2(Event event) {
274                                 /*if (DOM.eventGetType((Event) event) == Event.ONMOUSEDOWN && DOM.eventGetButton((Event) event) == NativeEvent.BUTTON_RIGHT){
275                                         fireClickEvent((Element) event.getEventTarget().cast());                                        
276                                 }*/
277                                 super.onBrowserEvent2(event);
278                         }
279                 };
280                 
281                 
282                 Column<FileResource, ImageResource> status = new Column<FileResource, ImageResource>(new ImageResourceCell()) {
283                   @Override
284                   public ImageResource getValue(FileResource entity) {
285                     return getFileIcon(entity);
286                   }
287                };
288                celltable.addColumn(status,"");
289                 
290                 
291                 celltable.addColumn(nameColumn,nameHeader = new SortableHeader("Name"));
292                 allHeaders.add(nameHeader);
293                 nameHeader.setSorted(true);
294                 nameHeader.toggleReverseSort();
295                 nameHeader.setUpdater(new FileValueUpdater(nameHeader, "name"));
296                 celltable.redrawHeaders();
297                 SortableHeader aheader;
298                 celltable.addColumn(new TextColumn<FileResource>() {
299                         @Override
300                         public String getValue(FileResource object) {
301                                 return GSS.get().findUserFullName(object.getOwner());
302                         }                       
303                 },aheader = new SortableHeader("Owner"));
304                 allHeaders.add(aheader);
305                 aheader.setUpdater(new FileValueUpdater(aheader, "owner"));
306                 celltable.addColumn(new TextColumn<FileResource>() {
307                         @Override
308                         public String getValue(FileResource object) {
309                                 // TODO Auto-generated method stub
310                                 return object.getPath();
311                         }                       
312                 },aheader = new SortableHeader("Path"));
313                 allHeaders.add(aheader);
314                 aheader.setUpdater(new FileValueUpdater(aheader, "path"));      
315                 celltable.addColumn(new TextColumn<FileResource>() {
316                         @Override
317                         public String getValue(FileResource object) {
318                                 // TODO Auto-generated method stub
319                                 return object.getVersion().toString();
320                         }                       
321                 },aheader = new SortableHeader("Version"));
322                 allHeaders.add(aheader);
323                 aheader.setUpdater(new FileValueUpdater(aheader, "version"));
324                 celltable.addColumn(new TextColumn<FileResource>() {
325                         @Override
326                         public String getValue(FileResource object) {
327                                 // TODO Auto-generated method stub
328                                 return object.getFileSizeAsString();
329                         }                       
330                 },aheader = new SortableHeader("Size"));
331                 allHeaders.add(aheader);
332                 aheader.setUpdater(new FileValueUpdater(aheader, "size"));      
333                 celltable.addColumn(new TextColumn<FileResource>() {
334                         @Override
335                         public String getValue(FileResource object) {
336                                 return formatter.format(object.getModificationDate());
337                         }                       
338                 },aheader = new SortableHeader("Last Modified"));
339                 allHeaders.add(aheader);
340                 aheader.setUpdater(new FileValueUpdater(aheader, "date"));
341                 initWidget(celltable);
342                 setStyleName("gss-List");
343                 selectionModel = new MultiSelectionModel<FileResource>();
344                 
345
346                  Handler selectionHandler = new SelectionChangeEvent.Handler() { 
347              @Override 
348              public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
349                  if(getSelectedFiles().size()==1)
350                          GSS.get().setCurrentSelection(getSelectedFiles().get(0));
351                  else
352                          GSS.get().setCurrentSelection(getSelectedFiles());
353                                 contextMenu.setFiles(getSelectedFiles());
354              }
355          };
356          selectionModel.addSelectionChangeHandler(selectionHandler);
357          
358                 celltable.setSelectionModel(selectionModel,GSSSelectionEventManager.<FileResource>createDefaultManager());
359                 celltable.setPageSize(GSS.VISIBLE_FILE_COUNT);
360                 celltable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
361                 Scheduler.get().scheduleIncremental(new RepeatingCommand() {
362
363                         @Override
364                         public boolean execute() {
365                                 return fetchRootFolder();
366                         }
367                 });
368                 sinkEvents(Event.ONCONTEXTMENU);
369                 sinkEvents(Event.ONMOUSEUP);
370                 sinkEvents(Event.ONMOUSEDOWN);
371                 sinkEvents(Event.ONCLICK);
372                 sinkEvents(Event.ONKEYDOWN);
373                 sinkEvents(Event.ONDBLCLICK);
374                 GSS.preventIESelection();
375         }
376         
377         //public native void fireClickEvent(Element element) /*-{
378           //  var evObj = $doc.createEvent('MouseEvents');
379             //evObj.initEvent('click', true, true);
380             //element.dispatchEvent(evObj);
381         //}-*/;
382
383          public List<FileResource> getSelectedFiles() {
384          return new ArrayList<FileResource>(selectionModel.getSelectedSet());
385          }
386         
387         
388
389         @Override
390         public void onBrowserEvent(Event event) {
391                 
392                 if (files == null || files.size() == 0) {
393                         if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
394                                 menuShowing = new FileContextMenu(images, false, true);
395                                 menuShowing=menuShowing.onEmptyEvent(event);
396                         }
397                         return;
398                 }
399                 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
400                         GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
401                         menuShowing =  new FileContextMenu(images, false, false);
402                         menuShowing=menuShowing.onEvent(event);
403                 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
404                         menuShowing = new FileContextMenu(images, false, true);
405                         menuShowing=menuShowing.onEmptyEvent(event);
406                 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
407                         if (getSelectedFiles().size() == 1) {
408                                 GSS app = GSS.get();
409                                 FileResource file = getSelectedFiles().get(0);
410                                 String dateString = RestCommand.getDate();
411                                 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
412                                 String sig = app.getCurrentUserResource().getUsername() + " " +
413                                                 RestCommand.calculateSig("GET", dateString, resource,
414                                                 RestCommand.base64decode(app.getToken()));
415                                 Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
416                                 event.preventDefault();
417                                 return;
418                         }
419                 super.onBrowserEvent(event);
420         }
421
422         /**
423          * Retrieve the root folder for the current user.
424          *
425          * @return true if the retrieval was successful
426          */
427         protected boolean fetchRootFolder() {
428                 UserResource user = GSS.get().getCurrentUserResource();
429                 if (user == null)
430                         return !DONE;
431                 // Update cache and clear selection.
432                 updateFileCache(true);
433                 return DONE;
434         }
435
436         
437
438         
439         /**
440          * Make the specified row look like selected or not, according to the
441          * <code>selected</code> flag.
442          *
443          * @param row
444          * @param selected
445          */
446         void styleRow(final int row, final boolean selected) {
447                 
448         }
449
450         /**
451          * Update the display of the file list.
452          */
453         void update(boolean sort) {
454                 int count = folderFileCount;
455                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
456                 if (max > count)
457                         max = count;
458                 folderTotalSize = 0;
459                 
460                 copyListAndContinue(files);
461                 
462                 if (folderFileCount == 0) {
463                         showingStats = "no files";
464                 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
465                         if (folderFileCount == 1)
466                                 showingStats = "1 file";
467                         else
468                                 showingStats = folderFileCount + " files";
469                         showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
470                 } else {
471                         showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
472                 }
473                 updateCurrentlyShowingStats();
474
475         }
476
477         /**
478          * Return the proper icon based on the MIME type of the file.
479          *
480          * @param file
481          * @return the icon
482          */
483         private ImageResource getFileIcon(FileResource file) {
484                 String mimetype = file.getContentType();
485                 boolean shared = false;
486                 Folders folders = GSS.get().getFolders();
487                 if(folders.getCurrent() != null && folders.isOthersSharedItem(folders.getCurrent())){
488                         DnDTreeItem otherUser = (DnDTreeItem) folders.getUserOfSharedItem(folders.getCurrent());
489                         if(otherUser==null)
490                                 shared = false;
491                         else{
492                                 String uname = otherUser.getOtherUserResource().getUsername();
493                                 if(uname==null)
494                                         uname = ((DnDTreeItem)folders.getSharesItem()).getOthersResource().getUsernameOfUri(otherUser.getOtherUserResource().getUri());
495                                 if(uname != null)
496                                         shared = file.isShared();
497                         }
498                 }
499                 else
500                         shared = file.isShared();
501                 if (mimetype == null)
502                         return shared ? images.documentShared() : images.document();
503                 mimetype = mimetype.toLowerCase();
504                 if (mimetype.startsWith("application/pdf"))
505                         return shared ? images.pdfShared() : images.pdf();
506                 else if (mimetype.endsWith("excel"))
507                         return shared ? images.spreadsheetShared() : images.spreadsheet();
508                 else if (mimetype.endsWith("msword"))
509                         return shared ? images.wordprocessorShared() : images.wordprocessor();
510                 else if (mimetype.endsWith("powerpoint"))
511                         return shared ? images.presentationShared() : images.presentation();
512                 else if (mimetype.startsWith("application/zip") ||
513                                         mimetype.startsWith("application/gzip") ||
514                                         mimetype.startsWith("application/x-gzip") ||
515                                         mimetype.startsWith("application/x-tar") ||
516                                         mimetype.startsWith("application/x-gtar"))
517                         return shared ? images.zipShared() : images.zip();
518                 else if (mimetype.startsWith("text/html"))
519                         return shared ? images.htmlShared() : images.html();
520                 else if (mimetype.startsWith("text/plain"))
521                         return shared ? images.txtShared() : images.txt();
522                 else if (mimetype.startsWith("image/"))
523                         return shared ? images.imageShared() : images.image();
524                 else if (mimetype.startsWith("video/"))
525                         return shared ? images.videoShared() : images.video();
526                 else if (mimetype.startsWith("audio/"))
527                         return shared ? images.audioShared() : images.audio();
528                 return shared ? images.documentShared() : images.document();
529         }
530
531         /**
532          * Update status panel with currently showing file stats.
533          */
534         public void updateCurrentlyShowingStats() {
535                 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
536         }
537
538         /**
539          * Adjust the height of the table by adding and removing rows as necessary.
540          *
541          * @param newHeight the new height to reach
542          */
543         //void resizeTableHeight(final int newHeight) {
544                 /*GWT.log("Panel: " + newHeight + ", parent: " + table.getParent().getOffsetHeight(), null);
545                 // Fill the rest with empty slots.
546                 if (newHeight > table.getOffsetHeight())
547                         while (newHeight > table.getOffsetHeight()) {
548                                 table.resizeRows(table.getRowCount() + 1);
549                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
550                         }
551                 else
552                         while (newHeight < table.getOffsetHeight()) {
553                                 table.resizeRows(table.getRowCount() - 1);
554                                 GWT.log("Table: " + table.getOffsetHeight() + ", rows: " + table.getRowCount(), null);
555                         }*/
556         //}
557
558         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection) {
559                 updateFileCache(updateSelectedFolder, clearSelection, null);
560         }
561
562         public void updateFileCache(boolean updateSelectedFolder, final boolean clearSelection, final String newFilename) {
563                 if (!updateSelectedFolder && !GSS.get().getFolders().getCurrent().equals(GSS.get().getFolders().getTrashItem()))
564                         updateFileCache(clearSelection);
565                 else if (GSS.get().getFolders().getCurrent() != null) {
566                         final DnDTreeItem folderItem = (DnDTreeItem) GSS.get().getFolders().getCurrent();
567                         if (folderItem.getFolderResource() != null) {
568                                 if(GSS.get().getFolders().isFileItem(folderItem) || GSS.get().getFolders().isMySharedItem(folderItem)  || GSS.get().getFolders().isOthersSharedItem(folderItem) ){
569                                 update(true);
570                                 GetCommand<FolderResource> gf = new GetCommand<FolderResource>(FolderResource.class, folderItem.getFolderResource().getUri(),folderItem.getFolderResource()) {
571
572                                         @Override
573                                         public void onComplete() {
574                                                 folderItem.setUserObject(getResult());
575                                                                 if(GSS.get().getFolders().isFileItem(folderItem)){
576                                                         String[] filePaths = new String[folderItem.getFolderResource().getFilePaths().size()];
577                                                         int c=0;
578                                                         for(String fpath : folderItem.getFolderResource().getFilePaths()){
579                                                                 filePaths[c] = fpath + "?" + Math.random();
580                                                                 c++;
581                                                         }
582                                                         MultipleHeadCommand<FileResource> getFiles = new MultipleHeadCommand<FileResource>(FileResource.class, filePaths, folderItem.getFolderResource().getFileCache()){
583
584                                                                 @Override
585                                                                 public void onComplete(){
586                                                                         List<FileResource> result = getResult();
587                                                                         //remove random from path
588                                                                         for(FileResource r : result){
589                                                                                 String p = r.getUri();
590                                                                                 int indexOfQuestionMark = p.lastIndexOf('?');
591                                                                                 if(indexOfQuestionMark>0)
592                                                                                         r.setUri(p.substring(0, indexOfQuestionMark));
593                                                                                 GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
594                                                                         }
595                                                                         folderItem.getFolderResource().setFiles(result);
596                                                                         folderItem.getFolderResource().setFilesExpanded(true);
597                                                                         updateFileCache(clearSelection, newFilename);
598                                                                 }
599
600                                                                 @Override
601                                                                 public void onError(String p, Throwable throwable) {
602                                                                         if(throwable instanceof RestException)
603                                                                                 GSS.get().displayError("Unable to retrieve file details:"+((RestException)throwable).getHttpStatusText());
604                                                                 }
605
606                                                                 @Override
607                                                                 public void onError(Throwable t) {
608                                                                         GWT.log("", t);
609                                                                         GSS.get().displayError("Unable to fetch files for folder " + folderItem.getFolderResource().getName());
610                                                                 }
611
612                                                         };
613                                                         DeferredCommand.addCommand(getFiles);
614                                                 }
615                                                 else
616                                                         updateFileCache(clearSelection, newFilename);
617                                         }
618
619                                         @Override
620                                         public void onError(Throwable t) {
621                                                 GWT.log("", t);
622                                                 GSS.get().displayError("Unable to fetch folder " + folderItem.getFolderResource().getName());
623                                         }
624                                 };
625                                 DeferredCommand.addCommand(gf);
626                                 }
627                         }
628                         else if (folderItem.getTrashResource() != null) {
629                                 GetCommand<TrashResource> gt = new GetCommand<TrashResource>(TrashResource.class, folderItem.getTrashResource().getUri(), null) {
630
631                                         @Override
632                                         public void onComplete() {
633                                                 folderItem.setUserObject(getResult());
634                                                 updateFileCache(clearSelection);
635                                         }
636
637                                         @Override
638                                         public void onError(Throwable t) {
639                                                 if (t instanceof RestException && (((RestException) t).getHttpStatusCode() == 204 || ((RestException) t).getHttpStatusCode() == 1223)) {
640                                                         folderItem.setUserObject(new TrashResource(folderItem.getTrashResource().getUri()));
641                                                         updateFileCache(clearSelection);
642                                                 } else {
643                                                         GWT.log("", t);
644                                                         GSS.get().displayError("Unable to fetch trash resource");
645                                                 }
646                                         }
647                                 };
648                                 DeferredCommand.addCommand(gt);
649                         } else if (folderItem.getSharedResource() != null) {
650                                 GetCommand<SharedResource> gt = new GetCommand<SharedResource>(SharedResource.class, folderItem.getSharedResource().getUri(), null) {
651
652                                         @Override
653                                         public void onComplete() {
654                                                 folderItem.setUserObject(getResult());
655                                                 for(FileResource r : folderItem.getSharedResource().getFiles()){
656                                                                         String p = r.getUri();
657                                                                         int indexOfQuestionMark = p.lastIndexOf('?');
658                                                                         if(indexOfQuestionMark>0)
659                                                                                 r.setUri(p.substring(0, indexOfQuestionMark));
660                                                                         GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
661                                                                 }
662                                                                 folderItem.getSharedResource().setFilesExpanded(true);
663                                                                 updateFileCache(clearSelection, newFilename);
664                                                 
665                                         }
666
667                                         @Override
668                                         public void onError(Throwable t) {
669                                                 GWT.log("", t);
670                                                 GSS.get().displayError("Unable to fetch My Shares resource");
671                                         }
672                                 };
673                                 DeferredCommand.addCommand(gt);
674                         } else if (folderItem.getOtherUserResource() != null) {
675                                 GetCommand<OtherUserResource> gt = new GetCommand<OtherUserResource>(OtherUserResource.class, folderItem.getOtherUserResource().getUri(), null) {
676
677                                         @Override
678                                         public void onComplete() {
679                                                 folderItem.setUserObject(getResult());
680                                                 //updateFileCache(clearSelection, newFilename);
681                                                 for(FileResource r : folderItem.getOtherUserResource().getFiles()){
682                                                                         String p = r.getUri();
683                                                                         int indexOfQuestionMark = p.lastIndexOf('?');
684                                                                         if(indexOfQuestionMark>0)
685                                                                                 r.setUri(p.substring(0, indexOfQuestionMark));
686                                                                         GWT.log("FETCHED:"+r.getLastModifiedSince(), null);
687                                                                 }
688                                                                 folderItem.getOtherUserResource().setFilesExpanded(true);
689                                                                 updateFileCache(clearSelection, newFilename);
690                                                 
691                                         }
692
693                                         @Override
694                                         public void onError(Throwable t) {
695                                                 GWT.log("", t);
696                                                 GSS.get().displayError("Unable to fetch My Shares resource");
697                                         }
698                                 };
699                                 DeferredCommand.addCommand(gt);
700                         }
701                 } else
702                         updateFileCache(clearSelection);
703         }
704
705
706         private void updateFileCache(boolean clearSelection) {
707                 updateFileCache(clearSelection, null);
708         }
709
710         /**
711          * Update the file cache with data from the server.
712          *
713          * @param newFilename the new name of the previously selected file,
714          *                      if a rename operation has taken place
715          */
716         private void updateFileCache(boolean clearSelection, String newFilename) {
717                 if (clearSelection)
718                         clearSelectedRows();
719                 startIndex = 0;
720                 final TreeItem folderItem = GSS.get().getFolders().getCurrent();
721                 // Validation.
722                 if (folderItem == null || GSS.get().getFolders().isOthersShared(folderItem)) {
723                         setFiles(new ArrayList<FileResource>());
724                         update(true);
725                         return;
726                 }
727                 if (folderItem instanceof DnDTreeItem) {
728                         DnDTreeItem dnd = (DnDTreeItem) folderItem;
729                         if (dnd.getFolderResource() != null) {
730                                 if (GSS.get().getFolders().isTrashItem(dnd))
731                                         setFiles(new ArrayList<FileResource>());
732                                 else
733                                         setFiles(dnd.getFolderResource().getFiles());
734
735                         } else if (dnd.getTrashResource() != null)
736                                 setFiles(dnd.getTrashResource().getFiles());
737                         else if (dnd.getSharedResource() != null)
738                                 setFiles(dnd.getSharedResource().getFiles());
739                         else if (dnd.getOtherUserResource() != null)
740                                 setFiles(dnd.getOtherUserResource().getFiles());
741                         else
742                                 setFiles(dnd.getFolderResource().getFiles());
743                         update(true);
744
745                 }
746         }
747
748         /**
749          * Fill the file cache with data.
750          */
751         public void setFiles(final List<FileResource> _files) {
752                 if (_files.size() > 0 && !GSS.get().getFolders().isTrash(GSS.get().getFolders().getCurrent())) {
753                         files = new ArrayList<FileResource>();
754                         for (FileResource fres : _files)
755                                 if (!fres.isDeleted())
756                                         files.add(fres);
757                 } else
758                         files = _files;
759                 Collections.sort(files, new Comparator<FileResource>() {
760
761                         @Override
762                         public int compare(FileResource arg0, FileResource arg1) {
763                                 return arg0.getName().compareTo(arg1.getName());
764                         }
765
766                 });
767                 folderFileCount = files.size();
768         }
769
770         
771
772         
773         /**
774          * Does the list contains the requested filename
775          *
776          * @param fileName
777          * @return true/false
778          */
779         public boolean contains(String fileName) {
780                 for (int i = 0; i < files.size(); i++)
781                         if (files.get(i).getName().equals(fileName))
782                                 return true;
783                 return false;
784         }
785
786         public void clearSelectedRows() {
787                 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
788                 while(it.hasNext()){
789                         selectionModel.setSelected(it.next(),false);
790                 }
791                 
792                 /*for (int r : selectedRows) {
793                         int row = r - startIndex;
794                         styleRow(row, false);
795                         makeRowNotDraggable(row+1);
796                 }
797                 selectedRows.clear();
798                 Object sel = GSS.get().getCurrentSelection();
799                 if (sel instanceof FileResource || sel instanceof List)
800                         GSS.get().setCurrentSelection(null);
801                 if(menuShowing != null && menuShowing.isShowing()){
802                         menuShowing.hide();
803                         menuShowing=null;
804                 }*/
805         }
806
807         /**
808          *
809          */
810         public void selectAllRows() {
811                 /*clearSelectedRows();
812                 int count = folderFileCount;
813                 if (count == 0)
814                         return;
815                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
816                 if (max > count)
817                         max = count;
818                 int i = 1;
819                 for (; i < GSS.VISIBLE_FILE_COUNT + 1; ++i) {
820                         // Don't read past the end.
821                         // if (i > folderFileCount)
822                         // break;
823                         if (startIndex + i > folderFileCount)
824                                 break;
825                         selectedRows.add(startIndex + i - 1);
826                         styleRow(i - 1, true);
827                         makeRowDraggable(i);
828                 }
829                 GSS.get().setCurrentSelection(getSelectedFiles());
830                 contextMenu.setFiles(getSelectedFiles());*/
831
832
833         }
834
835         private void makeRowDraggable(int row){
836         /*      int contextRow = getWidgetRow(contextMenu, table);
837                 if (contextRow != -1)
838                         table.setWidget(contextRow, 0, getFileIcon(files.get(contextRow - 1)).createImage());
839                 contextMenu.setWidget(new HTML(getFileIcon(files.get(row - 1)).getHTML()));
840                 table.setWidget(row, 0, contextMenu);
841                 //for(int i=1;i<table.getCellCount(row);i++)
842                         //GSS.get().getDragController().makeDraggable(table.getWidget(row, i));
843                 table.setWidget(row, 1, new DnDSimpleFocusPanel(table.getWidget(row, 1)));
844                 ((DnDSimpleFocusPanel)table.getWidget(row, 1)).setFiles(getSelectedFiles());
845                 GSS.get().getDragController().makeDraggable(table.getWidget(row, 1));*/
846         }
847         private void makeRowNotDraggable(int row){
848                 /*if(table.getWidget(row, 1) instanceof DnDSimpleFocusPanel){
849                         ((DnDSimpleFocusPanel)table.getWidget(row, 1)).setFiles(null);
850                         GSS.get().getDragController().makeNotDraggable(table.getWidget(row, 1));
851                         table.setWidget(row, 1, new DnDSimpleFocusPanel(((DnDSimpleFocusPanel)table.getWidget(row, 1)).getWidget()));
852
853                 }
854                 */
855         }
856
857         private int getWidgetRow(Widget widget, Grid grid) {
858                 /*for (int row = 0; row < grid.getRowCount(); row++)
859                         for (int col = 0; col < grid.getCellCount(row); col++) {
860                                 Widget w = table.getWidget(row, col);
861                                 if (w == widget)
862                                         return row;
863                         }*/
864                 return -1;
865         }
866         
867         
868         private void sortFiles(final String sortingProperty, final boolean sortingType){
869                 Collections.sort(files, new Comparator<FileResource>() {
870
871             @Override
872             public int compare(FileResource arg0, FileResource arg1) {
873                     AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
874                     AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
875                     if (sortingType){
876                             if (sortingProperty.equals("version")) {
877                                     return arg0.getVersion().compareTo(arg1.getVersion());
878                             } else if (sortingProperty.equals("owner")) {
879                                     return arg0.getOwner().compareTo(arg1.getOwner());
880                             } else if (sortingProperty.equals("date")) {
881                                     return arg0.getModificationDate().compareTo(arg1.getModificationDate());
882                             } else if (sortingProperty.equals("size")) {
883                                     return arg0.getContentLength().compareTo(arg1.getContentLength());
884                             } else if (sortingProperty.equals("name")) {
885                                     return arg0.getName().compareTo(arg1.getName());
886                             } else if (sortingProperty.equals("path")) {
887                                     return arg0.getUri().compareTo(arg1.getUri());
888                             } else {
889                                     return arg0.getName().compareTo(arg1.getName());
890                             }
891                     }
892                     else if (sortingProperty.equals("version")) {
893                             
894                             return arg1.getVersion().compareTo(arg0.getVersion());
895                     } else if (sortingProperty.equals("owner")) {
896                             
897                             return arg1.getOwner().compareTo(arg0.getOwner());
898                     } else if (sortingProperty.equals("date")) {
899                             
900                             return arg1.getModificationDate().compareTo(arg0.getModificationDate());
901                     } else if (sortingProperty.equals("size")) {
902                             
903                             return arg1.getContentLength().compareTo(arg0.getContentLength());
904                     } else if (sortingProperty.equals("name")) {
905                             
906                             return arg1.getName().compareTo(arg0.getName());
907                     } else if (sortingProperty.equals("path")) {
908                             
909                             return arg1.getUri().compareTo(arg0.getUri());
910                     } else {
911                             
912                             return arg1.getName().compareTo(arg0.getName());
913                     }
914             }
915
916                 });
917         }
918         
919         final class FileValueUpdater implements ValueUpdater<String>{
920                 private String property;
921                 private SortableHeader header;
922                 /**
923                  * 
924                  */
925                 public FileValueUpdater(SortableHeader header,String property) {
926                         this.property=property;
927                         this.header=header;
928                 }
929                 @Override
930                 public void update(String value) {
931                         header.setSorted(true);
932                         header.toggleReverseSort();
933
934                 for (SortableHeader otherHeader : allHeaders) {
935                   if (otherHeader != header) {
936                     otherHeader.setSorted(false);
937                     otherHeader.setReverseSort(true);
938                   }
939                 }
940                 celltable.redrawHeaders();
941                 sortFiles(property, header.getReverseSort());
942                 FileList.this.update(true);                     
943                 }
944                 
945         }
946         /**
947          * Creates a new ArrayList<FileResources> from the given files ArrayList 
948          * in order that the input files remain untouched 
949          * and continues to find user's full names of each FileResource element
950          * in the new ArrayList
951          *    
952          * @param filesInput
953          */
954         private void copyListAndContinue(List<FileResource> filesInput){
955                 List<FileResource> copiedFiles = new ArrayList<FileResource>();         
956                 for(FileResource file : filesInput) {
957                         copiedFiles.add(file);
958                 }
959                 handleFullNames(copiedFiles);
960         }
961         
962         /**
963          * Examines whether or not the user's full name exists in the 
964          * userFullNameMap in the GSS.java for every element of the input list.
965          * If the user's full name does not exist in the map then a command is being made.  
966          * 
967          * @param filesInput
968          */
969         private void handleFullNames(List<FileResource> filesInput){            
970                 if(filesInput.size() == 0){
971                         showCellTable();
972                         return;
973                 }               
974
975                 if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
976                         findFullNameAndUpdate(filesInput);              
977                         return;
978                 }
979                                 
980                 if(filesInput.size() >= 1){
981                         filesInput.remove(filesInput.get(0));
982                         if(filesInput.isEmpty()){
983                                 showCellTable();                                
984                         }else{
985                                 handleFullNames(filesInput);
986                         }
987                 }               
988         }
989         
990         /**
991          * Makes a command to search for full name from a given username. 
992          * Only after the completion of the command the celltable is shown
993          * or the search for the next full name continues.
994          *  
995          * @param filesInput
996          */
997         private void findFullNameAndUpdate(final List<FileResource> filesInput){                
998                 String aUserName = filesInput.get(0).getOwner();
999                 String path = GSS.get().getApiPath() + "users/" + aUserName; 
1000
1001                 GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
1002                         @Override
1003                         public void onComplete() {
1004                                 final UserSearchResource result = getResult();
1005                                 for (UserResource user : result.getUsers()){
1006                                         String username = user.getUsername();
1007                                         String userFullName = user.getName();
1008                                         GSS.get().putUserToMap(username, userFullName);
1009                                         if(filesInput.size() >= 1){
1010                                                 filesInput.remove(filesInput.get(0));
1011                                                 if(filesInput.isEmpty()){
1012                                                         showCellTable();
1013                                                 }else{
1014                                                         handleFullNames(filesInput);
1015                                                 }                                                                                               
1016                                         }                                                                       
1017                                 }
1018                         }
1019                         @Override
1020                         public void onError(Throwable t) {
1021                                 GWT.log("", t);
1022                                 GSS.get().displayError("Unable to fetch user's full name from the given username " + filesInput.get(0).getOwner());
1023                                 if(filesInput.size() >= 1){
1024                                         filesInput.remove(filesInput.get(0));
1025                                         handleFullNames(filesInput);                                    
1026                                 }
1027                         }
1028                 };
1029                 DeferredCommand.addCommand(gg);
1030         
1031         }
1032         /**
1033          * Shows the files in the cellTable 
1034          */
1035
1036         private void showCellTable(){
1037                 celltable.setRowCount(files.size());
1038                 celltable.setRowData(0,files);
1039                 celltable.redrawHeaders();              
1040         }
1041
1042         
1043 }