1 19 20 package org.openide.src; 21 22 import java.util.StringTokenizer ; 23 import java.util.HashMap ; 24 import java.io.Serializable ; 25 26 import org.openide.util.Utilities; 27 import org.openide.filesystems.FileObject; 28 29 33 public final class Type extends Object implements Cloneable , Serializable { 34 35 private static final int T_BOOLEAN = 0x0001; 36 private static final int T_INT = 0x0002; 37 private static final int T_CHAR = 0x0003; 38 private static final int T_BYTE = 0x0004; 39 private static final int T_SHORT = 0x0005; 40 private static final int T_LONG = 0x0006; 41 private static final int T_FLOAT = 0x0007; 42 private static final int T_DOUBLE = 0x0008; 43 private static final int T_VOID = 0x0009; 44 45 private static final int T_CLASS = 0x0010; 46 private static final int T_ARRAY = 0x0020; 47 48 private static final int T_PRIMITIVE= 0x000F; 49 50 51 public static final Type VOID = new Type(T_VOID); 52 53 public static final Type BOOLEAN = new Type(T_BOOLEAN); 54 55 public static final Type INT = new Type(T_INT); 56 57 public static final Type CHAR = new Type(T_CHAR); 58 59 public static final Type BYTE = new Type(T_BYTE); 60 61 public static final Type SHORT = new Type(T_SHORT); 62 63 public static final Type LONG = new Type(T_LONG); 64 65 public static final Type FLOAT = new Type(T_FLOAT); 66 67 public static final Type DOUBLE = new Type(T_DOUBLE); 68 69 private static HashMap text2type = new HashMap (); 71 72 private static final String L_VOID = "void"; private static final String L_BOOLEAN = "boolean"; private static final String L_INT = "int"; private static final String L_CHAR = "char"; private static final String L_BYTE = "byte"; private static final String L_SHORT = "short"; private static final String L_LONG = "long"; private static final String L_FLOAT = "float"; private static final String L_DOUBLE = "double"; 82 private static final String [] PRIMITIVE_NAMES = { 83 L_VOID, L_BOOLEAN, L_INT, L_CHAR, L_BYTE, L_SHORT, L_LONG, L_FLOAT, L_DOUBLE 84 }; 85 86 static { 87 text2type.put(L_VOID, VOID); 88 text2type.put(L_BOOLEAN, BOOLEAN); 89 text2type.put(L_INT, INT); 90 text2type.put(L_CHAR, CHAR); 91 text2type.put(L_BYTE, BYTE); 92 text2type.put(L_SHORT, SHORT); 93 text2type.put(L_LONG, LONG); 94 text2type.put(L_FLOAT, FLOAT); 95 text2type.put(L_DOUBLE, DOUBLE); 96 } 97 98 99 private int kind; 100 101 102 private Type elementType = null; 103 104 105 private Identifier classType = null; 106 107 static final long serialVersionUID =8997425134968958367L; 108 110 private Type(int kind) { 111 this.kind = kind; 112 } 113 114 117 private Type(Type type) { 118 this.kind = T_ARRAY; 119 elementType = type; 120 } 121 122 private Type(Identifier id) { 123 this.kind = T_CLASS; 124 classType = id; 125 } 126 127 private Object readResolve() { 128 switch (kind) { 129 case T_BOOLEAN: return BOOLEAN; 130 case T_INT: return INT; 131 case T_CHAR: return CHAR; 132 case T_BYTE: return BYTE; 133 case T_SHORT: return SHORT; 134 case T_LONG: return LONG; 135 case T_FLOAT: return FLOAT; 136 case T_DOUBLE: return DOUBLE; 137 case T_VOID: return VOID; 138 case T_CLASS: return createClass(classType); 139 case T_ARRAY: return createArray(elementType); 140 default: throw new InternalError (); 141 } 142 } 143 144 147 public static String [] getTypesNames() { 148 return PRIMITIVE_NAMES; 149 } 150 151 155 public static Type createArray (Type elementType) { 156 return new Type(elementType); 157 } 158 159 163 public static Type createClass (Identifier id) { 164 return new Type(id); 167 } 168 169 173 public static Type createFromClass (Class cl) { 174 if (cl.isArray ()) 175 return createArray (createFromClass (cl.getComponentType ())); 176 else if (cl.isPrimitive ()) { 177 if (Void.TYPE.equals (cl)) return VOID; 178 if (Boolean.TYPE.equals (cl)) return BOOLEAN; 179 if (Integer.TYPE.equals (cl)) return INT; 180 if (Character.TYPE.equals (cl)) return CHAR; 181 if (Byte.TYPE.equals (cl)) return BYTE; 182 if (Short.TYPE.equals (cl)) return SHORT; 183 if (Long.TYPE.equals (cl)) return LONG; 184 if (Float.TYPE.equals (cl)) return FLOAT; 185 if (Double.TYPE.equals (cl)) return DOUBLE; 186 throw new InternalError (); } 188 else 189 return createClass (Identifier.create (getClassIdentifier(cl))); 190 } 191 192 200 private static String getClassIdentifier(Class cl) { 201 if (cl.getDeclaringClass() == null) 202 return cl.getName(); 203 204 StringBuffer sb = new StringBuffer (cl.getName()); 205 cl = cl.getDeclaringClass(); 206 207 do { 208 sb.setCharAt(cl.getName().length(), '.'); cl = cl.getDeclaringClass(); 210 } while (cl != null); 211 return sb.toString(); 212 } 213 214 220 public static Type parse(String text) throws IllegalArgumentException { 221 if (text.endsWith(".TYPE")) { int len = text.length (); 227 String v = text.startsWith("java.lang.") ? text.substring (10, len - 5) : 229 text.substring (0, len - 5); 230 231 if ("Void".equals (v)) return VOID; if ("Boolean".equals (v)) return BOOLEAN; if ("Integer".equals (v)) return INT; if ("Character".equals (v)) return CHAR; if ("Byte".equals (v)) return BYTE; if ("Short".equals (v)) return SHORT; if ("Long".equals (v)) return LONG; if ("Float".equals (v)) return FLOAT; if ("Double".equals (v)) return DOUBLE; } 241 242 243 StringTokenizer tok = new StringTokenizer (text, " []", true); Type type = null; 245 int status = 0; 246 while (tok.hasMoreTokens()) { 247 String token = tok.nextToken(); 248 if (token.equals(" ")) continue; 250 251 switch (status) { 252 case 0: 253 { 254 type = (Type) text2type.get(token); 255 if (type == null) { 256 String localText=token; 257 int offset; 258 259 if (localText.length()==0) 260 throw new IllegalArgumentException (); 261 do 262 { String localToken; 263 264 offset=localText.indexOf("."); if (offset == -1) 266 localToken=localText; 267 else { 268 localToken=localText.substring(0,offset); 269 localText=localText.substring(offset+1,localText.length()); 270 } 271 if (localToken.length()==0 || !Utilities.isJavaIdentifier(localToken)) { 272 throw new IllegalArgumentException (); 273 } 274 }while (offset != -1); 275 type = createClass(Identifier.create(token)); 276 } 277 status = 1; 278 break; 279 } 280 case 1: 281 if (!token.equals("[")) throw new IllegalArgumentException (); 283 284 status = 2; 285 break; 286 case 2: 287 if (!token.equals("]")) throw new IllegalArgumentException (); 289 290 type = createArray(type); 291 status = 1; 292 break; 293 } 294 } 295 if (type == null) 297 throw new IllegalArgumentException (); 298 return type; 299 } 300 301 304 public boolean isPrimitive () { 305 return ((kind & T_PRIMITIVE) != 0); 306 } 307 308 311 public boolean isArray () { 312 return (kind == T_ARRAY); 313 } 314 315 318 public boolean isClass () { 319 return (kind == T_CLASS); 320 } 321 322 326 public Type getElementType () throws IllegalStateException { 327 if (isArray()) 328 return elementType; 329 else 330 throw new IllegalStateException (); 331 } 332 333 337 public Identifier getClassName () throws IllegalStateException { 338 if (isClass()) 339 return classType; 340 else 341 throw new IllegalStateException (); 342 } 343 344 348 public Class toClass() throws ClassNotFoundException { 349 return toClass (null); 350 } 351 352 357 public Class toClass(ClassLoader loader) throws ClassNotFoundException { 358 if (isPrimitive()) { 359 switch (kind) { 360 case T_BOOLEAN : return Boolean.TYPE; 361 case T_INT : return Integer.TYPE; 362 case T_CHAR : return Character.TYPE; 363 case T_BYTE : return Byte.TYPE; 364 case T_SHORT : return Short.TYPE; 365 case T_LONG : return Long.TYPE; 366 case T_FLOAT : return Float.TYPE; 367 case T_DOUBLE : return Double.TYPE; 368 default : return Void.TYPE; } 370 } 371 372 if (loader == null) { 374 loader = getClass ().getClassLoader (); 375 } 376 377 if (isClass()) 378 return Class.forName (classType.getFullName(), true, loader); 379 else { 380 String name = ""; Type t = this; 383 while (t.isArray ()) { 384 name = name + "["; t = t.getElementType (); 386 } 387 388 if (t.isClass ()) name = name + "L" + t.classType.getFullName () + ";"; else { 390 name = name + getPrimitiveCode(t.kind); 391 } 392 393 return Class.forName (name, true, loader); 394 } 395 } 396 397 402 StringBuffer getAsString(StringBuffer appendTo, boolean source) { 403 if (isPrimitive()) { 404 switch (kind) { 405 case T_BOOLEAN : return appendTo.append("boolean"); case T_INT : return appendTo.append("int"); case T_CHAR : return appendTo.append("char"); case T_BYTE : return appendTo.append("byte"); case T_SHORT : return appendTo.append("short"); case T_LONG : return appendTo.append("long"); case T_FLOAT : return appendTo.append("float"); case T_DOUBLE : return appendTo.append("double"); default : return appendTo.append("void"); } 415 } 416 else { 417 if (isClass()) 418 return appendTo.append(source ? 419 classType.getSourceName() : 420 classType.getFullName() 421 ); 422 else { 423 return elementType.getAsString(appendTo, source).append("[]"); } 425 } 426 } 427 428 private static String getPrimitiveCode(int t) { 429 switch (t) { 430 case T_BOOLEAN : return "Z"; case T_INT : return "I"; case T_CHAR : return "C"; case T_BYTE : return "B"; case T_SHORT : return "S"; case T_LONG : return "J"; case T_FLOAT : return "F"; case T_DOUBLE : return "D"; default: return "V"; } 440 } 441 444 public String getSourceString() { 445 return getAsString(new StringBuffer (), true).toString(); 446 } 447 448 451 public String getFullString() { 452 return getAsString(new StringBuffer (), false).toString(); 453 } 454 455 458 public String toString() { 459 return getSourceString(); 460 } 461 462 474 public final String getVMClassName() throws UnsupportedOperationException { 475 throw new UnsupportedOperationException ("Operation is not more supported. Use Type.getVMClassName(FileObject)"); } 477 478 489 public final String getVMClassName(final FileObject projectArtefact) throws UnsupportedOperationException { 490 if (isPrimitive()) { 491 throw new UnsupportedOperationException ("Primitive types unsupported"); } 493 return internalGetVMName(false, projectArtefact); 494 } 495 496 501 public final Identifier getTypeIdentifier() throws UnsupportedOperationException { 502 if (isPrimitive() || isArray()) 503 throw new UnsupportedOperationException ("Only class types supported"); return classType; 505 } 506 507 private String internalGetVMName(final boolean useSignature, final FileObject projectArtefact) { 508 if (!isArray()) { 509 String fqn = classType.getFullName(); 510 ClassElement cls = ClassElement.forName(fqn, projectArtefact); 511 if (cls == null) { 512 if (useSignature) 513 return fqn.replace('.', '/'); 514 else 515 return fqn; 516 } 517 return useSignature ? cls.getSignature() : cls.getVMName() ; 518 } 519 520 int depth = 0; 521 Type t = this; 522 523 do { 524 ++depth; 525 t = t.getElementType(); 526 } while (t.isArray()); 527 528 StringBuffer sb = new StringBuffer (depth + 1); 529 for (int i = 0; i < depth; i++) { 530 sb.append('['); 531 } 532 if (t.isPrimitive()) { 533 sb.append(getPrimitiveCode(t.kind)); 534 } else { 535 sb.append('L'); 536 sb.append(t.internalGetVMName(useSignature, projectArtefact)); 537 sb.append(';'); 538 } 539 return sb.toString(); 540 } 541 542 550 public final String getSignature () { 551 throw new UnsupportedOperationException ("Operation is not more supported. Use Type.getSignature(FileObject)"); } 553 554 562 public final String getSignature (final FileObject projectArtefact) { 563 if (isPrimitive()) { 564 return getPrimitiveCode(this.kind); 565 } 566 if (isClass()) { 567 StringBuffer sb; 568 String fqn = classType.getFullName(); 569 ClassElement el = ClassElement.forName(fqn, projectArtefact); 570 if (el != null) 571 fqn = el.getSignature(); 572 sb = new StringBuffer (fqn.length() + 2); 573 sb.append('L'); 574 sb.append(fqn); 575 sb.append(';'); 576 return sb.toString(); 577 } else { 578 return internalGetVMName(true, projectArtefact); 579 } 580 } 581 582 590 public boolean compareTo(Type type, boolean source) { 591 if (type.kind != kind) 592 return false; 593 594 switch (kind) { 595 case T_ARRAY: 596 return type.getElementType().compareTo(getElementType(), source); 597 case T_CLASS: 598 return type.getClassName().compareTo(getClassName(), source); 599 default: 600 return true; 601 } 602 } 603 604 610 public boolean equals(Object o) { 611 return (o instanceof Type) ? compareTo((Type) o, false) : false; 612 } 613 614 616 public int hashCode() { 617 switch (kind) { 618 case T_ARRAY: 619 return getElementType().hashCode() << 1; 620 case T_CLASS: 621 return getClassName().hashCode(); 622 default: 623 return System.identityHashCode(this); 624 } 625 } 626 } 627 | Popular Tags |