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