/******************************************************************************* * Copyright (c) 2004, 2008 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= 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= 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= 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= 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= u2At(classFileBytes, this.readOffset, offset); this.valuesNumber= numberOfValues; this.readOffset+= 2; if (numberOfValues != 0) { this.annotationComponentValues= new IAnnotationComponentValue[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 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 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; } }