/*******************************************************************************
* Copyright (c) 2005, 2009 BEA Systems, Inc.
* 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:
* tyeung@bea.com - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.classfmt;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.codegen.AttributeNamesConstants;
public class AnnotationMethodInfo extends MethodInfo {
protected Object defaultValue= null;
public static MethodInfo createAnnotationMethod(byte classFileBytes[], int offsets[], int offset) {
MethodInfo methodInfo= new MethodInfo(classFileBytes, offsets, offset);
int attributesCount= methodInfo.u2At(6);
int readOffset= 8;
AnnotationInfo[] annotations= null;
Object defaultValue= null;
for (int i= 0; i < attributesCount; i++) {
// check the name of each attribute
int utf8Offset= methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset)] - methodInfo.structOffset;
char[] attributeName= methodInfo.utf8At(utf8Offset + 3, methodInfo.u2At(utf8Offset + 1));
if (attributeName.length > 0) {
switch (attributeName[0]) {
case 'A':
if (CharOperation.equals(attributeName, AttributeNamesConstants.AnnotationDefaultName)) {
// readOffset + 6 so the offset is at the start of the 'member_value' entry
// u2 attribute_name_index + u4 attribute_length = + 6
AnnotationInfo info=
new AnnotationInfo(methodInfo.reference, methodInfo.constantPoolOffsets, readOffset + 6 + methodInfo.structOffset);
defaultValue= info.decodeDefaultValue();
}
break;
case 'S':
if (CharOperation.equals(AttributeNamesConstants.SignatureName, attributeName))
methodInfo.signatureUtf8Offset= methodInfo.constantPoolOffsets[methodInfo.u2At(readOffset + 6)] - methodInfo.structOffset;
break;
case 'R':
AnnotationInfo[] methodAnnotations= null;
if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeVisibleAnnotationsName)) {
methodAnnotations= decodeMethodAnnotations(readOffset, true, methodInfo);
} else if (CharOperation.equals(attributeName, AttributeNamesConstants.RuntimeInvisibleAnnotationsName)) {
methodAnnotations= decodeMethodAnnotations(readOffset, false, methodInfo);
}
if (methodAnnotations != null) {
if (annotations == null) {
annotations= methodAnnotations;
} else {
int length= annotations.length;
AnnotationInfo[] newAnnotations= new AnnotationInfo[length + methodAnnotations.length];
System.arraycopy(annotations, 0, newAnnotations, 0, length);
System.arraycopy(methodAnnotations, 0, newAnnotations, length, methodAnnotations.length);
annotations= newAnnotations;
}
}
break;
}
}
readOffset+= (6 + methodInfo.u4At(readOffset + 2));
}
methodInfo.attributeBytes= readOffset;
if (defaultValue != null) {
if (annotations != null) {
return new AnnotationMethodInfoWithAnnotations(methodInfo, defaultValue, annotations);
}
return new AnnotationMethodInfo(methodInfo, defaultValue);
}
if (annotations != null)
return new MethodInfoWithAnnotations(methodInfo, annotations);
return methodInfo;
}
AnnotationMethodInfo(MethodInfo methodInfo, Object defaultValue) {
super(methodInfo.reference, methodInfo.constantPoolOffsets, methodInfo.structOffset);
this.defaultValue= defaultValue;
this.accessFlags= methodInfo.accessFlags;
this.attributeBytes= methodInfo.attributeBytes;
this.descriptor= methodInfo.descriptor;
this.exceptionNames= methodInfo.exceptionNames;
this.name= methodInfo.name;
this.signature= methodInfo.signature;
this.signatureUtf8Offset= methodInfo.signatureUtf8Offset;
this.tagBits= methodInfo.tagBits;
}
public Object getDefaultValue() {
return this.defaultValue;
}
protected void toStringContent(StringBuffer buffer) {
super.toStringContent(buffer);
if (this.defaultValue != null) {
buffer.append(" default "); //$NON-NLS-1$
if (this.defaultValue instanceof Object[]) {
buffer.append('{');
Object[] elements= (Object[])this.defaultValue;
for (int i= 0, len= elements.length; i < len; i++) {
if (i > 0)
buffer.append(", "); //$NON-NLS-1$
buffer.append(elements[i]);
}
buffer.append('}');
} else {
buffer.append(this.defaultValue);
}
buffer.append('\n');
}
}
}