1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 package com.sun.star.lib.uno.typedesc; 25 26 import com.sun.star.lib.uno.typeinfo.AttributeTypeInfo; 27 import com.sun.star.lib.uno.typeinfo.MemberTypeInfo; 28 import com.sun.star.lib.uno.typeinfo.MethodTypeInfo; 29 import com.sun.star.lib.uno.typeinfo.ParameterTypeInfo; 30 import com.sun.star.lib.uno.typeinfo.TypeInfo; 31 import com.sun.star.uno.IFieldDescription; 32 import com.sun.star.uno.IMethodDescription; 33 import com.sun.star.uno.ITypeDescription; 34 import com.sun.star.uno.Type; 35 import com.sun.star.uno.TypeClass; 36 import java.lang.ref.ReferenceQueue; 37 import java.lang.ref.SoftReference; 38 import java.lang.reflect.Field; 39 import java.lang.reflect.Method; 40 import java.util.ArrayList; 41 import java.util.HashMap; 42 43 /** 44 * Supplies information about UNO types. 45 * 46 * @since UDK2.0 47 */ 48 public final class TypeDescription implements ITypeDescription { getTypeDescription(String typeName)49 public static TypeDescription getTypeDescription(String typeName) 50 throws ClassNotFoundException 51 { 52 Type t = new Type(typeName); 53 if (t.getTypeClass() == TypeClass.UNKNOWN) { 54 if (typeName.startsWith("[]")) { 55 t = new Type(typeName, TypeClass.SEQUENCE); 56 } else { 57 t = new Type(Class.forName(typeName)); 58 } 59 } 60 return get(t); 61 } 62 getTypeDescription(Class zClass)63 public static TypeDescription getTypeDescription(Class zClass) { 64 return getDefinitely(new Type(zClass)); 65 } 66 getTypeDescription(Type type)67 public static TypeDescription getTypeDescription(Type type) 68 throws ClassNotFoundException 69 { 70 //TODO: synchronize on type? 71 TypeDescription desc = (TypeDescription) type.getTypeDescription(); 72 if (desc == null) { 73 desc = getTypeDescription(type.getTypeName()); 74 type.setTypeDescription(desc); 75 } 76 return desc; 77 } 78 getTypeDescription(TypeClass typeClass)79 public static TypeDescription getTypeDescription(TypeClass typeClass) { 80 switch (typeClass.getValue()) { 81 case TypeClass.VOID_value: 82 return getDefinitely(Type.VOID); 83 84 case TypeClass.BOOLEAN_value: 85 return getDefinitely(Type.BOOLEAN); 86 87 case TypeClass.BYTE_value: 88 return getDefinitely(Type.BYTE); 89 90 case TypeClass.SHORT_value: 91 return getDefinitely(Type.SHORT); 92 93 case TypeClass.UNSIGNED_SHORT_value: 94 return getDefinitely(Type.UNSIGNED_SHORT); 95 96 case TypeClass.LONG_value: 97 return getDefinitely(Type.LONG); 98 99 case TypeClass.UNSIGNED_LONG_value: 100 return getDefinitely(Type.UNSIGNED_LONG); 101 102 case TypeClass.HYPER_value: 103 return getDefinitely(Type.HYPER); 104 105 case TypeClass.UNSIGNED_HYPER_value: 106 return getDefinitely(Type.UNSIGNED_HYPER); 107 108 case TypeClass.FLOAT_value: 109 return getDefinitely(Type.FLOAT); 110 111 case TypeClass.DOUBLE_value: 112 return getDefinitely(Type.DOUBLE); 113 114 case TypeClass.CHAR_value: 115 return getDefinitely(Type.CHAR); 116 117 case TypeClass.STRING_value: 118 return getDefinitely(Type.STRING); 119 120 case TypeClass.TYPE_value: 121 return getDefinitely(Type.TYPE); 122 123 case TypeClass.ANY_value: 124 return getDefinitely(Type.ANY); 125 126 default: 127 return null; 128 } 129 } 130 isTypeClassSimple(TypeClass typeClass)131 public static boolean isTypeClassSimple(TypeClass typeClass) { 132 return getTypeDescription(typeClass) != null; 133 } 134 135 // @see ITypeDescription#getSuperType getSuperType()136 public ITypeDescription getSuperType() { 137 // Arbitrarily take the first super type: 138 return superTypes == null || superTypes.length == 0 139 ? null : superTypes[0]; 140 } 141 142 // @see ITypeDescription#getMethodDescriptions getMethodDescriptions()143 public IMethodDescription[] getMethodDescriptions() { 144 initMethodDescriptions(); 145 return methodDescriptions; //TODO: clone? 146 } 147 148 // @see ITypeDescription#getMethodDescription(int) getMethodDescription(int methodId)149 public IMethodDescription getMethodDescription(int methodId) { 150 initMethodDescriptions(); 151 return methodId < 0 152 ? null 153 : methodId < superMethodDescriptions.length 154 ? superMethodDescriptions[methodId] 155 : (methodId - superMethodDescriptions.length 156 < methodDescriptions.length) 157 ? methodDescriptions[methodId - superMethodDescriptions.length] 158 : null; 159 } 160 161 // @see ITypeDescription#getMethodDescription(String) getMethodDescription(String name)162 public IMethodDescription getMethodDescription(String name) { 163 initMethodDescriptions(); 164 for (int i = 0; i < superMethodDescriptions.length; ++i) { 165 if (superMethodDescriptions[i].getName().equals(name)) { 166 return superMethodDescriptions[i]; 167 } 168 } 169 for (int i = 0; i < methodDescriptions.length; ++i) { 170 if (methodDescriptions[i].getName().equals(name)) { 171 return methodDescriptions[i]; 172 } 173 } 174 return null; 175 } 176 177 // @see ITypeDescription#getFieldDescriptions getFieldDescriptions()178 public IFieldDescription[] getFieldDescriptions() { 179 return fieldDescriptions; //TODO: clone? 180 } 181 182 // @see ITypeDescription#getFieldDescription getFieldDescription(String name)183 public IFieldDescription getFieldDescription(String name) { 184 for (int i = 0; i < fieldDescriptions.length; ++i) { 185 if (fieldDescriptions[i].getName().equals(name)) { 186 return fieldDescriptions[i]; 187 } 188 } 189 return superTypes != null && superTypes.length == 1 190 ? superTypes[0].getFieldDescription(name) : null; 191 } 192 193 // @see ITypeDescription#getTypeClass getTypeClass()194 public TypeClass getTypeClass() { 195 return typeClass; 196 } 197 198 // @see ITypeDescription#getComponentType getComponentType()199 public ITypeDescription getComponentType() { 200 return componentType; 201 } 202 203 // @see ITypeDescription#getTypeName getTypeName()204 public String getTypeName() { 205 return typeName; 206 } 207 208 // @see ITypeDescription#getArrayTypeName getArrayTypeName()209 public String getArrayTypeName() { 210 return arrayTypeName; 211 } 212 213 // @see ITypeDescription#getZClass getZClass()214 public Class getZClass() { 215 return zClass; 216 } 217 hasTypeArguments()218 public boolean hasTypeArguments() { 219 return hasTypeArguments; 220 } 221 222 // @see Object#toString toString()223 public String toString() { 224 return "[" + getClass().getName() + ": " + getTypeClass() + ", " 225 + getTypeName() + "]"; 226 } 227 getDefinitely(Type type)228 private static TypeDescription getDefinitely(Type type) { 229 try { 230 return get(type); 231 } catch (ClassNotFoundException e) { 232 throw new IllegalArgumentException("this cannot happen: " + e); 233 } 234 } 235 get(Type type)236 private static TypeDescription get(Type type) throws ClassNotFoundException 237 { 238 String typeName = type.getTypeName(); 239 TypeDescription desc = cache.get(typeName); 240 if (desc == null) { 241 desc = create(type); 242 cache.put(desc); 243 } 244 return desc; 245 } 246 create(Type type)247 private static TypeDescription create(Type type) 248 throws ClassNotFoundException 249 { 250 TypeClass typeClass = type.getTypeClass(); 251 String typeName = type.getTypeName(); 252 Class zClass = type.getZClass(); 253 if (zClass == null) { 254 throw new ClassNotFoundException("UNO type " + type); 255 } 256 switch (typeClass.getValue()) { 257 case TypeClass.VOID_value: 258 return new TypeDescription( 259 typeClass, typeName, "[Ljava.lang.Void;", zClass, null, null); 260 261 case TypeClass.BOOLEAN_value: 262 return new TypeDescription( 263 typeClass, typeName, "[Z", zClass, null, null); 264 265 case TypeClass.BYTE_value: 266 return new TypeDescription( 267 typeClass, typeName, "[B", zClass, null, null); 268 269 case TypeClass.SHORT_value: 270 case TypeClass.UNSIGNED_SHORT_value: 271 return new TypeDescription( 272 typeClass, typeName, "[S", zClass, null, null); 273 274 case TypeClass.LONG_value: 275 case TypeClass.UNSIGNED_LONG_value: 276 return new TypeDescription( 277 typeClass, typeName, "[I", zClass, null, null); 278 279 case TypeClass.HYPER_value: 280 case TypeClass.UNSIGNED_HYPER_value: 281 return new TypeDescription( 282 typeClass, typeName, "[J", zClass, null, null); 283 284 case TypeClass.FLOAT_value: 285 return new TypeDescription( 286 typeClass, typeName, "[F", zClass, null, null); 287 288 case TypeClass.DOUBLE_value: 289 return new TypeDescription( 290 typeClass, typeName, "[D", zClass, null, null); 291 292 case TypeClass.CHAR_value: 293 return new TypeDescription( 294 typeClass, typeName, "[C", zClass, null, null); 295 296 case TypeClass.STRING_value: 297 return new TypeDescription( 298 typeClass, typeName, "[Ljava.lang.String;", zClass, null, null); 299 300 case TypeClass.TYPE_value: 301 return new TypeDescription( 302 typeClass, typeName, "[Lcom.sun.star.uno.Type;", zClass, null, 303 null); 304 305 case TypeClass.ANY_value: 306 return new TypeDescription( 307 typeClass, typeName, "[Ljava.lang.Object;", zClass, null, null); 308 309 case TypeClass.SEQUENCE_value: 310 { 311 // assert typeName.startsWith("[]"); 312 ITypeDescription componentType = getTypeDescription( 313 typeName.substring("[]".length())); 314 // assert zClass.getName().startsWith("["); 315 return new TypeDescription( 316 typeClass, typeName, "[" + zClass.getName(), zClass, null, 317 componentType); 318 } 319 320 case TypeClass.ENUM_value: 321 // assert !zClass.getName().startsWith("["); 322 return new TypeDescription( 323 typeClass, typeName, "[L" + zClass.getName() + ";", zClass, 324 null, null); 325 326 case TypeClass.STRUCT_value: 327 { 328 // This code exploits the fact that an instantiated polymorphic 329 // struct type may not be the direct base of a struct type: 330 Class superClass = zClass.getSuperclass(); 331 TypeDescription[] superTypes = superClass != Object.class 332 ? new TypeDescription[] { get(new Type(superClass)) } 333 : null; 334 // assert !zClass.getName().startsWith("["); 335 return new TypeDescription( 336 typeClass, typeName, "[L" + zClass.getName() + ";", zClass, 337 superTypes, null); 338 } 339 340 case TypeClass.EXCEPTION_value: 341 { 342 TypeDescription[] superTypes 343 = typeName.equals("com.sun.star.uno.Exception") 344 || typeName.equals("com.sun.star.uno.RuntimeException") 345 ? null 346 : new TypeDescription[] { 347 get(new Type(zClass.getSuperclass())) }; 348 // assert !zClass.getName().startsWith("["); 349 return new TypeDescription( 350 typeClass, typeName, "[L" + zClass.getName() + ";", zClass, 351 superTypes, null); 352 } 353 354 case TypeClass.INTERFACE_value: 355 { 356 List superTypes = new List(); 357 Class[] interfaces = zClass.getInterfaces(); 358 for (int i = 0; i < interfaces.length; ++i) { 359 Type t = new Type(interfaces[i]); 360 if (t.getTypeClass() == TypeClass.INTERFACE) { 361 TypeDescription desc = getDefinitely(t); 362 TypeDescription[] descs = desc.superTypes; 363 for (int j = 0; j < descs.length; ++j) { 364 superTypes.add(descs[j]); 365 } 366 superTypes.add(desc); 367 } 368 } 369 // assert !zClass.getName().startsWith("["); 370 return new TypeDescription( 371 typeClass, typeName, "[L" + zClass.getName() + ";", zClass, 372 superTypes.toArray(), null); 373 } 374 375 default: 376 throw new IllegalArgumentException("given type has bad type class"); 377 } 378 } 379 TypeDescription( TypeClass typeClass, String typeName, String arrayTypeName, Class zClass, TypeDescription[] superTypes, ITypeDescription componentType)380 private TypeDescription( 381 TypeClass typeClass, String typeName, String arrayTypeName, 382 Class zClass, TypeDescription[] superTypes, 383 ITypeDescription componentType) 384 { 385 this.typeClass = typeClass; 386 this.typeName = typeName; 387 this.arrayTypeName = arrayTypeName; 388 this.zClass = zClass; 389 this.superTypes = superTypes; 390 this.componentType = componentType; 391 TypeDescription[] args = calculateTypeArguments(); 392 this.hasTypeArguments = args != null; 393 this.fieldDescriptions = calculateFieldDescriptions(args); 394 // methodDescriptions must be initialized lazily, to avoid problems with 395 // circular dependencies (a super-interface that has a sub-interface as 396 // method parameter type; an interface that has a struct as method 397 // parameter type, and the struct has the interface as member type) 398 } 399 initMethodDescriptions()400 private synchronized void initMethodDescriptions() { 401 if (methodDescriptions != null || typeClass != TypeClass.INTERFACE) { 402 return; 403 } 404 if (superTypes.length == 0) { // com.sun.star.uno.XInterface 405 superMethodDescriptions = new IMethodDescription[0]; 406 methodDescriptions = new IMethodDescription[] { 407 new MethodDescription( 408 "queryInterface", MethodDescription.ID_QUERY_INTERFACE, 409 false, new ITypeDescription[] { getDefinitely(Type.TYPE) }, 410 new ITypeDescription[] { null }, getDefinitely(Type.ANY), 411 null), 412 new MethodDescription( 413 "acquire", MethodDescription.ID_ACQUIRE, true, 414 new ITypeDescription[0], new ITypeDescription[0], 415 getDefinitely(Type.VOID), null), 416 new MethodDescription( 417 "release", MethodDescription.ID_RELEASE, true, 418 new ITypeDescription[0], new ITypeDescription[0], 419 getDefinitely(Type.VOID), null) }; 420 } else { 421 int methodOffset = 0; 422 ArrayList superList = new ArrayList(); 423 for (int i = 0; i < superTypes.length; ++i) { 424 IMethodDescription[] ds = superTypes[i].getMethodDescriptions(); 425 for (int j = 0; j < ds.length; ++j) { 426 superList.add(new MethodDescription(ds[j], methodOffset++)); 427 } 428 } 429 superMethodDescriptions = (IMethodDescription[]) superList.toArray( 430 new IMethodDescription[superList.size()]); 431 ArrayList directList = new ArrayList(); 432 TypeInfo[] infos = getTypeInfo(); 433 int infoCount = infos == null ? 0 : infos.length; 434 int index = 0; 435 Method[] methods = zClass.getDeclaredMethods(); 436 for (int i = 0; i < infoCount;) { 437 if (infos[i] instanceof AttributeTypeInfo) { 438 AttributeTypeInfo info = (AttributeTypeInfo) infos[i++]; 439 if (info.getIndex() != index) { 440 throw new IllegalArgumentException( 441 "Bad UNOTYPEINFO for " + zClass 442 + ": entries not ordererd"); 443 } 444 String getterName = "get" + info.getName(); 445 Method getter = findMethod(methods, getterName); 446 Type t = info.getUnoType(); 447 ITypeDescription type = t == null 448 ? getTypeDescription(getter.getReturnType(), info) 449 : getDefinitely(t); 450 directList.add( 451 new MethodDescription( 452 getterName, index++ + methodOffset, false, 453 new ITypeDescription[0], new ITypeDescription[0], 454 type, getter)); 455 if (!info.isReadOnly()) { 456 String setterName = "set" + info.getName(); 457 Method setter = findMethod(methods, setterName); 458 directList.add( 459 new MethodDescription( 460 setterName, index++ + methodOffset, false, 461 new ITypeDescription[] { type }, 462 new ITypeDescription[] { null }, 463 getDefinitely(Type.VOID), setter)); 464 } 465 } else { 466 MethodTypeInfo info = (MethodTypeInfo) infos[i++]; 467 if (info.getIndex() != index) { 468 throw new IllegalArgumentException( 469 "Bad UNOTYPEINFO for " + zClass 470 + ": entries not ordererd"); 471 } 472 Method method = findMethod(methods, info.getName()); 473 Class[] params = method.getParameterTypes(); 474 ITypeDescription[] in = new ITypeDescription[params.length]; 475 ITypeDescription[] out 476 = new ITypeDescription[params.length]; 477 for (int j = 0; j < params.length; ++j) { 478 ParameterTypeInfo p = null; 479 if (i < infoCount 480 && infos[i] instanceof ParameterTypeInfo 481 && ((ParameterTypeInfo) infos[i]).getIndex() == j) 482 { 483 p = (ParameterTypeInfo) infos[i++]; 484 } 485 Type pt = p == null ? null : p.getUnoType(); 486 ITypeDescription d = pt == null 487 ? getTypeDescription(params[j], p) 488 : getDefinitely(pt); 489 if (p == null || p.isIN()) { 490 in[j] = d; 491 } 492 if (p != null && p.isOUT()) { 493 out[j] = d; 494 } 495 } 496 Type t = info.getUnoType(); 497 directList.add( 498 new MethodDescription( 499 info.getName(), index++ + methodOffset, 500 info.isOneway(), in, out, 501 (t == null 502 ? getTypeDescription(method.getReturnType(), info) 503 : getDefinitely(t)), 504 method)); 505 } 506 } 507 methodDescriptions = (IMethodDescription[]) directList.toArray( 508 new IMethodDescription[directList.size()]); 509 } 510 } 511 calculateTypeArguments()512 private TypeDescription[] calculateTypeArguments() { 513 if (typeClass != TypeClass.STRUCT) { 514 return null; 515 } 516 int i = typeName.indexOf('<'); 517 if (i < 0) { 518 return null; 519 } 520 java.util.List args = new java.util.ArrayList(); 521 do { 522 ++i; // skip '<' or ',' 523 int j = i; 524 loop: 525 for (int level = 0; j != typeName.length(); ++j) { 526 switch (typeName.charAt(j)) { 527 case ',': 528 if (level == 0) { 529 break loop; 530 } 531 break; 532 533 case '<': 534 ++level; 535 break; 536 537 case '>': 538 if (level == 0) { 539 break loop; 540 } 541 --level; 542 break; 543 } 544 } 545 if (j != typeName.length()) { 546 Type t = new Type(typeName.substring(i, j)); 547 if (t.getZClass() == null) { 548 throw new IllegalArgumentException( 549 "UNO type name \"" + typeName 550 + "\" contains bad type argument \"" 551 + typeName.substring(i, j) + "\""); 552 } 553 args.add(getDefinitely(t)); 554 } 555 i = j; 556 } while (i != typeName.length() && typeName.charAt(i) != '>'); 557 if (i != typeName.length() - 1 || typeName.charAt(i) != '>' 558 || args.isEmpty()) 559 { 560 throw new IllegalArgumentException( 561 "UNO type name \"" + typeName + "\" is syntactically invalid"); 562 } 563 return (TypeDescription[]) args.toArray( 564 new TypeDescription[args.size()]); 565 } 566 calculateFieldDescriptions( TypeDescription[] typeArguments)567 private IFieldDescription[] calculateFieldDescriptions( 568 TypeDescription[] typeArguments) 569 { 570 if (typeClass != TypeClass.STRUCT && typeClass != TypeClass.EXCEPTION) { 571 return null; 572 } 573 TypeInfo[] infos = getTypeInfo(); 574 int infoCount = infos == null ? 0 : infos.length; 575 ITypeDescription superType = getSuperType(); 576 IFieldDescription[] superDescs = superType == null 577 ? null : superType.getFieldDescriptions(); 578 int superCount = superDescs == null ? 0 : superDescs.length; 579 IFieldDescription[] descs = new IFieldDescription[ 580 superCount + infoCount]; 581 if (superCount != 0) { 582 System.arraycopy(superDescs, 0, descs, 0, superCount); 583 } 584 for (int i = 0; i < infoCount; ++i) { 585 MemberTypeInfo info = (MemberTypeInfo) infos[i]; 586 if (info.getIndex() != i) { 587 throw new IllegalArgumentException( 588 "Bad UNOTYPEINFO for " + zClass + ": entries not ordererd"); 589 } 590 Field field; 591 try { 592 field = zClass.getDeclaredField(info.getName()); 593 } catch (NoSuchFieldException e) { 594 throw new IllegalArgumentException( 595 "Bad UNOTYPEINFO for " + zClass + ": " + e); 596 } 597 Type t = info.getUnoType(); 598 int index = info.getTypeParameterIndex(); 599 descs[i + superCount] = new FieldDescription( 600 info.getName(), i + superCount, 601 (index >= 0 602 ? typeArguments[index] 603 : t == null 604 ? getTypeDescription(field.getType(), info) 605 : getDefinitely(t)), 606 field); 607 } 608 return descs; 609 } 610 getTypeInfo()611 private TypeInfo[] getTypeInfo() { 612 try { 613 return (TypeInfo[]) 614 zClass.getDeclaredField("UNOTYPEINFO").get(null); 615 } catch (NoSuchFieldException e) { 616 return null; 617 } catch (IllegalAccessException e) { 618 throw new IllegalArgumentException( 619 "Bad UNOTYPEINFO for " + zClass + ": " + e); 620 } 621 } 622 findMethod(Method[] methods, String name)623 private Method findMethod(Method[] methods, String name) { 624 for (int i = 0; i < methods.length; ++i) { 625 if (methods[i].getName().equals(name)) { 626 return methods[i]; 627 } 628 } 629 throw new IllegalArgumentException( 630 "Bad UNOTYPEINFO for " + zClass + ": no method " + name); 631 } 632 getTypeDescription( Class zClass, TypeInfo typeInfo)633 private static ITypeDescription getTypeDescription( 634 Class zClass, TypeInfo typeInfo) 635 { 636 return getDefinitely( 637 new Type( 638 zClass, 639 typeInfo != null 640 && (typeInfo.isUnsigned() || typeInfo.isInterface()))); 641 } 642 643 private static final class List { List()644 public List() {} 645 add(TypeDescription desc)646 public void add(TypeDescription desc) { 647 if (!list.contains(desc)) { 648 list.add(desc); 649 } 650 } 651 isEmpty()652 public boolean isEmpty() { 653 return list.isEmpty(); 654 } 655 toArray()656 public TypeDescription[] toArray() { 657 return (TypeDescription[]) list.toArray( 658 new TypeDescription[list.size()]); 659 } 660 661 private final ArrayList list = new ArrayList(); 662 } 663 664 private static final class Cache { Cache()665 public Cache() {} 666 get(String typeName)667 public TypeDescription get(String typeName) { 668 synchronized (map) { 669 cleanUp(); 670 Entry e = (Entry) map.get(typeName); 671 return e == null ? null : (TypeDescription) e.get(); 672 } 673 } 674 put(TypeDescription desc)675 public void put(TypeDescription desc) { 676 synchronized (map) { 677 cleanUp(); 678 map.put(desc.getTypeName(), new Entry(desc, queue)); 679 } 680 } 681 cleanUp()682 private void cleanUp() { 683 for (;;) { 684 Entry e = (Entry) queue.poll(); 685 if (e == null) { 686 break; 687 } 688 map.remove(e.typeName); 689 } 690 } 691 692 private static final class Entry extends SoftReference { Entry(TypeDescription desc, ReferenceQueue queue)693 public Entry(TypeDescription desc, ReferenceQueue queue) { 694 super(desc, queue); 695 typeName = desc.getTypeName(); 696 } 697 698 public final String typeName; 699 } 700 701 private final HashMap map = new HashMap(); 702 private final ReferenceQueue queue = new ReferenceQueue(); 703 } 704 705 private static final Cache cache = new Cache(); 706 707 private final TypeClass typeClass; 708 private final String typeName; 709 private final String arrayTypeName; 710 private final Class zClass; 711 private final TypeDescription[] superTypes; 712 private final ITypeDescription componentType; 713 private final boolean hasTypeArguments; 714 private final IFieldDescription[] fieldDescriptions; 715 private IMethodDescription[] methodDescriptions = null; 716 private IMethodDescription[] superMethodDescriptions; 717 } 718