001    package edu.rice.cs.cunit.classFile.attributes;
002    
003    import edu.rice.cs.cunit.classFile.constantPool.AUTFPoolInfo;
004    import edu.rice.cs.cunit.classFile.constantPool.ConstantPool;
005    import edu.rice.cs.cunit.util.Types;
006    
007    import java.io.IOException;
008    import java.io.ByteArrayOutputStream;
009    
010    /**
011     * Represents a single abstract Annotations attribute in a class file.
012     *
013     * @author Mathias Ricken
014     */
015    public abstract class ASingleAnnotationsAttributeInfo extends AAnnotationsAttributeInfo {
016        /**
017         * Creates a new abstract parameter annotations attribute.
018         * @param name name of attribute
019         * @param data data array
020         * @param cp constant pool
021         */
022        public ASingleAnnotationsAttributeInfo(AUTFPoolInfo name, byte data[], ConstantPool cp) {
023            super(name, data, cp);
024        }
025    
026    
027        /**
028         * Return the number of annotations.
029         *
030         * @return number of exceptions
031         *
032         * @throws ClassFormatError
033         */
034        public int getAnnotationCount() throws ClassFormatError {
035            int res = Types.ushortFromBytes(_data, 0);
036            assert(res <= 0xffff);
037            return res;
038        }
039    
040        /**
041         * Return the annotations list.
042         *
043         * @return list of annotations.
044         *
045         * @throws ClassFormatError
046         */
047        public Annotation[] getAnnotations() throws ClassFormatError {
048            int count = getAnnotationCount();
049            Annotation[] ann = new Annotation[count];
050            int index = 2;
051            for(short i = 0; i < count; ++i) {
052                ann[i] = new Annotation(_constantPool,_data,index);
053                index += ann[i].getSize();
054            }
055            return ann;
056        }
057    
058        /**
059         * Set the annotations list.
060         *
061         * @param ann list of checked exceptions
062         *
063         * @throws ClassFormatError
064         */
065        public void setAnnotations(Annotation[] ann) throws IOException {
066            ByteArrayOutputStream baos = new ByteArrayOutputStream();
067            baos.write(Types.bytesFromShort((short)ann.length));
068            for(int i = 0; i < ann.length; ++i) {
069                ann[i].writeToByteArrayOutputStream(_constantPool,baos);
070            }
071            setData(baos.toByteArray());
072        }
073    
074        /**
075         * Return a human-readable version of this attribute.
076         *
077         * @return string
078         */
079        public String toString() {
080            StringBuilder x = new StringBuilder();
081            x.append(_name + " <" + getAnnotationCount() + " annotations { ");
082            boolean first = true;
083            for(Annotation ann : getAnnotations()) {
084                if (first) {
085                    first = false;
086                }
087                else {
088                    x.append(", ");
089                }
090                x.append(ann.toString());
091            }
092            x.append(" } >");
093            return x.toString();
094        }
095    
096        /**
097         * Creates and returns a copy of this object.
098         */
099        public Object clone() throws CloneNotSupportedException {
100            return super.clone();
101        }
102    }