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}