001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.compress.harmony.unpack200; 018 019import java.util.ArrayList; 020import java.util.Collection; 021import java.util.HashMap; 022import java.util.List; 023import java.util.Map; 024 025import org.apache.commons.compress.harmony.pack200.Pack200Exception; 026 027/** 028 * Stores a mapping from attribute names to their corresponding layout types. Note that names of attribute layouts and 029 * their formats are <em>not</em> internationalized, and should not be translated. 030 */ 031public class AttributeLayoutMap { 032 033 // Create all the default AttributeLayouts here 034 private static AttributeLayout[] getDefaultAttributeLayouts() throws Pack200Exception { 035 return new AttributeLayout[] { 036 new AttributeLayout(AttributeLayout.ACC_PUBLIC, AttributeLayout.CONTEXT_CLASS, "", 0), 037 new AttributeLayout(AttributeLayout.ACC_PUBLIC, AttributeLayout.CONTEXT_FIELD, "", 0), 038 new AttributeLayout(AttributeLayout.ACC_PUBLIC, AttributeLayout.CONTEXT_METHOD, "", 0), 039 new AttributeLayout(AttributeLayout.ACC_PRIVATE, AttributeLayout.CONTEXT_CLASS, "", 1), 040 new AttributeLayout(AttributeLayout.ACC_PRIVATE, AttributeLayout.CONTEXT_FIELD, "", 1), 041 new AttributeLayout(AttributeLayout.ACC_PRIVATE, AttributeLayout.CONTEXT_METHOD, "", 1), 042 new AttributeLayout(AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE, AttributeLayout.CONTEXT_CODE, "NH[PHH]", 043 1), 044 045 new AttributeLayout(AttributeLayout.ACC_PROTECTED, AttributeLayout.CONTEXT_CLASS, "", 2), 046 new AttributeLayout(AttributeLayout.ACC_PROTECTED, AttributeLayout.CONTEXT_FIELD, "", 2), 047 new AttributeLayout(AttributeLayout.ACC_PROTECTED, AttributeLayout.CONTEXT_METHOD, "", 2), 048 new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE, AttributeLayout.CONTEXT_CODE, 049 "NH[PHOHRUHRSHH]", 2), 050 051 new AttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_CLASS, "", 3), 052 new AttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_FIELD, "", 3), 053 new AttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_METHOD, "", 3), 054 new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE, AttributeLayout.CONTEXT_CODE, 055 "NH[PHOHRUHRSHH]", 3), 056 057 new AttributeLayout(AttributeLayout.ACC_FINAL, AttributeLayout.CONTEXT_CLASS, "", 4), 058 new AttributeLayout(AttributeLayout.ACC_FINAL, AttributeLayout.CONTEXT_FIELD, "", 4), 059 new AttributeLayout(AttributeLayout.ACC_FINAL, AttributeLayout.CONTEXT_METHOD, "", 4), 060 new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED, AttributeLayout.CONTEXT_CLASS, "", 5), 061 new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED, AttributeLayout.CONTEXT_FIELD, "", 5), 062 new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED, AttributeLayout.CONTEXT_METHOD, "", 5), 063 new AttributeLayout(AttributeLayout.ACC_VOLATILE, AttributeLayout.CONTEXT_CLASS, "", 6), 064 new AttributeLayout(AttributeLayout.ACC_VOLATILE, AttributeLayout.CONTEXT_FIELD, "", 6), 065 new AttributeLayout(AttributeLayout.ACC_VOLATILE, AttributeLayout.CONTEXT_METHOD, "", 6), 066 new AttributeLayout(AttributeLayout.ACC_TRANSIENT, AttributeLayout.CONTEXT_CLASS, "", 7), 067 new AttributeLayout(AttributeLayout.ACC_TRANSIENT, AttributeLayout.CONTEXT_FIELD, "", 7), 068 new AttributeLayout(AttributeLayout.ACC_TRANSIENT, AttributeLayout.CONTEXT_METHOD, "", 7), 069 new AttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_CLASS, "", 8), 070 new AttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_FIELD, "", 8), 071 new AttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_METHOD, "", 8), 072 new AttributeLayout(AttributeLayout.ACC_INTERFACE, AttributeLayout.CONTEXT_CLASS, "", 9), 073 new AttributeLayout(AttributeLayout.ACC_INTERFACE, AttributeLayout.CONTEXT_FIELD, "", 9), 074 new AttributeLayout(AttributeLayout.ACC_INTERFACE, AttributeLayout.CONTEXT_METHOD, "", 9), 075 new AttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_CLASS, "", 10), 076 new AttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_FIELD, "", 10), 077 new AttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_METHOD, "", 10), 078 new AttributeLayout(AttributeLayout.ACC_STRICT, AttributeLayout.CONTEXT_CLASS, "", 11), 079 new AttributeLayout(AttributeLayout.ACC_STRICT, AttributeLayout.CONTEXT_FIELD, "", 11), 080 new AttributeLayout(AttributeLayout.ACC_STRICT, AttributeLayout.CONTEXT_METHOD, "", 11), 081 new AttributeLayout(AttributeLayout.ACC_SYNTHETIC, AttributeLayout.CONTEXT_CLASS, "", 12), 082 new AttributeLayout(AttributeLayout.ACC_SYNTHETIC, AttributeLayout.CONTEXT_FIELD, "", 12), 083 new AttributeLayout(AttributeLayout.ACC_SYNTHETIC, AttributeLayout.CONTEXT_METHOD, "", 12), 084 new AttributeLayout(AttributeLayout.ACC_ANNOTATION, AttributeLayout.CONTEXT_CLASS, "", 13), 085 new AttributeLayout(AttributeLayout.ACC_ANNOTATION, AttributeLayout.CONTEXT_FIELD, "", 13), 086 new AttributeLayout(AttributeLayout.ACC_ANNOTATION, AttributeLayout.CONTEXT_METHOD, "", 13), 087 new AttributeLayout(AttributeLayout.ACC_ENUM, AttributeLayout.CONTEXT_CLASS, "", 14), 088 new AttributeLayout(AttributeLayout.ACC_ENUM, AttributeLayout.CONTEXT_FIELD, "", 14), 089 new AttributeLayout(AttributeLayout.ACC_ENUM, AttributeLayout.CONTEXT_METHOD, "", 14), 090 new AttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE, AttributeLayout.CONTEXT_CLASS, "RUNH", 17), 091 new AttributeLayout(AttributeLayout.ATTRIBUTE_CONSTANT_VALUE, AttributeLayout.CONTEXT_FIELD, "KQH", 17), 092 new AttributeLayout(AttributeLayout.ATTRIBUTE_CODE, AttributeLayout.CONTEXT_METHOD, "", 17), 093 new AttributeLayout(AttributeLayout.ATTRIBUTE_ENCLOSING_METHOD, AttributeLayout.CONTEXT_CLASS, "RCHRDNH", 094 18), 095 new AttributeLayout(AttributeLayout.ATTRIBUTE_EXCEPTIONS, AttributeLayout.CONTEXT_METHOD, "NH[RCH]", 18), 096 new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_CLASS, "RSH", 19), 097 new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_FIELD, "RSH", 19), 098 new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_METHOD, "RSH", 19), 099 new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_CLASS, "", 20), 100 new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_FIELD, "", 20), 101 new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_METHOD, "", 20), 102 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_CLASS, 103 "*", 21), 104 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_FIELD, 105 "*", 21), 106 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_METHOD, 107 "*", 21), 108 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_CLASS, 109 "*", 22), 110 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_FIELD, 111 "*", 22), 112 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_METHOD, 113 "*", 22), 114 new AttributeLayout(AttributeLayout.ATTRIBUTE_INNER_CLASSES, AttributeLayout.CONTEXT_CLASS, "", 23), 115 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, 116 AttributeLayout.CONTEXT_METHOD, "*", 23), 117 new AttributeLayout(AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION, AttributeLayout.CONTEXT_CLASS, "", 24), 118 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, 119 AttributeLayout.CONTEXT_METHOD, "*", 24), 120 new AttributeLayout(AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT, AttributeLayout.CONTEXT_METHOD, "*", 25)}; 121 } 122 123 private final Map<Integer, AttributeLayout> classLayouts = new HashMap<>(); 124 private final Map<Integer, AttributeLayout> fieldLayouts = new HashMap<>(); 125 private final Map<Integer, AttributeLayout> methodLayouts = new HashMap<>(); 126 private final Map<Integer, AttributeLayout> codeLayouts = new HashMap<>(); 127 128 /** 129 * The order of the maps in this array should not be changed as their indices correspond to the value of their context constants 130 * (AttributeLayout.CONTEXT_CLASS etc.) 131 * <p> 132 * All elements are of type {@code Map<Integer, AttributeLayout>}. 133 * </p> 134 */ 135 @SuppressWarnings("unchecked") // Cannot create a generic array 136 private final Map<Integer, AttributeLayout>[] layouts = new Map[] { classLayouts, fieldLayouts, methodLayouts, codeLayouts }; 137 138 private final Map<AttributeLayout, NewAttributeBands> layoutsToBands = new HashMap<>(); 139 140 public AttributeLayoutMap() throws Pack200Exception { 141 for (final AttributeLayout defaultAttributeLayout : getDefaultAttributeLayouts()) { 142 add(defaultAttributeLayout); 143 } 144 } 145 146 public void add(final AttributeLayout layout) { 147 getLayout(layout.getContext()).put(Integer.valueOf(layout.getIndex()), layout); 148 } 149 150 public void add(final AttributeLayout layout, final NewAttributeBands newBands) { 151 add(layout); 152 layoutsToBands.put(layout, newBands); 153 } 154 155 /** 156 * The map should not contain the same layout and name combination more than once for each context. 157 * 158 * @throws Pack200Exception Thrown when the name layout/name combination exists twice for a context. 159 */ 160 public void checkMap() throws Pack200Exception { 161 for (final Map<Integer, AttributeLayout> map : layouts) { 162 Collection<AttributeLayout> c = map.values(); 163 if (!(c instanceof List)) { 164 c = new ArrayList<>(c); 165 } 166 final List<AttributeLayout> layouts = (List<AttributeLayout>) c; 167 for (int j = 0; j < layouts.size(); j++) { 168 final AttributeLayout layout1 = layouts.get(j); 169 for (int j2 = j + 1; j2 < layouts.size(); j2++) { 170 final AttributeLayout layout2 = layouts.get(j2); 171 if (layout1.getName().equals(layout2.getName()) 172 && layout1.getLayout().equals(layout2.getLayout())) { 173 throw new Pack200Exception( 174 "Same layout/name combination: " + layout1.getLayout() + "/" + layout1.getName() 175 + " exists twice for context: " + AttributeLayout.contextNames[layout1.getContext()]); 176 } 177 } 178 } 179 } 180 } 181 182 public NewAttributeBands getAttributeBands(final AttributeLayout layout) { 183 return layoutsToBands.get(layout); 184 } 185 186 public AttributeLayout getAttributeLayout(final int index, final int context) { 187 final Map<Integer, AttributeLayout> map = getLayout(context); 188 return map.get(Integer.valueOf(index)); 189 } 190 191 public AttributeLayout getAttributeLayout(final String name, final int context) { 192 final Map<Integer, AttributeLayout> map = getLayout(context); 193 for (final AttributeLayout layout : map.values()) { 194 if (layout.getName().equals(name)) { 195 return layout; 196 } 197 } 198 return null; 199 } 200 201 private Map<Integer, AttributeLayout> getLayout(final int context) { 202 return layouts[context]; 203 } 204 205}