001: /*******************************************************************************
002: * Copyright (c) 2004, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.internal.core.util;
011:
012: import org.eclipse.jdt.core.util.ClassFormatException;
013: import org.eclipse.jdt.core.util.IAnnotation;
014: import org.eclipse.jdt.core.util.IAnnotationComponentValue;
015: import org.eclipse.jdt.core.util.IConstantPool;
016: import org.eclipse.jdt.core.util.IConstantPoolConstant;
017: import org.eclipse.jdt.core.util.IConstantPoolEntry;
018:
019: /**
020: * Default implementation of IAnnotationComponent
021: */
022: public class AnnotationComponentValue extends ClassFileStruct implements
023: IAnnotationComponentValue {
024: private static final IAnnotationComponentValue[] NO_VALUES = new AnnotationComponentValue[0];
025:
026: private IAnnotationComponentValue[] annotationComponentValues;
027: private IAnnotation annotationValue;
028: private IConstantPoolEntry classInfo;
029: private int classFileInfoIndex;
030: private IConstantPoolEntry constantValue;
031: private int constantValueIndex;
032: private int enumConstantTypeNameIndex;
033: private int enumConstantNameIndex;
034: private char[] enumConstantTypeName;
035: private char[] enumConstantName;
036:
037: private int readOffset;
038: private int tag;
039: private int valuesNumber;
040:
041: public AnnotationComponentValue(byte[] classFileBytes,
042: IConstantPool constantPool, int offset)
043: throws ClassFormatException {
044: this .classFileInfoIndex = -1;
045: this .constantValueIndex = -1;
046: this .enumConstantTypeNameIndex = -1;
047: this .enumConstantNameIndex = -1;
048: final int t = u1At(classFileBytes, 0, offset);
049: this .tag = t;
050: this .readOffset = 1;
051: switch (t) {
052: case 'B':
053: case 'C':
054: case 'D':
055: case 'F':
056: case 'I':
057: case 'J':
058: case 'S':
059: case 'Z':
060: case 's':
061: final int constantIndex = this .u2At(classFileBytes,
062: this .readOffset, offset);
063: this .constantValueIndex = constantIndex;
064: if (constantIndex != 0) {
065: IConstantPoolEntry constantPoolEntry = constantPool
066: .decodeEntry(constantIndex);
067: switch (constantPoolEntry.getKind()) {
068: case IConstantPoolConstant.CONSTANT_Long:
069: case IConstantPoolConstant.CONSTANT_Float:
070: case IConstantPoolConstant.CONSTANT_Double:
071: case IConstantPoolConstant.CONSTANT_Integer:
072: case IConstantPoolConstant.CONSTANT_Utf8:
073: break;
074: default:
075: throw new ClassFormatException(
076: ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
077: }
078: this .constantValue = constantPoolEntry;
079: }
080: this .readOffset += 2;
081: break;
082: case 'e':
083: int index = this .u2At(classFileBytes, this .readOffset,
084: offset);
085: this .enumConstantTypeNameIndex = index;
086: if (index != 0) {
087: IConstantPoolEntry constantPoolEntry = constantPool
088: .decodeEntry(index);
089: if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
090: throw new ClassFormatException(
091: ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
092: }
093: this .enumConstantTypeName = constantPoolEntry
094: .getUtf8Value();
095: }
096: this .readOffset += 2;
097: index = this .u2At(classFileBytes, this .readOffset, offset);
098: this .enumConstantNameIndex = index;
099: if (index != 0) {
100: IConstantPoolEntry constantPoolEntry = constantPool
101: .decodeEntry(index);
102: if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
103: throw new ClassFormatException(
104: ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
105: }
106: this .enumConstantName = constantPoolEntry
107: .getUtf8Value();
108: }
109: this .readOffset += 2;
110: break;
111: case 'c':
112: final int classFileIndex = this .u2At(classFileBytes,
113: this .readOffset, offset);
114: this .classFileInfoIndex = classFileIndex;
115: if (classFileIndex != 0) {
116: IConstantPoolEntry constantPoolEntry = constantPool
117: .decodeEntry(classFileIndex);
118: if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
119: throw new ClassFormatException(
120: ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
121: }
122: this .classInfo = constantPoolEntry;
123: }
124: this .readOffset += 2;
125: break;
126: case '@':
127: Annotation annotation = new Annotation(classFileBytes,
128: constantPool, this .readOffset + offset);
129: this .annotationValue = annotation;
130: this .readOffset += annotation.sizeInBytes();
131: break;
132: case '[':
133: final int numberOfValues = this .u2At(classFileBytes,
134: this .readOffset, offset);
135: this .valuesNumber = numberOfValues;
136: if (numberOfValues != 0) {
137: this .readOffset += 2;
138: this .annotationComponentValues = new IAnnotationComponentValue[numberOfValues];
139: for (int i = 0; i < numberOfValues; i++) {
140: AnnotationComponentValue value = new AnnotationComponentValue(
141: classFileBytes, constantPool, offset
142: + readOffset);
143: this .annotationComponentValues[i] = value;
144: this .readOffset += value.sizeInBytes();
145: }
146: } else {
147: this .annotationComponentValues = NO_VALUES;
148: }
149: break;
150: }
151: }
152:
153: /* (non-Javadoc)
154: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationComponentValues()
155: */
156: public IAnnotationComponentValue[] getAnnotationComponentValues() {
157: return this .annotationComponentValues;
158: }
159:
160: /* (non-Javadoc)
161: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationValue()
162: */
163: public IAnnotation getAnnotationValue() {
164: return this .annotationValue;
165: }
166:
167: /* (non-Javadoc)
168: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfo()
169: */
170: public IConstantPoolEntry getClassInfo() {
171: return this .classInfo;
172: }
173:
174: /* (non-Javadoc)
175: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfoIndex()
176: */
177: public int getClassInfoIndex() {
178: return this .classFileInfoIndex;
179: }
180:
181: /* (non-Javadoc)
182: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValue()
183: */
184: public IConstantPoolEntry getConstantValue() {
185: return this .constantValue;
186: }
187:
188: /* (non-Javadoc)
189: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValueIndex()
190: */
191: public int getConstantValueIndex() {
192: return this .constantValueIndex;
193: }
194:
195: /* (non-Javadoc)
196: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantName()
197: */
198: public char[] getEnumConstantName() {
199: return this .enumConstantName;
200: }
201:
202: /* (non-Javadoc)
203: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantNameIndex()
204: */
205: public int getEnumConstantNameIndex() {
206: return this .enumConstantNameIndex;
207: }
208:
209: /* (non-Javadoc)
210: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantTypeName()
211: */
212: public char[] getEnumConstantTypeName() {
213: return this .enumConstantTypeName;
214: }
215:
216: /* (non-Javadoc)
217: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantTypeNameIndex()
218: */
219: public int getEnumConstantTypeNameIndex() {
220: return enumConstantTypeNameIndex;
221: }
222:
223: /* (non-Javadoc)
224: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getTag()
225: */
226: public int getTag() {
227: return this .tag;
228: }
229:
230: /* (non-Javadoc)
231: * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getValuesNumber()
232: */
233: public int getValuesNumber() {
234: return this .valuesNumber;
235: }
236:
237: int sizeInBytes() {
238: return this.readOffset;
239: }
240: }
|