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