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