summaryrefslogtreecommitdiff
path: root/sources/scala/tools/util/PlainFile.java
blob: aee80cb52f4491f984346b5c35ccec6aada3029e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*     ____ ____  ____ ____  ______                                     *\
**    / __// __ \/ __// __ \/ ____/    SOcos COmpiles Scala             **
**  __\_ \/ /_/ / /__/ /_/ /\_ \       (c) 2002, LAMP/EPFL              **
** /_____/\____/\___/\____/____/                                        **
\*                                                                      */

// $Id$

package scala.tools.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;

/** This class implements an abstract file backed by a File. */
public class PlainFile extends AbstractFile {

    //########################################################################
    // Public Factories

    /** Returns "fromFile(new File(path))". */
    public static AbstractFile fromPath(String path) {
        return fromFile(new File(path));
    }

    /**
     * If the specified File exists, returns an abstract file backed
     * by it. Otherwise, returns null.
     */
    public static AbstractFile fromFile(File file) {
        return file.exists() ? new PlainFile(file) : null;
    }

    //########################################################################
    // Private Fields

    /** The underlying File */
    private final File file;

    //########################################################################
    // Protected Constructors

    /** Initializes this instance with the specified File. */
    protected PlainFile(File file) {
        this.file = file;
        assert file != null;
    }

    //########################################################################
    // Public Methods

    /** Returns the name of this abstract file. */
    public String getName() {
        return file.getName();
    }

    /** Returns the path of this abstract file. */
    public String getPath() {
        return file.getPath();
    }

    /** Returns the underlying File if any and null otherwise. */
    public File getFile() {
        return file;
    }


    public int hashCode() {
	try {
	    return file.getCanonicalPath().hashCode();
	} catch (IOException ex) {
	    return 0;
	}
    }

    public boolean equals(Object that) {
	try {
	    return that instanceof PlainFile &&
		file.getCanonicalPath().equals(((PlainFile) that).file.getCanonicalPath());
	} catch (IOException ex) {
	    return that instanceof PlainFile &&
		file.getAbsolutePath().equals(((PlainFile) that).file.getAbsolutePath());
	}
    }

    /** Is this abstract file a directory? */
    public boolean isDirectory() {
        return file.isDirectory();
    }

    /** Returns the time that this abstract file was last modified. */
    public long lastModified() {
	return file.lastModified();
    }

    /** Reads the content of this abstract file into a byte array. */
    public byte[] read() throws IOException {
        assert !isDirectory(): "cannot read directory '" + this + "'";
        FileInputStream in = new FileInputStream(file);
        int rest = (int)file.length();
        byte[] buf = new byte[rest];
        do {
            int res = in.read(buf, buf.length - rest, rest);
            if (res == -1)
                throw new IOException("read error");
            rest -= res;
        } while (rest > 0);
        in.close();
        return buf;
    }

    /** Returns all abstract subfiles of this abstract directory. */
    public Iterator/*<AbstractFile>*/ list() {
        assert isDirectory(): "not a directory '" + this + "'";
        final String[] names = file.list();
        if (names == null || names.length == 0) return EmptyIterator.object;
        class ListIterator implements Iterator {
            private int i;
            public boolean hasNext() {
                return i < names.length;
            }
            public Object next() {
                if (i == names.length) throw new NoSuchElementException();
                return new PlainFile(new File(file, names[i++]));
            }
            public void remove() {
                throw new UnsupportedOperationException();
            }
        }
        return new ListIterator();
    }

    /**
     * Returns the abstract file in this abstract directory with the
     * specified name. If there is no such file, returns null. The
     * argument "directory" tells whether to look for a directory or
     * or a regular file.
     */
    public AbstractFile lookupName(String name, boolean directory) {
        assert isDirectory(): "not a directory '" + this + "'";
        File child = new File(file, name);
        if (directory ? !child.isDirectory() : !child.isFile()) return null;
        return new PlainFile(child);
    }

    //########################################################################
}