1 52 53 package com.go.trove.classfile; 54 55 64 public class TypeDescriptor extends Descriptor { 65 private String mStr; 66 private String mClassName; 67 private Class mClass; 68 private int mDim; 69 private TypeDescriptor mComponentType; 70 private int mSpecifiedDim; 71 72 public TypeDescriptor(String className) { 73 mClassName = className; 74 mStr = generate(className); 75 } 76 77 81 public TypeDescriptor(Class clazz) { 82 int dim = 0; 83 84 while (clazz.isArray()) { 86 dim++; 87 clazz = clazz.getComponentType(); 88 } 89 90 mClassName = clazz.getName(); 91 mClass = clazz; 92 mDim = dim; 93 94 mStr = generate(clazz, dim); 95 } 96 97 106 public TypeDescriptor(TypeDescriptor componentType, int dim) 107 throws IllegalArgumentException { 108 109 if (dim <= 0) { 110 throw new IllegalArgumentException 111 ("Array dimensions must be greater than zero: " + dim); 112 } 113 114 mClassName = componentType.getClassName(); 115 mClass = componentType.getClassArg(); 116 mDim = componentType.getDimensions() + dim; 117 118 if (mClass != null) { 119 mStr = generate(mClass, mDim); 120 } 121 else { 122 mStr = generate(mClassName, mDim); 123 } 124 125 mComponentType = componentType; 126 mSpecifiedDim = dim; 127 } 128 129 public String getClassName() { 130 return mClassName; 131 } 132 133 144 public Class getClassArg() { 145 return mClass; 146 } 147 148 154 public TypeDescriptor getComponentType() { 155 if (mComponentType == null && mDim > 0) { 156 if (mClass != null) { 157 mComponentType = new TypeDescriptor(mClass); 158 } 159 else { 160 mComponentType = new TypeDescriptor(mClassName); 161 } 162 } 163 164 return mComponentType; 165 } 166 167 173 public int getDimensions() { 174 return mDim; 175 } 176 177 183 public int getSpecifiedDimensions() { 184 return (mSpecifiedDim != 0) ? mSpecifiedDim : mDim; 185 } 186 187 public int hashCode() { 188 return mStr.hashCode(); 189 } 190 191 public boolean equals(Object other) { 192 if (other instanceof TypeDescriptor) { 193 return ((TypeDescriptor)other).mStr.equals(mStr); 194 } 195 else { 196 return false; 197 } 198 } 199 200 203 public String toString() { 204 return mStr; 205 } 206 207 static String generate(String className) { 208 return generate(className, 0); 209 } 210 211 214 static String generate(String className, int dim) { 215 StringBuffer desc = new StringBuffer (className.length() + dim + 2); 216 217 while (dim-- > 0) { 218 desc.append('['); 219 } 220 221 desc.append('L'); 222 desc.append(className.replace('.', '/')); 223 desc.append(';'); 224 225 return desc.toString(); 226 } 227 228 232 static String generate(Class clazz) { 233 return generate(clazz, 0); 234 } 235 236 static String generate(Class clazz, int dim) { 237 while (clazz.isArray()) { 239 dim++; 240 clazz = clazz.getComponentType(); 241 } 242 243 if (!clazz.isPrimitive()) { 244 return generate(clazz.getName(), dim); 245 } 246 247 StringBuffer desc = new StringBuffer (dim + 1); 248 249 while (dim-- > 0) { 250 desc.append('['); 251 } 252 253 char type = 'V'; 254 255 if (clazz == int.class) 256 type = 'I'; 257 else if (clazz == char.class) 258 type = 'C'; 259 else if (clazz == boolean.class) 260 type = 'Z'; 261 else if (clazz == double.class) 262 type = 'D'; 263 else if (clazz == float.class) 264 type = 'F'; 265 else if (clazz == long.class) 266 type = 'J'; 267 else if (clazz == byte.class) 268 type = 'B'; 269 else if (clazz == short.class) 270 type = 'S'; 271 272 desc.append(type); 273 274 return desc.toString(); 275 } 276 277 public static TypeDescriptor parseTypeDesc(String desc) 278 throws IllegalArgumentException { 279 280 TypeDescriptor td = null; 281 int cursor = 0; 282 try { 283 int dim = 0; 284 char c; 285 while ((c = desc.charAt(cursor++)) == '[') { 286 dim++; 287 } 288 289 Class primitiveClass = null; 290 291 switch (c) { 292 case 'V': 293 primitiveClass = void.class; 294 break; 295 case 'I': 296 primitiveClass = int.class; 297 break; 298 case 'C': 299 primitiveClass = char.class; 300 break; 301 case 'Z': 302 primitiveClass = boolean.class; 303 break; 304 case 'D': 305 primitiveClass = double.class; 306 break; 307 case 'F': 308 primitiveClass = float.class; 309 break; 310 case 'J': 311 primitiveClass = long.class; 312 break; 313 case 'B': 314 primitiveClass = byte.class; 315 break; 316 case 'S': 317 primitiveClass = short.class; 318 break; 319 case 'L': 320 StringBuffer name = new StringBuffer (desc.length()); 321 while ((c = desc.charAt(cursor++)) != ';') { 322 if (c == '/') { 323 c = '.'; 324 } 325 name.append(c); 326 } 327 328 td = new TypeDescriptor(name.toString()); 329 330 if (dim > 0) { 331 td = new TypeDescriptor(td, dim); 332 } 333 334 break; 335 } 336 337 if (primitiveClass != null) { 338 td = new TypeDescriptor(primitiveClass); 339 340 if (dim > 0) { 341 td = new TypeDescriptor(td, dim); 342 } 343 } 344 } 345 catch (NullPointerException e) { 346 throw new IllegalArgumentException ("Invalid descriptor: " + desc); 347 } 348 catch (IndexOutOfBoundsException e) { 349 throw new IllegalArgumentException ("Invalid descriptor: " + desc); 350 } 351 352 if (td == null || cursor != desc.length()) { 353 throw new IllegalArgumentException ("Invalid descriptor: " + desc); 354 } 355 356 return td; 357 } 358 } 359 | Popular Tags |