001package serp.bytecode;
002
003import java.io.*;
004
005import serp.bytecode.lowlevel.*;
006import serp.bytecode.visitor.*;
007
008/**
009 * Attribute naming the source file for this class.
010 *
011 * @author Abe White
012 */
013public class SourceFile extends Attribute {
014    int _sourceFileIndex = 0;
015
016    SourceFile(int nameIndex, Attributes owner) {
017        super(nameIndex, owner);
018    }
019
020    int getLength() {
021        return 2;
022    }
023
024    /**
025     * Return the index into the class {@link ConstantPool} of the
026     * {@link UTF8Entry} naming the source file for this class, or 0 if not set.
027     */
028    public int getFileIndex() {
029        return _sourceFileIndex;
030    }
031
032    /**
033     * Set the index into the class {@link ConstantPool} of the
034     * {@link UTF8Entry} naming the source file for this class.
035     */
036    public void setFileIndex(int sourceFileIndex) {
037        if (sourceFileIndex < 0)
038            sourceFileIndex = 0;
039        _sourceFileIndex = sourceFileIndex;
040    }
041
042    /**
043     * Return the name of the source file, or null if not set.
044     */
045    public String getFileName() {
046        if (_sourceFileIndex == 0)
047            return null;
048        return ((UTF8Entry) getPool().getEntry(_sourceFileIndex)).getValue();
049    }
050
051    /**
052     * Return the file object for the source file, or null if not set.
053     *
054     * @param dir the directory of the file, or null
055     */
056    public File getFile(File dir) {
057        String name = getFileName();
058        if (name == null)
059            return null;
060        return new File(dir, name);
061    }
062
063    /**
064     * Set the name of the source file. The name should be the file name
065     * only; it should not include the path to the file.
066     */
067    public void setFile(String name) {
068        if (name == null)
069            setFileIndex(0);
070        else
071            setFileIndex(getPool().findUTF8Entry(name, true));
072    }
073
074    /**
075     * Set the source file. Note that only the file name is recorded;
076     * the path to the file is discarded.
077     */
078    public void setFile(File file) {
079        if (file == null)
080            setFile((String) null);
081        else
082            setFile(file.getName());
083    }
084
085    /**
086     * Set the file name from the current class name plus the .java extension.
087     */
088    public void setFromClassName() {
089        setFile(((BCClass) getOwner()).getClassName() + ".java");
090    }
091
092    public void acceptVisit(BCVisitor visit) {
093        visit.enterSourceFile(this);
094        visit.exitSourceFile(this);
095    }
096
097    void read(Attribute other) {
098        setFile(((SourceFile) other).getFileName());
099    }
100
101    void read(DataInput in, int length) throws IOException {
102        setFileIndex(in.readUnsignedShort());
103    }
104
105    void write(DataOutput out, int length) throws IOException {
106        out.writeShort(getFileIndex());
107    }
108}