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.DataInput; 21 import java.io.DataOutputStream; 22 import java.io.IOException; 23 24 import org.apache.bcel.classfile.AnnotationElementValue; 25 import org.apache.bcel.classfile.AnnotationEntry; 26 import org.apache.bcel.classfile.ArrayElementValue; 27 import org.apache.bcel.classfile.ClassElementValue; 28 import org.apache.bcel.classfile.ElementValue; 29 import org.apache.bcel.classfile.EnumElementValue; 30 import org.apache.bcel.classfile.SimpleElementValue; 31 32 /** 33 * @since 6.0 34 */ 35 public abstract class ElementValueGen 36 { 37 /** 38 * @deprecated (since 6.0) will be made private and final; do not access directly, use getter 39 */ 40 @Deprecated 41 protected int type; 42 43 /** 44 * @deprecated (since 6.0) will be made private and final; do not access directly, use getter 45 */ 46 @Deprecated 47 protected ConstantPoolGen cpGen; 48 ElementValueGen(final int type, final ConstantPoolGen cpGen)49 protected ElementValueGen(final int type, final ConstantPoolGen cpGen) 50 { 51 this.type = type; 52 this.cpGen = cpGen; 53 } 54 55 /** 56 * Subtypes return an immutable variant of the ElementValueGen 57 */ getElementValue()58 public abstract ElementValue getElementValue(); 59 getElementValueType()60 public int getElementValueType() 61 { 62 return type; 63 } 64 stringifyValue()65 public abstract String stringifyValue(); 66 dump(DataOutputStream dos)67 public abstract void dump(DataOutputStream dos) throws IOException; 68 69 public static final int STRING = 's'; 70 71 public static final int ENUM_CONSTANT = 'e'; 72 73 public static final int CLASS = 'c'; 74 75 public static final int ANNOTATION = '@'; 76 77 public static final int ARRAY = '['; 78 79 public static final int PRIMITIVE_INT = 'I'; 80 81 public static final int PRIMITIVE_BYTE = 'B'; 82 83 public static final int PRIMITIVE_CHAR = 'C'; 84 85 public static final int PRIMITIVE_DOUBLE = 'D'; 86 87 public static final int PRIMITIVE_FLOAT = 'F'; 88 89 public static final int PRIMITIVE_LONG = 'J'; 90 91 public static final int PRIMITIVE_SHORT = 'S'; 92 93 public static final int PRIMITIVE_BOOLEAN = 'Z'; 94 readElementValue(final DataInput dis, final ConstantPoolGen cpGen)95 public static ElementValueGen readElementValue(final DataInput dis, 96 final ConstantPoolGen cpGen) throws IOException 97 { 98 final int type = dis.readUnsignedByte(); 99 switch (type) 100 { 101 case 'B': // byte 102 return new SimpleElementValueGen(PRIMITIVE_BYTE, dis 103 .readUnsignedShort(), cpGen); 104 case 'C': // char 105 return new SimpleElementValueGen(PRIMITIVE_CHAR, dis 106 .readUnsignedShort(), cpGen); 107 case 'D': // double 108 return new SimpleElementValueGen(PRIMITIVE_DOUBLE, dis 109 .readUnsignedShort(), cpGen); 110 case 'F': // float 111 return new SimpleElementValueGen(PRIMITIVE_FLOAT, dis 112 .readUnsignedShort(), cpGen); 113 case 'I': // int 114 return new SimpleElementValueGen(PRIMITIVE_INT, dis 115 .readUnsignedShort(), cpGen); 116 case 'J': // long 117 return new SimpleElementValueGen(PRIMITIVE_LONG, dis 118 .readUnsignedShort(), cpGen); 119 case 'S': // short 120 return new SimpleElementValueGen(PRIMITIVE_SHORT, dis 121 .readUnsignedShort(), cpGen); 122 case 'Z': // boolean 123 return new SimpleElementValueGen(PRIMITIVE_BOOLEAN, dis 124 .readUnsignedShort(), cpGen); 125 case 's': // String 126 return new SimpleElementValueGen(STRING, dis.readUnsignedShort(), 127 cpGen); 128 case 'e': // Enum constant 129 return new EnumElementValueGen(dis.readUnsignedShort(), dis 130 .readUnsignedShort(), cpGen); 131 case 'c': // Class 132 return new ClassElementValueGen(dis.readUnsignedShort(), cpGen); 133 case '@': // Annotation 134 // TODO: isRuntimeVisible ?????????? 135 // FIXME 136 return new AnnotationElementValueGen(ANNOTATION, 137 new AnnotationEntryGen(AnnotationEntry.read(dis, cpGen 138 .getConstantPool(), true), cpGen, false), cpGen); 139 case '[': // Array 140 final int numArrayVals = dis.readUnsignedShort(); 141 final ElementValue[] evalues = new ElementValue[numArrayVals]; 142 for (int j = 0; j < numArrayVals; j++) 143 { 144 evalues[j] = ElementValue.readElementValue(dis, cpGen 145 .getConstantPool()); 146 } 147 return new ArrayElementValueGen(ARRAY, evalues, cpGen); 148 default: 149 throw new RuntimeException("Unexpected element value kind in annotation: " + type); 150 } 151 } 152 getConstantPool()153 protected ConstantPoolGen getConstantPool() 154 { 155 return cpGen; 156 } 157 158 /** 159 * Creates an (modifiable) ElementValueGen copy of an (immutable) 160 * ElementValue - constant pool is assumed correct. 161 */ copy(final ElementValue value, final ConstantPoolGen cpool, final boolean copyPoolEntries)162 public static ElementValueGen copy(final ElementValue value, 163 final ConstantPoolGen cpool, final boolean copyPoolEntries) 164 { 165 switch (value.getElementValueType()) 166 { 167 case 'B': // byte 168 case 'C': // char 169 case 'D': // double 170 case 'F': // float 171 case 'I': // int 172 case 'J': // long 173 case 'S': // short 174 case 'Z': // boolean 175 case 's': // String 176 return new SimpleElementValueGen((SimpleElementValue) value, cpool, 177 copyPoolEntries); 178 case 'e': // Enum constant 179 return new EnumElementValueGen((EnumElementValue) value, cpool, 180 copyPoolEntries); 181 case '@': // Annotation 182 return new AnnotationElementValueGen( 183 (AnnotationElementValue) value, cpool, copyPoolEntries); 184 case '[': // Array 185 return new ArrayElementValueGen((ArrayElementValue) value, cpool, 186 copyPoolEntries); 187 case 'c': // Class 188 return new ClassElementValueGen((ClassElementValue) value, cpool, 189 copyPoolEntries); 190 default: 191 throw new RuntimeException("Not implemented yet! (" + value.getElementValueType() + ")"); 192 } 193 } 194 } 195