Synthetic.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.bcel.classfile;

  18. import java.io.DataInput;
  19. import java.io.DataOutputStream;
  20. import java.io.IOException;

  21. import org.apache.bcel.Const;
  22. import org.apache.bcel.util.Args;

  23. /**
  24.  * This class is derived from <em>Attribute</em> and declares this class as 'synthetic', i.e., it needs special
  25.  * handling. The JVM specification states "A class member that does not appear in the source code must be marked using a
  26.  * Synthetic attribute." It may appear in the ClassFile attribute table, a field_info table or a method_info table. This
  27.  * class is intended to be instantiated from the <em>Attribute.readAttribute()</em> method.
  28.  *
  29.  * @see Attribute
  30.  */
  31. public final class Synthetic extends Attribute {

  32.     private byte[] bytes;

  33.     /**
  34.      * @param nameIndex Index in constant pool to CONSTANT_Utf8, which should represent the string "Synthetic".
  35.      * @param length Content length in bytes - should be zero.
  36.      * @param bytes Attribute contents
  37.      * @param constantPool The constant pool this attribute is associated with.
  38.      */
  39.     public Synthetic(final int nameIndex, final int length, final byte[] bytes, final ConstantPool constantPool) {
  40.         super(Const.ATTR_SYNTHETIC, nameIndex, Args.require0(length, "Synthetic attribute length"), constantPool);
  41.         this.bytes = bytes;
  42.     }

  43.     /**
  44.      * Constructs object from input stream.
  45.      *
  46.      * @param nameIndex Index in constant pool to CONSTANT_Utf8
  47.      * @param length Content length in bytes
  48.      * @param input Input stream
  49.      * @param constantPool Array of constants
  50.      * @throws IOException if an I/O error occurs.
  51.      */
  52.     Synthetic(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
  53.         this(nameIndex, length, (byte[]) null, constantPool);
  54.         if (length > 0) {
  55.             bytes = new byte[length];
  56.             input.readFully(bytes);
  57.             println("Synthetic attribute with length > 0");
  58.         }
  59.     }

  60.     /**
  61.      * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a
  62.      * physical copy.
  63.      *
  64.      * @param c Source to copy.
  65.      */
  66.     public Synthetic(final Synthetic c) {
  67.         this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
  68.     }

  69.     /**
  70.      * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
  71.      * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
  72.      *
  73.      * @param v Visitor object
  74.      */
  75.     @Override
  76.     public void accept(final Visitor v) {
  77.         v.visitSynthetic(this);
  78.     }

  79.     /**
  80.      * @return deep copy of this attribute
  81.      */
  82.     @Override
  83.     public Attribute copy(final ConstantPool constantPool) {
  84.         final Synthetic c = (Synthetic) clone();
  85.         if (bytes != null) {
  86.             c.bytes = bytes.clone();
  87.         }
  88.         c.setConstantPool(constantPool);
  89.         return c;
  90.     }

  91.     /**
  92.      * Dump source file attribute to file stream in binary format.
  93.      *
  94.      * @param file Output file stream
  95.      * @throws IOException if an I/O error occurs.
  96.      */
  97.     @Override
  98.     public void dump(final DataOutputStream file) throws IOException {
  99.         super.dump(file);
  100.         if (super.getLength() > 0) {
  101.             file.write(bytes, 0, super.getLength());
  102.         }
  103.     }

  104.     /**
  105.      * @return data bytes.
  106.      */
  107.     public byte[] getBytes() {
  108.         return bytes;
  109.     }

  110.     /**
  111.      * @param bytes
  112.      */
  113.     public void setBytes(final byte[] bytes) {
  114.         this.bytes = bytes;
  115.     }

  116.     /**
  117.      * @return String representation.
  118.      */
  119.     @Override
  120.     public String toString() {
  121.         final StringBuilder buf = new StringBuilder("Synthetic");
  122.         if (super.getLength() > 0) {
  123.             buf.append(" ").append(Utility.toHexString(bytes));
  124.         }
  125.         return buf.toString();
  126.     }
  127. }