2 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
4 * This file is part of GSS.
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.
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.
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/>.
19 package gr.ebs.gss.client;
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;
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;
57 import org.hibernate.mapping.Array;
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;
107 * A composite that displays a list of search results for a particular query on
110 public class SearchResults extends Composite{
111 private HTML searchResults = new HTML("Results for search:");
112 private String lastQuery;
113 SearchDataProvider provider = new SearchDataProvider();
115 * Specifies that the images available for this composite will be the ones
116 * available in FileContextMenu.
118 public interface Images extends ClientBundle,FileContextMenu.Images, CellTreeView.Images, FileList.Images {
120 @Source("gr/ebs/gss/resources/blank.gif")
121 ImageResource blank();
123 @Source("gr/ebs/gss/resources/asc.png")
126 @Source("gr/ebs/gss/resources/desc.png")
127 ImageResource desc();
131 interface TableResources extends DragAndDropCellTable.Resources {
132 @Source({CellTable.Style.DEFAULT_CSS, "GssCellTable.css"})
133 TableStyle cellTableStyle();
136 static interface Templates extends SafeHtmlTemplates {
137 Templates INSTANCE = GWT.create(Templates.class);
139 @Template("<div id='dragHelper' style='border:1px solid black; background-color:#ffffff; color:black; width:150px;z-index:100'></div>")
140 SafeHtml outerHelper();
145 * The styles applied to the table.
147 interface TableStyle extends CellTable.Style {
150 private String showingStats = "";
152 private int startIndex = 0;
155 * A constant that denotes the completion of an IncrementalCommand.
157 public static final boolean DONE = false;
161 private final DateTimeFormat formatter = DateTimeFormat.getFormat("d/M/yyyy h:mm a");
165 DragStopEventHandler dragStop = new DragStopEventHandler() {
168 public void onDragStop(DragStopEvent event) {
169 GWT.log("DRAG STOPPED");
174 private static class ContactCell extends AbstractCell<gr.ebs.gss.client.rest.resource.FileResource> {
177 * The html of the image used for contacts.
180 private final String imageHtml;
182 public ContactCell(ImageResource image) {
183 this.imageHtml = AbstractImagePrototype.create(image).getHTML();
191 public void render(Context context, FileResource value, SafeHtmlBuilder sb) {
192 // Value can be null, so do a null check..
197 sb.appendHtmlConstant("<table>");
199 // Add the contact image.
200 sb.appendHtmlConstant("<tr><td rowspan='3'>");
201 sb.appendHtmlConstant(imageHtml);
202 sb.appendHtmlConstant("</td>");
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>");
216 * Retrieve the celltable.
218 * @return the celltable
220 public DragAndDropCellTable<FileResource> getCelltable() {
227 * The number of files in this folder.
234 long folderTotalSize;
237 * A cache of the files in the list.
239 private List<FileResource> files;
242 * The widget's image bundle.
244 private final Images images;
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;
252 SimplePager pagerTop;
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.
261 public SearchResults(Images _images) {
263 DragAndDropCellTable.Resources resources = GWT.create(TableResources.class);
264 ProvidesKey<FileResource> keyProvider = new ProvidesKey<FileResource>(){
267 public Object getKey(FileResource item) {
268 return item.getUri();
272 final DragAndDropColumn<FileResource,SafeHtml> nameColumn = new DragAndDropColumn<FileResource,SafeHtml>(new SafeHtmlCell()) {
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;'>" +
292 sb.appendHtmlConstant("<span id='fileList."+ object.getName() +"'>");
293 sb.appendEscaped(object.getName());
294 sb.appendHtmlConstant("</span>");
296 return sb.toSafeHtml();
301 initDragOperation(nameColumn);
302 celltable = new DragAndDropCellTable<FileResource>(GSS.VISIBLE_FILE_COUNT,resources,keyProvider){
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());
308 super.onBrowserEvent2(event);
311 provider.addDataDisplay(celltable);
312 celltable.addDragStopHandler(dragStop);
313 celltable.addDragStartHandler(new DragStartEventHandler() {
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());
327 Column<FileResource, ImageResource> status = new Column<FileResource, ImageResource>(new ImageResourceCell()) {
329 public ImageResource getValue(FileResource entity) {
330 return getFileIcon(entity);
333 celltable.addColumn(status,"");
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>() {
345 public String getValue(FileResource object) {
346 return GSS.get().findUserFullName(object.getOwner());
348 },aheader = new SortableHeader("Owner"));
349 allHeaders.add(aheader);
350 aheader.setUpdater(new FileValueUpdater(aheader, "owner"));
351 celltable.addColumn(new TextColumn<FileResource>() {
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();
359 },aheader = new SortableHeader("Path"));
360 allHeaders.add(aheader);
361 aheader.setUpdater(new FileValueUpdater(aheader, "path"));
362 celltable.addColumn(new TextColumn<FileResource>() {
364 public String getValue(FileResource object) {
365 // TODO Auto-generated method stub
366 return object.getVersion().toString();
368 },aheader = new SortableHeader("Version"));
369 allHeaders.add(aheader);
370 aheader.setUpdater(new FileValueUpdater(aheader, "version"));
371 celltable.addColumn(new TextColumn<FileResource>() {
373 public String getValue(FileResource object) {
374 // TODO Auto-generated method stub
375 return object.getFileSizeAsString();
377 },aheader = new SortableHeader("Size"));
378 allHeaders.add(aheader);
379 aheader.setUpdater(new FileValueUpdater(aheader, "size"));
380 celltable.addColumn(new TextColumn<FileResource>() {
382 public String getValue(FileResource object) {
383 return formatter.format(object.getModificationDate());
385 },aheader = new SortableHeader("Last Modified"));
386 allHeaders.add(aheader);
387 aheader.setUpdater(new FileValueUpdater(aheader, "date"));
388 VerticalPanel vp = new VerticalPanel();
390 celltable.setWidth("100%");
391 vp.add(searchResults);
392 searchResults.addStyleName("gss-searchLabel");
393 pagerTop = new SimplePager(SimplePager.TextLocation.CENTER);
394 pagerTop.setDisplay(celltable);
397 pager = new SimplePager(SimplePager.TextLocation.CENTER);
398 pager.setDisplay(celltable);
399 //celltable.setPageSize(2);
402 vp.setCellWidth(celltable, "100%");
406 //initWidget(celltable);
407 celltable.setStyleName("gss-List");
408 selectionModel = new MultiSelectionModel<FileResource>();
411 Handler selectionHandler = new SelectionChangeEvent.Handler() {
413 public void onSelectionChange(com.google.gwt.view.client.SelectionChangeEvent event) {
414 if(getSelectedFiles().size()==1)
415 GSS.get().setCurrentSelection(getSelectedFiles().get(0));
417 GSS.get().setCurrentSelection(getSelectedFiles());
418 //contextMenu.setFiles(getSelectedFiles());
421 selectionModel.addSelectionChangeHandler(selectionHandler);
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() {
429 public boolean execute() {
430 return fetchRootFolder();
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();
442 //public native void fireClickEvent(Element element) /*-{
443 // var evObj = $doc.createEvent('MouseEvents');
444 //evObj.initEvent('click', true, true);
445 //element.dispatchEvent(evObj);
448 public List<FileResource> getSelectedFiles() {
449 return new ArrayList<FileResource>(selectionModel.getSelectedSet());
452 private void initDragOperation(DragAndDropColumn<?, ?> column) {
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
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");
471 draggableOptions.setOnBeforeDragStart(new DragFunction() {
474 public void f(DragContext context) {
475 FileResource value = context.getDraggableData();
476 if(!selectionModel.isSelected(value)){
477 throw new StopDragException();
484 public void showContextMenu(Event event){
485 menuShowing = new FileContextMenu(images, false, true);
486 menuShowing=menuShowing.onEmptyEvent(event);
489 public void onBrowserEvent(Event event) {
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);
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) {
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", "");
523 event.preventDefault();
526 super.onBrowserEvent(event);
530 * Retrieve the root folder for the current user.
532 * @return true if the retrieval was successful
534 protected boolean fetchRootFolder() {
535 UserResource user = GSS.get().getCurrentUserResource();
538 // Update cache and clear selection.
539 updateFileCache(null);
545 * Update the display of the file list.
547 void update(boolean sort) {
548 int count = folderFileCount;
549 int max = startIndex + GSS.VISIBLE_FILE_COUNT;
554 copyListAndContinue(files);
555 for(FileResource f : files){
556 folderTotalSize += f.getContentLength();
558 if (folderFileCount == 0) {
559 showingStats = "no files";
560 } else if (folderFileCount < GSS.VISIBLE_FILE_COUNT) {
561 if (folderFileCount == 1)
562 showingStats = "1 file";
564 showingStats = folderFileCount + " files";
565 showingStats += " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
567 showingStats = "" + (startIndex + 1) + " - " + max + " of " + count + " files" + " (" + FileResource.getFileSizeAsString(folderTotalSize) + ")";
569 updateCurrentlyShowingStats();
574 * Return the proper icon based on the MIME type of the file.
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();
613 * Update status panel with currently showing file stats.
615 public void updateCurrentlyShowingStats() {
616 GSS.get().getStatusPanel().updateCurrentlyShowing(showingStats);
619 public void updateFileCache(String query) {
620 final GSS app = GSS.get();
625 app.showLoadingIndicator();
626 if (query == null || query.trim().equals("")) {
627 searchResults.setHTML("You must specify a query.");
628 setFiles(new ArrayList());
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());
635 app.hideLoadingIndicator();
637 searchResults.setHTML("Search results for " + query);
644 * Fill the file cache with data.
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)
654 Collections.sort(files, new Comparator<FileResource>() {
657 public int compare(FileResource arg0, FileResource arg1) {
658 return arg0.getName().compareTo(arg1.getName());
662 folderFileCount = files.size();
669 * Does the list contains the requested filename
674 public boolean contains(String fileName) {
675 for (int i = 0; i < files.size(); i++)
676 if (files.get(i).getName().equals(fileName))
681 public void clearSelectedRows() {
682 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
684 selectionModel.setSelected(it.next(),false);
691 public void selectAllRows() {
692 Iterator<FileResource> it = selectionModel.getSelectedSet().iterator();
694 selectionModel.setSelected(it.next(),true);
701 private void sortFiles(final String sortingProperty, final boolean sortingType){
702 Collections.sort(files, new Comparator<FileResource>() {
705 public int compare(FileResource arg0, FileResource arg1) {
706 AbstractImagePrototype descPrototype = AbstractImagePrototype.create(images.desc());
707 AbstractImagePrototype ascPrototype = AbstractImagePrototype.create(images.asc());
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());
722 return arg0.getName().compareTo(arg1.getName());
725 else if (sortingProperty.equals("version")) {
727 return arg1.getVersion().compareTo(arg0.getVersion());
728 } else if (sortingProperty.equals("owner")) {
730 return arg1.getOwner().compareTo(arg0.getOwner());
731 } else if (sortingProperty.equals("date")) {
733 return arg1.getModificationDate().compareTo(arg0.getModificationDate());
734 } else if (sortingProperty.equals("size")) {
736 return arg1.getContentLength().compareTo(arg0.getContentLength());
737 } else if (sortingProperty.equals("name")) {
739 return arg1.getName().compareTo(arg0.getName());
740 } else if (sortingProperty.equals("path")) {
742 return arg1.getUri().compareTo(arg0.getUri());
745 return arg1.getName().compareTo(arg0.getName());
752 final class FileValueUpdater implements ValueUpdater<String>{
753 private String property;
754 private SortableHeader header;
758 public FileValueUpdater(SortableHeader header,String property) {
759 this.property=property;
763 public void update(String value) {
764 header.setSorted(true);
765 header.toggleReverseSort();
767 for (SortableHeader otherHeader : allHeaders) {
768 if (otherHeader != header) {
769 otherHeader.setSorted(false);
770 otherHeader.setReverseSort(true);
773 celltable.redrawHeaders();
774 sortFiles(property, header.getReverseSort());
775 SearchResults.this.update(true);
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
787 private void copyListAndContinue(List<FileResource> filesInput){
788 List<FileResource> copiedFiles = new ArrayList<FileResource>();
789 for(FileResource file : filesInput) {
790 copiedFiles.add(file);
792 handleFullNames(copiedFiles);
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.
802 private void handleFullNames(List<FileResource> filesInput){
803 if(filesInput.size() == 0){
804 showCellTable(false);
808 if(GSS.get().findUserFullName(filesInput.get(0).getOwner()) == null){
809 findFullNameAndUpdate(filesInput);
813 if(filesInput.size() >= 1){
814 filesInput.remove(filesInput.get(0));
815 if(filesInput.isEmpty()){
816 showCellTable(false);
818 handleFullNames(filesInput);
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.
830 private void findFullNameAndUpdate(final List<FileResource> filesInput){
831 String aUserName = filesInput.get(0).getOwner();
832 String path = GSS.get().getApiPath() + "users/" + aUserName;
834 GetCommand<UserSearchResource> gg = new GetCommand<UserSearchResource>(UserSearchResource.class, path, false,null) {
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);
847 handleFullNames(filesInput);
853 public void onError(Throwable 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);
862 DeferredCommand.addCommand(gg);
866 * Shows the files in the cellTable
869 private void showCellTable(boolean update){
870 if(files.size()>=GSS.VISIBLE_FILE_COUNT){
871 pager.setVisible(true);
872 pagerTop.setVisible(true);
875 pager.setVisible(false);
876 pagerTop.setVisible(false);
879 provider.onRangeChanged(celltable);
880 celltable.redrawHeaders();
885 * Retrieve the lastQuery.
887 * @return the lastQuery
889 public String getLastQuery() {
895 * Modify the lastQuery.
897 * @param lastQuery the lastQuery to set
899 public void setLastQuery(String lastQuery) {
900 this.lastQuery = lastQuery;
903 class SearchDataProvider extends AsyncDataProvider<FileResource>{
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);
914 GetCommand<SearchResource> eg = new GetCommand<SearchResource>(SearchResource.class,
915 app.getApiPath() + "search/" +URL.encodeComponent(getLastQuery())+"?start="+start, null) {
918 public void onComplete() {
919 SearchResource s = getResult();
920 display.setRowCount(s.getSize(),true);
921 display.setRowData(start, s.getFiles());
922 setFiles(s.getFiles());
928 public void onError(Throwable t) {
929 if(t instanceof RestException)
930 app.displayError("Unable to perform search:"+((RestException)t).getHttpStatusText());
932 app.displayError("System error performing search:"+t.getMessage());
938 DeferredCommand.addCommand(eg);