View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   https://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.bcel.classfile;
20  
21  import java.io.DataInput;
22  import java.io.DataOutputStream;
23  import java.io.IOException;
24  
25  import org.apache.bcel.Const;
26  import org.apache.bcel.util.Args;
27  
28  /**
29   * This class is derived from <em>Attribute</em> and represents a constant value, that is, a default value for initializing
30   * a class field. This class is instantiated by the <em>Attribute.readAttribute()</em> method.
31   *
32   * <pre>
33   * ConstantValue_attribute {
34   *   u2 attribute_name_index;
35   *   u4 attribute_length;
36   *   u2 constantvalue_index;
37   * }
38   * </pre>
39   *
40   * @see Attribute
41   */
42  public final class ConstantValue extends Attribute {
43  
44      private int constantValueIndex;
45  
46      /**
47       * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a
48       * physical copy.
49       *
50       * @param c Source to copy.
51       */
52      public ConstantValue(final ConstantValue c) {
53          this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool());
54      }
55  
56      /**
57       * Constructs object from input stream.
58       *
59       * @param nameIndex Name index in constant pool.
60       * @param length Content length in bytes.
61       * @param input Input stream.
62       * @param constantPool Array of constants.
63       * @throws IOException if an I/O error occurs.
64       */
65      ConstantValue(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
66          this(nameIndex, length, input.readUnsignedShort(), constantPool);
67      }
68  
69      /**
70       * Constructs a ConstantValue.
71       *
72       * @param nameIndex Name index in constant pool.
73       * @param length Content length in bytes.
74       * @param constantValueIndex Index in constant pool.
75       * @param constantPool Array of constants.
76       */
77      public ConstantValue(final int nameIndex, final int length, final int constantValueIndex, final ConstantPool constantPool) {
78          super(Const.ATTR_CONSTANT_VALUE, nameIndex, Args.require(length, 2, "ConstantValue attribute length"), constantPool);
79          this.constantValueIndex = constantValueIndex;
80      }
81  
82      /**
83       * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
84       * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
85       *
86       * @param v Visitor object.
87       */
88      @Override
89      public void accept(final Visitor v) {
90          v.visitConstantValue(this);
91      }
92  
93      /**
94       * Creates a deep copy of this attribute.
95       *
96       * @param constantPool the constant pool.
97       * @return deep copy of this attribute.
98       */
99      @Override
100     public Attribute copy(final ConstantPool constantPool) {
101         final ConstantValue c = (ConstantValue) clone();
102         c.setConstantPool(constantPool);
103         return c;
104     }
105 
106     /**
107      * Dumps constant value attribute to file stream on binary format.
108      *
109      * @param file Output file stream.
110      * @throws IOException if an I/O error occurs.
111      */
112     @Override
113     public void dump(final DataOutputStream file) throws IOException {
114         super.dump(file);
115         file.writeShort(constantValueIndex);
116     }
117 
118     /**
119      * Gets the index in constant pool of constant value.
120      *
121      * @return Index in constant pool of constant value.
122      */
123     public int getConstantValueIndex() {
124         return constantValueIndex;
125     }
126 
127     /**
128      * Sets the constant value index.
129      *
130      * @param constantValueIndex the index info the constant pool of this constant value.
131      */
132     public void setConstantValueIndex(final int constantValueIndex) {
133         this.constantValueIndex = constantValueIndex;
134     }
135 
136     /**
137      * @return String representation of constant value.
138      */
139     @Override
140     public String toString() {
141         Constant c = super.getConstantPool().getConstant(constantValueIndex);
142         final String buf;
143         final int i;
144         // Print constant to string depending on its type
145         switch (c.getTag()) {
146         case Const.CONSTANT_Long:
147             buf = String.valueOf(((ConstantLong) c).getBytes());
148             break;
149         case Const.CONSTANT_Float:
150             buf = String.valueOf(((ConstantFloat) c).getBytes());
151             break;
152         case Const.CONSTANT_Double:
153             buf = String.valueOf(((ConstantDouble) c).getBytes());
154             break;
155         case Const.CONSTANT_Integer:
156             buf = String.valueOf(((ConstantInteger) c).getBytes());
157             break;
158         case Const.CONSTANT_String:
159             i = ((ConstantString) c).getStringIndex();
160             c = super.getConstantPool().getConstantUtf8(i);
161             buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\"";
162             break;
163         default:
164             throw new IllegalStateException("Type of ConstValue invalid: " + c);
165         }
166         return buf;
167     }
168 }