blob: 735880627c584e9965d893681e6a256dd2d3a6c0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.core.util;
import org.eclipse.jdt.core.util.ClassFormatException;
import org.eclipse.jdt.core.util.IAnnotation;
import org.eclipse.jdt.core.util.IAnnotationComponentValue;
import org.eclipse.jdt.core.util.IConstantPool;
import org.eclipse.jdt.core.util.IConstantPoolConstant;
import org.eclipse.jdt.core.util.IConstantPoolEntry;
/**
* Default implementation of IAnnotationComponent
*/
public class AnnotationComponentValue extends ClassFileStruct implements IAnnotationComponentValue {
private static final IAnnotationComponentValue[] NO_VALUES = new AnnotationComponentValue[0];
private IAnnotationComponentValue[] annotationComponentValues;
private IAnnotation annotationValue;
private IConstantPoolEntry classInfo;
private int classFileInfoIndex;
private IConstantPoolEntry constantValue;
private int constantValueIndex;
private int enumConstantTypeNameIndex;
private int enumConstantNameIndex;
private char[] enumConstantTypeName;
private char[] enumConstantName;
private int readOffset;
private int tag;
private int valuesNumber;
public AnnotationComponentValue(
byte[] classFileBytes,
IConstantPool constantPool,
int offset) throws ClassFormatException {
this.classFileInfoIndex = -1;
this.constantValueIndex = -1;
this.enumConstantTypeNameIndex = -1;
this.enumConstantNameIndex = -1;
final int t = u1At(classFileBytes, 0, offset);
this.tag = t;
this.readOffset = 1;
switch(t) {
case 'B' :
case 'C' :
case 'D' :
case 'F' :
case 'I' :
case 'J' :
case 'S' :
case 'Z' :
case 's' :
final int constantIndex = this.u2At(classFileBytes, this.readOffset, offset);
this.constantValueIndex = constantIndex;
if (constantIndex != 0) {
IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(constantIndex);
switch(constantPoolEntry.getKind()) {
case IConstantPoolConstant.CONSTANT_Long :
case IConstantPoolConstant.CONSTANT_Float :
case IConstantPoolConstant.CONSTANT_Double :
case IConstantPoolConstant.CONSTANT_Integer :
case IConstantPoolConstant.CONSTANT_Utf8 :
break;
default :
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.constantValue = constantPoolEntry;
}
this.readOffset += 2;
break;
case 'e' :
int index = this.u2At(classFileBytes, this.readOffset, offset);
this.enumConstantTypeNameIndex = index;
if (index != 0) {
IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.enumConstantTypeName = constantPoolEntry.getUtf8Value();
}
this.readOffset += 2;
index = this.u2At(classFileBytes, this.readOffset, offset);
this.enumConstantNameIndex = index;
if (index != 0) {
IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.enumConstantName = constantPoolEntry.getUtf8Value();
}
this.readOffset += 2;
break;
case 'c' :
final int classFileIndex = this.u2At(classFileBytes, this.readOffset, offset);
this.classFileInfoIndex = classFileIndex;
if (classFileIndex != 0) {
IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(classFileIndex);
if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.classInfo = constantPoolEntry;
}
this.readOffset += 2;
break;
case '@' :
Annotation annotation = new Annotation(classFileBytes, constantPool, this.readOffset + offset);
this.annotationValue = annotation;
this.readOffset += annotation.sizeInBytes();
break;
case '[' :
final int numberOfValues = this.u2At(classFileBytes, this.readOffset, offset);
this.valuesNumber = numberOfValues;
if (numberOfValues != 0) {
this.readOffset += 2;
this.annotationComponentValues = new IAnnotationComponentValue[numberOfValues];
for (int i = 0; i < numberOfValues; i++) {
AnnotationComponentValue value = new AnnotationComponentValue(classFileBytes, constantPool, offset + readOffset);
this.annotationComponentValues[i] = value;
this.readOffset += value.sizeInBytes();
}
} else {
this.annotationComponentValues = NO_VALUES;
}
break;
}
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationComponentValues()
*/
public IAnnotationComponentValue[] getAnnotationComponentValues() {
return this.annotationComponentValues;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationValue()
*/
public IAnnotation getAnnotationValue() {
return this.annotationValue;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfo()
*/
public IConstantPoolEntry getClassInfo() {
return this.classInfo;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfoIndex()
*/
public int getClassInfoIndex() {
return this.classFileInfoIndex;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValue()
*/
public IConstantPoolEntry getConstantValue() {
return this.constantValue;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValueIndex()
*/
public int getConstantValueIndex() {
return this.constantValueIndex;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantName()
*/
public char[] getEnumConstantName() {
return this.enumConstantName;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantNameIndex()
*/
public int getEnumConstantNameIndex() {
return this.enumConstantNameIndex;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantTypeName()
*/
public char[] getEnumConstantTypeName() {
return this.enumConstantTypeName;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantTypeNameIndex()
*/
public int getEnumConstantTypeNameIndex() {
return enumConstantTypeNameIndex;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getTag()
*/
public int getTag() {
return this.tag;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getValuesNumber()
*/
public int getValuesNumber() {
return this.valuesNumber;
}
int sizeInBytes() {
return this.readOffset;
}
}