Coverage Report - wjhk.jupload2.gui.filepanel.FilePanelFlatDataModel2
 
Classes in this File Line Coverage Branch Coverage Complexity
FilePanelFlatDataModel2
55 %
53/96
36 %
13/36
2,556
 
 1  
 //
 2  
 // $Id: FilePanelFlatDataModel2.java 1721 2015-03-29 17:48:44Z etienne_sf $
 3  
 //
 4  
 // jupload - A file upload applet.
 5  
 // Copyright 2007 The JUpload Team
 6  
 //
 7  
 // Created: 2006-04-21
 8  
 // Creator: etienne_sf
 9  
 // Last modified: $Date: 2015-03-29 19:48:44 +0200 (dim., 29 mars 2015) $
 10  
 //
 11  
 // This program is free software; you can redistribute it and/or modify it under
 12  
 // the terms of the GNU General Public License as published by the Free Software
 13  
 // Foundation; either version 2 of the License, or (at your option) any later
 14  
 // version. This program is distributed in the hope that it will be useful, but
 15  
 // WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 16  
 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 17  
 // details. You should have received a copy of the GNU General Public License
 18  
 // along with this program; if not, write to the Free Software Foundation, Inc.,
 19  
 // 675 Mass Ave, Cambridge, MA 02139, USA.
 20  
 
 21  
 package wjhk.jupload2.gui.filepanel;
 22  
 
 23  
 import java.io.File;
 24  
 import java.util.ArrayList;
 25  
 import java.util.Collections;
 26  
 import java.util.Date;
 27  
 import java.util.List;
 28  
 
 29  
 import javax.swing.table.AbstractTableModel;
 30  
 
 31  
 import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles;
 32  
 import wjhk.jupload2.filedata.DefaultFileData;
 33  
 import wjhk.jupload2.filedata.FileData;
 34  
 import wjhk.jupload2.policies.UploadPolicy;
 35  
 
 36  
 /**
 37  
  * This class replaces FilePanelDataModel. The data for each row is now contained in an instance of FileData (or one of
 38  
  * its subclasses, like {@link wjhk.jupload2.filedata.PictureFileData}). This allow easy add of new functionalites,
 39  
  * during upload, by adding attributes or methods to these classes, or create new ones. <BR>
 40  
  * Some ides of improvements :
 41  
  * <UL>
 42  
  * <LI>Compression of picture before Upload (see {@link wjhk.jupload2.filedata.PictureFileData})
 43  
  * <LI>Could be XML validation before sending to the server
 44  
  * <LI>Up to your imagination...
 45  
  * </UL>
 46  
  */
 47  
 public class FilePanelFlatDataModel2 extends AbstractTableModel {
 48  
 
 49  
     /** A generated serialVersionUID, to avoid warning during compilation */
 50  
     private static final long serialVersionUID = 1473262424494858913L;
 51  
 
 52  
     /**
 53  
      * The default colum indices of the columns, as displayed by the applet. Index of the column "Filename"
 54  
      */
 55  
     public final static int COLINDEX_NAME = 0;
 56  
 
 57  
     /**
 58  
      * The default colum indices of the columns, as displayed by the applet. Index of the column "Filename"
 59  
      */
 60  
     public final static int COLINDEX_SIZE = 1;
 61  
 
 62  
     /**
 63  
      * The default colum indices of the columns, as displayed by the applet. Index of the column "Filesize"
 64  
      */
 65  
     public final static int COLINDEX_DIRECTORY = 2;
 66  
 
 67  
     /**
 68  
      * The default colum indices of the columns, as displayed by the applet. Index of the column "Last modified"
 69  
      */
 70  
     public final static int COLINDEX_MODIFIED = 3;
 71  
 
 72  
     /**
 73  
      * The uploadPolicy contains all current parameter, including the FileDataParam
 74  
      */
 75  237
     private UploadPolicy uploadPolicy = null;
 76  
 
 77  
     /**
 78  
      * The column names, as displayed on the applet. They are not real final values, as they are translated: we need to
 79  
      * have an uploadPolicy for this translation, and the uploadPolicy is 'given' to the constructor.
 80  
      */
 81  237
     private String COL_NAME = null;
 82  
 
 83  237
     private String COL_SIZE = null;
 84  
 
 85  237
     private String COL_DIRECTORY = null;
 86  
 
 87  237
     private String COL_MODIFIED = null;
 88  
 
 89  237
     private String COL_CHECKED = "";
 90  
 
 91  237
     protected String[] columnNames = null;
 92  
 
 93  
     /**
 94  
      * This array indicates, for each column, the percentage of the available width it should use. It's initialized in
 95  
      * the constructor of this class.
 96  
      * 
 97  
      * @see #getColumnSize(int)
 98  
      */
 99  237
     protected int[] columnSizePercentage = null;
 100  
 
 101  
     /**
 102  
      * Indicates whether each column is editable or not. Only the check box should be editable.
 103  
      */
 104  237
     protected boolean[] columnEditable = null;
 105  
 
 106  237
     protected Class<?> columnClasses[] = null;
 107  
 
 108  
     /**
 109  
      * This Vector contains all FileData.
 110  
      */
 111  237
     private List<FileData> rows = new ArrayList<FileData>();
 112  
 
 113  
     /**
 114  
      * @param uploadPolicy
 115  
      */
 116  
     public FilePanelFlatDataModel2(UploadPolicy uploadPolicy) {
 117  
         // Property initialization is done ... for each property. Nothing to do
 118  
         // here.
 119  237
         super();
 120  
         //
 121  237
         this.uploadPolicy = uploadPolicy;
 122  
 
 123  
         // Initialization for column name, type and size.
 124  237
         this.COL_NAME = uploadPolicy.getLocalizedString("colName");
 125  237
         this.COL_SIZE = uploadPolicy.getLocalizedString("colSize");
 126  237
         this.COL_DIRECTORY = uploadPolicy.getLocalizedString("colDirectory");
 127  237
         this.COL_MODIFIED = uploadPolicy.getLocalizedString("colModified");
 128  
 
 129  237
         this.columnNames = new String[] {
 130  
                 this.COL_NAME, this.COL_SIZE, this.COL_DIRECTORY, this.COL_MODIFIED, this.COL_CHECKED
 131  
         // COL_CHECKED is unnamed.
 132  
         };
 133  
 
 134  
         // Initial size (before percentage) was: 150, 75, 199, 130, 75
 135  237
         this.columnSizePercentage = new int[] {
 136  
                 29, 11, 35, 20, 5
 137  
         };
 138  
 
 139  
         // Initial size (before percentage) was: 150, 75, 199, 130, 75
 140  237
         this.columnEditable = new boolean[] {
 141  
                 false, false, false, false, true
 142  
         };
 143  
 
 144  
         // Check that the sum of the previous values is actually 100%
 145  237
         int total = 0;
 146  1422
         for (int i = 0; i < this.columnSizePercentage.length; i += 1) {
 147  1185
             total += this.columnSizePercentage[i];
 148  
         }
 149  237
         if (total != 100) {
 150  0
             throw new java.lang.AssertionError("Total sum of '" + this.getClass().getName()
 151  
                     + ".columnSizePercentage' should be 100% (but was " + total + ")");
 152  
         }
 153  
 
 154  237
         this.columnClasses = new Class[] {
 155  
                 String.class, Long.class, String.class, Date.class, Boolean.class, Boolean.class
 156  
         };
 157  237
     }
 158  
 
 159  
     /**
 160  
      * Get the FileData representing a given file.
 161  
      * 
 162  
      * @param file : the file that could be contained...
 163  
      * @return The FileData representing this file. Null if the file is not already contained in the file list.
 164  
      */
 165  
     public FileData contains(String absolutePath) {
 166  199
         FileData foundFileData = null;
 167  
 
 168  199
         for (FileData fd : rows) {
 169  1548
             if (absolutePath.equals(fd.getAbsolutePath())) {
 170  0
                 foundFileData = fd;
 171  0
                 break;
 172  
             }
 173  1548
         } // for
 174  
 
 175  199
         return foundFileData;
 176  
     }
 177  
 
 178  
     /**
 179  
      * Add a file to the panel (at the end of the list)
 180  
      * 
 181  
      * @param file
 182  
      * @param root
 183  
      * @throws JUploadExceptionStopAddingFiles
 184  
      */
 185  
     public FileData addFile(File file) throws JUploadExceptionStopAddingFiles {
 186  199
         synchronized (this.rows) {
 187  199
             FileData foundFileData = contains(file.getAbsolutePath());
 188  199
             if (foundFileData != null) {
 189  0
                 this.uploadPolicy.displayWarn("File " + file.getName() + " already exists");
 190  0
                 return foundFileData;
 191  
             } else {
 192  
                 // We first call the upload policy, to get :
 193  
                 // - The correct fileData instance (for instance the
 194  
                 // PictureUploadPolicy returns a PictureFileData)
 195  
                 // - The reference to this newly FileData, or null if an error
 196  
                 // occurs (for instance: invalid file content, according to the
 197  
                 // current upload policy, or non allowed file extension).
 198  199
                 FileData fd = this.uploadPolicy.createFileData(file);
 199  199
                 if (fd != null) {
 200  
                     // The file is Ok, let's add it.
 201  199
                     this.rows.add(fd);
 202  
 
 203  
                     // It's slow to call fireTableDataChanged(); for each file. So, this call is done when all
 204  
                     // files have been added. This is done in FilePanelTableImp.addFiles
 205  
                 }
 206  199
                 return fd;
 207  
             }// else
 208  0
         }// synchronized
 209  
     }
 210  
 
 211  
     /**
 212  
      * Ask for the file contained at specified row number.
 213  
      * 
 214  
      * @param row The row number
 215  
      * @return The return instance of File.
 216  
      */
 217  
     public FileData getFileDataAt(int row) {
 218  9
         if (row >= 0) {
 219  
             try {
 220  9
                 return this.rows.get(row);
 221  0
             } catch (ArrayIndexOutOfBoundsException e) {
 222  
                 // Nothing to do. It seems that it can occurs when upload is very fast (for instance: small files to
 223  
                 // localhost).
 224  0
                 this.uploadPolicy.displayWarn(e.getClass().getName() + " in FilePanelDataModel2.getFileDataAt(" + row
 225  
                         + ")");
 226  
             }
 227  
         }
 228  0
         return null;
 229  
     }
 230  
 
 231  
     /**
 232  
      * Remove a specified row.
 233  
      * 
 234  
      * @param row The row to remove.
 235  
      */
 236  
     public void removeRow(int row) {
 237  8
         this.rows.remove(row);
 238  8
         fireTableDataChanged();
 239  8
     }
 240  
 
 241  
     /**
 242  
      * Returns the row number, for the given fileData, in the current list.
 243  
      * 
 244  
      * @param fileData The {@link FileData} to find
 245  
      * @return The row number for fileData, or -1 if it was not found.
 246  
      */
 247  
     public int getRow(FileData fileData) {
 248  4
         synchronized (this.rows) {
 249  9
             for (int i = 0; i < this.rows.size(); i += 1) {
 250  8
                 if (rows.get(i).getAbsolutePath().equals(fileData.getAbsolutePath())) {
 251  3
                     return i;
 252  
                 }
 253  
             }// for
 254  1
             return -1;
 255  0
         }// synchronized(rows)
 256  
     }
 257  
 
 258  
     /** @see javax.swing.table.TableModel#getColumnCount() */
 259  
     public int getColumnCount() {
 260  240
         return this.columnNames.length;
 261  
     }
 262  
 
 263  
     /** @see javax.swing.table.TableModel#getRowCount() */
 264  
     public int getRowCount() {
 265  71
         return this.rows.size();
 266  
     }
 267  
 
 268  
     /**
 269  
      * Always return false here : no editable cell.
 270  
      * 
 271  
      * @see javax.swing.table.TableModel#isCellEditable(int, int)
 272  
      */
 273  
     @Override
 274  
     public boolean isCellEditable(int arg0, int arg1) {
 275  0
         return columnEditable[arg1];
 276  
     }
 277  
 
 278  
     /**
 279  
      * Sort the rows, according to one column.
 280  
      * 
 281  
      * @param col The index of the column to sort
 282  
      * @param ascending true if ascending, false if descending.
 283  
      */
 284  
     public void sortColumn(int col, boolean ascending) {
 285  0
         synchronized (this.rows) {
 286  0
             Collections.sort(this.rows, new ColumnComparator(col, ascending));
 287  0
         }
 288  0
         fireTableDataChanged();
 289  0
     }
 290  
 
 291  
     /**
 292  
      * Return true if this column can be sorted.
 293  
      * 
 294  
      * @param col The index of the column which can sortable or not.
 295  
      * @return true if the column can be sorted. false otherwise.
 296  
      */
 297  
     public boolean isSortable(int col) {
 298  0
         return (Boolean.class != getColumnClass(col));
 299  
     }
 300  
 
 301  
     /**
 302  
      * @see javax.swing.table.TableModel#getColumnClass(int)
 303  
      */
 304  
     @Override
 305  
     public Class<?> getColumnClass(int arg0) {
 306  0
         return this.columnClasses[arg0];
 307  
     }
 308  
 
 309  
     /**
 310  
      * @see javax.swing.table.TableModel#getValueAt(int, int)
 311  
      */
 312  
     public Object getValueAt(int row, int col) {
 313  0
         FileData fileData = getFileDataAt(row);
 314  0
         if (fileData != null) {
 315  0
             String colName = getColumnName(col);
 316  
             // Don't know if it will be useful, but the switch below allows the
 317  
             // column to be in any order.
 318  0
             if (colName.equals(this.COL_NAME)) {
 319  0
                 return fileData.getFileName();
 320  0
             } else if (colName.equals(this.COL_SIZE)) {
 321  0
                 return Long.valueOf(fileData.getFileLength());
 322  0
             } else if (colName.equals(this.COL_DIRECTORY)) {
 323  0
                 return fileData.getDirectory();
 324  0
             } else if (colName.equals(this.COL_MODIFIED)) {
 325  0
                 return fileData.getLastModified();
 326  0
             } else if (colName.equals(this.COL_CHECKED)) {
 327  0
                 return fileData.getUploadFlag();
 328  
             } else {
 329  0
                 this.uploadPolicy.displayErr("Unknown column in " + this.getClass().getName() + ": " + colName);
 330  0
                 return null;
 331  
             }
 332  
         } else {
 333  0
             return null;
 334  
         }
 335  
     }
 336  
 
 337  
     /**
 338  
      * This method doesn't do anything : no changeable values.
 339  
      * 
 340  
      * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
 341  
      */
 342  
     @Override
 343  
     public void setValueAt(Object aValue, int row, int col) {
 344  0
         if (!columnEditable[col]) {
 345  0
             this.uploadPolicy.displayWarn(this.getClass().getName() + ".setValueAt: no action");
 346  
         } else {
 347  0
             FileData fd = getFileDataAt(row);
 348  0
             if (!(aValue instanceof Boolean)) {
 349  0
                 this.uploadPolicy.displayErr("Internal error in " + this.getClass().getName()
 350  0
                         + ": o should be a Boolean but is a " + aValue.getClass().getName());
 351  
             } else {
 352  0
                 fd.setUploadFlag((Boolean) aValue);
 353  
             }
 354  
         }
 355  0
     }
 356  
 
 357  
     /**
 358  
      * @see javax.swing.table.TableModel#getColumnName(int)
 359  
      */
 360  
     @Override
 361  
     public String getColumnName(int arg0) {
 362  200
         return this.columnNames[arg0];
 363  
     }
 364  
 
 365  
     /**
 366  
      * Retrieves the default colum percentage size of a column, that is: its percentage of the available width.
 367  
      * 
 368  
      * @param col The index of the column to query.
 369  
      * @return the default size of the requested column.
 370  
      */
 371  
     public int getColumnSizePercentage(int col) {
 372  0
         return this.columnSizePercentage[col];
 373  
     }
 374  
 
 375  
     /**
 376  
      * Get the common Root of all files in the current list. Only 'checked' files (uploadFlag to true) are taken into
 377  
      * account.
 378  
      * 
 379  
      * @return
 380  
      */
 381  
     public File getFileRoot() {
 382  8
         return DefaultFileData.getRoot(rows);
 383  
     }
 384  
 
 385  
     public List<FileData> getFiles() {
 386  15
         return rows;
 387  
     }
 388  
 }