NewAttribute.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.harmony.pack200;

  18. import org.objectweb.asm.Attribute;
  19. import org.objectweb.asm.ClassReader;
  20. import org.objectweb.asm.Label;

  21. /**
  22.  * NewAttribute extends {@code Attribute} and manages unknown attributes encountered by ASM that have had a layout definition given to pack200 (e.g. via one of
  23.  * the -C, -M, -F or -D command line options)
  24.  */
  25. public class NewAttribute extends Attribute {

  26.     /**
  27.      * ErrorAttribute extends {@code NewAttribute} and manages attributes encountered by ASM that have had an error action specified to pack200 (e.g. via one of
  28.      * the -C, -M, -F or -D command line options such as -Cattribute-name=error)
  29.      */
  30.     public static class ErrorAttribute extends NewAttribute {

  31.         public ErrorAttribute(final String type, final int context) {
  32.             super(type, "", context);
  33.         }

  34.         @Override
  35.         protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, final Label[] labels) {
  36.             throw new Error("Attribute " + type + " was found");
  37.         }

  38.     }

  39.     /**
  40.      * PassAttribute extends {@code NewAttribute} and manages attributes encountered by ASM that have had a pass action specified to pack200 (e.g. via one of
  41.      * the -C, -M, -F or -D command line options such as -Cattribute-name=pass)
  42.      */
  43.     public static class PassAttribute extends NewAttribute {

  44.         public PassAttribute(final String type, final int context) {
  45.             super(type, "", context);
  46.         }

  47.         @Override
  48.         protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, final Label[] labels) {
  49.             throw new Segment.PassException();
  50.         }

  51.     }

  52.     /**
  53.      * StripAttribute extends {@code NewAttribute} and manages attributes encountered by ASM that have had a strip action specified to pack200 (e.g. via one of
  54.      * the -C, -M, -F or -D command line options such as -Cattribute-name=strip)
  55.      */
  56.     public static class StripAttribute extends NewAttribute {

  57.         public StripAttribute(final String type, final int context) {
  58.             super(type, "", context);
  59.         }

  60.         @Override
  61.         protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, final Label[] labels) {
  62.             // TODO Not sure if this works, can we really strip an attribute if we don't know the layout?
  63.             return null;
  64.         }
  65.     }

  66.     private boolean contextClass;

  67.     private boolean contextMethod;
  68.     private boolean contextField;
  69.     private boolean contextCode;
  70.     private final String layout;
  71.     private byte[] contents;
  72.     private int codeOff;

  73.     private Label[] labels;

  74.     private ClassReader classReader;

  75.     private char[] buf;

  76.     public NewAttribute(final ClassReader classReader, final String type, final String layout, final byte[] contents, final char[] buf, final int codeOff,
  77.             final Label[] labels) {
  78.         super(type);
  79.         this.classReader = classReader;
  80.         this.contents = contents;
  81.         this.layout = layout;
  82.         this.codeOff = codeOff;
  83.         this.labels = labels;
  84.         this.buf = buf;
  85.     }

  86.     public NewAttribute(final String type, final String layout, final int context) {
  87.         super(type);
  88.         this.layout = layout;
  89.         addContext(context);
  90.     }

  91.     public void addContext(final int context) {
  92.         switch (context) {
  93.         case AttributeDefinitionBands.CONTEXT_CLASS:
  94.             contextClass = true;
  95.             break;
  96.         case AttributeDefinitionBands.CONTEXT_METHOD:
  97.             contextMethod = true;
  98.             break;
  99.         case AttributeDefinitionBands.CONTEXT_FIELD:
  100.             contextField = true;
  101.             break;
  102.         case AttributeDefinitionBands.CONTEXT_CODE:
  103.             contextCode = true;
  104.             break;
  105.         }
  106.     }

  107.     public byte[] getBytes() {
  108.         return contents;
  109.     }

  110.     public Label getLabel(final int index) {
  111.         return labels[index];
  112.     }

  113.     public String getLayout() {
  114.         return layout;
  115.     }

  116.     @Override
  117.     public boolean isCodeAttribute() {
  118.         return codeOff != -1;
  119.     }

  120.     public boolean isContextClass() {
  121.         return contextClass;
  122.     }

  123.     public boolean isContextCode() {
  124.         return contextCode;
  125.     }

  126.     public boolean isContextField() {
  127.         return contextField;
  128.     }

  129.     public boolean isContextMethod() {
  130.         return contextMethod;
  131.     }

  132.     @Override
  133.     public boolean isUnknown() {
  134.         return false;
  135.     }

  136.     public boolean isUnknown(final int context) {
  137.         switch (context) {
  138.         case AttributeDefinitionBands.CONTEXT_CLASS:
  139.             return !contextClass;
  140.         case AttributeDefinitionBands.CONTEXT_METHOD:
  141.             return !contextMethod;
  142.         case AttributeDefinitionBands.CONTEXT_FIELD:
  143.             return !contextField;
  144.         case AttributeDefinitionBands.CONTEXT_CODE:
  145.             return !contextCode;
  146.         }
  147.         return false;
  148.     }

  149.     @Override
  150.     protected Attribute read(final ClassReader cr, final int off, final int len, final char[] buf, final int codeOff, final Label[] labels) {
  151.         final byte[] attributeContents = new byte[len];
  152.         System.arraycopy(cr.b, off, attributeContents, 0, len);
  153.         return new NewAttribute(cr, type, layout, attributeContents, buf, codeOff, labels);
  154.     }

  155.     public String readClass(final int index) {
  156.         return classReader.readClass(index, buf);
  157.     }

  158.     public Object readConst(final int index) {
  159.         return classReader.readConst(index, buf);
  160.     }

  161.     public String readUTF8(final int index) {
  162.         return classReader.readUTF8(index, buf);
  163.     }
  164. }