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 */ 132 private final Map[] layouts = { classLayouts, fieldLayouts, methodLayouts, codeLayouts }; 133 134 private final Map<AttributeLayout, NewAttributeBands> layoutsToBands = new HashMap<>(); 135 136 public AttributeLayoutMap() throws Pack200Exception { 137 for (final AttributeLayout defaultAttributeLayout : getDefaultAttributeLayouts()) { 138 add(defaultAttributeLayout); 139 } 140 } 141 142 public void add(final AttributeLayout layout) { 143 getLayout(layout.getContext()).put(Integer.valueOf(layout.getIndex()), layout); 144 } 145 146 public void add(final AttributeLayout layout, final NewAttributeBands newBands) { 147 add(layout); 148 layoutsToBands.put(layout, newBands); 149 } 150 151 /** 152 * The map should not contain the same layout and name combination more than once for each context. 153 * 154 * @throws Pack200Exception Thrown when the name layout/name combination exists twice for a context. 155 */ 156 public void checkMap() throws Pack200Exception { 157 for (final Map<Integer, AttributeLayout> map : layouts) { 158 Collection<AttributeLayout> c = map.values(); 159 if (!(c instanceof List)) { 160 c = new ArrayList<>(c); 161 } 162 final List<AttributeLayout> layouts = (List<AttributeLayout>) c; 163 for (int j = 0; j < layouts.size(); j++) { 164 final AttributeLayout layout1 = layouts.get(j); 165 for (int j2 = j + 1; j2 < layouts.size(); j2++) { 166 final AttributeLayout layout2 = layouts.get(j2); 167 if (layout1.getName().equals(layout2.getName()) 168 && layout1.getLayout().equals(layout2.getLayout())) { 169 throw new Pack200Exception( 170 "Same layout/name combination: " + layout1.getLayout() + "/" + layout1.getName() 171 + " exists twice for context: " + AttributeLayout.contextNames[layout1.getContext()]); 172 } 173 } 174 } 175 } 176 } 177 178 public NewAttributeBands getAttributeBands(final AttributeLayout layout) { 179 return layoutsToBands.get(layout); 180 } 181 182 public AttributeLayout getAttributeLayout(final int index, final int context) { 183 final Map<Integer, AttributeLayout> map = getLayout(context); 184 return map.get(Integer.valueOf(index)); 185 } 186 187 public AttributeLayout getAttributeLayout(final String name, final int context) { 188 final Map<Integer, AttributeLayout> map = getLayout(context); 189 for (final AttributeLayout layout : map.values()) { 190 if (layout.getName().equals(name)) { 191 return layout; 192 } 193 } 194 return null; 195 } 196 197 private Map<Integer, AttributeLayout> getLayout(final int context) { 198 return layouts[context]; 199 } 200 201}