1 29 30 package com.caucho.bytecode; 31 32 import java.io.IOException ; 33 import java.io.InputStream ; 34 import java.lang.reflect.Method ; 35 import java.util.HashMap ; 36 import java.util.logging.Level ; 37 import java.util.logging.Logger ; 38 39 42 public class JavaAnnotation extends JAnnotation { 43 static private final Logger log = 44 Logger.getLogger(JavaAnnotation.class.getName()); 45 46 private static Method _enumValueOf; 47 48 private JavaClassLoader _loader; 49 private HashMap <String ,Object > _valueMap = new HashMap <String ,Object >(8); 50 private String _type; 51 52 55 public void setClassLoader(JavaClassLoader loader) 56 { 57 _loader = loader; 58 } 59 60 63 public JavaClassLoader getClassLoader() 64 { 65 return _loader; 66 } 67 68 71 public void setType(String type) 72 { 73 _type = type; 74 } 75 76 79 public String getType() 80 { 81 return _type; 82 } 83 84 87 public HashMap <String ,Object > getValueMap() 88 { 89 return _valueMap; 90 } 91 92 95 public Object putValue(String key, Object value) 96 { 97 return _valueMap.put(key, value); 98 } 99 100 103 static JavaAnnotation []parseAnnotations(InputStream is, 104 ConstantPool cp, 105 JavaClassLoader loader) 106 throws IOException 107 { 108 int n = readShort(is); 109 110 JavaAnnotation []annArray = new JavaAnnotation[n]; 111 112 for (int i = 0; i < n; i++) { 113 annArray[i] = parseAnnotation(is, cp, loader); 114 } 115 116 return annArray; 117 } 118 119 private static JavaAnnotation parseAnnotation(InputStream is, 120 ConstantPool cp, 121 JavaClassLoader loader) 122 throws IOException 123 { 124 JavaAnnotation ann = new JavaAnnotation(); 125 ann.setClassLoader(loader); 126 127 int type = readShort(is); 128 129 String typeName = cp.getUtf8(type).getValue(); 130 131 if (typeName.endsWith(";")) 132 typeName = typeName.substring(1, typeName.length() - 1).replace('/', '.'); 133 134 ann.setType(typeName); 135 136 try { 137 Class aClass = Class.forName(typeName, false, Thread.currentThread().getContextClassLoader()); 138 139 for (Method method : aClass.getDeclaredMethods()) { 140 Object value = method.getDefaultValue(); 141 142 if (value instanceof Class ) { 143 String className = ((Class ) value).getName(); 144 145 ann.putValue(method.getName(), loader.forName(className)); 146 } 147 else if (value != null) 148 ann.putValue(method.getName(), value); 149 } 150 } catch (Exception e) { 151 log.log(Level.FINER, e.toString(), e); 152 } 153 154 int nPairs = readShort(is); 155 for (int j = 0; j < nPairs; j++) { 156 int nameIndex = readShort(is); 157 158 String name = cp.getUtf8(nameIndex).getValue(); 159 160 Object value = parseElementValue(is, cp, loader); 161 162 ann.putValue(name, value); 163 } 164 165 return ann; 166 } 167 168 private static Object parseElementValue(InputStream is, 169 ConstantPool cp, 170 JavaClassLoader loader) 171 throws IOException 172 { 173 int tag = is.read(); 174 175 switch (tag) { 176 case 'Z': 177 { 178 int i = readShort(is); 179 180 return cp.getInteger(i).getValue() == 0 ? Boolean.FALSE : Boolean.TRUE; 181 } 182 183 case 'B': 184 { 185 int i = readShort(is); 186 187 return new Byte ((byte) cp.getInteger(i).getValue()); 188 } 189 190 case 'S': 191 { 192 int i = readShort(is); 193 194 return new Short ((short) cp.getInteger(i).getValue()); 195 } 196 197 case 'I': 198 { 199 int i = readShort(is); 200 201 return new Integer (cp.getInteger(i).getValue()); 202 } 203 204 case 'J': 205 { 206 int i = readShort(is); 207 208 return new Long (cp.getLong(i).getValue()); 209 } 210 211 case 'F': 212 { 213 int i = readShort(is); 214 215 return new Float (cp.getFloat(i).getValue()); 216 } 217 218 case 'D': 219 { 220 int i = readShort(is); 221 222 return new Double (cp.getDouble(i).getValue()); 223 } 224 225 case 'C': 226 { 227 int i = readShort(is); 228 229 return new Character ((char) cp.getInteger(i).getValue()); 230 } 231 232 case 's': 233 int i = readShort(is); 234 return cp.getUtf8(i).getValue(); 235 case 'e': 236 { 237 int type = readShort(is); 238 int value = readShort(is); 239 String enumClassName = cp.getUtf8(type).getValue(); 240 enumClassName = enumClassName.substring(1, enumClassName.length() - 1); 241 enumClassName = enumClassName.replace('/', '.'); 242 243 try { 244 Class enumClass = Class.forName(enumClassName, false, Thread.currentThread().getContextClassLoader()); 245 String enumName = cp.getUtf8(value).getValue(); 246 247 return _enumValueOf.invoke(null, enumClass, enumName); 248 249 } catch (Exception e) { 250 log.log(Level.FINE, e.toString(), e); 251 252 return null; 253 } 254 } 255 case 'c': 256 { 258 String className = cp.getUtf8(readShort(is)).getValue(); 259 260 return loader.descriptorToClass(className, 0); 261 } 262 case '@': 263 return parseAnnotation(is, cp, loader); 264 case '[': 265 { 266 int n = readShort(is); 267 268 Object []array = new Object [n]; 269 for (int j = 0; j < n; j++) { 270 array[j] = parseElementValue(is, cp, loader); 271 } 272 273 return array; 274 } 275 default: 276 throw new IllegalStateException (); 277 } 278 } 279 280 static int readShort(InputStream is) 281 throws IOException 282 { 283 return (((is.read() & 0xff) << 8) + 284 (is.read() & 0xff)); 285 } 286 287 static int readInt(InputStream is) 288 throws IOException 289 { 290 return (((is.read() & 0xff) << 24) + 291 ((is.read() & 0xff) << 16) + 292 ((is.read() & 0xff) << 8) + 293 ((is.read() & 0xff))); 294 } 295 296 public String toString() 297 { 298 return "JavaAnnotation[" + _type + "]"; 299 } 300 301 static { 302 try { 303 Class cl = Class.forName("java.lang.Enum"); 304 _enumValueOf = cl.getMethod("valueOf", 305 new Class [] { Class .class, String .class }); 306 } catch (Throwable e) { 307 e.printStackTrace(); 308 } 309 } 310 } 311 | Popular Tags |