Updated copyright notice
[pithos-web-client] / src / gr / grnet / pithos / web / client / SearchResults.java
1 /*
2  * Copyright (c) 2011 Greek Research and Technology Network
3  */
4 package gr.grnet.pithos.web.client;
5
6
7 import static com.google.gwt.query.client.GQuery.$;
8
9 import gr.grnet.pithos.web.client.rest.GetCommand;
10 import gr.grnet.pithos.web.client.rest.RestCommand;
11 import gr.grnet.pithos.web.client.rest.RestException;
12 import gr.grnet.pithos.web.client.rest.resource.FileResource;
13 import gr.grnet.pithos.web.client.rest.resource.SearchResource;
14 import gr.grnet.pithos.web.client.rest.resource.TrashResource;
15 import gr.grnet.pithos.web.client.rest.resource.UserResource;
16 import gr.grnet.pithos.web.client.rest.resource.UserSearchResource;
17 import gwtquery.plugins.draggable.client.DraggableOptions;
18 import gwtquery.plugins.draggable.client.StopDragException;
19 import gwtquery.plugins.draggable.client.DraggableOptions.DragFunction;
20 import gwtquery.plugins.draggable.client.DraggableOptions.RevertOption;
21 import gwtquery.plugins.draggable.client.events.DragContext;
22 import gwtquery.plugins.draggable.client.events.DragStartEvent;
23 import gwtquery.plugins.draggable.client.events.DragStopEvent;
24 import gwtquery.plugins.draggable.client.events.DragStartEvent.DragStartEventHandler;
25 import gwtquery.plugins.draggable.client.events.DragStopEvent.DragStopEventHandler;
26 import gwtquery.plugins.droppable.client.gwt.DragAndDropCellTable;
27 import gwtquery.plugins.droppable.client.gwt.DragAndDropColumn;
28
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.Comparator;
32 import java.util.Iterator;
33 import java.util.List;
34
35 import com.google.gwt.cell.client.AbstractCell;
36 import com.google.gwt.cell.client.ImageResourceCell;
37 import com.google.gwt.cell.client.SafeHtmlCell;
38 import com.google.gwt.cell.client.TextCell;
39 import com.google.gwt.core.client.GWT;
40 import com.google.gwt.core.client.Scheduler;
41 import com.google.gwt.core.client.Scheduler.RepeatingCommand;
42 import com.google.gwt.dom.client.Style.Cursor;
43 import com.google.gwt.http.client.URL;
44 import com.google.gwt.i18n.client.DateTimeFormat;
45 import com.google.gwt.resources.client.ClientBundle;
46 import com.google.gwt.resources.client.ImageResource;
47 import com.google.gwt.safehtml.shared.SafeHtml;
48 import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
49 import com.google.gwt.user.cellview.client.CellTable;
50 import com.google.gwt.user.cellview.client.GssSimplePager;
51 import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
52 import com.google.gwt.user.client.DOM;
53 import com.google.gwt.user.client.DeferredCommand;
54 import com.google.gwt.user.client.Event;
55 import com.google.gwt.user.client.Window;
56 import com.google.gwt.user.client.ui.AbstractImagePrototype;
57 import com.google.gwt.user.client.ui.Composite;
58 import com.google.gwt.user.client.ui.HTML;
59 import com.google.gwt.user.client.ui.VerticalPanel;
60 import com.google.gwt.view.client.AsyncDataProvider;
61 import com.google.gwt.view.client.HasData;
62 import com.google.gwt.view.client.MultiSelectionModel;
63 import com.google.gwt.view.client.ProvidesKey;
64 import com.google.gwt.view.client.SelectionChangeEvent;
65 import com.google.gwt.view.client.SelectionChangeEvent.Handler;
66
67 /**
68  * A composite that displays a list of search results for a particular query on
69  * files.
70  */
71 public class SearchResults extends Composite{
72         private HTML searchResults = new HTML("Results for search:");
73         private String lastQuery;
74         SearchDataProvider provider = new SearchDataProvider();
75         /**
76          * Specifies that the images available for this composite will be the ones
77          * available in FileContextMenu.
78          */
79         public interface Images extends ClientBundle,FileContextMenu.Images, CellTreeView.Images, FileList.Images {
80
81                 @Source("gr/grnet/pithos/resources/blank.gif")
82                 ImageResource blank();
83
84                 @Source("gr/grnet/pithos/resources/asc.png")
85                 ImageResource asc();
86
87                 @Source("gr/grnet/pithos/resources/desc.png")
88                 ImageResource desc();
89         }
90
91         
92         interface TableResources extends DragAndDropCellTable.Resources {
93             @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
94             TableStyle cellTableStyle();
95           }
96         
97         /**
98            * The styles applied to the table.
99            */
100           interface TableStyle extends CellTable.Style {
101           }
102
103         private String showingStats = "";
104
105         private int startIndex = 0;
106
107         /**
108          * A constant that denotes the completion of an IncrementalCommand.
109          */
110         public static final boolean DONE = false;
111
112         
113         
114         private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
115
116         
117         
118         DragStopEventHandler dragStop = new DragStopEventHandler() {
119                 
120                 @Override
121                 public void onDragStop(DragStopEvent event) {
122                         GWT.log("DRAG STOPPED");
123                         
124                 }
125         };
126         
127         private static class ContactCell extends AbstractCell<gr.grnet.pithos.web.client.rest.resource.FileResource> {
128
129             /**
130              * The html of the image used for contacts.
131              * 
132              */
133             private final String imageHtml;
134
135             public ContactCell(ImageResource image) {
136               this.imageHtml = AbstractImagePrototype.create(image).getHTML();
137             }
138
139             
140
141                 
142
143             @Override
144             public void render(Context context, FileResource value, SafeHtmlBuilder sb) {
145               // Value can be null, so do a null check..
146               if (value == null) {
147                 return;
148               }
149
150           sb.append(FileList.Templates.INSTANCE.rendelContactCell(imageHtml, value.getName(), value.getFileSizeAsString()));
151             }
152
153
154           }
155         /**
156          * Retrieve the celltable.
157          *
158          * @return the celltable
159          */
160         public DragAndDropCellTable<FileResource> getCelltable() {
161                 return celltable;
162         }
163         
164
165         
166         /**
167          * The number of files in this folder.
168          */
169         int folderFileCount;
170
171         /**
172          * Total folder size
173          */
174         long folderTotalSize;
175
176         /**
177          * A cache of the files in the list.
178          */
179         private List<FileResource> files;
180
181         /**
182          * The widget's image bundle.
183          */
184         private final Images images;
185         
186         private FileContextMenu menuShowing;
187         private DragAndDropCellTable<FileResource> celltable;
188         private final MultiSelectionModel<FileResource> selectionModel;
189         
190         GssSimplePager pager;
191         GssSimplePager pagerTop;
192         /**
193          * Construct the file list widget. This entails setting up the widget
194          * layout, fetching the number of files in the current folder from the
195          * server and filling the local file cache of displayed files with data from
196          * the server, as well.
197          *
198          * @param _images
199          */
200         public SearchResults(Images _images) {
201                 images = _images;
202                 DragAndDropCellTable.Resources resources = GWT.create(TableResources.class);
203                 ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
204
205                         @Override
206                         public Object getKey(FileResource item) {
207                                 return item.getUri();
208                         }
209                         
210                 };
211                 
212                 celltable = new DragAndDropCellTable<FileResource>(GSS.VISIBLE_FILE_COUNT,resources,keyProvider){
213                         @Override
214                         protected void onBrowserEvent2(Event event) {
215                                 /*if (DOM.eventGetType((Event) event) == Event.ONMOUSEDOWN && DOM.eventGetButton((Event) event) == NativeEvent.BUTTON_RIGHT){
216                                         fireClickEvent((Element) event.getEventTarget().cast());                                        
217                                 }*/
218                                 super.onBrowserEvent2(event);
219                         }
220                 };
221                 provider.addDataDisplay(celltable);
222                 celltable.addDragStopHandler(dragStop);
223                 celltable.addDragStartHandler(new DragStartEventHandler() {
224
225                       public void onDragStart(DragStartEvent event) {
226                         FileResource value = event.getDraggableData();
227                         
228                         com.google.gwt.dom.client.Element helper = event.getHelper();
229                         SafeHtmlBuilder sb = new SafeHtmlBuilder();
230                         sb.appendHtmlConstant("<b>");
231                         DisplayHelper.log(value.getName());
232                         if(getSelectedFiles().size()==1)
233                                 sb.appendEscaped(value.getName());
234                         else
235                                 sb.appendEscaped(getSelectedFiles().size()+" files");
236                         sb.appendHtmlConstant("</b>");
237                         helper.setInnerHTML(sb.toSafeHtml().asString());
238
239                       }
240                     });
241                 DragAndDropColumn<FileResource, ImageResource> status = new DragAndDropColumn<FileResource, ImageResource>(new ImageResourceCell(){
242                         @Override
243                   public boolean handlesSelection() {
244                             return false;
245                           }
246                 }) {
247                   @Override
248                   public ImageResource getValue(FileResource entity) {
249                     return getFileIcon(entity);
250                   }
251                   
252                };
253             celltable.addColumn(status,"");
254             
255             initDragOperation(status);
256                 final DragAndDropColumn<FileResource,SafeHtml> nameColumn = new DragAndDropColumn<FileResource,SafeHtml>(new SafeHtmlCell()) {
257
258
259                         @Override
260                         public SafeHtml getValue(FileResource object) {
261                                 SafeHtmlBuilder sb = new SafeHtmlBuilder();
262                 sb.append(FileList.Templates.INSTANCE.filenameSpan(object.getName()));
263                                 if (object.getContentType().endsWith("png") || object.getContentType().endsWith("gif") || object.getContentType().endsWith("jpeg") ){
264                     sb.appendHtmlConstant("&nbsp;").append(FileList.Templates.INSTANCE.viewLink(GSS.get().getTopPanel().getFileMenu().getDownloadURL(object), object.getOwner() + " : " + object.getPath() + object.getName()));
265                                 }
266
267                                 return sb.toSafeHtml();
268                         }
269                         
270                 };
271                 initDragOperation(nameColumn);
272                 celltable.addColumn(nameColumn,"Name");
273                 
274             DragAndDropColumn<FileResource,String> aColumn;
275                 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
276                         @Override
277                         public String getValue(FileResource object) {
278                                 return GSS.get().findUserFullName(object.getOwner());
279                         }                       
280                 },"Owner");
281                 initDragOperation(aColumn);
282                 
283                 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
284                         @Override
285                         public String getValue(FileResource object) {
286                                 if(object.isDeleted())
287                                         return object.getPath()+" (In Trash)";
288                                 return object.getPath();
289                         }                       
290                 },"Path");
291                 initDragOperation(aColumn);
292                 
293                 
294                         
295                 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
296                         @Override
297                         public String getValue(FileResource object) {
298                                 return object.getVersion().toString();
299                         }                       
300                 },"Version");
301                 initDragOperation(aColumn);
302                 
303                 
304                 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
305                         @Override
306                         public String getValue(FileResource object) {
307                                 // TODO Auto-generated method stub
308                                 return object.getFileSizeAsString();
309                         }                       
310                 },"Size");
311                 initDragOperation(aColumn);
312                         
313                 celltable.addColumn(aColumn=new DragAndDropColumn<FileResource,String>(new TextCell()) {
314                         @Override
315                         public String getValue(FileResource object) {
316                                 return formatter.format(object.getModificationDate());
317                         }                       
318                 },"Last Modified");
319                 
320                 
321                
322
323                 VerticalPanel vp = new VerticalPanel();
324                 vp.setWidth("100%");
325                 celltable.setWidth("100%");
326                 vp.add(searchResults);
327                 searchResults.addStyleName("pithos-searchLabel");
328                 pagerTop = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
329                 pagerTop.setDisplay(celltable);
330                 vp.add(pagerTop);
331                 vp.add(celltable);
332                 pager = new GssSimplePager(GssSimplePager.TextLocation.CENTER);
333                 pager.setDisplay(celltable);
334                 //celltable.setPageSize(2);
335                 
336                 vp.add(pager);
337                 vp.setCellWidth(celltable, "100%");
338                 
339                 initWidget(vp);
340                 
341                 //initWidget(celltable);
342                 celltable.setStyleName("pithos-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          private void initDragOperation(DragAndDropColumn<?, ?> column) {
388
389                     // retrieve draggableOptions on the column
390                     DraggableOptions draggableOptions = column.getDraggableOptions();
391                     // use template to construct the helper. The content of the div will be set
392                     // after
393                     draggableOptions.setHelper($(FileList.Templates.INSTANCE.outerHelper().asString()));
394                     //draggableOptions.setZIndex(100);
395                     // opacity of the helper
396                     draggableOptions.setAppendTo("body"); 
397                     //draggableOptions.setOpacity((float) 0.8);
398                     draggableOptions.setContainment("document");
399                     // cursor to use during the drag operation
400                     draggableOptions.setCursor(Cursor.MOVE);
401                     // set the revert option
402                     draggableOptions.setRevert(RevertOption.ON_INVALID_DROP);
403                     // prevents dragging when user click on the category drop-down list
404                     draggableOptions.setCancel("select");
405                     
406                     draggableOptions.setOnBeforeDragStart(new DragFunction() {
407                                 
408                                 @Override
409                                 public void f(DragContext context) {
410                                          FileResource value = context.getDraggableData();
411                                      if(!selectionModel.isSelected(value)){
412                                         throw new StopDragException();
413                                       }
414                                         
415                                 }
416                         });
417                   }
418         
419          public void showContextMenu(Event event){
420                  menuShowing = new FileContextMenu(images, false, true);
421                         menuShowing=menuShowing.onEmptyEvent(event);
422          }
423         @Override
424         public void onBrowserEvent(Event event) {
425                 
426                 if (files == null || files.size() == 0) {
427                         if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
428                                 menuShowing = new FileContextMenu(images, false, true);
429                                 menuShowing=menuShowing.onEmptyEvent(event);
430                                 event.preventDefault();
431                                 event.cancelBubble(true);
432                         }
433                         return;
434                 }
435                 if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() != 0) {
436                         GWT.log("*****GOING TO SHOW CONTEXT MENU ****", null);
437                         menuShowing =  new FileContextMenu(images, false, false);
438                         menuShowing=menuShowing.onEvent(event);
439                         event.cancelBubble(true);
440                         event.preventDefault();
441                 } else if (DOM.eventGetType(event) == Event.ONCONTEXTMENU && getSelectedFiles().size() == 0) {
442                         menuShowing = new FileContextMenu(images, false, true);
443                         menuShowing=menuShowing.onEmptyEvent(event);
444                         event.cancelBubble(true);
445                         event.preventDefault();
446                 } else if (DOM.eventGetType(event) == Event.ONDBLCLICK)
447                         if (getSelectedFiles().size() == 1) {
448                                 GSS app = GSS.get();
449                                 FileResource file = getSelectedFiles().get(0);
450                                 String dateString = RestCommand.getDate();
451                                 String resource = file.getUri().substring(app.getApiPath().length() - 1, file.getUri().length());
452                                 String sig = app.getCurrentUserResource().getUsername() + " " +
453                                                 RestCommand.calculateSig("GET", dateString, resource,
454                                                 RestCommand.base64decode(app.getToken()));
455                                 if(!file.isDeleted()){
456                                         Window.open(file.getUri() + "?Authorization=" + URL.encodeComponent(sig) + "&Date=" + URL.encodeComponent(dateString), "_blank", "");
457                                 }
458                                 event.preventDefault();
459                                 return;
460                         }
461                 super.onBrowserEvent(event);
462         }
463
464         /**
465          * Retrieve the root folder for the current user.
466          *
467          * @return true if the retrieval was successful
468          */
469         protected boolean fetchRootFolder() {
470                 UserResource user = GSS.get().getCurrentUserResource();
471                 if (user == null)
472                         return !DONE;
473                 // Update cache and clear selection.
474                 updateFileCache(null);
475                 return DONE;
476         }
477
478
479         /**
480          * Update the display of the file list.
481          */
482         void update(boolean sort) {
483                 int count = folderFileCount;
484                 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
485                 if (max > count)
486                         max = count;
487                 folderTotalSize = 0;
488                 
489                 copyListAndContinue(files);
490                 for(FileResource f : files){
491                         folderTotalSize += f.getContentLength();
492                 }
493                 if (folderFileCount == 0) {
494                         showingStats = "no files";
495                 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
496                         if (folderFileCount == 1)
497                                 showingStats = "1 file";
498                         else
499                                 showingStats = folderFileCount + " files";
500                         showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
501                 } else {
502                         showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
503                 }
504                 updateCurrentlyShowingStats();
505
506         }
507
508         /**
509          * Return the proper icon based on the MIME type of the file.
510          *
511          * @param file
512          * @return the icon
513          */
514         private ImageResource getFileIcon(FileResource file) {
515                 String mimetype = file.getContentType();
516                 boolean shared = file.isShared();
517                 if (mimetype == null)
518                         return shared ? images.documentShared() : images.document();
519                 mimetype = mimetype.toLowerCase();
520                 if (mimetype.startsWith("application/pdf"))
521                         return shared ? images.pdfShared() : images.pdf();
522                 else if (mimetype.endsWith("excel"))
523                         return shared ? images.spreadsheetShared() : images.spreadsheet();
524                 else if (mimetype.endsWith("msword"))
525                         return shared ? images.wordprocessorShared() : images.wordprocessor();
526                 else if (mimetype.endsWith("powerpoint"))
527                         return shared ? images.presentationShared() : images.presentation();
528                 else if (mimetype.startsWith("application/zip") ||
529                                         mimetype.startsWith("application/gzip") ||
530                                         mimetype.startsWith("application/x-gzip") ||
531                                         mimetype.startsWith("application/x-tar") ||
532                                         mimetype.startsWith("application/x-gtar"))
533                         return shared ? images.zipShared() : images.zip();
534                 else if (mimetype.startsWith("text/html"))
535                         return shared ? images.htmlShared() : images.html();
536                 else if (mimetype.startsWith("text/plain"))
537                         return shared ? images.txtShared() : images.txt();
538                 else if (mimetype.startsWith("image/"))
539                         return shared ? images.imageShared() : images.image();
540                 else if (mimetype.startsWith("video/"))
541                         return shared ? images.videoShared() : images.video();
542                 else if (mimetype.startsWith("audio/"))
543                         return shared ? images.audioShared() : images.audio();
544                 return shared ? images.documentShared() : images.document();
545         }
546
547         /**
548          * Update status panel with currently showing file stats.
549          */
550         public void updateCurrentlyShowingStats() {
551                 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
552         }
553
554         public void updateFileCache(String query) {
555                 final GSS app = GSS.get();
556                 setLastQuery(query);
557                 clearSelectedRows();
558                 //clearLabels();
559                 startIndex = 0;
560                 app.showLoadingIndicator("Getting Search Results",null);
561                 if (query == null || query.trim().equals("")) {
562                         searchResults.setHTML("You must specify a query.");
563                         setFiles(new ArrayList());
564                         update(true);
565                         app.hideLoadingIndicator();
566                 } else if (!GSS.isValidResourceName(query)) {
567                         searchResults.setHTML("The query was invalid. Try to use words that appear in the file's name, contents or tags.");
568                         setFiles(new ArrayList());
569                         update(true);
570                         app.hideLoadingIndicator();
571                 } else{
572                         searchResults.setHTML("Search results for " + query);
573                         showCellTable(true);
574                         
575                 }
576         }
577
578         /**
579          * Fill the file cache with data.
580          */
581         public void setFiles(final List<FileResource> _files) {
582                 if (_files.size() > 0 && ! (GSS.get().getTreeView().getSelection() instanceof TrashResource)) {
583                         files = new ArrayList<FileResource>();
584                         for (FileResource fres : _files)
585                                 files.add(fres);
586                 }
587                 else
588                         files = _files;
589                 Collections.sort(files, new Comparator<FileResource>() {
590
591                         @Override
592                         public int compare(FileResource arg0, FileResource arg1) {
593                                 return arg0.getName().compareTo(arg1.getName());
594                         }
595
596                 });
597                 folderFileCount = files.size();
598         }
599
600         
601
602         
603         /**
604          * Does the list contains the requested filename
605          *
606          * @param fileName
607          * @return true/false
608          */
609         public boolean contains(String fileName) {
610                 for (int i = 0; i < files.size(); i++)
611                         if (files.get(i).getName().equals(fileName))
612                                 return true;
613                 return false;
614         }
615
616         public void clearSelectedRows() {
617                 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
618                 while(it.hasNext()){
619                         selectionModel.setSelected(it.next(),false);
620                 }
621         }
622
623         /**
624          *
625          */
626         public void selectAllRows() {
627                 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
628                 while(it.hasNext()){
629                         selectionModel.setSelected(it.next(),true);
630                 }
631
632
633         }
634
635         
636         private void sortFiles(final String sortingProperty, final boolean sortingType){
637                 Collections.sort(files, new Comparator<FileResource>() {
638
639             @Override
640             public int compare(FileResource arg0, FileResource arg1) {
641                     AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
642                     AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
643                     if (sortingType){
644                             if (sortingProperty.equals("version")) {
645                                     return arg0.getVersion().compareTo(arg1.getVersion());
646                             } else if (sortingProperty.equals("owner")) {
647                                     return arg0.getOwner().compareTo(arg1.getOwner());
648                             } else if (sortingProperty.equals("date")) {
649                                     return arg0.getModificationDate().compareTo(arg1.getModificationDate());
650                             } else if (sortingProperty.equals("size")) {
651                                     return arg0.getContentLength().compareTo(arg1.getContentLength());
652                             } else if (sortingProperty.equals("name")) {
653                                     return arg0.getName().compareTo(arg1.getName());
654                             } else if (sortingProperty.equals("path")) {
655                                     return arg0.getUri().compareTo(arg1.getUri());
656                             } else {
657                                     return arg0.getName().compareTo(arg1.getName());
658                             }
659                     }
660                     else if (sortingProperty.equals("version")) {
661                             
662                             return arg1.getVersion().compareTo(arg0.getVersion());
663                     } else if (sortingProperty.equals("owner")) {
664                             
665                             return arg1.getOwner().compareTo(arg0.getOwner());
666                     } else if (sortingProperty.equals("date")) {
667                             
668                             return arg1.getModificationDate().compareTo(arg0.getModificationDate());
669                     } else if (sortingProperty.equals("size")) {
670                             
671                             return arg1.getContentLength().compareTo(arg0.getContentLength());
672                     } else if (sortingProperty.equals("name")) {
673                             
674                             return arg1.getName().compareTo(arg0.getName());
675                     } else if (sortingProperty.equals("path")) {
676                             
677                             return arg1.getUri().compareTo(arg0.getUri());
678                     } else {
679                             
680                             return arg1.getName().compareTo(arg0.getName());
681                     }
682             }
683
684                 });
685         }
686         
687         
688         /**
689          * Creates a new ArrayList<FileResources> from the given files ArrayList 
690          * in order that the input files remain untouched 
691          * and continues to find user's full names of each FileResource element
692          * in the new ArrayList
693          *    
694          * @param filesInput
695          */
696         private void copyListAndContinue(List<FileResource> filesInput){
697                 List<FileResource> copiedFiles = new ArrayList<FileResource>();         
698                 for(FileResource file : filesInput) {
699                         copiedFiles.add(file);
700                 }
701                 handleFullNames(copiedFiles);
702         }
703         
704         /**
705          * Examines whether or not the user's full name exists in the 
706          * userFullNameMap in the GSS.java for every element of the input list.
707          * If the user's full name does not exist in the map then a command is being made.  
708          * 
709          * @param filesInput
710          */
711         private void handleFullNames(List<FileResource> filesInput){            
712                 if(filesInput.size() == 0){
713                         showCellTable(false);
714                         return;
715                 }               
716
717                 if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
718                         findFullNameAndUpdate(filesInput);              
719                         return;
720                 }
721                                 
722                 if(filesInput.size() >= 1){
723                         filesInput.remove(filesInput.get(0));
724                         if(filesInput.isEmpty()){
725                                 showCellTable(false);                           
726                         }else{
727                                 handleFullNames(filesInput);
728                         }
729                 }               
730         }
731         
732         /**
733          * Makes a command to search for full name from a given username. 
734          * Only after the completion of the command the celltable is shown
735          * or the search for the next full name continues.
736          *  
737          * @param filesInput
738          */
739         private void findFullNameAndUpdate(final List<FileResource> filesInput){                
740                 String aUserName = filesInput.get(0).getOwner();
741                 String path = GSS.get().getApiPath() + "users/" + aUserName; 
742
743                 GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
744                         @Override
745                         public void onComplete() {
746                                 final UserSearchResource result = getResult();
747                                 for (UserResource user : result.getUsers()){
748                                         String username = user.getUsername();
749                                         String userFullName = user.getName();
750                                         GSS.get().putUserToMap(username, userFullName);
751                                         if(filesInput.size() >= 1){
752                                                 filesInput.remove(filesInput.get(0));
753                                                 if(filesInput.isEmpty()){
754                                                         showCellTable(false);
755                                                 }else{
756                                                         handleFullNames(filesInput);
757                                                 }                                                                                               
758                                         }                                                                       
759                                 }
760                         }
761                         @Override
762                         public void onError(Throwable t) {
763                                 GWT.log("", t);
764                                 GSS.get().displayError("Unable to fetch user's full name from the given username " + filesInput.get(0).getOwner());
765                                 if(filesInput.size() >= 1){
766                                         filesInput.remove(filesInput.get(0));
767                                         handleFullNames(filesInput);                                    
768                                 }
769                         }
770                 };
771                 DeferredCommand.addCommand(gg);
772         
773         }
774         /**
775          * Shows the files in the cellTable 
776          */
777
778         private void showCellTable(boolean update){
779                 if(celltable.getRowCount()>GSS.VISIBLE_FILE_COUNT){
780                         pager.setVisible(true);
781                         pagerTop.setVisible(true);
782                 }
783                 else{
784                         pager.setVisible(false);
785                         pagerTop.setVisible(false);
786                 }
787                 if(update)
788                         provider.onRangeChanged(celltable);
789                 celltable.redrawHeaders();              
790         }
791         
792         
793         /**
794          * Retrieve the lastQuery.
795          *
796          * @return the lastQuery
797          */
798         public String getLastQuery() {
799                 return lastQuery;
800         }
801         
802         
803         /**
804          * Modify the lastQuery.
805          *
806          * @param lastQuery the lastQuery to set
807          */
808         public void setLastQuery(String lastQuery) {
809                 this.lastQuery = lastQuery;
810         }
811         
812         class SearchDataProvider extends AsyncDataProvider<FileResource>{
813
814                 @Override
815                 protected void onRangeChanged(final HasData<FileResource> display) {
816                         final int start = display.getVisibleRange().getStart();
817                         final GSS app = GSS.get();
818                         if(getLastQuery()==null||getLastQuery().equals("")){
819                                 display.setRowCount(0,true);
820                                 return;
821                                 
822                         }
823                         GetCommand<SearchResource> eg = new GetCommand<SearchResource>(SearchResource.class,
824                                                 app.getApiPath() + "search/" +URL.encodeComponent(getLastQuery())+"?start="+start, null) {
825
826                                 @Override
827                                 public void onComplete() {
828                                         SearchResource s = getResult();
829                                         display.setRowCount(s.getSize(),true);
830                                         display.setRowData(start, s.getFiles());
831                                         setFiles(s.getFiles());
832                                         update(true);
833                                         
834                                 }
835
836                                 @Override
837                                 public void onError(Throwable t) {
838                                         if(t instanceof RestException)
839                                                 app.displayError("Unable to perform search:"+((RestException)t).getHttpStatusText());
840                                         else
841                                                 app.displayError("System error performing search:"+t.getMessage());
842                                         GWT.log("",t);
843                                         updateFileCache("");
844                                 }
845
846                         };
847                         DeferredCommand.addCommand(eg);
848                         
849                 }
850                 
851         }
852
853 }