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      public SimpleElementValue(final int type, final int index, final ConstantPool cpool) {
35          super(type, cpool);
36          this.index = index;
37      }
38  
39      @Override
40      public void dump(final DataOutputStream dos) throws IOException {
41          final int type = super.getType();
42          dos.writeByte(type); // u1 kind of value
43          switch (type) {
44          case PRIMITIVE_INT:
45          case PRIMITIVE_BYTE:
46          case PRIMITIVE_CHAR:
47          case PRIMITIVE_FLOAT:
48          case PRIMITIVE_LONG:
49          case PRIMITIVE_BOOLEAN:
50          case PRIMITIVE_SHORT:
51          case PRIMITIVE_DOUBLE:
52          case STRING:
53              dos.writeShort(getIndex());
54              break;
55          default:
56              throw new ClassFormatException("SimpleElementValue doesn't know how to write out type " + type);
57          }
58      }
59  
60      /**
61       * @return Value entry index in the constant pool.
62       */
63      public int getIndex() {
64          return index;
65      }
66  
67      public boolean getValueBoolean() {
68          if (super.getType() != PRIMITIVE_BOOLEAN) {
69              throw new IllegalStateException("Don't call getValueBoolean() on a non BOOLEAN ElementValue");
70          }
71          final ConstantInteger bo = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
72          return bo.getBytes() != 0;
73      }
74  
75      public byte getValueByte() {
76          if (super.getType() != PRIMITIVE_BYTE) {
77              throw new IllegalStateException("Don't call getValueByte() on a non BYTE ElementValue");
78          }
79          return (byte) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
80      }
81  
82      public char getValueChar() {
83          if (super.getType() != PRIMITIVE_CHAR) {
84              throw new IllegalStateException("Don't call getValueChar() on a non CHAR ElementValue");
85          }
86          return (char) super.getConstantPool().getConstantInteger(getIndex()).getBytes();
87      }
88  
89      public double getValueDouble() {
90          if (super.getType() != PRIMITIVE_DOUBLE) {
91              throw new IllegalStateException("Don't call getValueDouble() on a non DOUBLE ElementValue");
92          }
93          final ConstantDouble d = (ConstantDouble) super.getConstantPool().getConstant(getIndex());
94          return d.getBytes();
95      }
96  
97      public float getValueFloat() {
98          if (super.getType() != PRIMITIVE_FLOAT) {
99              throw new IllegalStateException("Don't call getValueFloat() on a non FLOAT ElementValue");
100         }
101         final ConstantFloat f = (ConstantFloat) super.getConstantPool().getConstant(getIndex());
102         return f.getBytes();
103     }
104 
105     public int getValueInt() {
106         if (super.getType() != PRIMITIVE_INT) {
107             throw new IllegalStateException("Don't call getValueInt() on a non INT ElementValue");
108         }
109         return super.getConstantPool().getConstantInteger(getIndex()).getBytes();
110     }
111 
112     public long getValueLong() {
113         if (super.getType() != PRIMITIVE_LONG) {
114             throw new IllegalStateException("Don't call getValueLong() on a non LONG ElementValue");
115         }
116         final ConstantLong j = (ConstantLong) super.getConstantPool().getConstant(getIndex());
117         return j.getBytes();
118     }
119 
120     public short getValueShort() {
121         if (super.getType() != PRIMITIVE_SHORT) {
122             throw new IllegalStateException("Don't call getValueShort() on a non SHORT ElementValue");
123         }
124         final ConstantInteger s = (ConstantInteger) super.getConstantPool().getConstant(getIndex());
125         return (short) s.getBytes();
126     }
127 
128     public String getValueString() {
129         if (super.getType() != STRING) {
130             throw new IllegalStateException("Don't call getValueString() on a non STRING ElementValue");
131         }
132         return super.getConstantPool().getConstantUtf8(getIndex()).getBytes();
133     }
134 
135     public void setIndex(final int index) {
136         this.index = index;
137     }
138 
139     // Whatever kind of value it is, return it as a string
140     @Override
141     public String stringifyValue() {
142         final ConstantPool cpool = super.getConstantPool();
143         final int type = super.getType();
144         switch (type) {
145         case PRIMITIVE_INT:
146             return Integer.toString(cpool.getConstantInteger(getIndex()).getBytes());
147         case PRIMITIVE_LONG:
148             final ConstantLong j = cpool.getConstant(getIndex(), Const.CONSTANT_Long, ConstantLong.class);
149             return Long.toString(j.getBytes());
150         case PRIMITIVE_DOUBLE:
151             final ConstantDouble d = cpool.getConstant(getIndex(), Const.CONSTANT_Double, ConstantDouble.class);
152             return Double.toString(d.getBytes());
153         case PRIMITIVE_FLOAT:
154             final ConstantFloat f = cpool.getConstant(getIndex(), Const.CONSTANT_Float, ConstantFloat.class);
155             return Float.toString(f.getBytes());
156         case PRIMITIVE_SHORT:
157             final ConstantInteger s = cpool.getConstantInteger(getIndex());
158             return Integer.toString(s.getBytes());
159         case PRIMITIVE_BYTE:
160             final ConstantInteger b = cpool.getConstantInteger(getIndex());
161             return Integer.toString(b.getBytes());
162         case PRIMITIVE_CHAR:
163             final ConstantInteger ch = cpool.getConstantInteger(getIndex());
164             return String.valueOf((char) ch.getBytes());
165         case PRIMITIVE_BOOLEAN:
166             final ConstantInteger bo = cpool.getConstantInteger(getIndex());
167             if (bo.getBytes() == 0) {
168                 return "false";
169             }
170             return "true";
171         case STRING:
172             return cpool.getConstantUtf8(getIndex()).getBytes();
173         default:
174             throw new IllegalStateException("SimpleElementValue class does not know how to stringify type " + type);
175         }
176     }
177 
178     @Override
179     public String toString() {
180         return stringifyValue();
181     }
182 }