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