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