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.DataOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.bcel.Const;
25  
26  /**
27   * Represents a simple element value in an annotation.
28   *
29   * @since 6.0
30   */
31  public class SimpleElementValue extends ElementValue {
32      private int index;
33  
34      /**
35       * Constructs a SimpleElementValue.
36       *
37       * @param type The element value type.
38       * @param index The index into the constant pool.
39       * @param cpool The constant pool.
40       */
41      public SimpleElementValue(final int type, final int index, final ConstantPool cpool) {
42          super(type, cpool);
43          this.index = index;
44      }
45  
46      @Override
47      public void dump(final DataOutputStream dos) throws IOException {
48          final int type = super.getType();
49          dos.writeByte(type); // u1 kind of value
50          switch (type) {
51          case PRIMITIVE_INT:
52          case PRIMITIVE_BYTE:
53          case PRIMITIVE_CHAR:
54          case PRIMITIVE_FLOAT:
55          case PRIMITIVE_LONG:
56          case PRIMITIVE_BOOLEAN:
57          case PRIMITIVE_SHORT:
58          case PRIMITIVE_DOUBLE:
59          case STRING:
60              dos.writeShort(getIndex());
61              break;
62          default:
63              throw new ClassFormatException("SimpleElementValue doesn't know how to write out type " + type);
64          }
65      }
66  
67      /**
68       * Gets the value entry index in the constant pool.
69       *
70       * @return Value entry index in the constant pool.
71       */
72      public int getIndex() {
73          return index;
74      }
75  
76      /**
77       * Gets the boolean value.
78       *
79       * @return The boolean value.
80       */
81      public boolean getValueBoolean() {
82          if (super.getType() != PRIMITIVE_BOOLEAN) {
83              throw new IllegalStateException("Don't call getValueBoolean() on a non BOOLEAN ElementValue");
84          }
85          final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
86          return bo.getBytes() != 0;
87      }
88  
89      /**
90       * Gets the byte value.
91       *
92       * @return The byte value.
93       */
94      public byte getValueByte() {
95          if (super.getType() != PRIMITIVE_BYTE) {
96              throw new IllegalStateException("Don't call getValueByte() on a non BYTE ElementValue");
97          }
98          return (byte) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
99      }
100 
101     /**
102      * Gets the char value.
103      *
104      * @return The char value.
105      */
106     public char getValueChar() {
107         if (super.getType() != PRIMITIVE_CHAR) {
108             throw new IllegalStateException("Don't call getValueChar() on a non CHAR ElementValue");
109         }
110         return (char) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
111     }
112 
113     /**
114      * Gets the double value.
115      *
116      * @return The double value.
117      */
118     public double getValueDouble() {
119         if (super.getType() != PRIMITIVE_DOUBLE) {
120             throw new IllegalStateException("Don't call getValueDouble() on a non DOUBLE ElementValue");
121         }
122         final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex());
123         return d.getBytes();
124     }
125 
126     /**
127      * Gets the float value.
128      *
129      * @return The float value.
130      */
131     public float getValueFloat() {
132         if (super.getType() != PRIMITIVE_FLOAT) {
133             throw new IllegalStateException("Don't call getValueFloat() on a non FLOAT ElementValue");
134         }
135         final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex());
136         return f.getBytes();
137     }
138 
139     /**
140      * Gets the int value.
141      *
142      * @return The int value.
143      */
144     public int getValueInt() {
145         if (super.getType() != PRIMITIVE_INT) {
146             throw new IllegalStateException("Don't call getValueInt() on a non INT ElementValue");
147         }
148         return super.getConstantPool().getConstantInteger(getIndex()).getBytes();
149     }
150 
151     /**
152      * Gets the long value.
153      *
154      * @return The long value.
155      */
156     public long getValueLong() {
157         if (super.getType() != PRIMITIVE_LONG) {
158             throw new IllegalStateException("Don't call getValueLong() on a non LONG ElementValue");
159         }
160         final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex());
161         return j.getBytes();
162     }
163 
164     /**
165      * Gets the short value.
166      *
167      * @return The short value.
168      */
169     public short getValueShort() {
170         if (super.getType() != PRIMITIVE_SHORT) {
171             throw new IllegalStateException("Don't call getValueShort() on a non SHORT ElementValue");
172         }
173         final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
174         return (short) s.getBytes();
175     }
176 
177     /**
178      * Gets the string value.
179      *
180      * @return The string value.
181      */
182     public String getValueString() {
183         if (super.getType() != STRING) {
184             throw new IllegalStateException("Don't call getValueString() on a non STRING ElementValue");
185         }
186         return super.getConstantPool().getConstantUtf8(getIndex()).getBytes();
187     }
188 
189     /**
190      * Sets the index into the constant pool.
191      *
192      * @param index The index.
193      */
194     public void setIndex(final int index) {
195         this.index = index;
196     }
197 
198     // Whatever kind of value it is, return it as a string
199     @Override
200     public String stringifyValue() {
201         final ConstantPool cpool = super.getConstantPool();
202         final int type = super.getType();
203         switch (type) {
204         case PRIMITIVE_INT:
205             return Integer.toString(cpool.getConstantInteger(getIndex()).getBytes());
206         case PRIMITIVE_LONG:
207             final ConstantLong j = cpool.getConstant(getIndex(), Const.CONSTANT_Long, ConstantLong.class);
208             return Long.toString(j.getBytes());
209         case PRIMITIVE_DOUBLE:
210             final ConstantDouble d = cpool.getConstant(getIndex(), Const.CONSTANT_Double, ConstantDouble.class);
211             return Double.toString(d.getBytes());
212         case PRIMITIVE_FLOAT:
213             final ConstantFloat f = cpool.getConstant(getIndex(), Const.CONSTANT_Float, ConstantFloat.class);
214             return Float.toString(f.getBytes());
215         case PRIMITIVE_SHORT:
216             final ConstantInteger s = cpool.getConstantInteger(getIndex());
217             return Integer.toString(s.getBytes());
218         case PRIMITIVE_BYTE:
219             final ConstantInteger b = cpool.getConstantInteger(getIndex());
220             return Integer.toString(b.getBytes());
221         case PRIMITIVE_CHAR:
222             final ConstantInteger ch = cpool.getConstantInteger(getIndex());
223             return String.valueOf((char) ch.getBytes());
224         case PRIMITIVE_BOOLEAN:
225             final ConstantInteger bo = cpool.getConstantInteger(getIndex());
226             if (bo.getBytes() == 0) {
227                 return "false";
228             }
229             return "true";
230         case STRING:
231             return cpool.getConstantUtf8(getIndex()).getBytes();
232         default:
233             throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + type);
234         }
235     }
236 
237     @Override
238     public String toString() {
239         return stringifyValue();
240     }
241 }