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