    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.commons.compress.harmony.unpack200.bytecode;
    020
    021import java.io.DataOutputStream;
    022import java.io.IOException;
    023import java.util.ArrayList;
    024import java.util.List;
    025
    026/**
    027 * Parameter annotations class file attribute, either a RuntimeVisibleParameterAnnotations attribute or a RuntimeInvisibleParameterAnnotations attribute.
    028 */
    029public class RuntimeVisibleorInvisibleParameterAnnotationsAttribute extends AnnotationsAttribute {
    030
    031    /**
    032     * ParameterAnnotation represents the annotations on a single parameter.
    033     */
    034    public static class ParameterAnnotation {
    035
    036        private final Annotation[] annotations;
    037
    038        /**
    039         * Constructs a new instance.
    040         *
    041         * @param annotations Annotation.
    042         */
    043        public ParameterAnnotation(final Annotation[] annotations) {
    044            this.annotations = annotations;
    045        }
    046
    047        /**
    048         * Gets all annotation class file entries.
    049         *
    050         * @return all annotation class file entries.
    051         */
    052        public List<Object> getClassFileEntries() {
    053            final List<Object> nested = new ArrayList<>();
    054            for (final Annotation annotation : annotations) {
    055                nested.addAll(annotation.getClassFileEntries());
    056            }
    057            return nested;
    058        }
    059
    060        /**
    061         * Gets the cumulative length of all annotations.
    062         *
    063         * @return the cumulative length of all annotations.
    064         */
    065        public int getLength() {
    066            int length = 2;
    067            for (final Annotation annotation : annotations) {
    068                length += annotation.getLength();
    069            }
    070            return length;
    071        }
    072
    073        /**
    074         * Resolves all annotations in this instance against the given pool.
    075         *
    076         * @param pool A class constant pool.
    077         */
    078        public void resolve(final ClassConstantPool pool) {
    079            for (final Annotation annotation : annotations) {
    080                annotation.resolve(pool);
    081            }
    082        }
    083
    084        /**
    085         * Writes this body to the given output stream.
    086         *
    087         * @param dos the output stream.
    088         * @throws IOException if an I/O error occurs.
    089         */
    090        public void writeBody(final DataOutputStream dos) throws IOException {
    091            dos.writeShort(annotations.length);
    092            for (final Annotation annotation : annotations) {
    093                annotation.writeBody(dos);
    094            }
    095        }
    096
    097    }
    098
    099    private final ParameterAnnotation[] parameterAnnotations;
    100
    101    /**
    102     * Constructs a new instance for an attribute name.
    103     *
    104     * @param name an attribute name.
    105     * @param parameterAnnotations Annotations.
    106     */
    107    public RuntimeVisibleorInvisibleParameterAnnotationsAttribute(final CPUTF8 name, final ParameterAnnotation[] parameterAnnotations) {
    108        super(name);
    109        this.parameterAnnotations = parameterAnnotations;
    110    }
    111
    112    @Override
    113    protected int getLength() {
    114        int length = 1;
    115        for (final ParameterAnnotation parameterAnnotation : parameterAnnotations) {
    116            length += parameterAnnotation.getLength();
    117        }
    118        return length;
    119    }
    120
    121    @Override
    122    protected ClassFileEntry[] getNestedClassFileEntries() {
    123        final List<Object> nested = new ArrayList<>();
    124        nested.add(attributeName);
    125        for (final ParameterAnnotation parameterAnnotation : parameterAnnotations) {
    126            nested.addAll(parameterAnnotation.getClassFileEntries());
    127        }
    128        return nested.toArray(NONE);
    129    }
    130
    131    @Override
    132    protected void resolve(final ClassConstantPool pool) {
    133        super.resolve(pool);
    134        for (final ParameterAnnotation parameterAnnotation : parameterAnnotations) {
    135            parameterAnnotation.resolve(pool);
    136        }
    137    }
    138
    139    @Override
    140    public String toString() {
    141        return attributeName.underlyingString() + ": " + parameterAnnotations.length + " parameter annotations";
    142    }
    143
    144    @Override
    145    protected void writeBody(final DataOutputStream dos) throws IOException {
    146        dos.writeByte(parameterAnnotations.length);
    147        for (final ParameterAnnotation parameterAnnotation : parameterAnnotations) {
    148            parameterAnnotation.writeBody(dos);
    149        }
    150    }
    151
    152}