| /******************************************************************************* |
| * 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; |
| } |
| } |