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:         if (File.separator.equals("/"))
 176:           defaultFileSystemView = new UnixFileSystemView();
 177:         // FIXME: need to implement additional views
 178:         // else if (File.Separator.equals("\"))
 179:         //   return new Win32FileSystemView();
 180:         // else 
 181:         //   return new GenericFileSystemView();
 182:       }
 183:     return defaultFileSystemView;
 184:   }
 185: 
 186:   /**
 187:    * Returns the home directory for the current user.
 188:    *
 189:    * @return The home directory for the current user.
 190:    */
 191:   public File getHomeDirectory()
 192:   {
 193:     return createFileObject(System.getProperty("user.home"));
 194:   }
 195: 
 196:   /**
 197:    * Returns the parent directory for the given file/directory.
 198:    *
 199:    * @param f  the file/directory.
 200:    *
 201:    * @return The parent directory (or <code>null</code> if there is no parent
 202:    *         directory).
 203:    */
 204:   public File getParentDirectory(File f)
 205:   {
 206:     if (f == null)
 207:       return null;
 208:     return f.getParentFile();
 209:   }
 210: 
 211:   /**
 212:    * Returns an array containing the file system roots.  On Unix-like platforms,
 213:    * this array will contain just a single item ("/"), while other platforms
 214:    * may return multiple roots.
 215:    * <p>
 216:    * This method is implemented to return <code>null</code>, subclasses must
 217:    * override this method.
 218:    *
 219:    * @return An array containing the file system roots.
 220:    */
 221:   public File[] getRoots()
 222:   {
 223:     // subclass
 224:     return null;
 225:   }
 226: 
 227:   /**
 228:    * Returns the name of a file as it would be displayed by the underlying 
 229:    * system.
 230:    *
 231:    * @param f  the file.
 232:    *
 233:    * @return the name of a file as it would be displayed by the underlying 
 234:    *         system
 235:    *
 236:    * @specnote The specification suggests that the information here is
 237:    *           fetched from a ShellFolder class. This seems to be a non public
 238:    *           private file handling class. We simply return File.getName()
 239:    *           here and leave special handling to subclasses.
 240:    */
 241:   public String getSystemDisplayName(File f)
 242:   {
 243:     String name = null;
 244:     if (f != null)
 245:       name = f.getName();
 246:     return name;
 247:   }
 248: 
 249:   /**
 250:    * Returns the icon that would be displayed for the given file by the 
 251:    * underlying system.  This implementation returns <code>null</code>, 
 252:    * subclasses must override.
 253:    *
 254:    * @param f  the file.
 255:    *
 256:    * @return <code>null</code>.
 257:    */
 258:   public Icon getSystemIcon(File f)
 259:   {
 260:     return null;
 261:   }
 262: 
 263:   /**
 264:    * Returns the type description of a file that would be displayed by the 
 265:    * underlying system.  This implementation returns <code>null</code>, 
 266:    * subclasses must override.
 267:    *
 268:    * @param f  the file.
 269:    *
 270:    * @return <code>null</code>.
 271:    */
 272:   public String getSystemTypeDescription(File f)
 273:   {
 274:     return null;
 275:   }
 276: 
 277:   /**
 278:    * DOCUMENT ME!
 279:    *
 280:    * @param dir DOCUMENT ME!
 281:    *
 282:    * @return DOCUMENT ME!
 283:    */
 284:   public boolean isComputerNode(File dir)
 285:   {
 286:     return false;
 287:   }
 288: 
 289:   /**
 290:    * Returns <code>true</code> if the given directory represents a disk 
 291:    * drive, and <code>false</code> otherwise.  This default implementation
 292:    * always returns <code>false</code>.
 293:    *
 294:    * @param dir  the directory.
 295:    *
 296:    * @return <code>false</code>.
 297:    */
 298:   public boolean isDrive(File dir)
 299:   {
 300:     return false;
 301:   }
 302: 
 303:   /**
 304:    * Returns <code>true</code> if <code>f</code> is a file or directory, and
 305:    * <code>false</code> otherwise.
 306:    *
 307:    * @param f  the file/directory.
 308:    *
 309:    * @return <code>true</code> if <code>f</code> is a file or directory, and
 310:    * <code>false</code> otherwise.
 311:    */
 312:   public boolean isFileSystem(File f)
 313:   {
 314:     return (f.isFile() || f.isDirectory());
 315:   }
 316: 
 317:   /**
 318:    * Returns <code>true</code> if the given directory is a file system root,
 319:    * and <code>false</code> otherwise.
 320:    *
 321:    * @param dir  the directory.
 322:    *
 323:    * @return <code>true</code> if the given directory is a file system root,
 324:    *          and <code>false</code> otherwise.
 325:    */
 326:   public boolean isFileSystemRoot(File dir)
 327:   {
 328:     File[] roots = File.listRoots();
 329:     if (roots == null || dir == null)
 330:       return false;
 331:     String filename = dir.getAbsolutePath();
 332:     for (int i = 0; i < roots.length; i++)
 333:       if (roots[i].getAbsolutePath().equals(filename))
 334:     return true;
 335:     return false;
 336:   }
 337: 
 338:   /**
 339:    * Returns <code>true</code> if the given directory represents a floppy 
 340:    * drive, and <code>false</code> otherwise.  This default implementation
 341:    * always returns <code>false</code>.
 342:    *
 343:    * @param dir  the directory.
 344:    *
 345:    * @return <code>false</code>.
 346:    */
 347:   public boolean isFloppyDrive(File dir)
 348:   {
 349:     return false;
 350:   }
 351: 
 352:   /**
 353:    * Returns <code>true</code> if the given file is hidden, and 
 354:    * <code>false</code> otherwise.
 355:    *
 356:    * @param f  the file.
 357:    *
 358:    * @return <code>true</code> if the given file is hidden, and 
 359:    *         <code>false</code> otherwise.
 360:    */
 361:   public boolean isHiddenFile(File f)
 362:   {
 363:     return f.isHidden();
 364:   }
 365: 
 366:   /**
 367:    * Returns <code>true</code> if <code>folder</code> is the parent of 
 368:    * <code>file</code>, and <code>false</code> otherwise.
 369:    *
 370:    * @param folder  the folder (<code>null</code> not permitted).
 371:    * @param file  the file (<code>null</code> not permitted).
 372:    *
 373:    * @return <code>true</code> if <code>folder</code> is the parent of 
 374:    *         <code>file</code>, and <code>false</code> otherwise.
 375:    */
 376:   public boolean isParent(File folder, File file)
 377:   {
 378:     File parent = file.getParentFile();
 379:     if (parent == null)
 380:       return false;
 381:     return folder.equals(parent);
 382:   }
 383: 
 384:   /**
 385:    * DOCUMENT ME!
 386:    *
 387:    * @param f DOCUMENT ME!
 388:    *
 389:    * @return DOCUMENT ME!
 390:    */
 391:   public boolean isRoot(File f)
 392:   {
 393:     // These are not file system roots.
 394:     return false;
 395:   }
 396: 
 397:   /**
 398:    * Returns <code>true</code> if the file is traversable, and 
 399:    * <code>false</code> otherwise.  Here, all directories are considered
 400:    * traversable, and files are considered non-traversable. 
 401:    *
 402:    * @param f  the file or directory (<code>null</code> not permitted).
 403:    *
 404:    * @return <code>true</code> if the file is traversable, and 
 405:    *         <code>false</code> otherwise.
 406:    */
 407:   public Boolean isTraversable(File f)
 408:   {
 409:     // Tested. A directory where the user has no permission to rwx is still
 410:     // traversable. (No files are listed when you traverse the directory)
 411:     // My best guess is that as long as it's a directory, the file is
 412:     // traversable.
 413:     return Boolean.valueOf(f.isDirectory());
 414:   }
 415: }