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