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(/*@non_null*/String n) {
105 String dir = super.getParent();
106 if (dir==null)
107 return null;
108
109 return new NormalGenericFile(dir + separator + n);
110 }
111 }