001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   https://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.bcel.classfile;
020
021import java.io.DataInput;
022import java.io.DataOutputStream;
023import java.io.IOException;
024import java.util.Iterator;
025import java.util.stream.Stream;
026
027/**
028 * base class for parameter annotations
029 *
030 * @since 6.0
031 */
032public abstract class ParameterAnnotations extends Attribute implements Iterable<ParameterAnnotationEntry> {
033
034    private static final ParameterAnnotationEntry[] EMPTY_ARRAY = {};
035
036    /** Table of parameter annotations */
037    private ParameterAnnotationEntry[] parameterAnnotationTable;
038
039    /**
040     * Constructs a new instance.
041     *
042     * @param parameterAnnotationType the subclass type of the parameter annotation
043     * @param nameIndex Index pointing to the name <em>Code</em>
044     * @param length Content length in bytes
045     * @param input Input stream
046     * @param constantPool Array of constants
047     */
048    ParameterAnnotations(final byte parameterAnnotationType, final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool)
049        throws IOException {
050        this(parameterAnnotationType, nameIndex, length, (ParameterAnnotationEntry[]) null, constantPool);
051        final int numParameters = input.readUnsignedByte();
052        parameterAnnotationTable = new ParameterAnnotationEntry[numParameters];
053        for (int i = 0; i < numParameters; i++) {
054            parameterAnnotationTable[i] = new ParameterAnnotationEntry(input, constantPool);
055        }
056    }
057
058    /**
059     * Constructs a new instance.
060     *
061     * @param parameterAnnotationType the subclass type of the parameter annotation
062     * @param nameIndex Index pointing to the name <em>Code</em>
063     * @param length Content length in bytes
064     * @param parameterAnnotationTable the actual parameter annotations
065     * @param constantPool Array of constants
066     */
067    public ParameterAnnotations(final byte parameterAnnotationType, final int nameIndex, final int length,
068        final ParameterAnnotationEntry[] parameterAnnotationTable, final ConstantPool constantPool) {
069        super(parameterAnnotationType, nameIndex, length, constantPool);
070        this.parameterAnnotationTable = parameterAnnotationTable;
071    }
072
073    /**
074     * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
075     * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
076     *
077     * @param v Visitor object
078     */
079    @Override
080    public void accept(final Visitor v) {
081        v.visitParameterAnnotation(this);
082    }
083
084    /**
085     * @return deep copy of this attribute
086     */
087    @Override
088    public Attribute copy(final ConstantPool constantPool) {
089        return (Attribute) clone();
090    }
091
092    @Override
093    public void dump(final DataOutputStream dos) throws IOException {
094        super.dump(dos);
095        dos.writeByte(parameterAnnotationTable.length);
096
097        for (final ParameterAnnotationEntry element : parameterAnnotationTable) {
098            element.dump(dos);
099        }
100
101    }
102
103    /**
104     * returns the array of parameter annotation entries in this parameter annotation
105     */
106    public ParameterAnnotationEntry[] getParameterAnnotationEntries() {
107        return parameterAnnotationTable;
108    }
109
110    /**
111     * @return the parameter annotation entry table
112     */
113    public final ParameterAnnotationEntry[] getParameterAnnotationTable() {
114        return parameterAnnotationTable;
115    }
116
117    @Override
118    public Iterator<ParameterAnnotationEntry> iterator() {
119        return Stream.of(parameterAnnotationTable).iterator();
120    }
121
122    /**
123     * @param parameterAnnotationTable the entries to set in this parameter annotation
124     */
125    public final void setParameterAnnotationTable(final ParameterAnnotationEntry[] parameterAnnotationTable) {
126        this.parameterAnnotationTable = parameterAnnotationTable != null ? parameterAnnotationTable : EMPTY_ARRAY;
127    }
128}