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