Make the warning message more informative.
[pithos] / src / gr / ebs / gss / admin / client / ui / FilesTable.java
1 /*
2  * Copyright 2010 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.admin.client.ui;
20
21 import gr.ebs.gss.admin.client.ui.FilesTable.FileSorter.FileComparator;
22 import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.Comparator;
27 import java.util.Date;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.LinkedHashMap;
31 import java.util.LinkedList;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35
36 import com.google.gwt.core.client.GWT;
37 import com.google.gwt.gen2.table.client.AbstractColumnDefinition;
38 import com.google.gwt.gen2.table.client.AbstractScrollTable.ScrollPolicy;
39 import com.google.gwt.gen2.table.client.AbstractScrollTable.SortPolicy;
40 import com.google.gwt.gen2.table.client.CachedTableModel;
41 import com.google.gwt.gen2.table.client.CellRenderer;
42 import com.google.gwt.gen2.table.client.ColumnDefinition;
43 import com.google.gwt.gen2.table.client.DefaultRowRenderer;
44 import com.google.gwt.gen2.table.client.DefaultTableDefinition;
45 import com.google.gwt.gen2.table.client.FixedWidthGridBulkRenderer;
46 import com.google.gwt.gen2.table.client.MutableTableModel;
47 import com.google.gwt.gen2.table.client.PagingOptions;
48 import com.google.gwt.gen2.table.client.PagingScrollTable;
49 import com.google.gwt.gen2.table.client.ScrollTable;
50 import com.google.gwt.gen2.table.client.SelectionGrid.SelectionPolicy;
51 import com.google.gwt.gen2.table.client.TableDefinition;
52 import com.google.gwt.gen2.table.client.TableDefinition.AbstractCellView;
53 import com.google.gwt.gen2.table.client.TableModel;
54 import com.google.gwt.gen2.table.client.TableModelHelper.Request;
55 import com.google.gwt.gen2.table.client.TableModelHelper.Response;
56 import com.google.gwt.gen2.table.event.client.RowSelectionEvent;
57 import com.google.gwt.gen2.table.event.client.RowSelectionHandler;
58 import com.google.gwt.gen2.table.event.client.TableEvent.Row;
59 import com.google.gwt.i18n.client.DateTimeFormat;
60 import com.google.gwt.user.client.ui.CheckBox;
61 import com.google.gwt.user.client.ui.Composite;
62 import com.google.gwt.user.client.ui.FlexTable;
63 import com.google.gwt.user.client.ui.HTML;
64 import com.google.gwt.user.client.ui.HasHorizontalAlignment;
65 import com.google.gwt.user.client.ui.Label;
66 import com.google.gwt.user.client.ui.VerticalPanel;
67
68
69 /**
70  * @author kman
71  *
72  */
73 public class FilesTable extends Composite {
74         private CachedTableModel<FileHeaderDTO> cachedTableModel = null;
75         private DefaultTableDefinition<FileHeaderDTO> tableDefinition = null;
76         private PagingScrollTable<FileHeaderDTO> pagingScrollTable = null;
77         private Label countLabel = new Label("There are no files to display.");
78         private DataSourceTableModel tableModel = null;
79
80         private VerticalPanel vPanel = new VerticalPanel();
81         private FlexTable flexTable = new FlexTable();
82
83         /**
84          * Constructor
85          */
86         public FilesTable() {
87                 super();
88                 pagingScrollTable = createScrollTable();
89                 pagingScrollTable.setHeight("200px");
90                 pagingScrollTable.setScrollPolicy(ScrollPolicy.DISABLED);
91                 PagingOptions pagingOptions = new PagingOptions(pagingScrollTable);
92
93                 flexTable.setWidget(0, 0, pagingScrollTable);
94                 flexTable.getFlexCellFormatter().setColSpan(0, 0, 2);
95                 flexTable.setWidget(1, 0, pagingOptions);
96
97                 countLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
98                 vPanel.add(countLabel);
99                 vPanel.add(flexTable);
100
101                 vPanel.setWidth("100%");
102                 flexTable.setWidth("100%");
103
104                 super.initWidget(vPanel);
105                 showUsers(new ArrayList<FileHeaderDTO>());
106                 pagingScrollTable.setFooterGenerated(true);
107         }
108
109         public void showUsers(List<FileHeaderDTO> newList) {
110                 countLabel.setText("There are "+ newList.size() + " files.");
111                 tableModel.setData(newList);
112                 tableModel.setRowCount(newList.size());
113                 cachedTableModel.clearCache();
114                 cachedTableModel.setRowCount(newList.size());
115
116                 pagingScrollTable.gotoPage(0, true);
117                 if(newList.size()<2)
118                         flexTable.setWidget(1, 0, new HTML());
119                 else{
120                         PagingOptions pagingOptions = new PagingOptions(pagingScrollTable);
121                         flexTable.setWidget(1, 0, pagingOptions);
122                 }
123         }
124
125         public FileHeaderDTO getUserOnRow(int rowIdx){
126                 String id = pagingScrollTable.getDataTable().getHTML(rowIdx, 0);
127                 final FileHeaderDTO m = tableModel.getUserById(Long.parseLong(id));
128                 return m;
129         }
130
131
132         public FileHeaderDTO getSelectedRowObject(RowSelectionEvent event){
133                 Set<Row> set = event.getSelectedRows();
134                 if(set.size() == 1) {
135                         int rowIdx = set.iterator().next().getRowIndex();
136                         String id = pagingScrollTable.getDataTable().getHTML(rowIdx, 0);
137                         FileHeaderDTO m = tableModel.getUserById(Long.parseLong(id));
138                         return m;
139                 }
140                 return null;
141         }
142
143         public FileHeaderDTO getUser(Long id){
144
145                 return tableModel.getUserById(id);
146         }
147
148
149
150         /**
151          * Initializes the scroll table
152          * @return
153          */
154         private PagingScrollTable<FileHeaderDTO> createScrollTable() {
155                 // create our own table model
156                 tableModel = new DataSourceTableModel();
157                 // add it to cached table model
158                 cachedTableModel = createCachedTableModel(tableModel);
159
160                 // create the table definition
161                 TableDefinition<FileHeaderDTO> tableDef = createTableDefinition();
162
163                 // create the paging scroll table
164                 pagingScrollTable = new PagingScrollTable<FileHeaderDTO>(cachedTableModel, tableDef);
165                 pagingScrollTable.setPageSize(10);
166                 pagingScrollTable.setEmptyTableWidget(new HTML("There is no data to display"));
167                 pagingScrollTable.getDataTable().setSelectionPolicy(SelectionPolicy.ONE_ROW);
168
169                 FixedWidthGridBulkRenderer<FileHeaderDTO> bulkRenderer = new FixedWidthGridBulkRenderer<FileHeaderDTO>(pagingScrollTable.getDataTable(), pagingScrollTable);
170                 pagingScrollTable.setBulkRenderer(bulkRenderer);
171
172
173                 pagingScrollTable.setCellPadding(3);
174                 pagingScrollTable.setCellSpacing(0);
175                 pagingScrollTable.setResizePolicy(ScrollTable.ResizePolicy.FILL_WIDTH);
176
177                 pagingScrollTable.setSortPolicy(SortPolicy.SINGLE_CELL);
178
179                 return pagingScrollTable;
180         }
181
182         public void addRowSelectionHandler(RowSelectionHandler handler){
183                 pagingScrollTable.getDataTable().addRowSelectionHandler(handler);
184         }
185
186         /**
187          * Create the {@link CachedTableModel}
188          * @param aTableModel
189          * @return
190          */
191         private CachedTableModel<FileHeaderDTO> createCachedTableModel(DataSourceTableModel aTableModel) {
192                 CachedTableModel<FileHeaderDTO> tm = new CachedTableModel<FileHeaderDTO>(aTableModel);
193                 tm.setPreCachedRowCount(20);
194                 tm.setPostCachedRowCount(20);
195                 tm.setRowCount(20);
196                 return tm;
197         }
198
199         private DefaultTableDefinition<FileHeaderDTO> createTableDefinition() {
200                 tableDefinition = new DefaultTableDefinition<FileHeaderDTO>();
201
202                 final String[] rowColors = new String[] { "#FFFFDD", "EEEEEE" };
203                 tableDefinition.setRowRenderer(new DefaultRowRenderer<FileHeaderDTO>(rowColors));
204
205                 // id
206                 {
207                         IdColumnDefinition columnDef = new IdColumnDefinition();
208                         columnDef.setColumnSortable(true);
209                         columnDef.setColumnTruncatable(false);
210                         columnDef.setPreferredColumnWidth(35);
211                         columnDef.setHeader(0, new HTML("Id"));
212                         columnDef.setHeaderCount(1);
213                         columnDef.setHeaderTruncatable(false);
214                         tableDefinition.addColumnDefinition(columnDef);
215                 }
216                 {
217                         NameColumnDefinition columnDef = new NameColumnDefinition();
218                         columnDef.setColumnSortable(true);
219                         columnDef.setColumnTruncatable(true);
220                         columnDef.setHeader(0, new HTML("File Name"));
221                         columnDef.setHeaderCount(1);
222                         columnDef.setHeaderTruncatable(false);
223                         tableDefinition.addColumnDefinition(columnDef);
224                 }
225                 {
226                         UriColumnDefinition columnDef = new UriColumnDefinition();
227                         columnDef.setColumnSortable(true);
228                         columnDef.setColumnTruncatable(true);
229                         columnDef.setHeader(0, new HTML("URI"));
230                         columnDef.setHeaderCount(1);
231                         columnDef.setHeaderTruncatable(false);
232                         tableDefinition.addColumnDefinition(columnDef);
233                 }
234                 // username
235                 {
236                         UserColumnDefinition columnDef = new UserColumnDefinition();
237                         columnDef.setColumnSortable(true);
238                         columnDef.setColumnTruncatable(true);
239                         columnDef.setHeader(0, new HTML("Username"));
240                         columnDef.setHeaderCount(1);
241                         columnDef.setHeaderTruncatable(false);
242                         tableDefinition.addColumnDefinition(columnDef);
243                 }
244                 {
245                         FilesizeDefinition columnDef = new FilesizeDefinition();
246                         columnDef.setColumnSortable(true);
247                         columnDef.setColumnTruncatable(true);
248                         columnDef.setHeader(0, new HTML("File Size"));
249                         columnDef.setHeaderCount(1);
250                         columnDef.setHeaderTruncatable(false);
251                         tableDefinition.addColumnDefinition(columnDef);
252                 }
253                 {
254                         DeletedColumnDefinition columnDef = new DeletedColumnDefinition();
255                         columnDef.setColumnSortable(true);
256                         columnDef.setColumnTruncatable(true);
257                         columnDef.setHeader(0, new HTML("Deleted"));
258                         columnDef.setHeaderCount(1);
259                         columnDef.setHeaderTruncatable(false);
260                         columnDef.setCellRenderer(new CellRenderer<FileHeaderDTO, Boolean>() {
261
262                                 @Override
263                                 public void renderRowValue(FileHeaderDTO rowValue, ColumnDefinition<FileHeaderDTO, Boolean> aColumnDef, AbstractCellView<FileHeaderDTO> view) {
264                                         CheckBox check = new CheckBox();
265                                         check.setValue(aColumnDef.getCellValue(rowValue));
266                                         check.setEnabled(false);
267                                         view.setWidget(check);
268
269                                 }
270                         });
271                         tableDefinition.addColumnDefinition(columnDef);
272                 }
273
274
275                 {
276                         CreationColumnDefinition columnDef = new CreationColumnDefinition();
277                         columnDef.setColumnSortable(true);
278                         columnDef.setColumnTruncatable(true);
279                         columnDef.setHeader(0, new HTML("Creation Date"));
280                         columnDef.setHeaderCount(1);
281                         columnDef.setHeaderTruncatable(false);
282                         tableDefinition.addColumnDefinition(columnDef);
283                 }
284
285                 {
286                         LastModifiedColumnDefinition columnDef = new LastModifiedColumnDefinition();
287                         columnDef.setColumnSortable(true);
288                         columnDef.setColumnTruncatable(true);
289                         columnDef.setHeader(0, new HTML("Modification Date"));
290                         columnDef.setHeaderCount(1);
291                         columnDef.setHeaderTruncatable(false);
292                         tableDefinition.addColumnDefinition(columnDef);
293                 }
294
295
296
297                 return tableDefinition;
298         }
299
300
301         private class DataSourceTableModel extends MutableTableModel<FileHeaderDTO> {
302                 private Map<Long, FileHeaderDTO> map;
303                 private FileSorter sorter = new FileSorter();
304                 public void setData(List<FileHeaderDTO> list) {
305                         // toss the list, index by id in a map.
306                         map = new HashMap<Long, FileHeaderDTO>(list.size());
307                         for(FileHeaderDTO m : list)
308                                 map.put(m.getId(), m);
309                 }
310
311                 public FileHeaderDTO getUserById(long id) {
312                         return map.get(id);
313                 }
314
315                 @Override
316                 protected boolean onRowInserted(int beforeRow) {
317                         return true;
318                 }
319
320                 @Override
321                 protected boolean onRowRemoved(int row) {
322                         return true;
323                 }
324
325                 @Override
326                 protected boolean onSetRowValue(int row, FileHeaderDTO rowValue) {
327
328                         return true;
329                 }
330
331                 @Override
332                 public void requestRows(
333                                 final Request request,
334                                 TableModel.Callback<FileHeaderDTO> callback) {
335
336                         callback.onRowsReady(request, new Response<FileHeaderDTO>(){
337
338                                 @Override
339                                 public Iterator<FileHeaderDTO> getRowValues() {
340                                         final int col = request.getColumnSortList().getPrimaryColumn();
341                                         final boolean ascending = request.getColumnSortList().isPrimaryAscending();
342                                         if(col < 0)
343                                                 map = sorter.sort(map, new FileComparator(ascending,0));
344                                         else
345                                                 map = sorter.sort(map, new FileComparator(ascending,col));
346                                         return map.values().iterator();
347                                 }});
348                 }
349
350         }
351
352
353         private final class IdColumnDefinition extends AbstractColumnDefinition<FileHeaderDTO, Long> {
354                 @Override
355                 public Long getCellValue(FileHeaderDTO rowValue) {
356                         return rowValue.getId();
357                 }
358                 @Override
359                 public void setCellValue(FileHeaderDTO rowValue, Long cellValue) { }
360         }
361
362
363         private final class NameColumnDefinition extends
364                         AbstractColumnDefinition<FileHeaderDTO, String> {
365                 @Override
366                 public String getCellValue(final FileHeaderDTO rowValue) {
367                         return rowValue.getName();
368                 }
369
370                 @Override
371                 public void setCellValue(final FileHeaderDTO rowValue, final String cellValue) {}
372         }
373
374
375         private final class UriColumnDefinition extends
376                 AbstractColumnDefinition<FileHeaderDTO, String> {
377                 @Override
378                 public String getCellValue(final FileHeaderDTO rowValue) {
379                         return rowValue.getURI();
380                 }
381
382                 @Override
383                 public void setCellValue(final FileHeaderDTO rowValue, final String cellValue) {}
384         }
385
386
387         private final class FilesizeDefinition extends
388                         AbstractColumnDefinition<FileHeaderDTO, String> {
389                 @Override
390                 public String getCellValue(final FileHeaderDTO rowValue) {
391                         return rowValue.getFileSizeAsString();
392                 }
393
394                 @Override
395                 public void setCellValue(final FileHeaderDTO rowValue, final String cellValue) {}
396         }
397
398
399         private final class UserColumnDefinition extends
400                         AbstractColumnDefinition<FileHeaderDTO, String> {
401                 @Override
402                 public String getCellValue(final FileHeaderDTO rowValue) {
403                         return rowValue.getOwner().getUsername();
404                 }
405
406                 @Override
407                 public void setCellValue(final FileHeaderDTO rowValue, final String cellValue) {}
408         }
409
410
411         private final class DeletedColumnDefinition extends
412                         AbstractColumnDefinition<FileHeaderDTO, Boolean> {
413                 @Override
414                 public Boolean getCellValue(final FileHeaderDTO rowValue) {
415                         return rowValue.isDeleted();
416                 }
417
418                 @Override
419                 public void setCellValue(final FileHeaderDTO rowValue, final Boolean cellValue) {
420
421                 }
422         }
423
424         private final class CreationColumnDefinition extends AbstractColumnDefinition<FileHeaderDTO, String> {
425
426                 @Override
427                 public String getCellValue(final FileHeaderDTO rowValue) {
428                         return DateTimeFormat.getFormat("dd/MM/yyyy hh:mm:ss tt").format(rowValue.getAuditInfo().getCreationDate());
429                 }
430
431                 @Override
432                 public void setCellValue(final FileHeaderDTO rowValue, final String cellValue) {}
433         }
434
435         private final class LastModifiedColumnDefinition extends AbstractColumnDefinition<FileHeaderDTO, String> {
436
437                 @Override
438                 public String getCellValue(final FileHeaderDTO rowValue) {
439                         return DateTimeFormat.getFormat("dd/MM/yyyy hh:mm:ss tt").format(rowValue.getAuditInfo().getModificationDate());
440                 }
441
442                 @Override
443                 public void setCellValue(final FileHeaderDTO rowValue, final String cellValue) {}
444         }
445
446
447
448         public static class FileSorter {
449
450
451                 public Map<Long, FileHeaderDTO> sort(Map<Long, FileHeaderDTO> map, Comparator<FileHeaderDTO> comparator) {
452                         final List<FileHeaderDTO> list = new LinkedList<FileHeaderDTO>(map.values());
453                         Collections.sort(list, comparator);
454                         Map<Long, FileHeaderDTO> result = new LinkedHashMap<Long, FileHeaderDTO>(list.size());
455                         for(FileHeaderDTO p : list)
456                                 result.put(p.getId(), p);
457                         return result;
458                 }
459
460                 public final static class FileComparator implements Comparator<FileHeaderDTO> {
461
462                         private final boolean ascending;
463                         private int property;
464                         public FileComparator(boolean isAscending, int aProperty) {
465                                 ascending = isAscending;
466                                 property = aProperty;
467                         }
468
469                         @Override
470                         public int compare(FileHeaderDTO m1, FileHeaderDTO m2) {
471                                 GWT.log("sorting:"+property+" "+m1.getFileSize()+" "+m2.getFileSize());
472                                 switch(property){
473                                         case 0://id
474                                                 if(ascending)
475                                                         return m1.getId().compareTo(m2.getId());
476                                                 return m2.getId().compareTo(m1.getId());
477                                         case 1://name
478                                                 if(ascending)
479                                                         return m1.getName().compareTo(m2.getName());
480                                                 return m2.getName().compareTo(m1.getName());
481                                         case 2://uri
482                                                 if(ascending)
483                                                         return m1.getURI().compareTo(m2.getURI());
484                                                 return m2.getURI().compareTo(m1.getURI());
485                                         case 3://file size
486                                                 if(ascending)
487                                                         return new Long(m1.getFileSize()).compareTo(new Long(m2.getFileSize()));
488                                                 return new Long(m2.getFileSize()).compareTo(new Long(m1.getFileSize()));
489                                         case 4://deleted
490                                                 if(ascending)
491                                                         return new Boolean(m1.isDeleted()).compareTo(new Boolean(m2.isDeleted()));
492                                                 return new Boolean(m2.isDeleted()).compareTo(new Boolean(m1.isDeleted()));
493                                         case 5://created
494                                                         return new DateComparator(ascending).compare(m1.getAuditInfo().getCreationDate(), m2.getAuditInfo().getCreationDate());
495                                         case 6://modified
496                                                 return new DateComparator(ascending).compare(m1.getAuditInfo().getModificationDate(), m2.getAuditInfo().getModificationDate());
497                                         default:
498                                                 if(ascending)
499                                                         return m1.getId().compareTo(m2.getId());
500                                                 return m2.getId().compareTo(m1.getId());
501                                 }
502
503                         }
504                 }
505
506
507                 public final static class DateComparator implements Comparator<Date> {
508
509                         private final boolean ascending;
510
511                         public DateComparator(boolean isAscending) {
512                                 ascending = isAscending;
513                         }
514
515                         @Override
516                         public int compare(Date d1, Date d2) {
517                                 if(d1==null && d2==null)
518                                         return 0;
519                                 if(d1==null && d2 != null)
520                                         return -1;
521                                 if(d2==null && d1 != null)
522                                         return 1;
523                                 if(ascending)
524                                         return d1.compareTo(d2);
525                                 return d2.compareTo(d1);
526                         }
527                 }
528         }
529
530
531
532 }