View Javadoc
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   */
18  package org.apache.bcel.classfile;
19  
20  import java.io.DataInput;
21  import java.io.DataOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.bcel.Const;
25  
26  /**
27   * This class is derived from <em>Attribute</em> and declares this class as
28   * `synthetic', i.e., it needs special handling.  The JVM specification
29   * states "A class member that does not appear in the source code must be
30   * marked using a Synthetic attribute."  It may appear in the ClassFile
31   * attribute table, a field_info table or a method_info table.  This class
32   * is intended to be instantiated from the
33   * <em>Attribute.readAttribute()</em> method.
34   *
35   * @version $Id: Synthetic.html 1018313 2017-09-18 09:03:04Z britter $
36   * @see     Attribute
37   */
38  public final class Synthetic extends Attribute {
39  
40      private byte[] bytes;
41  
42  
43      /**
44       * Initialize from another object. Note that both objects use the same
45       * references (shallow copy). Use copy() for a physical copy.
46       */
47      public Synthetic(final Synthetic c) {
48          this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
49      }
50  
51  
52      /**
53       * @param name_index Index in constant pool to CONSTANT_Utf8, which
54       * should represent the string "Synthetic".
55       * @param length Content length in bytes - should be zero.
56       * @param bytes Attribute contents
57       * @param constant_pool The constant pool this attribute is associated
58       * with.
59       */
60      public Synthetic(final int name_index, final int length, final byte[] bytes, final ConstantPool constant_pool) {
61          super(Const.ATTR_SYNTHETIC, name_index, length, constant_pool);
62          this.bytes = bytes;
63      }
64  
65  
66      /**
67       * Construct object from input stream.
68       *
69       * @param name_index Index in constant pool to CONSTANT_Utf8
70       * @param length Content length in bytes
71       * @param input Input stream
72       * @param constant_pool Array of constants
73       * @throws IOException
74       */
75      Synthetic(final int name_index, final int length, final DataInput input, final ConstantPool constant_pool)
76              throws IOException {
77          this(name_index, length, (byte[]) null, constant_pool);
78          if (length > 0) {
79              bytes = new byte[length];
80              input.readFully(bytes);
81              System.err.println("Synthetic attribute with length > 0");
82          }
83      }
84  
85  
86      /**
87       * Called by objects that are traversing the nodes of the tree implicitely
88       * defined by the contents of a Java class. I.e., the hierarchy of methods,
89       * fields, attributes, etc. spawns a tree of objects.
90       *
91       * @param v Visitor object
92       */
93      @Override
94      public void accept( final Visitor v ) {
95          v.visitSynthetic(this);
96      }
97  
98  
99      /**
100      * Dump source file attribute to file stream in binary format.
101      *
102      * @param file Output file stream
103      * @throws IOException
104      */
105     @Override
106     public final void dump( final DataOutputStream file ) throws IOException {
107         super.dump(file);
108         if (super.getLength() > 0) {
109             file.write(bytes, 0, super.getLength());
110         }
111     }
112 
113 
114     /**
115      * @return data bytes.
116      */
117     public final byte[] getBytes() {
118         return bytes;
119     }
120 
121 
122     /**
123      * @param bytes
124      */
125     public final void setBytes( final byte[] bytes ) {
126         this.bytes = bytes;
127     }
128 
129 
130     /**
131      * @return String representation.
132      */
133     @Override
134     public final String toString() {
135         final StringBuilder buf = new StringBuilder("Synthetic");
136         if (super.getLength() > 0) {
137             buf.append(" ").append(Utility.toHexString(bytes));
138         }
139         return buf.toString();
140     }
141 
142 
143     /**
144      * @return deep copy of this attribute
145      */
146     @Override
147     public Attribute copy( final ConstantPool _constant_pool ) {
148         final Synthetic c = (Synthetic) clone();
149         if (bytes != null) {
150             c.bytes = new byte[bytes.length];
151             System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
152         }
153         c.setConstantPool(_constant_pool);
154         return c;
155     }
156 }