    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.Arrays;
    024
    025/**
    026 * Exceptions class file attribute
    027 */
    028public class ExceptionsAttribute extends Attribute {
    029
    030    private static CPUTF8 attributeName;
    031
    032    private static int hashCode(final Object[] array) {
    033        final int prime = 31;
    034        if (array == null) {
    035            return 0;
    036        }
    037        int result = 1;
    038        for (final Object element : array) {
    039            result = prime * result + (element == null ? 0 : element.hashCode());
    040        }
    041        return result;
    042    }
    043
    044    public static void setAttributeName(final CPUTF8 cpUTF8Value) {
    045        attributeName = cpUTF8Value;
    046    }
    047
    048    private transient int[] exceptionIndexes;
    049
    050    private final CPClass[] exceptions;
    051
    052    public ExceptionsAttribute(final CPClass[] exceptions) {
    053        super(attributeName);
    054        this.exceptions = exceptions;
    055    }
    056
    057    @Override
    058    public boolean equals(final Object obj) {
    059        if (this == obj) {
    060            return true;
    061        }
    062        if (!super.equals(obj) || getClass() != obj.getClass()) {
    063            return false;
    064        }
    065        final ExceptionsAttribute other = (ExceptionsAttribute) obj;
    066        if (!Arrays.equals(exceptions, other.exceptions)) {
    067            return false;
    068        }
    069        return true;
    070    }
    071
    072    @Override
    073    protected int getLength() {
    074        return 2 + 2 * exceptions.length;
    075    }
    076
    077    @Override
    078    protected ClassFileEntry[] getNestedClassFileEntries() {
    079        final ClassFileEntry[] result = new ClassFileEntry[exceptions.length + 1];
    080        System.arraycopy(exceptions, 0, result, 0, exceptions.length);
    081        result[exceptions.length] = getAttributeName();
    082        return result;
    083    }
    084
    085    @Override
    086    public int hashCode() {
    087        final int prime = 31;
    088        int result = super.hashCode();
    089        result = prime * result + hashCode(exceptions);
    090        return result;
    091    }
    092
    093    @Override
    094    protected void resolve(final ClassConstantPool pool) {
    095        super.resolve(pool);
    096        exceptionIndexes = new int[exceptions.length];
    097        for (int i = 0; i < exceptions.length; i++) {
    098            exceptions[i].resolve(pool);
    099            exceptionIndexes[i] = pool.indexOf(exceptions[i]);
    100        }
    101    }
    102
    103    @Override
    104    public String toString() {
    105        final StringBuilder sb = new StringBuilder("Exceptions: ");
    106        for (final CPClass exception : exceptions) {
    107            sb.append(exception);
    108            sb.append(' ');
    109        }
    110        return sb.toString();
    111    }
    112
    113    @Override
    114    protected void writeBody(final DataOutputStream dos) throws IOException {
    115        dos.writeShort(exceptionIndexes.length);
    116        for (final int element : exceptionIndexes) {
    117            dos.writeShort(element);
    118        }
    119    }
    120
    121}