| /* ******************************************************************* |
| * Copyright (c) 2004 IBM |
| * 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: |
| * Andy Clement - initial implementation {date} |
| * ******************************************************************/ |
| package org.aspectj.apache.bcel.classfile.annotation; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.DataInputStream; |
| import java.io.DataOutputStream; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.aspectj.apache.bcel.classfile.Attribute; |
| import org.aspectj.apache.bcel.classfile.ConstantPool; |
| |
| public abstract class RuntimeParamAnnos extends Attribute { |
| |
| private List<AnnotationGen[]> parameterAnnotations; |
| private boolean visible; |
| |
| |
| // Keep just a byte stream of the data until someone actually asks for it |
| private boolean inflated = false; |
| private byte[] annotation_data; |
| |
| |
| public RuntimeParamAnnos(byte attrid, boolean visible, |
| int nameIdx, int len, ConstantPool cpool) { |
| super(attrid,nameIdx,len,cpool); |
| this.visible = visible; |
| parameterAnnotations = new ArrayList<AnnotationGen[]>(); |
| } |
| |
| public RuntimeParamAnnos(byte attrid,boolean visible,int nameIdx,int len,byte[] data,ConstantPool cpool) { |
| super(attrid,nameIdx,len,cpool); |
| this.visible = visible; |
| parameterAnnotations = new ArrayList<AnnotationGen[]>(); |
| annotation_data = data; |
| } |
| |
| public final void dump(DataOutputStream dos) throws IOException { |
| super.dump(dos); |
| writeAnnotations(dos); |
| } |
| |
| public Attribute copy(ConstantPool constant_pool) { |
| throw new RuntimeException("Not implemented yet!"); |
| } |
| |
| /** Return a list of Annotation[] - each list entry contains the annotations for one parameter */ |
| public List /*Annotation[]*/<AnnotationGen[]> getParameterAnnotations() { |
| if (!inflated) inflate(); |
| return parameterAnnotations; |
| } |
| |
| public AnnotationGen[] getAnnotationsOnParameter(int parameterIndex) { |
| if (!inflated) inflate(); |
| // This may happen. In a ctor for a non static inner type the compiler |
| // may have added an extra parameter to the generated ctor (the parameter |
| // contains the instance of the outer class) - in this case |
| // it may appear that there are more parameters than there are entries |
| // in the parameter annotations array |
| if (parameterIndex>=parameterAnnotations.size()) { |
| return AnnotationGen.NO_ANNOTATIONS; |
| } |
| return parameterAnnotations.get(parameterIndex); |
| } |
| |
| public boolean areVisible() { |
| return visible; |
| } |
| |
| protected void readParameterAnnotations(DataInputStream dis,ConstantPool cpool) throws IOException { |
| annotation_data = new byte[length]; |
| dis.readFully(annotation_data,0,length); |
| } |
| |
| private void inflate() { |
| try { |
| DataInputStream dis = new DataInputStream(new ByteArrayInputStream(annotation_data)); |
| int numParameters = dis.readUnsignedByte(); |
| if (numParameters > 0) { |
| List<AnnotationGen[]> inflatedParameterAnnotations = new ArrayList<AnnotationGen[]>(); |
| for (int i=0; i<numParameters; i++) { |
| int numAnnotations = dis.readUnsignedShort(); |
| if (numAnnotations == 0 ) { |
| inflatedParameterAnnotations.add(AnnotationGen.NO_ANNOTATIONS); |
| } else { |
| AnnotationGen[] annotations = new AnnotationGen[numAnnotations]; |
| for (int j=0; j<numAnnotations; j++) { |
| annotations[j] = AnnotationGen.read(dis,getConstantPool(),visible); |
| } |
| inflatedParameterAnnotations.add(annotations); |
| } |
| } |
| parameterAnnotations = inflatedParameterAnnotations; |
| } |
| inflated = true; |
| } catch (IOException ioe) { |
| throw new RuntimeException("Unabled to inflate annotation data, badly formed?"); |
| } |
| } |
| |
| |
| protected void writeAnnotations(DataOutputStream dos) throws IOException { |
| if (!inflated) { |
| dos.write(annotation_data,0,length); |
| } else { |
| dos.writeByte(parameterAnnotations.size()); |
| for (int i=0; i<parameterAnnotations.size(); i++) { |
| AnnotationGen[] annotations = parameterAnnotations.get(i); |
| dos.writeShort(annotations.length); |
| for (int j=0; j<annotations.length;j++) { |
| annotations[j].dump(dos); |
| } |
| } |
| } |
| } |
| |
| /** FOR TESTING ONLY: Tells you if the annotations have been inflated to an object graph */ |
| public boolean isInflated() { |
| return inflated; |
| } |
| |
| public String toString() { |
| return "Runtime"+(visible?"Visible":"Invisible")+"ParameterAnnotations ["+(inflated?"inflated":"not yet inflated")+"]"; |
| } |
| |
| } |