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.pack200; 018 019import org.objectweb.asm.Attribute; 020import org.objectweb.asm.ClassReader; 021import org.objectweb.asm.Label; 022 023/** 024 * NewAttribute extends <code>Attribute</code> and manages unknown attributes encountered by ASM that have had a layout 025 * definition given to pack200 (e.g. via one of the -C, -M, -F or -D command line options) 026 */ 027public class NewAttribute extends Attribute { 028 029 private boolean contextClass = false; 030 private boolean contextMethod = false; 031 private boolean contextField = false; 032 private boolean contextCode = false; 033 034 private final String layout; 035 private byte[] contents; 036 private int codeOff; 037 private Label[] labels; 038 private ClassReader classReader; 039 private char[] buf; 040 041 public NewAttribute(final String type, final String layout, final int context) { 042 super(type); 043 this.layout = layout; 044 addContext(context); 045 } 046 047 public NewAttribute(final ClassReader classReader, final String type, final String layout, final byte[] contents, 048 final char[] buf, final int codeOff, final Label[] labels) { 049 super(type); 050 this.classReader = classReader; 051 this.contents = contents; 052 this.layout = layout; 053 this.codeOff = codeOff; 054 this.labels = labels; 055 this.buf = buf; 056 } 057 058 public void addContext(final int context) { 059 switch (context) { 060 case AttributeDefinitionBands.CONTEXT_CLASS: 061 contextClass = true; 062 break; 063 case AttributeDefinitionBands.CONTEXT_METHOD: 064 contextMethod = true; 065 break; 066 case AttributeDefinitionBands.CONTEXT_FIELD: 067 contextField = true; 068 break; 069 case AttributeDefinitionBands.CONTEXT_CODE: 070 contextCode = true; 071 break; 072 } 073 } 074 075 public boolean isContextClass() { 076 return contextClass; 077 } 078 079 public boolean isContextMethod() { 080 return contextMethod; 081 } 082 083 public boolean isContextField() { 084 return contextField; 085 } 086 087 public boolean isContextCode() { 088 return contextCode; 089 } 090 091 public String getLayout() { 092 return layout; 093 } 094 095 @Override 096 public boolean isUnknown() { 097 return false; 098 } 099 100 @Override 101 public boolean isCodeAttribute() { 102 return codeOff != -1; 103 } 104 105 @Override 106 protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, 107 final Label[] labels) { 108 final byte[] attributeContents = new byte[len]; 109 System.arraycopy(cr.b, off, attributeContents, 0, len); 110 return new NewAttribute(cr, type, layout, attributeContents, buf, codeOff, labels); 111 } 112 113 public boolean isUnknown(final int context) { 114 switch (context) { 115 case AttributeDefinitionBands.CONTEXT_CLASS: 116 return !contextClass; 117 case AttributeDefinitionBands.CONTEXT_METHOD: 118 return !contextMethod; 119 case AttributeDefinitionBands.CONTEXT_FIELD: 120 return !contextField; 121 case AttributeDefinitionBands.CONTEXT_CODE: 122 return !contextCode; 123 } 124 return false; 125 } 126 127 public String readUTF8(final int index) { 128 return classReader.readUTF8(index, buf); 129 } 130 131 public String readClass(final int index) { 132 return classReader.readClass(index, buf); 133 } 134 135 public Object readConst(final int index) { 136 return classReader.readConst(index, buf); 137 } 138 139 public byte[] getBytes() { 140 return contents; 141 } 142 143 public Label getLabel(final int index) { 144 return labels[index]; 145 } 146 147 /** 148 * ErrorAttribute extends <code>NewAttribute</code> and manages attributes encountered by ASM that have had an error 149 * action specified to pack200 (e.g. via one of the -C, -M, -F or -D command line options such as 150 * -Cattribute-name=error) 151 */ 152 public static class ErrorAttribute extends NewAttribute { 153 154 public ErrorAttribute(final String type, final int context) { 155 super(type, "", context); 156 } 157 158 @Override 159 protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, 160 final int codeOff, final Label[] labels) { 161 throw new Error("Attribute " + type + " was found"); 162 } 163 164 } 165 166 /** 167 * StripAttribute extends <code>NewAttribute</code> and manages attributes encountered by ASM that have had an strip 168 * action specified to pack200 (e.g. via one of the -C, -M, -F or -D command line options such as 169 * -Cattribute-name=strip) 170 */ 171 public static class StripAttribute extends NewAttribute { 172 173 public StripAttribute(final String type, final int context) { 174 super(type, "", context); 175 } 176 177 @Override 178 protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, 179 final int codeOff, final Label[] labels) { 180 // TODO Not sure if this works, can we really strip an attribute if we don't know the layout? 181 return null; 182 } 183 } 184 185 /** 186 * PassAttribute extends <code>NewAttribute</code> and manages attributes encountered by ASM that have had an pass 187 * action specified to pack200 (e.g. via one of the -C, -M, -F or -D command line options such as 188 * -Cattribute-name=pass) 189 */ 190 public static class PassAttribute extends NewAttribute { 191 192 public PassAttribute(final String type, final int context) { 193 super(type, "", context); 194 } 195 196 @Override 197 protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, 198 final int codeOff, final Label[] labels) { 199 throw new Segment.PassException(); 200 } 201 202 } 203}