blob: 74a26447c66e0b18980c028b6a5d735027efc67c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 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.equinox.p2.internal.repository.comparator.java;
public class AnnotationComponentValue extends ClassFileStruct {
/**
* Tag value for a constant of type <code>byte</code>
* @since 3.1
*/
public static final int BYTE_TAG = 'B';
/**
* Tag value for a constant of type <code>char</code>
* @since 3.1
*/
public static final int CHAR_TAG = 'C';
/**
* Tag value for a constant of type <code>double</code>
* @since 3.1
*/
public static final int DOUBLE_TAG = 'D';
/**
* Tag value for a constant of type <code>float</code>
* @since 3.1
*/
public static final int FLOAT_TAG = 'F';
/**
* Tag value for a constant of type <code>int</code>
* @since 3.1
*/
public static final int INTEGER_TAG = 'I';
/**
* Tag value for a constant of type <code>long</code>
* @since 3.1
*/
public static final int LONG_TAG = 'J';
/**
* Tag value for a constant of type <code>short</code>
* @since 3.1
*/
public static final int SHORT_TAG = 'S';
/**
* Tag value for a constant of type <code>boolean</code>
* @since 3.1
*/
public static final int BOOLEAN_TAG = 'Z';
/**
* Tag value for a constant of type <code>java.lang.String</code>
* @since 3.1
*/
public static final int STRING_TAG = 's';
/**
* Tag value for a value that represents an enum constant
* @since 3.1
*/
public static final int ENUM_TAG = 'e';
/**
* Tag value for a value that represents a class
* @since 3.1
*/
public static final int CLASS_TAG = 'c';
/**
* Tag value for a value that represents an annotation
* @since 3.1
*/
public static final int ANNOTATION_TAG = '@';
/**
* Tag value for a value that represents an array
* @since 3.1
*/
public static final int ARRAY_TAG = '[';
private static final AnnotationComponentValue[] NO_VALUES = new AnnotationComponentValue[0];
private AnnotationComponentValue[] annotationComponentValues;
private Annotation annotationValue;
private ConstantPoolEntry classInfo;
private int classFileInfoIndex;
private ConstantPoolEntry 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, ConstantPool 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 = u2At(classFileBytes, this.readOffset, offset);
this.constantValueIndex = constantIndex;
if (constantIndex != 0) {
ConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(constantIndex);
switch (constantPoolEntry.getKind()) {
case ConstantPoolConstant.CONSTANT_Long :
case ConstantPoolConstant.CONSTANT_Float :
case ConstantPoolConstant.CONSTANT_Double :
case ConstantPoolConstant.CONSTANT_Integer :
case ConstantPoolConstant.CONSTANT_Utf8 :
break;
default :
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.constantValue = constantPoolEntry;
}
this.readOffset += 2;
break;
case 'e' :
int index = u2At(classFileBytes, this.readOffset, offset);
this.enumConstantTypeNameIndex = index;
if (index != 0) {
ConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != ConstantPoolConstant.CONSTANT_Utf8) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.enumConstantTypeName = constantPoolEntry.getUtf8Value();
}
this.readOffset += 2;
index = u2At(classFileBytes, this.readOffset, offset);
this.enumConstantNameIndex = index;
if (index != 0) {
ConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index);
if (constantPoolEntry.getKind() != ConstantPoolConstant.CONSTANT_Utf8) {
throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY);
}
this.enumConstantName = constantPoolEntry.getUtf8Value();
}
this.readOffset += 2;
break;
case 'c' :
final int classFileIndex = u2At(classFileBytes, this.readOffset, offset);
this.classFileInfoIndex = classFileIndex;
if (classFileIndex != 0) {
ConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(classFileIndex);
if (constantPoolEntry.getKind() != ConstantPoolConstant.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 = u2At(classFileBytes, this.readOffset, offset);
this.valuesNumber = numberOfValues;
this.readOffset += 2;
if (numberOfValues != 0) {
this.annotationComponentValues = new AnnotationComponentValue[numberOfValues];
for (int i = 0; i < numberOfValues; i++) {
AnnotationComponentValue value = new AnnotationComponentValue(classFileBytes, constantPool, offset + this.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 AnnotationComponentValue[] getAnnotationComponentValues() {
return this.annotationComponentValues;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationValue()
*/
public Annotation getAnnotationValue() {
return this.annotationValue;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfo()
*/
public ConstantPoolEntry 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 ConstantPoolEntry 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 this.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;
}
}