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.ArrayList;
025import java.util.Collections;
026import java.util.List;
027
028import org.apache.bcel.util.Args;
029
030/**
031 * represents one parameter annotation in the parameter annotation table
032 *
033 * @since 6.0
034 */
035public class ParameterAnnotationEntry implements Node {
036
037    static final ParameterAnnotationEntry[] EMPTY_ARRAY = {};
038
039    /**
040     * Creates parameter annotation entries from attributes.
041     *
042     * @param attributes The attributes.
043     * @return The parameter annotation entries.
044     */
045    public static ParameterAnnotationEntry[] createParameterAnnotationEntries(final Attribute[] attributes) {
046        if (attributes == null) {
047            return EMPTY_ARRAY;
048        }
049        // Find attributes that contain parameter annotation data
050        final List<ParameterAnnotationEntry> accumulatedAnnotations = new ArrayList<>(attributes.length);
051        for (final Attribute attribute : attributes) {
052            if (attribute instanceof ParameterAnnotations) {
053                final ParameterAnnotations runtimeAnnotations = (ParameterAnnotations) attribute;
054                final ParameterAnnotationEntry[] parameterAnnotationEntries = runtimeAnnotations.getParameterAnnotationEntries();
055                if (parameterAnnotationEntries != null) {
056                    Collections.addAll(accumulatedAnnotations, parameterAnnotationEntries);
057                }
058            }
059        }
060        return accumulatedAnnotations.toArray(EMPTY_ARRAY);
061    }
062
063    private final AnnotationEntry[] annotationTable;
064
065    /**
066     * Constructs object from input stream.
067     *
068     * @param input Input stream.
069     * @param constantPool The constant pool.
070     * @param isRuntimeVisible whether the contained annotations are runtime visible.
071     * @throws IOException Thrown if an I/O error occurs.
072     */
073    ParameterAnnotationEntry(final DataInput input, final ConstantPool constantPool, final boolean isRuntimeVisible) throws IOException {
074        final int annotationTableLength = input.readUnsignedShort();
075        annotationTable = new AnnotationEntry[annotationTableLength];
076        for (int i = 0; i < annotationTableLength; i++) {
077            annotationTable[i] = AnnotationEntry.read(input, constantPool, isRuntimeVisible);
078        }
079    }
080
081    /**
082     * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
083     * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
084     *
085     * @param v Visitor object.
086     */
087    @Override
088    public void accept(final Visitor v) {
089        v.visitParameterAnnotationEntry(this);
090    }
091
092    /**
093     * Dumps parameter annotation entry to file stream.
094     *
095     * @param dos Output file stream.
096     * @throws IOException Thrown if an I/O error occurs.
097     */
098    public void dump(final DataOutputStream dos) throws IOException {
099        dos.writeShort(Args.requireU2(annotationTable.length, "annotationTable.length"));
100        for (final AnnotationEntry entry : annotationTable) {
101            entry.dump(dos);
102        }
103    }
104
105    /**
106     * Gets the annotation entries.
107     *
108     * @return The array of annotation entries in this annotation.
109     */
110    public AnnotationEntry[] getAnnotationEntries() {
111        return annotationTable;
112    }
113}