Source for javax.swing.filechooser.FileSystemView

   1: /* FileSystemView.java --
   2:    Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath 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 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: package javax.swing.filechooser;
  39: 
  40: import java.io.File;
  41: import java.io.IOException;
  42: import java.util.ArrayList;
  43: 
  44: import javax.swing.Icon;
  45: import javax.swing.JFileChooser;
  46: 
  47: 
  48: /**
  49:  * The base class providing a view of the file system for use by the 
  50:  * {@link JFileChooser} component.
  51:  */
  52: public abstract class FileSystemView
  53: {
  54:   /** The instance returned by {@link #getFileSystemView()}. */
  55:   private static FileSystemView defaultFileSystemView;
  56:   
  57:   /**
  58:    * Creates a new file object with the given name in the specified directory.
  59:    *
  60:    * @param dir  the directory (<code>null</code> permitted).
  61:    * @param filename  the file name.
  62:    *
  63:    * @return A new file object.
  64:    */
  65:   public File createFileObject(File dir, String filename)
  66:   {
  67:     return new File(dir, filename);
  68:   }
  69: 
  70:   /**
  71:    * Creates a new file object from the specified path.
  72:    *
  73:    * @param path  the path.
  74:    *
  75:    * @return A new file object.
  76:    */
  77:   public File createFileObject(String path)
  78:   {
  79:     File f = new File(path);
  80:     if (isFileSystemRoot(f))
  81:       f = this.createFileSystemRoot(f);
  82:     return f;
  83:   }
  84: 
  85:   /**
  86:    * DOCUMENT ME!
  87:    *
  88:    * @param f DOCUMENT ME!
  89:    *
  90:    * @return DOCUMENT ME!
  91:    */
  92:   protected File createFileSystemRoot(File f)
  93:   {
  94:     File[] roots = File.listRoots();
  95:     if (roots == null)
  96:       return null;
  97:     return roots[0];
  98:   }
  99: 
 100:   /**
 101:    * Creates a new folder with a unique name in the specified directory and
 102:    * returns a {@link File} object representing the new directory.
 103:    *
 104:    * @param containingDir  the directory to contain the new folder 
 105:    *                       (<code>null</code> not permitted).
 106:    *
 107:    * @return A {@link File} object representing the new directory.
 108:    *
 109:    * @throws IOException if an exception occurs while creating the new 
 110:    *                     directory.
 111:    */
 112:   public abstract File createNewFolder(File containingDir)
 113:                                 throws IOException;
 114: 
 115:   /**
 116:    * DOCUMENT ME!
 117:    *
 118:    * @param parent DOCUMENT ME!
 119:    * @param fileName DOCUMENT ME!
 120:    *
 121:    * @return DOCUMENT ME!
 122:    */
 123:   public File getChild(File parent, String fileName)
 124:   {
 125:     // FIXME: Handle the case when parent and child are special folders.
 126:     return new File(parent, fileName);
 127:   }
 128: 
 129:   /**
 130:    * Returns the default directory.
 131:    *
 132:    * @return The default directory.
 133:    */
 134:   public File getDefaultDirectory()
 135:   {
 136:     return getHomeDirectory();
 137:   }
 138: 
 139:   /**
 140:    * Returns an array containing the files in the given directory.  The 
 141:    * <code>useFileHiding</code> controls whether or not hidden files are 
 142:    * included in the result.
 143:    *
 144:    * @param dir  the directory (if <code>null</code>
 145:    * @param useFileHiding  a flag that controls whether or not hidden files are
 146:    *                       included in the result (pass in <code>true</code> to
 147:    *                       exclude hidden files).
 148:    *
 149:    * @return The files in the given directory (possibly <code>null</code>).
 150:    */
 151:   public File[] getFiles(File dir, boolean useFileHiding)
 152:   {
 153:     if (dir == null || dir.listFiles() == null)
 154:       return null;
 155:     File[] files = dir.listFiles();
 156:     if (! useFileHiding)
 157:       return files;
 158:     ArrayList trim = new ArrayList();
 159:     for (int i = 0; i < files.length; i++)
 160:       if (! files[i].isHidden())
 161:     trim.add(files[i]);
 162:     File[] value = (File[]) trim.toArray(new File[trim.size()]);
 163:     return value;
 164:   }
 165: 
 166:   /**
 167:    * Returns a default {@link FileSystemView} appropriate for the platform.
 168:    *
 169:    * @return A default {@link FileSystemView} appropriate for the platform.
 170:    */
 171:   public static FileSystemView getFileSystemView()
 172:   {
 173:     if (defaultFileSystemView == null)
 174:       {
 175:         // FIXME: We need to support other file systems too.
 176:         defaultFileSystemView = new UnixFileSystemView();
 177:       }
 178:     return defaultFileSystemView;
 179:   }
 180: 
 181:   /**
 182:    * Returns the home directory for the current user.
 183:    *
 184:    * @return The home directory for the current user.
 185:    */
 186:   public File getHomeDirectory()
 187:   {
 188:     return createFileObject(System.getProperty("user.home"));
 189:   }
 190: 
 191:   /**
 192:    * Returns the parent directory for the given file/directory.
 193:    *
 194:    * @param f  the file/directory.
 195:    *
 196:    * @return The parent directory (or <code>null</code> if there is no parent
 197:    *         directory).
 198:    */
 199:   public File getParentDirectory(File f)
 200:   {
 201:     if (f == null)
 202:       return null;
 203:     return f.getParentFile();
 204:   }
 205: 
 206:   /**
 207:    * Returns an array containing the file system roots.  On Unix-like platforms,
 208:    * this array will contain just a single item ("/"), while other platforms
 209:    * may return multiple roots.
 210:    * <p>
 211:    * This method is implemented to return <code>null</code>, subclasses must
 212:    * override this method.
 213:    *
 214:    * @return An array containing the file system roots.
 215:    */
 216:   public File[] getRoots()
 217:   {
 218:     // subclass
 219:     return null;
 220:   }
 221: 
 222:   /**
 223:    * Returns the name of a file as it would be displayed by the underlying 
 224:    * system.
 225:    *
 226:    * @param f  the file.
 227:    *
 228:    * @return the name of a file as it would be displayed by the underlying 
 229:    *         system
 230:    *
 231:    * @specnote The specification suggests that the information here is
 232:    *           fetched from a ShellFolder class. This seems to be a non public
 233:    *           private file handling class. We simply return File.getName()
 234:    *           here and leave special handling to subclasses.
 235:    */
 236:   public String getSystemDisplayName(File f)
 237:   {
 238:     String name = null;
 239:     if (f != null)
 240:       name = f.getName();
 241:     return name;
 242:   }
 243: 
 244:   /**
 245:    * Returns the icon that would be displayed for the given file by the 
 246:    * underlying system.  This implementation returns <code>null</code>, 
 247:    * subclasses must override.
 248:    *
 249:    * @param f  the file.
 250:    *
 251:    * @return <code>null</code>.
 252:    */
 253:   public Icon getSystemIcon(File f)
 254:   {
 255:     return null;
 256:   }
 257: 
 258:   /**
 259:    * Returns the type description of a file that would be displayed by the 
 260:    * underlying system.  This implementation returns <code>null</code>, 
 261:    * subclasses must override.
 262:    *
 263:    * @param f  the file.
 264:    *
 265:    * @return <code>null</code>.
 266:    */
 267:   public String getSystemTypeDescription(File f)
 268:   {
 269:     return null;
 270:   }
 271: 
 272:   /**
 273:    * DOCUMENT ME!
 274:    *
 275:    * @param dir DOCUMENT ME!
 276:    *
 277:    * @return DOCUMENT ME!
 278:    */
 279:   public boolean isComputerNode(File dir)
 280:   {
 281:     return false;
 282:   }
 283: 
 284:   /**
 285:    * Returns <code>true</code> if the given directory represents a disk 
 286:    * drive, and <code>false</code> otherwise.  This default implementation
 287:    * always returns <code>false</code>.
 288:    *
 289:    * @param dir  the directory.
 290:    *
 291:    * @return <code>false</code>.
 292:    */
 293:   public boolean isDrive(File dir)
 294:   {
 295:     return false;
 296:   }
 297: 
 298:   /**
 299:    * Returns <code>true</code> if <code>f</code> is a file or directory, and
 300:    * <code>false</code> otherwise.
 301:    *
 302:    * @param f  the file/directory.
 303:    *
 304:    * @return <code>true</code> if <code>f</code> is a file or directory, and
 305:    * <code>false</code> otherwise.
 306:    */
 307:   public boolean isFileSystem(File f)
 308:   {
 309:     return (f.isFile() || f.isDirectory());
 310:   }
 311: 
 312:   /**
 313:    * Returns <code>true</code> if the given directory is a file system root,
 314:    * and <code>false</code> otherwise.
 315:    *
 316:    * @param dir  the directory.
 317:    *
 318:    * @return <code>true</code> if the given directory is a file system root,
 319:    *          and <code>false</code> otherwise.
 320:    */
 321:   public boolean isFileSystemRoot(File dir)
 322:   {
 323:     File[] roots = File.listRoots();
 324:     if (roots == null || dir == null)
 325:       return false;
 326:     String filename = dir.getAbsolutePath();
 327:     for (int i = 0; i < roots.length; i++)
 328:       if (roots[i].getAbsolutePath().equals(filename))
 329:     return true;
 330:     return false;
 331:   }
 332: 
 333:   /**
 334:    * Returns <code>true</code> if the given directory represents a floppy 
 335:    * drive, and <code>false</code> otherwise.  This default implementation
 336:    * always returns <code>false</code>.
 337:    *
 338:    * @param dir  the directory.
 339:    *
 340:    * @return <code>false</code>.
 341:    */
 342:   public boolean isFloppyDrive(File dir)
 343:   {
 344:     return false;
 345:   }
 346: 
 347:   /**
 348:    * Returns <code>true</code> if the given file is hidden, and 
 349:    * <code>false</code> otherwise.
 350:    *
 351:    * @param f  the file.
 352:    *
 353:    * @return <code>true</code> if the given file is hidden, and 
 354:    *         <code>false</code> otherwise.
 355:    */
 356:   public boolean isHiddenFile(File f)
 357:   {
 358:     return f.isHidden();
 359:   }
 360: 
 361:   /**
 362:    * Returns <code>true</code> if <code>folder</code> is the parent of 
 363:    * <code>file</code>, and <code>false</code> otherwise.
 364:    *
 365:    * @param folder  the folder (<code>null</code> not permitted).
 366:    * @param file  the file (<code>null</code> not permitted).
 367:    *
 368:    * @return <code>true</code> if <code>folder</code> is the parent of 
 369:    *         <code>file</code>, and <code>false</code> otherwise.
 370:    */
 371:   public boolean isParent(File folder, File file)
 372:   {
 373:     File parent = file.getParentFile();
 374:     if (parent == null)
 375:       return false;
 376:     return folder.equals(parent);
 377:   }
 378: 
 379:   /**
 380:    * DOCUMENT ME!
 381:    *
 382:    * @param f DOCUMENT ME!
 383:    *
 384:    * @return DOCUMENT ME!
 385:    */
 386:   public boolean isRoot(File f)
 387:   {
 388:     // These are not file system roots.
 389:     return false;
 390:   }
 391: 
 392:   /**
 393:    * Returns <code>true</code> if the file is traversable, and 
 394:    * <code>false</code> otherwise.  Here, all directories are considered
 395:    * traversable, and files are considered non-traversable. 
 396:    *
 397:    * @param f  the file or directory (<code>null</code> not permitted).
 398:    *
 399:    * @return <code>true</code> if the file is traversable, and 
 400:    *         <code>false</code> otherwise.
 401:    */
 402:   public Boolean isTraversable(File f)
 403:   {
 404:     // Tested. A directory where the user has no permission to rwx is still
 405:     // traversable. (No files are listed when you traverse the directory)
 406:     // My best guess is that as long as it's a directory, the file is
 407:     // traversable.
 408:     return Boolean.valueOf(f.isDirectory());
 409:   }
 410: }