001 /* Copyright 2000, 2001, Compaq Computer Corporation */ 002 003 package javafe.genericfile; 004 005 import javafe.Tool; 006 import java.io.File; 007 import java.io.FileInputStream; 008 import java.io.IOException; 009 import java.io.InputStream; 010 011 /** 012 * A NormalGenericFile represents a normal file ({@link java.io.File}) 013 * as a GenericFile. 014 */ 015 016 public class NormalGenericFile extends File implements GenericFile { 017 private static final long serialVersionUID = 4996822143630105487L; 018 019 /** 020 * Create a NormalGenericFile to represent an existing {@link 021 * File}. 022 */ 023 //@ requires underlyingFile != null; 024 025 public NormalGenericFile(File underlyingFile) { 026 super(underlyingFile.getPath()); 027 } 028 029 /** 030 * Create a NormalGenericFile from a filename. 031 */ 032 //@ requires name != null; 033 public NormalGenericFile(String name) { 034 super(name); 035 } 036 037 /** 038 * @return a name that uniquely identifies us to the user. 039 * 040 * Warning: the result may not be a conventional filename or use 041 * the system separators. 042 */ 043 public String getHumanName() { 044 String result = null; 045 if (Tool.options.testMode) 046 result = this.toString().replace('/', '|').replace('\\', '|'); 047 else 048 result = this.toString(); 049 return result; 050 } 051 052 /** 053 * @return a String that canonically represents the identity of 054 * our underlying file. 055 * 056 * This function must be defined such that if two GenericFiles 057 * return non-null canonical ID's then the IDs are the same 058 * (modulo .equals) => the GenericFiles represent the same 059 * underlying file. Ideally, under normal circumstances, the => 060 * is actually a <=>. 061 * 062 * This function should only return null in exceptional cases, 063 * such as when an I/O error in the underlying storage media 064 * prevents construction of a canonical ID. 065 * 066 * Convention: Canonical IDs start with <X> where X is the 067 * fully-qualified name of the class that mediates I/O to the 068 * underlying file. E.g., java.io.File for a normal disk file. 069 */ 070 public String getCanonicalID() { 071 try { 072 return "<java.io.File>" + this.getCanonicalPath(); 073 } catch (IOException e) { 074 return null; 075 } 076 } 077 078 /** 079 * @return our local name, the name that distinguishes us within 080 * the directory that contains us. 081 * 082 * E.g., "/a/b/c" has local name "c", "/e/r/" has local name "r", and 083 * "/" has local name "". (assuming "/" is the separator char) 084 */ 085 public String getLocalName() { return getName(); } 086 087 /** 088 * Open the file we represent as an {@link InputStream}. 089 * 090 * @exception IOException May be thrown for many reasons, 091 * including no such file and read permission denied. 092 */ 093 public InputStream getInputStream() throws IOException { 094 return new FileInputStream(this); 095 } 096 097 /** 098 * @return a GenericFile that describes the file in the same 099 * "directory" as us that has the local name <code>n</code>. No 100 * attempt is made to verify whether or not that file exists. In 101 * cases where the notion of "containing directory" makes no sense 102 * (e.g., streams or root directories), null is returned. 103 */ 104 public GenericFile getSibling(String n) { 105 String dir = super.getParent(); 106 if (dir==null) 107 return null; 108 109 return new NormalGenericFile(dir + separator + n); 110 } 111 }