001    package serp.bytecode;
002    
003    import java.io.*;
004    
005    import serp.bytecode.lowlevel.*;
006    import serp.bytecode.visitor.*;
007    
008    /**
009     * Attribute naming the source file for this class.
010     *
011     * @author Abe White
012     */
013    public 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    }