Coverage Report - wjhk.jupload2.gui.filepanel.treeview.FileDataTreeViewModel
 
Classes in this File Line Coverage Branch Coverage Complexity
FileDataTreeViewModel
88 %
76/86
82 %
37/45
4,727
FileDataTreeViewModel$1
100 %
1/1
N/A
4,727
 
 1  
 package wjhk.jupload2.gui.filepanel.treeview;
 2  
 
 3  
 import java.io.File;
 4  
 import java.util.Date;
 5  
 
 6  
 import javax.swing.table.TableModel;
 7  
 import javax.swing.tree.TreePath;
 8  
 
 9  
 import wjhk.jupload2.exception.JUploadExceptionStopAddingFiles;
 10  
 import wjhk.jupload2.gui.filepanel.FilePanel;
 11  
 import wjhk.jupload2.gui.filepanel.FilePanelFlatDataModel2;
 12  
 import wjhk.jupload2.policies.UploadPolicy;
 13  
 
 14  
 /**
 15  
  * This code is taken from the tutorial written by Jörn Hameister, <A
 16  
  * HREF="http://www.hameister.org/JavaSwingTreeTable.html">available here</A>.<BR/>
 17  
  * <BR/>
 18  
  * In the class MyDataModel the concrete data model view is defined. Ie, the columns are defined including data type.
 19  
  * The class also contains the unimplemented methods of the interface TreeModel . It should be noted the method
 20  
  * isCellEditable . This has the value true return so that the Listener on a treeExpanded or treeCollapsed can respond.
 21  
  * One could in this method only for the first column ( column ) the value true and otherwise return the value false .
 22  
  * 
 23  
  * @author Jörn Hameister
 24  
  */
 25  0
 public class FileDataTreeViewModel extends MyAbstractTreeTableModel<TreeFileDataNode> {
 26  
 
 27  
     /**
 28  
      * The uploadPolicy contains all current parameter, including the FileDataParam
 29  
      */
 30  266
     UploadPolicy uploadPolicy = null;
 31  
 
 32  
     /**
 33  
      * The column names, as displayed on the applet. They are not real final values, as they are translated: we need to
 34  
      * have an uploadPolicy for this translation, and the uploadPolicy is 'given' to the constructor.
 35  
      */
 36  
     final static String COL_NAME = "colName";
 37  
 
 38  
     final static String COL_SIZE = "colSize";
 39  
 
 40  
     final static String COL_DIRECTORY = "colDirectory";
 41  
 
 42  
     final static String COL_MODIFIED = "colModified";
 43  
 
 44  
     /** The localized column name, for the file name */
 45  266
     String colName = null;
 46  
 
 47  
     /** The localized column name, for the file size */
 48  266
     String colSize = null;
 49  
 
 50  
     /** The localized column name, for the file directory */
 51  266
     String colDirectory = null;
 52  
 
 53  
     /** The localized column name, for the file last modification date */
 54  266
     String colModified = null;
 55  
 
 56  266
     String[] columnNames = null;
 57  
 
 58  
     /**
 59  
      * This array indicates, for each column, the percentage of the available width it should use. It's initialized in
 60  
      * the constructor of this class.
 61  
      * 
 62  
      * @see #getColumnSize(int)
 63  
      */
 64  266
     int[] columnSizePercentage = null;
 65  
 
 66  
     /**
 67  
      * Indicates whether each column is editable or not. Only the check box should be editable.
 68  
      */
 69  266
     boolean[] columnEditable = null;
 70  
 
 71  266
     Class<?> columnClasses[] = null;
 72  
 
 73  
     public FileDataTreeViewModel(UploadPolicy uploadPolicy, FilePanelFlatDataModel2 flatModel) {
 74  
         // The models are unknown now. They will be set later.
 75  266
         super(uploadPolicy, new RootNode(uploadPolicy, null, flatModel));
 76  
 
 77  266
         this.uploadPolicy = uploadPolicy;
 78  
 
 79  
         // Initialization for column name
 80  266
         colName = this.uploadPolicy.getLocalizedString(COL_NAME);
 81  266
         colSize = this.uploadPolicy.getLocalizedString(COL_SIZE);
 82  266
         colDirectory = this.uploadPolicy.getLocalizedString(COL_DIRECTORY);
 83  266
         colModified = this.uploadPolicy.getLocalizedString(COL_MODIFIED);
 84  266
         this.columnNames = new String[] {
 85  
                 colName, colSize, colDirectory, colModified, ""
 86  
         };
 87  
 
 88  
         // Initial size (before percentage) was: 150, 75, 199, 130, 75
 89  266
         this.columnSizePercentage = new int[] {
 90  
                 50, 17, 15, 15, 3
 91  
         };
 92  
 
 93  266
         this.columnClasses = new Class[] {
 94  
                 MyTreeTableModel.class, Long.class, String.class, Date.class, Boolean.class
 95  
         };
 96  
 
 97  
         // Initial size (before percentage) was: 150, 75, 199, 130, 75
 98  266
         this.columnEditable = new boolean[] {
 99  
                 true, false, false, false, true
 100  
         };
 101  266
     }
 102  
 
 103  
     /** {@inheritDoc} */
 104  
     public int getColumnCount() {
 105  241
         return columnNames.length;
 106  
     }
 107  
 
 108  
     /** {@inheritDoc} */
 109  
     public String getColumnName(int column) {
 110  235
         return columnNames[column];
 111  
     }
 112  
 
 113  
     /** {@inheritDoc} */
 114  
     public int getColumnSizePercentage(int col) {
 115  5
         return this.columnSizePercentage[col];
 116  
     }
 117  
 
 118  
     /** {@inheritDoc} */
 119  
     public Class<?> getColumnClass(int column) {
 120  5
         return columnClasses[column];
 121  
     }
 122  
 
 123  
     /** {@inheritDoc} */
 124  
     public Object getValueAt(TreeFileDataNode node, int column) {
 125  31
         if (node != null) {
 126  30
             String columnName = getColumnName(column);
 127  
             // Don't know if it will be useful, but the switch below allows the
 128  
             // column to be in any order.
 129  30
             if (columnName.equals(colName)) {
 130  6
                 return node.getFileName();
 131  24
             } else if (columnName.equals(colSize)) {
 132  6
                 return Long.valueOf(node.getFileLength());
 133  18
             } else if (columnName.equals(colDirectory)) {
 134  6
                 return node.getDirectory();
 135  12
             } else if (columnName.equals(colModified)) {
 136  6
                 return node.getLastModified();
 137  6
             } else if (columnName.equals("")) {
 138  6
                 return node.getUploadFlag();
 139  
             } else {
 140  0
                 this.uploadPolicy.displayErr("Unknown column in " + this.getClass().getName() + ": " + columnName);
 141  0
                 return null;
 142  
             }
 143  
         } else {
 144  1
             return null;
 145  
         }
 146  
     }
 147  
 
 148  
     /** @see TableModel#isCellEditable(int, int) */
 149  
     public boolean isCellEditable(TreeFileDataNode node, int column) {
 150  5
         return columnEditable[column];
 151  
     }
 152  
 
 153  
     /** @see TableModel#setValueAt(Object, int, int) */
 154  
     public void setValueAt(Object aValue, TreeFileDataNode node, int col) {
 155  6
         if (!columnEditable[col]) {
 156  3
             this.uploadPolicy.displayWarn(this.getClass().getName() + ".setValueAt: no action");
 157  
         } else {
 158  3
             if (!(aValue instanceof Boolean)) {
 159  2
                 this.uploadPolicy.displayErr("Internal error in " + this.getClass().getName()
 160  1
                         + ": aValue should be a Boolean but is a " + aValue.getClass().getName());
 161  
             } else {
 162  2
                 node.setUploadFlag((Boolean) aValue);
 163  
             }
 164  
         }
 165  5
     }
 166  
 
 167  
     /**
 168  
      * Returns the {@link TreePath} for the given {@link File}. This TreePath is basically the array of
 169  
      * {@link TreeFileDataNode}, representing the given file. the root path if the filename for the {@link RootNode},
 170  
      * that is: the empty String: ""
 171  
      * 
 172  
      * @param fileRoot The File we want the path for. It may be the root, a folder, leaf...
 173  
      * @return The TreePath for this file, or null if this file doesn't exist in the existing hierarchy. public TreePath
 174  
      *         getTreePath(TreeFileDataNode fileData) { TreeFileDataNode parent = (TreeFileDataNode)
 175  
      *         fileData.getParent(); if (parent == null) { TreeFileDataNode[] path = (TreeFileDataNode[])
 176  
      *         (Array.newInstance(TreeFileDataNode.class, 2)); path[0] = absoluteRoot; path[1] = ((FolderNode)
 177  
      *         absoluteRoot).getChild(fileData.getFileName()); return new TreePath(path); } else { TreePath
 178  
      *         treePathParent = getTreePath(parent); if (treePathParent == null) { // The parent is not in the file
 179  
      *         hierarchy, so this file is not either. return null; } else { FolderNode folderNodeParent = (FolderNode)
 180  
      *         treePathParent.getLastPathComponent(); TreeFileDataNode tfdn =
 181  
      *         folderNodeParent.getChild(fileData.getFileName()); if (tfdn == null) { // This file doesn't exist in the
 182  
      *         hierarchy. return null; } else { return treePathParent.pathByAddingChild(tfdn); } } } }
 183  
      */
 184  
 
 185  
     /**
 186  
      * Returns the {@link TreePath} for the given {@link File}. This TreePath is basically the array of
 187  
      * {@link TreeFileDataNode}, representing the given file. the root path if the filename for the {@link RootNode},
 188  
      * that is: the empty String: ""
 189  
      * 
 190  
      * @param fileRoot The File we want the path for. It may be the root, a folder, leaf... If the given file is null,
 191  
      *            the returned {@link TreePath} is a one level {@link TreePath}, containing only the absolute root of
 192  
      *            the tree view.
 193  
      * @param createIntermediateNode If true, all missing intermediate nodes are created. If false, no node are created.
 194  
      *            In this last case, the returned {@link TreePath} is null, if one or mode nodes are missing.
 195  
      * @return The TreePath for this file, or null if this file doesn't exist in the existing hierarchy.
 196  
      * @throws JUploadExceptionStopAddingFiles
 197  
      */
 198  
     public TreePath getTreePathFromFile(File file, boolean createIntermediateNode)
 199  
             throws JUploadExceptionStopAddingFiles {
 200  739
         if (this.uploadPolicy.getFileListViewMode() != FilePanel.FileListViewMode.FLAT
 201  1
                 && this.uploadPolicy.getFileListViewMode() != FilePanel.FileListViewMode.TREE_VIEW) {
 202  1
             throw new IllegalStateException(this.getClass().getName()
 203  
                     + ".getTreePathFromFile(File) may not be called when the ListViewMode is in "
 204  1
                     + this.uploadPolicy.getFileListViewMode() + " mode");
 205  
         }
 206  738
         if (file == null) {
 207  72
             return new TreePath(absoluteRoot);
 208  
         } else {
 209  666
             TreePath parentTreePath = getTreePathFromFile(file.getParentFile(), createIntermediateNode);
 210  666
             if (parentTreePath == null) {
 211  
                 // At least one node is missing. We can't build the TreePath
 212  23
                 return null;
 213  
             } else {
 214  
                 // The parent TreePath should finish by a folder ... as it's our parent !
 215  643
                 FolderNode parentNode = (FolderNode) parentTreePath.getLastPathComponent();
 216  643
                 TreeFileDataNode node = parentNode.getChild(file);
 217  
 
 218  
                 // If file is not a child of the node for the parent file, we may have to create a new Node.
 219  643
                 if (node == null && createIntermediateNode) {
 220  304
                     node = parentNode.addChild(file);
 221  
                 }
 222  
 
 223  
                 // If there is no node for our file ... there is no valid TreePath
 224  643
                 if (node == null) {
 225  4
                     return null;
 226  
                 } else {
 227  639
                     return parentTreePath.pathByAddingChild(node);
 228  
                 }
 229  
             }/*
 230  
               * File parent = file.getParentFile(); if (parent == null) { TreeFileDataNode[] path = (TreeFileDataNode[])
 231  
               * (Array.newInstance(TreeFileDataNode.class, 2)); path[0] = absoluteRoot; path[1] = ((FolderNode)
 232  
               * absoluteRoot).getChild(file); // if the root doesn't return new TreePath(path); } else { TreePath
 233  
               * treePathParent = getTreePathFromFile(parent, createIntermediateNode); if (treePathParent == null) { //
 234  
               * The parent is not in the file hierarchy, so this file is not either. return null; } else { FolderNode
 235  
               * folderNodeParent = (FolderNode) treePathParent.getLastPathComponent(); TreeFileDataNode tfdn =
 236  
               * folderNodeParent.getChild(file); if (tfdn == null) { // This file doesn't exist in the hierarchy. return
 237  
               * null; } else { return treePathParent.pathByAddingChild(tfdn); } } }
 238  
               */
 239  
         }// if (file == null)
 240  
     }
 241  
 
 242  
     /**
 243  
      * Returns the node corresponding to the given treePath, or null if this node is'nt found, when crawling the
 244  
      * hierarchy behind {@link #absoluteRoot}.
 245  
      * 
 246  
      * @param treePath A {@link TreePath} made of String. If it's made of String, each represents a filename. If it's a
 247  
      *            {@link TreePath} made of TreeFileDataNode, this method works, but it's much quicker to just use
 248  
      *            {@link TreePath#getLastPathComponent()} instead of this method.
 249  
      * @return TreeFileDataNode getNode(TreePath treePath) { TreePath parent = treePath.getParentPath(); if (parent ==
 250  
      *         null) { return absoluteRoot; } else { TreeFileDataNode parentNode = getNode(parent); return
 251  
      *         (TreeFileDataNode) parentNode.getChild((String) treePath.getLastPathComponent()); } }
 252  
      */
 253  
 
 254  
     /**
 255  
      * This method returns
 256  
      * 
 257  
      * @param file
 258  
      * @return
 259  
      * @throws JUploadExceptionStopAddingFiles public FolderNode getFolderNodeForNewFile(File file) throws
 260  
      *             JUploadExceptionStopAddingFiles { return getFolderNodeForNewFile(file.getParentFile(), null); }
 261  
      */
 262  
 
 263  
     /**
 264  
      * This method searches in the hierarchy of files and folder to upload, the node which contains this file. If this
 265  
      * node doesn't exist, it is first created and attached into the hierarchy.
 266  
      * 
 267  
      * @param o A File or Folder. If o is a file, it will just be added. If o is a folder, it will be added, including
 268  
      *            all its content (child, grand-child...)
 269  
      * @return The number of files added to the hierarchy. Folders are not counted.
 270  
      * @throws JUploadExceptionStopAddingFiles When an exception occurs
 271  
      * @throws NullPointerException When o is null
 272  
      * @throws IllegalArgumentException When o is not a {@link File}
 273  
      * @see MyAbstractTreeTableModel
 274  
      */
 275  
     public int attachObject(Object o) throws NullPointerException, IllegalArgumentException,
 276  
             JUploadExceptionStopAddingFiles {
 277  26
         if (o == null) {
 278  0
             throw new NullPointerException(this.getClass().getName() + " has been called with a null parameter");
 279  26
         } else if (!(o instanceof File)) {
 280  1
             throw new IllegalArgumentException(this.getClass().getName() + " has been called with a "
 281  1
                     + o.getClass().getName() + ". It must be a File");
 282  
         }
 283  25
         File file = (File) o;
 284  
 
 285  25
         FolderNode parentNode = null;
 286  1
         switch (uploadPolicy.getFileListViewMode()) {
 287  
             case FLAT:
 288  
             case TREE_VIEW:
 289  
                 // We're mapped to the file system, we need to find the parent for this file.
 290  25
                 if (file.getParentFile() != null) {
 291  25
                     parentNode = (FolderNode) getTreePathFromFile(file.getParentFile(), true).getLastPathComponent();
 292  
                 } else {
 293  0
                     parentNode = (FolderNode) absoluteRoot;
 294  
                 }
 295  0
                 break;
 296  
             case INDEPENDENT_TREE_VIEW:
 297  
                 // Otherwise, it's just a new child of the root.
 298  0
                 parentNode = (FolderNode) absoluteRoot;
 299  
         }
 300  
 
 301  25
         if (parentNode == null) {
 302  0
             throw new IllegalArgumentException("Root not found for file " + file.getAbsolutePath());
 303  
         }
 304  
 
 305  25
         return parentNode.addChildAndDescendants(file);
 306  
     }
 307  
 
 308  
     /** {@inheritDoc} */
 309  
     public TreePath getTreePathForObject(Object o) {
 310  11
         if (o != null && !(o instanceof File)) {
 311  1
             throw new IllegalArgumentException(this.getClass().getName() + " has been called with a "
 312  1
                     + o.getClass().getName() + ". It must be a File");
 313  
         }
 314  
         try {
 315  10
             return getTreePathFromFile((File) o, false);
 316  0
         } catch (JUploadExceptionStopAddingFiles e) {
 317  0
             throw new IllegalStateException(e.getMessage(), e);
 318  
         }
 319  
     }
 320  
 
 321  
 }