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  package org.apache.bcel.generic;
18  
19  import java.io.DataOutputStream;
20  import java.io.IOException;
21  
22  import org.apache.bcel.classfile.ConstantDouble;
23  import org.apache.bcel.classfile.ConstantFloat;
24  import org.apache.bcel.classfile.ConstantInteger;
25  import org.apache.bcel.classfile.ConstantLong;
26  import org.apache.bcel.classfile.ConstantUtf8;
27  import org.apache.bcel.classfile.ElementValue;
28  import org.apache.bcel.classfile.SimpleElementValue;
29  
30  /**
31   * @since 6.0
32   */
33  public class SimpleElementValueGen extends ElementValueGen {
34      // For primitive types and string type, this points to the value entry in
35      // the cpGen
36      // For 'class' this points to the class entry in the cpGen
37      private final int idx;
38  
39      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final boolean value) {
40          super(type, cpGen);
41          if (value) {
42              idx = getConstantPool().addInteger(1);
43          } else {
44              idx = getConstantPool().addInteger(0);
45          }
46      }
47  
48      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final byte value) {
49          super(type, cpGen);
50          idx = getConstantPool().addInteger(value);
51      }
52  
53      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final char value) {
54          super(type, cpGen);
55          idx = getConstantPool().addInteger(value);
56      }
57  
58      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final double value) {
59          super(type, cpGen);
60          idx = getConstantPool().addDouble(value);
61      }
62  
63      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final float value) {
64          super(type, cpGen);
65          idx = getConstantPool().addFloat(value);
66      }
67  
68      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final int value) {
69          super(type, cpGen);
70          idx = getConstantPool().addInteger(value);
71      }
72  
73      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final long value) {
74          super(type, cpGen);
75          idx = getConstantPool().addLong(value);
76      }
77  
78      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final short value) {
79          super(type, cpGen);
80          idx = getConstantPool().addInteger(value);
81      }
82  
83      public SimpleElementValueGen(final int type, final ConstantPoolGen cpGen, final String value) {
84          super(type, cpGen);
85          idx = getConstantPool().addUtf8(value);
86      }
87  
88      // ctors for each supported type... type could be inferred but for now lets
89      // force it to be passed
90      /**
91       * Protected ctor used for deserialization, doesn't *put* an entry in the constant pool, assumes the one at the supplied
92       * index is correct.
93       */
94      protected SimpleElementValueGen(final int type, final int idx, final ConstantPoolGen cpGen) {
95          super(type, cpGen);
96          this.idx = idx;
97      }
98  
99      /**
100      * The boolean controls whether we copy info from the 'old' constant pool to the 'new'. You need to use this ctor if the
101      * annotation is being copied from one file to another.
102      */
103     public SimpleElementValueGen(final SimpleElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries) {
104         super(value.getElementValueType(), cpool);
105         if (!copyPoolEntries) {
106             // J5ASSERT: Could assert value.stringifyValue() is the same as
107             // cpool.getConstant(SimpleElementValuevalue.getIndex())
108             idx = value.getIndex();
109         } else {
110             switch (value.getElementValueType()) {
111             case STRING:
112                 idx = cpool.addUtf8(value.getValueString());
113                 break;
114             case PRIMITIVE_INT:
115                 idx = cpool.addInteger(value.getValueInt());
116                 break;
117             case PRIMITIVE_BYTE:
118                 idx = cpool.addInteger(value.getValueByte());
119                 break;
120             case PRIMITIVE_CHAR:
121                 idx = cpool.addInteger(value.getValueChar());
122                 break;
123             case PRIMITIVE_LONG:
124                 idx = cpool.addLong(value.getValueLong());
125                 break;
126             case PRIMITIVE_FLOAT:
127                 idx = cpool.addFloat(value.getValueFloat());
128                 break;
129             case PRIMITIVE_DOUBLE:
130                 idx = cpool.addDouble(value.getValueDouble());
131                 break;
132             case PRIMITIVE_BOOLEAN:
133                 if (value.getValueBoolean()) {
134                     idx = cpool.addInteger(1);
135                 } else {
136                     idx = cpool.addInteger(0);
137                 }
138                 break;
139             case PRIMITIVE_SHORT:
140                 idx = cpool.addInteger(value.getValueShort());
141                 break;
142             default:
143                 throw new IllegalArgumentException("SimpleElementValueGen class does not know how to copy this type " + super.getElementValueType());
144             }
145         }
146     }
147 
148     @Override
149     public void dump(final DataOutputStream dos) throws IOException {
150         dos.writeByte(super.getElementValueType()); // u1 kind of value
151         switch (super.getElementValueType()) {
152         case PRIMITIVE_INT:
153         case PRIMITIVE_BYTE:
154         case PRIMITIVE_CHAR:
155         case PRIMITIVE_FLOAT:
156         case PRIMITIVE_LONG:
157         case PRIMITIVE_BOOLEAN:
158         case PRIMITIVE_SHORT:
159         case PRIMITIVE_DOUBLE:
160         case STRING:
161             dos.writeShort(idx);
162             break;
163         default:
164             throw new IllegalStateException("SimpleElementValueGen doesn't know how to write out type " + super.getElementValueType());
165         }
166     }
167 
168     /**
169      * Return immutable variant
170      */
171     @Override
172     public ElementValue getElementValue() {
173         return new SimpleElementValue(super.getElementValueType(), idx, getConstantPool().getConstantPool());
174     }
175 
176     public int getIndex() {
177         return idx;
178     }
179 
180     public int getValueInt() {
181         if (super.getElementValueType() != PRIMITIVE_INT) {
182             throw new IllegalStateException("Don't call getValueString() on a non STRING ElementValue");
183         }
184         final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx);
185         return c.getBytes();
186     }
187 
188     public String getValueString() {
189         if (super.getElementValueType() != STRING) {
190             throw new IllegalStateException("Don't call getValueString() on a non STRING ElementValue");
191         }
192         final ConstantUtf8 c = (ConstantUtf8) getConstantPool().getConstant(idx);
193         return c.getBytes();
194     }
195 
196     // Whatever kind of value it is, return it as a string
197     @Override
198     public String stringifyValue() {
199         switch (super.getElementValueType()) {
200         case PRIMITIVE_INT:
201             final ConstantInteger c = (ConstantInteger) getConstantPool().getConstant(idx);
202             return Integer.toString(c.getBytes());
203         case PRIMITIVE_LONG:
204             final ConstantLong j = (ConstantLong) getConstantPool().getConstant(idx);
205             return Long.toString(j.getBytes());
206         case PRIMITIVE_DOUBLE:
207             final ConstantDouble d = (ConstantDouble) getConstantPool().getConstant(idx);
208             return Double.toString(d.getBytes());
209         case PRIMITIVE_FLOAT:
210             final ConstantFloat f = (ConstantFloat) getConstantPool().getConstant(idx);
211             return Float.toString(f.getBytes());
212         case PRIMITIVE_SHORT:
213             final ConstantInteger s = (ConstantInteger) getConstantPool().getConstant(idx);
214             return Integer.toString(s.getBytes());
215         case PRIMITIVE_BYTE:
216             final ConstantInteger b = (ConstantInteger) getConstantPool().getConstant(idx);
217             return Integer.toString(b.getBytes());
218         case PRIMITIVE_CHAR:
219             final ConstantInteger ch = (ConstantInteger) getConstantPool().getConstant(idx);
220             return Integer.toString(ch.getBytes());
221         case PRIMITIVE_BOOLEAN:
222             final ConstantInteger bo = (ConstantInteger) getConstantPool().getConstant(idx);
223             if (bo.getBytes() == 0) {
224                 return "false";
225             }
226             return "true";
227         case STRING:
228             final ConstantUtf8 cu8 = (ConstantUtf8) getConstantPool().getConstant(idx);
229             return cu8.getBytes();
230         default:
231             throw new IllegalStateException("SimpleElementValueGen class does not know how to stringify type " + super.getElementValueType());
232         }
233     }
234 }