001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.bytecode;
030:
031: import com.caucho.log.Log;
032:
033: import java.io.ByteArrayInputStream;
034: import java.io.IOException;
035: import java.lang.reflect.Modifier;
036: import java.util.ArrayList;
037: import java.util.logging.Level;
038: import java.util.logging.Logger;
039:
040: /**
041: * Represents a java field.
042: */
043: public class JavaField extends JField {
044: static private final Logger log = Logger.getLogger(JavaField.class
045: .getName());
046:
047: private JavaClass _jClass;
048: private int _accessFlags;
049: private String _name;
050: private String _descriptor;
051:
052: private boolean _isWrite;
053:
054: private ArrayList<Attribute> _attributes = new ArrayList<Attribute>();
055:
056: private JavaAnnotation[] _annotations;
057:
058: /**
059: * Sets the JavaClass.
060: */
061: public void setJavaClass(JavaClass jClass) {
062: _jClass = jClass;
063: }
064:
065: public void setWrite(boolean isWrite) {
066: _isWrite = isWrite;
067: }
068:
069: /**
070: * Returns the declaring class.
071: */
072: public JClass getDeclaringClass() {
073: return _jClass;
074: }
075:
076: /**
077: * Returns the class loader.
078: */
079: public JavaClassLoader getClassLoader() {
080: return _jClass.getClassLoader();
081: }
082:
083: /**
084: * Sets the name.
085: */
086: public void setName(String name) {
087: _name = name;
088:
089: if (_isWrite)
090: _jClass.getConstantPool().addUTF8(name);
091: }
092:
093: /**
094: * Gets the name.
095: */
096: public String getName() {
097: return _name;
098: }
099:
100: /**
101: * Sets the access flags
102: */
103: public void setAccessFlags(int flags) {
104: _accessFlags = flags;
105: }
106:
107: /**
108: * Gets the access flags
109: */
110: public int getAccessFlags() {
111: return _accessFlags;
112: }
113:
114: /**
115: * Sets the descriptor.
116: */
117: public void setDescriptor(String descriptor) {
118: _descriptor = descriptor;
119:
120: if (_isWrite)
121: _jClass.getConstantPool().addUTF8(descriptor);
122: }
123:
124: /**
125: * Gets the descriptor.
126: */
127: public String getDescriptor() {
128: return _descriptor;
129: }
130:
131: /**
132: * Gets the typename.
133: */
134: public JClass getType() {
135: return getClassLoader().descriptorToClass(getDescriptor(), 0);
136: }
137:
138: /**
139: * Returns true for a static field.
140: */
141: public boolean isStatic() {
142: return Modifier.isStatic(getAccessFlags());
143: }
144:
145: /**
146: * Returns true for a private field.
147: */
148: public boolean isPrivate() {
149: return Modifier.isPrivate(getAccessFlags());
150: }
151:
152: /**
153: * Returns true for a transient field.
154: */
155: public boolean isTransient() {
156: return Modifier.isTransient(getAccessFlags());
157: }
158:
159: /**
160: * Gets the typename.
161: */
162: public JType getGenericType() {
163: SignatureAttribute sigAttr = (SignatureAttribute) getAttribute("Signature");
164:
165: if (sigAttr != null) {
166: return getClassLoader().parseParameterizedType(
167: sigAttr.getSignature());
168: }
169:
170: return getType();
171: }
172:
173: /**
174: * Adds an attribute.
175: */
176: public void addAttribute(Attribute attr) {
177: _attributes.add(attr);
178: }
179:
180: /**
181: * Returns the attribute.
182: */
183: public Attribute getAttribute(String name) {
184: for (int i = _attributes.size() - 1; i >= 0; i--) {
185: Attribute attr = _attributes.get(i);
186:
187: if (attr.getName().equals(name))
188: return attr;
189: }
190:
191: return null;
192: }
193:
194: /**
195: * Returns the declared annotations.
196: */
197: public JAnnotation[] getDeclaredAnnotations() {
198: if (_annotations == null) {
199: Attribute attr = getAttribute("RuntimeVisibleAnnotations");
200:
201: if (attr instanceof OpaqueAttribute) {
202: byte[] buffer = ((OpaqueAttribute) attr).getValue();
203:
204: try {
205: ByteArrayInputStream is = new ByteArrayInputStream(
206: buffer);
207:
208: ConstantPool cp = _jClass.getConstantPool();
209:
210: _annotations = JavaAnnotation.parseAnnotations(is,
211: cp, getClassLoader());
212: } catch (IOException e) {
213: log.log(Level.FINER, e.toString(), e);
214: }
215: }
216:
217: if (_annotations == null) {
218: _annotations = new JavaAnnotation[0];
219: }
220: }
221:
222: return _annotations;
223: }
224:
225: /**
226: * Writes the field to the output.
227: */
228: public void write(ByteCodeWriter out) throws IOException {
229: out.writeShort(_accessFlags);
230: out.writeUTF8Const(_name);
231: out.writeUTF8Const(_descriptor);
232: out.writeShort(_attributes.size());
233:
234: for (int i = 0; i < _attributes.size(); i++) {
235: Attribute attr = _attributes.get(i);
236:
237: attr.write(out);
238: }
239: }
240:
241: /**
242: * exports the field
243: */
244: public JavaField export(JavaClass cl, JavaClass target) {
245: JavaField field = new JavaField();
246: field.setName(_name);
247: field.setDescriptor(_descriptor);
248: field.setAccessFlags(_accessFlags);
249:
250: target.getConstantPool().addUTF8(_name);
251: target.getConstantPool().addUTF8(_descriptor);
252:
253: for (int i = 0; i < _attributes.size(); i++) {
254: Attribute attr = _attributes.get(i);
255:
256: field.addAttribute(attr.export(cl, target));
257: }
258:
259: return field;
260: }
261:
262: public boolean equals(Object o) {
263: if (o == null || !JavaField.class.equals(o.getClass()))
264: return false;
265:
266: JavaField field = (JavaField) o;
267:
268: return _name.equals(field._name);
269: }
270:
271: public String toString() {
272: return "JavaField[" + _name + "]";
273: }
274: }
|