001 package edu.rice.cs.cunit.classFile; 002 003 import edu.rice.cs.cunit.classFile.attributes.AAttributeInfo; 004 import edu.rice.cs.cunit.classFile.attributes.SourceFileAttributeInfo; 005 import edu.rice.cs.cunit.classFile.constantPool.APoolInfo; 006 import edu.rice.cs.cunit.classFile.constantPool.AUTFPoolInfo; 007 import edu.rice.cs.cunit.classFile.constantPool.ConstantPool; 008 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckUTFVisitor; 009 010 import java.io.DataInputStream; 011 import java.io.DataOutputStream; 012 import java.io.IOException; 013 import java.util.ArrayList; 014 015 /** 016 * Represents a field in a class file. 017 * 018 * @author Mathias Ricken 019 */ 020 021 public final class FieldInfo { 022 /** 023 * Field access flags 024 */ 025 private short _accessFlags; 026 027 /** 028 * Name information. 029 */ 030 private AUTFPoolInfo _name; 031 032 /** 033 * Type descriptor information. 034 */ 035 private AUTFPoolInfo _descriptor; 036 037 /** 038 * Attributes. 039 */ 040 private ArrayList<AAttributeInfo> _attributes = new ArrayList<AAttributeInfo>(); 041 042 /** 043 * Constructor. 044 * 045 * @param accessFlags field access flags 046 * @param name field name 047 * @param descriptor field descriptor 048 * @param attributes array of attributes 049 */ 050 public FieldInfo(short accessFlags, 051 AUTFPoolInfo name, 052 AUTFPoolInfo descriptor, 053 SourceFileAttributeInfo[] attributes) { 054 _accessFlags = accessFlags; 055 _name = name; 056 _descriptor = descriptor; 057 if (attributes != null) { 058 for(AAttributeInfo attr : attributes) { 059 _attributes.add(attr); 060 } 061 } 062 } 063 064 /** 065 * Constructor. 066 * 067 * @param di input stream 068 * @param pool constant pool 069 * 070 * @throws IOException 071 * @throws ClassFormatError 072 */ 073 public FieldInfo(DataInputStream di, ConstantPool pool) throws IOException, ClassFormatError { 074 _accessFlags = di.readShort(); 075 _name = pool.get(di.readShort()).execute(CheckUTFVisitor.singleton(), null); 076 _descriptor = pool.get(di.readShort()).execute(CheckUTFVisitor.singleton(), null); 077 078 int count = di.readShort(); 079 for(int i = 0; i < count; i++) { 080 _attributes.add(AAttributeInfo.read(di, pool)); 081 } 082 } 083 084 /** 085 * Write this field into a stream. 086 * 087 * @param dos output stream 088 * @param pool constant pool 089 * 090 * @throws IOException 091 */ 092 public void write(DataOutputStream dos, ConstantPool pool) throws IOException { 093 dos.writeShort(_accessFlags); 094 dos.writeShort(pool.indexOf(_name)); 095 dos.writeShort(pool.indexOf(_descriptor)); 096 dos.writeShort(_attributes.size()); 097 for(AAttributeInfo attr : _attributes) { 098 attr.write(dos); 099 } 100 } 101 102 /** 103 * Return a human-readable version of this field. 104 * 105 * @return string 106 */ 107 public String toString() { 108 StringBuilder x = new StringBuilder(); 109 110 x.append(ClassFileTools.getAccessString(_accessFlags)); 111 x.append(ClassFileTools.getTypeString(_descriptor.toStringVerbose(), _name.toStringVerbose())); 112 if (_attributes.size() != 0) { 113 x.append(" = " + _attributes.get(0).toString()); 114 } 115 return x.toString(); 116 } 117 118 /** 119 * Return a human-readable version of this field and correctly handle booleans and strings. 120 * 121 * @param pool constant pool 122 * 123 * @return string 124 */ 125 public final String toString(ConstantPool pool) { 126 StringBuilder x = new StringBuilder(); 127 128 x.append(ClassFileTools.getAccessString(_accessFlags)); 129 String t = ClassFileTools.getTypeString(_descriptor.toString(), _name.toString()); 130 x.append(t); 131 for(AAttributeInfo attr : _attributes) { 132 x.append(", " + attr); 133 } 134 return x.toString(); 135 } 136 137 /** 138 * Accessor for access flags. 139 * 140 * @return access flags 141 */ 142 public short getAccessFlags() { 143 return _accessFlags; 144 } 145 146 /** 147 * Mutator for access flags. 148 * 149 * @param accessFlags new access flags 150 */ 151 public void setAccessFlags(short accessFlags) { 152 _accessFlags = accessFlags; 153 } 154 155 /** 156 * Accessor for field name. 157 * 158 * @return field name 159 */ 160 public AUTFPoolInfo getName() { 161 return _name; 162 } 163 164 /** 165 * Mutator for field name. 166 * 167 * @param name new field name 168 */ 169 public void setName(AUTFPoolInfo name) { 170 _name = name; 171 } 172 173 /** 174 * Accessor for descriptor. 175 * 176 * @return descriptor 177 */ 178 public AUTFPoolInfo getDescriptor() { 179 return _descriptor; 180 } 181 182 /** 183 * Mutator for descriptor. 184 * 185 * @param descriptor new descriptor 186 */ 187 public void setDescriptor(AUTFPoolInfo descriptor) { 188 _descriptor = descriptor; 189 } 190 191 /** 192 * Accessor for attributes. 193 * 194 * @return attributes 195 */ 196 public ArrayList<AAttributeInfo> getAttributes() { 197 return _attributes; 198 } 199 200 /** 201 * Return the attribute with the specified name. 202 * 203 * @param name attribute name 204 * 205 * @return attribute or null if not found 206 */ 207 public AAttributeInfo getAttribute(String name) { 208 if (0 == _attributes.size()) { 209 return null; 210 } 211 for(AAttributeInfo attr : _attributes) { 212 if (0 == name.compareTo(attr.getName().toString())) { 213 return attr; 214 } 215 } 216 return null; 217 } 218 219 /** 220 * Mutator for attributes. 221 * 222 * @param attributes new attributes 223 */ 224 public void setAttributes(ArrayList<AAttributeInfo> attributes) { 225 _attributes = attributes; 226 } 227 }