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, i.e., 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   * @see Attribute
40   */
41  public final class ConstantValue extends Attribute {
42  
43      private int constantValueIndex;
44  
45      /**
46       * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a
47       * physical copy.
48       *
49       * @param c Source to copy.
50       */
51      public ConstantValue(final ConstantValue c) {
52          this(c.getNameIndex(), c.getLength(), c.getConstantValueIndex(), c.getConstantPool());
53      }
54  
55      /**
56       * Constructs object from input stream.
57       *
58       * @param nameIndex Name index in constant pool
59       * @param length Content length in bytes
60       * @param input Input stream
61       * @param constantPool Array of constants
62       * @throws IOException if an I/O error occurs.
63       */
64      ConstantValue(final int nameIndex, final int length, final DataInput input, final ConstantPool constantPool) throws IOException {
65          this(nameIndex, length, input.readUnsignedShort(), constantPool);
66      }
67  
68      /**
69       * @param nameIndex Name index in constant pool
70       * @param length Content length in bytes
71       * @param constantValueIndex Index in constant pool
72       * @param constantPool Array of constants
73       */
74      public ConstantValue(final int nameIndex, final int length, final int constantValueIndex, final ConstantPool constantPool) {
75          super(Const.ATTR_CONSTANT_VALUE, nameIndex, Args.require(length, 2, "ConstantValue attribute length"), constantPool);
76          this.constantValueIndex = constantValueIndex;
77      }
78  
79      /**
80       * Called by objects that are traversing the nodes of the tree implicitly defined by the contents of a Java class.
81       * I.e., the hierarchy of methods, fields, attributes, etc. spawns a tree of objects.
82       *
83       * @param v Visitor object
84       */
85      @Override
86      public void accept(final Visitor v) {
87          v.visitConstantValue(this);
88      }
89  
90      /**
91       * @return deep copy of this attribute
92       */
93      @Override
94      public Attribute copy(final ConstantPool constantPool) {
95          final ConstantValue c = (ConstantValue) clone();
96          c.setConstantPool(constantPool);
97          return c;
98      }
99  
100     /**
101      * Dump constant value attribute to file stream on binary format.
102      *
103      * @param file Output file stream
104      * @throws IOException if an I/O error occurs.
105      */
106     @Override
107     public void dump(final DataOutputStream file) throws IOException {
108         super.dump(file);
109         file.writeShort(constantValueIndex);
110     }
111 
112     /**
113      * @return Index in constant pool of constant value.
114      */
115     public int getConstantValueIndex() {
116         return constantValueIndex;
117     }
118 
119     /**
120      * @param constantValueIndex the index info the constant pool of this constant value
121      */
122     public void setConstantValueIndex(final int constantValueIndex) {
123         this.constantValueIndex = constantValueIndex;
124     }
125 
126     /**
127      * @return String representation of constant value.
128      */
129     @Override
130     public String toString() {
131         Constant c = super.getConstantPool().getConstant(constantValueIndex);
132         final String buf;
133         final int i;
134         // Print constant to string depending on its type
135         switch (c.getTag()) {
136         case Const.CONSTANT_Long:
137             buf = String.valueOf(((ConstantLong) c).getBytes());
138             break;
139         case Const.CONSTANT_Float:
140             buf = String.valueOf(((ConstantFloat) c).getBytes());
141             break;
142         case Const.CONSTANT_Double:
143             buf = String.valueOf(((ConstantDouble) c).getBytes());
144             break;
145         case Const.CONSTANT_Integer:
146             buf = String.valueOf(((ConstantInteger) c).getBytes());
147             break;
148         case Const.CONSTANT_String:
149             i = ((ConstantString) c).getStringIndex();
150             c = super.getConstantPool().getConstantUtf8(i);
151             buf = "\"" + Utility.convertString(((ConstantUtf8) c).getBytes()) + "\"";
152             break;
153         default:
154             throw new IllegalStateException("Type of ConstValue invalid: " + c);
155         }
156         return buf;
157     }
158 }