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 their formats are <em>not</em> 029 * 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[] { new AttributeLayout(AttributeLayout.ACC_PUBLIC, AttributeLayout.CONTEXT_CLASS, "", 0), 036 new AttributeLayout(AttributeLayout.ACC_PUBLIC, AttributeLayout.CONTEXT_FIELD, "", 0), 037 new AttributeLayout(AttributeLayout.ACC_PUBLIC, AttributeLayout.CONTEXT_METHOD, "", 0), 038 new AttributeLayout(AttributeLayout.ACC_PRIVATE, AttributeLayout.CONTEXT_CLASS, "", 1), 039 new AttributeLayout(AttributeLayout.ACC_PRIVATE, AttributeLayout.CONTEXT_FIELD, "", 1), 040 new AttributeLayout(AttributeLayout.ACC_PRIVATE, AttributeLayout.CONTEXT_METHOD, "", 1), 041 new AttributeLayout(AttributeLayout.ATTRIBUTE_LINE_NUMBER_TABLE, AttributeLayout.CONTEXT_CODE, "NH[PHH]", 1), 042 043 new AttributeLayout(AttributeLayout.ACC_PROTECTED, AttributeLayout.CONTEXT_CLASS, "", 2), 044 new AttributeLayout(AttributeLayout.ACC_PROTECTED, AttributeLayout.CONTEXT_FIELD, "", 2), 045 new AttributeLayout(AttributeLayout.ACC_PROTECTED, AttributeLayout.CONTEXT_METHOD, "", 2), 046 new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TABLE, AttributeLayout.CONTEXT_CODE, "NH[PHOHRUHRSHH]", 2), 047 048 new AttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_CLASS, "", 3), 049 new AttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_FIELD, "", 3), 050 new AttributeLayout(AttributeLayout.ACC_STATIC, AttributeLayout.CONTEXT_METHOD, "", 3), 051 new AttributeLayout(AttributeLayout.ATTRIBUTE_LOCAL_VARIABLE_TYPE_TABLE, AttributeLayout.CONTEXT_CODE, "NH[PHOHRUHRSHH]", 3), 052 053 new AttributeLayout(AttributeLayout.ACC_FINAL, AttributeLayout.CONTEXT_CLASS, "", 4), 054 new AttributeLayout(AttributeLayout.ACC_FINAL, AttributeLayout.CONTEXT_FIELD, "", 4), 055 new AttributeLayout(AttributeLayout.ACC_FINAL, AttributeLayout.CONTEXT_METHOD, "", 4), 056 new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED, AttributeLayout.CONTEXT_CLASS, "", 5), 057 new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED, AttributeLayout.CONTEXT_FIELD, "", 5), 058 new AttributeLayout(AttributeLayout.ACC_SYNCHRONIZED, AttributeLayout.CONTEXT_METHOD, "", 5), 059 new AttributeLayout(AttributeLayout.ACC_VOLATILE, AttributeLayout.CONTEXT_CLASS, "", 6), 060 new AttributeLayout(AttributeLayout.ACC_VOLATILE, AttributeLayout.CONTEXT_FIELD, "", 6), 061 new AttributeLayout(AttributeLayout.ACC_VOLATILE, AttributeLayout.CONTEXT_METHOD, "", 6), 062 new AttributeLayout(AttributeLayout.ACC_TRANSIENT, AttributeLayout.CONTEXT_CLASS, "", 7), 063 new AttributeLayout(AttributeLayout.ACC_TRANSIENT, AttributeLayout.CONTEXT_FIELD, "", 7), 064 new AttributeLayout(AttributeLayout.ACC_TRANSIENT, AttributeLayout.CONTEXT_METHOD, "", 7), 065 new AttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_CLASS, "", 8), 066 new AttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_FIELD, "", 8), 067 new AttributeLayout(AttributeLayout.ACC_NATIVE, AttributeLayout.CONTEXT_METHOD, "", 8), 068 new AttributeLayout(AttributeLayout.ACC_INTERFACE, AttributeLayout.CONTEXT_CLASS, "", 9), 069 new AttributeLayout(AttributeLayout.ACC_INTERFACE, AttributeLayout.CONTEXT_FIELD, "", 9), 070 new AttributeLayout(AttributeLayout.ACC_INTERFACE, AttributeLayout.CONTEXT_METHOD, "", 9), 071 new AttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_CLASS, "", 10), 072 new AttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_FIELD, "", 10), 073 new AttributeLayout(AttributeLayout.ACC_ABSTRACT, AttributeLayout.CONTEXT_METHOD, "", 10), 074 new AttributeLayout(AttributeLayout.ACC_STRICT, AttributeLayout.CONTEXT_CLASS, "", 11), 075 new AttributeLayout(AttributeLayout.ACC_STRICT, AttributeLayout.CONTEXT_FIELD, "", 11), 076 new AttributeLayout(AttributeLayout.ACC_STRICT, AttributeLayout.CONTEXT_METHOD, "", 11), 077 new AttributeLayout(AttributeLayout.ACC_SYNTHETIC, AttributeLayout.CONTEXT_CLASS, "", 12), 078 new AttributeLayout(AttributeLayout.ACC_SYNTHETIC, AttributeLayout.CONTEXT_FIELD, "", 12), 079 new AttributeLayout(AttributeLayout.ACC_SYNTHETIC, AttributeLayout.CONTEXT_METHOD, "", 12), 080 new AttributeLayout(AttributeLayout.ACC_ANNOTATION, AttributeLayout.CONTEXT_CLASS, "", 13), 081 new AttributeLayout(AttributeLayout.ACC_ANNOTATION, AttributeLayout.CONTEXT_FIELD, "", 13), 082 new AttributeLayout(AttributeLayout.ACC_ANNOTATION, AttributeLayout.CONTEXT_METHOD, "", 13), 083 new AttributeLayout(AttributeLayout.ACC_ENUM, AttributeLayout.CONTEXT_CLASS, "", 14), 084 new AttributeLayout(AttributeLayout.ACC_ENUM, AttributeLayout.CONTEXT_FIELD, "", 14), 085 new AttributeLayout(AttributeLayout.ACC_ENUM, AttributeLayout.CONTEXT_METHOD, "", 14), 086 new AttributeLayout(AttributeLayout.ATTRIBUTE_SOURCE_FILE, AttributeLayout.CONTEXT_CLASS, "RUNH", 17), 087 new AttributeLayout(AttributeLayout.ATTRIBUTE_CONSTANT_VALUE, AttributeLayout.CONTEXT_FIELD, "KQH", 17), 088 new AttributeLayout(AttributeLayout.ATTRIBUTE_CODE, AttributeLayout.CONTEXT_METHOD, "", 17), 089 new AttributeLayout(AttributeLayout.ATTRIBUTE_ENCLOSING_METHOD, AttributeLayout.CONTEXT_CLASS, "RCHRDNH", 18), 090 new AttributeLayout(AttributeLayout.ATTRIBUTE_EXCEPTIONS, AttributeLayout.CONTEXT_METHOD, "NH[RCH]", 18), 091 new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_CLASS, "RSH", 19), 092 new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_FIELD, "RSH", 19), 093 new AttributeLayout(AttributeLayout.ATTRIBUTE_SIGNATURE, AttributeLayout.CONTEXT_METHOD, "RSH", 19), 094 new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_CLASS, "", 20), 095 new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_FIELD, "", 20), 096 new AttributeLayout(AttributeLayout.ATTRIBUTE_DEPRECATED, AttributeLayout.CONTEXT_METHOD, "", 20), 097 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_CLASS, "*", 21), 098 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_FIELD, "*", 21), 099 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_METHOD, "*", 21), 100 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_CLASS, "*", 22), 101 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_FIELD, "*", 22), 102 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeLayout.CONTEXT_METHOD, "*", 22), 103 new AttributeLayout(AttributeLayout.ATTRIBUTE_INNER_CLASSES, AttributeLayout.CONTEXT_CLASS, "", 23), 104 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, AttributeLayout.CONTEXT_METHOD, "*", 23), 105 new AttributeLayout(AttributeLayout.ATTRIBUTE_CLASS_FILE_VERSION, AttributeLayout.CONTEXT_CLASS, "", 24), 106 new AttributeLayout(AttributeLayout.ATTRIBUTE_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, AttributeLayout.CONTEXT_METHOD, "*", 24), 107 new AttributeLayout(AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT, AttributeLayout.CONTEXT_METHOD, "*", 25) }; 108 } 109 110 private final Map<Integer, AttributeLayout> classLayouts = new HashMap<>(); 111 private final Map<Integer, AttributeLayout> fieldLayouts = new HashMap<>(); 112 private final Map<Integer, AttributeLayout> methodLayouts = new HashMap<>(); 113 private final Map<Integer, AttributeLayout> codeLayouts = new HashMap<>(); 114 115 /** 116 * The order of the maps in this array should not be changed as their indices correspond to the value of their context constants 117 * (AttributeLayout.CONTEXT_CLASS etc.) 118 * <p> 119 * All elements are of type {@code Map<Integer, AttributeLayout>}. 120 * </p> 121 */ 122 @SuppressWarnings("unchecked") // Cannot create a generic array 123 private final Map<Integer, AttributeLayout>[] layouts = new Map[] { classLayouts, fieldLayouts, methodLayouts, codeLayouts }; 124 125 private final Map<AttributeLayout, NewAttributeBands> layoutsToBands = new HashMap<>(); 126 127 public AttributeLayoutMap() throws Pack200Exception { 128 for (final AttributeLayout defaultAttributeLayout : getDefaultAttributeLayouts()) { 129 add(defaultAttributeLayout); 130 } 131 } 132 133 public void add(final AttributeLayout layout) { 134 getLayout(layout.getContext()).put(Integer.valueOf(layout.getIndex()), layout); 135 } 136 137 public void add(final AttributeLayout layout, final NewAttributeBands newBands) { 138 add(layout); 139 layoutsToBands.put(layout, newBands); 140 } 141 142 /** 143 * The map should not contain the same layout and name combination more than once for each context. 144 * 145 * @throws Pack200Exception Thrown when the name layout/name combination exists twice for a context. 146 */ 147 public void checkMap() throws Pack200Exception { 148 for (final Map<Integer, AttributeLayout> map : layouts) { 149 Collection<AttributeLayout> c = map.values(); 150 if (!(c instanceof List)) { 151 c = new ArrayList<>(c); 152 } 153 final List<AttributeLayout> layouts = (List<AttributeLayout>) c; 154 for (int j = 0; j < layouts.size(); j++) { 155 final AttributeLayout layout1 = layouts.get(j); 156 for (int j2 = j + 1; j2 < layouts.size(); j2++) { 157 final AttributeLayout layout2 = layouts.get(j2); 158 if (layout1.getName().equals(layout2.getName()) && layout1.getLayout().equals(layout2.getLayout())) { 159 throw new Pack200Exception("Same layout/name combination: " + layout1.getLayout() + "/" + layout1.getName() 160 + " exists twice for context: " + AttributeLayout.contextNames[layout1.getContext()]); 161 } 162 } 163 } 164 } 165 } 166 167 public NewAttributeBands getAttributeBands(final AttributeLayout layout) { 168 return layoutsToBands.get(layout); 169 } 170 171 public AttributeLayout getAttributeLayout(final int index, final int context) { 172 final Map<Integer, AttributeLayout> map = getLayout(context); 173 return map.get(Integer.valueOf(index)); 174 } 175 176 public AttributeLayout getAttributeLayout(final String name, final int context) { 177 final Map<Integer, AttributeLayout> map = getLayout(context); 178 for (final AttributeLayout layout : map.values()) { 179 if (layout.getName().equals(name)) { 180 return layout; 181 } 182 } 183 return null; 184 } 185 186 private Map<Integer, AttributeLayout> getLayout(final int context) { 187 return layouts[context]; 188 } 189 190}