1 26 package net.sf.javaguard; 27 28 import java.lang.reflect.*; 29 import java.util.*; 30 import net.sf.javaguard.classfile.ClassConstants; 31 import net.sf.javaguard.log.*; 32 33 34 39 public class Cl extends PkCl implements NameListUp, NameListDown { 40 private Map mds = new TreeMap(); private Map fds = new TreeMap(); private boolean isResolved = false; private boolean isScanned = false; private String superClass; private String [] superInterfaces; private boolean isInnerClass; private Vector nameListUps = new Vector(); private Vector nameListDowns = new Vector(); public static int nameSpace = 0; 51 private static NameMaker methodNameMaker; 52 private static NameMaker fieldNameMaker; 53 54 55 56 private boolean isSerializableClass; 57 58 private boolean isRemoteClass; 59 60 61 private FileLogger logger; 62 63 64 65 66 75 public Cl(TreeItem parent, boolean isInnerClass, String name, String superClass, String [] superInterfaces) { 76 super(parent, name); 77 this.superClass = superClass; 78 this.superInterfaces = superInterfaces; 79 this.isInnerClass = isInnerClass; 80 if (parent == null || name.equals("")) { 81 throw new InternalError ("Internal error: class must have parent and name"); 82 } 83 if (parent instanceof Cl) { 84 setSeparator(ClassConstants.SEP_INNER); 85 } 86 87 setSerializable(false); 88 setRemoteClass(false); 89 90 if (isInnerClass && Character.isDigit(name.charAt(0))) { 92 setOutName(getInName()); 93 } 94 95 logger = FileLogger.getInstance(); 96 } 97 98 99 100 public boolean isInnerClass() { 101 return isInnerClass; 102 } 103 104 105 106 public Md getMethod(String name, String descriptor) { 107 return (Md) mds.get(name + descriptor); 108 } 109 110 111 112 public Fd getField(String name) { 113 return (Fd) fds.get(name); 114 } 115 116 117 120 public Iterator getMethodIterator() { 121 return mds.values().iterator(); 122 } 123 124 125 128 public Iterator getFieldIterator() { 129 return fds.values().iterator(); 130 } 131 132 133 134 public boolean hasAsSuper(String queryName) { 135 if (superClass == null) return false; 137 138 try { 139 if (superClass.equals(queryName)) { 140 return true; 141 } else { 142 Cl superClassItem = getClassTree().getCl(superClass); 143 if (superClassItem != null) { 144 return superClassItem.hasAsSuper(queryName); 145 } else { 146 Class extSuper = Class.forName(Tools.translate(superClass), false, getClass().getClassLoader()); 147 while (extSuper != null) { 148 if (extSuper.getName().equals(Tools.translate(queryName))) { 149 return true; 150 } 151 extSuper = extSuper.getSuperclass(); 152 } 153 return false; 154 } 155 } 156 } catch (Exception e) { 157 return false; 158 } 159 } 160 161 162 163 public Cl addClass(String name, String superName, String [] interfaceNames) { 164 return addClass(name, true, superName, interfaceNames); 165 } 166 167 168 169 public Cl addClass(Cl cl) { 170 cls.put(cl.getInName(), cl); 171 return cl; 172 } 173 174 175 176 public Cl addPlaceholderClass(String name) { 177 return addPlaceholderClass(name, true); 178 } 179 180 181 182 public Md addMethod(boolean isSynthetic, String name, String descriptor, int access) { 183 if (name.charAt(0) == '<') { 185 return null; 186 } 187 Md md = getMethod(name, descriptor); 188 if (md == null) { 189 md = new Md(this, isSynthetic, name, descriptor, access); 190 mds.put(name + descriptor, md); 191 } 192 return md; 193 } 194 195 196 197 public Fd addField(boolean isSynthetic, String name, String descriptor, int access) { 198 Fd fd = getField(name); 199 if (fd == null) { 200 fd = new Fd(this, isSynthetic, name, descriptor, access); 201 fds.put(name, fd); 202 } 203 return fd; 204 } 205 206 207 208 public void resetResolve() { 209 isScanned = false; 210 isResolved = false; 211 nameListDowns.removeAllElements(); 212 } 213 214 215 public void setupNameListDowns() { 216 if (superClass == null) return; 218 219 Cl superClassItem = getClassTree().getCl(superClass); 221 if (superClassItem != null) { 222 superClassItem.nameListDowns.addElement(this); 223 } 224 for (int i = 0; i < superInterfaces.length; i++) { 225 Cl interfaceItem = getClassTree().getCl(superInterfaces[i]); 226 if (interfaceItem != null) { 227 interfaceItem.nameListDowns.addElement(this); 228 } 229 } 230 } 231 232 233 237 public void resolveOptimally() { 238 if (!isResolved) { 240 Vector methods = new Vector(); 242 Vector fields = new Vector(); 243 scanNameSpaceExcept(null, methods, fields); 244 String [] methodNames = new String [methods.size()]; 245 for (int i = 0; i < methodNames.length; i++) { 246 methodNames[i] = (String )methods.elementAt(i); 247 } 248 String [] fieldNames = new String [fields.size()]; 249 for (int i = 0; i < fieldNames.length; i++) { 250 fieldNames[i] = (String )fields.elementAt(i); 251 } 252 253 methodNameMaker = new KeywordNameMaker(methodNames); 255 fieldNameMaker = new KeywordNameMaker(fieldNames); 256 257 resolveNameSpaceExcept(null); 259 260 nameSpace++; 262 } 263 } 264 265 266 private void scanNameSpaceExcept(Cl ignoreCl, Vector methods, Vector fields) { 268 if (superClass == null) return; 270 271 if (!isScanned) { 273 Cl superCl = getClassTree().getCl(superClass); 275 if (superCl != null) { 277 if (superCl != ignoreCl) { 278 superCl.scanNameSpaceExcept(this, methods, fields); 279 } 280 } 281 else { 283 scanExtSupers(superClass, methods, fields); 284 } 285 for (int i = 0; i < superInterfaces.length; i++) { 286 Cl interfaceItem = getClassTree().getCl(superInterfaces[i]); 287 if (interfaceItem != null && interfaceItem != ignoreCl) { 288 interfaceItem.scanNameSpaceExcept(this, methods, fields); 289 } 290 } 291 292 if (!isScanned) { 294 scanThis(methods, fields); 295 296 isScanned = true; 298 } 299 300 for (Iterator iter = nameListDowns.iterator(); iter.hasNext(); ) { 302 Cl cl = (Cl) iter.next(); 303 if (cl != ignoreCl) { 304 cl.scanNameSpaceExcept(this, methods, fields); 305 } 306 } 307 } 308 } 309 310 private void scanExtSupers(String name, Vector methods, Vector fields) { 312 Class extClass = null; 313 try { 314 extClass = Class.forName(Tools.translate(name), false, getClass().getClassLoader()); 315 } catch (ClassNotFoundException ex) { 316 return; 317 } 318 Method[] allPubMethods = extClass.getMethods(); 320 if (allPubMethods != null) { 321 for (int i = 0; i < allPubMethods.length; i++) { 322 String methodName = allPubMethods[i].getName(); 323 if (methods.indexOf(methodName) == -1) { 324 methods.addElement(methodName); 325 } 326 } 327 } 328 Field[] allPubFields = extClass.getFields(); 329 if (allPubFields != null) { 330 for (int i = 0; i < allPubFields.length; i++) { 331 String fieldName = allPubFields[i].getName(); 332 if (fields.indexOf(fieldName) == -1) { 333 fields.addElement(fieldName); 334 } 335 } 336 } 337 while (extClass != null) { 339 Method[] allClassMethods = extClass.getDeclaredMethods(); 340 if (allClassMethods != null) { 341 for (int i = 0; i < allClassMethods.length; i++) { 342 if (!Modifier.isPublic(allClassMethods[i].getModifiers())) { 343 String methodName = allClassMethods[i].getName(); 344 if (methods.indexOf(methodName) == -1) { 345 methods.addElement(methodName); 346 } 347 } 348 } 349 } 350 Field[] allClassFields = extClass.getDeclaredFields(); 351 if (allClassFields != null) { 352 for (int i = 0; i < allClassFields.length; i++) { 353 if (!Modifier.isPublic(allClassFields[i].getModifiers())) { 354 String fieldName = allClassFields[i].getName(); 355 if (fields.indexOf(fieldName) == -1) { 356 fields.addElement(fieldName); 357 } 358 } 359 } 360 } 361 extClass = extClass.getSuperclass(); 362 } 363 } 364 365 366 private void scanThis(Vector methods, Vector fields) { 368 for (Iterator mdEnum = getMethodIterator(); mdEnum.hasNext(); ) { 369 Md md = (Md) mdEnum.next(); 370 if (md.isFixed()) { 371 String name = md.getOutName(); 372 if (methods.indexOf(name) == -1) { 373 methods.addElement(name); 374 } 375 } 376 } 377 for (Iterator fdEnum = getFieldIterator(); fdEnum.hasNext(); ) { 378 Fd fd = (Fd) fdEnum.next(); 379 if (fd.isFixed()) { 380 String name = fd.getOutName(); 381 if (fields.indexOf(name) == -1) { 382 fields.addElement(name); 383 } 384 } 385 } 386 } 387 388 389 private void resolveNameSpaceExcept(Cl ignoreCl) { 391 if (superClass == null) return; 393 394 if (!isResolved) { 396 Cl superCl = getClassTree().getCl(superClass); 398 if (superCl != null && superCl != ignoreCl) { 399 superCl.resolveNameSpaceExcept(this); 400 } 401 for (int i = 0; i < superInterfaces.length; i++) { 402 Cl interfaceItem = getClassTree().getCl(superInterfaces[i]); 403 if (interfaceItem != null && interfaceItem != ignoreCl) { 404 interfaceItem.resolveNameSpaceExcept(this); 405 } 406 } 407 408 if (!isResolved) { 410 resolveThis(); 411 412 isResolved = true; 414 } 415 416 for (Iterator iter = nameListDowns.iterator(); iter.hasNext(); ) { 418 Cl cl = (Cl) iter.next(); 419 if (cl != ignoreCl) { 420 cl.resolveNameSpaceExcept(this); 421 } 422 } 423 } 424 } 425 426 427 428 private void resolveThis() { 432 if (superClass == null) return; 434 435 Cl superClassItem = getClassTree().getCl(superClass); 436 nameListUps.addElement(superClassItem != null 437 ? (NameListUp)superClassItem 438 : getExtNameListUp(superClass)); 439 440 for (int i = 0; i < superInterfaces.length; i++) { 441 Cl interfaceItem = getClassTree().getCl(superInterfaces[i]); 442 nameListUps.addElement(interfaceItem != null 443 ? (NameListUp)interfaceItem 444 : getExtNameListUp(superInterfaces[i])); 445 } 446 447 nextMethod: 450 for (Iterator mdIter = getMethodIterator(); mdIter.hasNext(); ) { 451 Md md = (Md) mdIter.next(); 452 if (!md.isFixed()) { 453 for (Iterator nlIter = nameListDowns.iterator(); nlIter.hasNext(); ) { 455 String theOutName = ((NameListDown) nlIter.next()).getMethodObfNameDown(this, md.getInName(), md.getDescriptor()); 456 if (theOutName != null) { 457 md.setOutName(theOutName); 458 continue nextMethod; 459 } 460 } 461 for (Iterator nlIter = nameListUps.iterator(); nlIter.hasNext(); ) { 463 NameListUp nlu = (NameListUp) nlIter.next(); 464 if (null != nlu) { 465 String theOutName = nlu.getMethodOutNameUp(md.getInName(), md.getDescriptor()); 466 if (theOutName != null) { 467 md.setOutName(theOutName); 468 continue nextMethod; 469 } 470 } else { 471 logger.addWarning("# Warning: name list contains null pointer (check your classpath settings)!"); 472 logger.addWarning("# method: " + md.getFullInName() + " / " + md.getDescriptor()); 473 logger.addWarning("# in: Cl.resolveThis()"); 474 } 475 } 476 md.setOutName(methodNameMaker.nextName(md.getDescriptor())); 478 } 479 } 480 481 nextField: 482 for (Iterator fdIter = getFieldIterator(); fdIter.hasNext(); ) { 483 Fd fd = (Fd) fdIter.next(); 484 if (!fd.isFixed()) { 485 for (Iterator nlIter = nameListDowns.iterator(); nlIter.hasNext(); ) { 487 String theOutName = ((NameListDown) nlIter.next()).getFieldObfNameDown(this, fd.getInName()); 488 if (theOutName != null) { 489 fd.setOutName(theOutName); 490 continue nextField; 491 } 492 } 493 for (Iterator nlIter = nameListUps.iterator(); nlIter.hasNext(); ) { 495 NameListUp nlu = (NameListUp) nlIter.next(); 496 if (null != nlu) { 497 String superOutName = nlu.getFieldOutNameUp(fd.getInName()); 498 if (superOutName != null) { 499 fd.setOutName(superOutName); 500 continue nextField; 501 } 502 } else { 503 logger.addWarning("# Warning: name list contains null pointer (check your classpath settings)!"); 504 logger.addWarning("# field: " + fd.getFullInName() + " / " + fd.getDescriptor()); 505 logger.addWarning("# in: Cl.resolveThis()"); 506 } 507 } 508 fd.setOutName(fieldNameMaker.nextName(null)); 510 } 511 } 512 } 513 514 515 516 public String getMethodOutNameUp(String name, String descriptor) { 517 for (Iterator iter = nameListUps.iterator(); iter.hasNext(); ) { 519 NameListUp nlu = (NameListUp) iter.next(); 520 if (null != nlu) { 521 String superOutName = nlu.getMethodOutNameUp(name, descriptor); 522 if (superOutName != null) { 523 return superOutName; 524 } 525 } else { 526 logger.addWarning("# Warning: Cannot lookup output method name (check your classpath settings)!"); 527 logger.addWarning("# method: " + getFullInName() + " / " + name + " / " + descriptor); 528 } 529 } 530 531 Md md = getMethod(name, descriptor); 533 if (md != null && !Modifier.isPrivate(md.getModifiers())) { 534 return md.getOutName(); 535 } 536 else { 537 return null; 538 } 539 } 540 541 542 543 public String getMethodObfNameUp(String name, String descriptor) { 544 for (Iterator iter = nameListUps.iterator(); iter.hasNext(); ) { 546 NameListUp nlu = (NameListUp) iter.next(); 547 if (null != nlu) { 548 String superObfName = nlu.getMethodObfNameUp(name, descriptor); 549 if (superObfName != null) { 550 return superObfName; 551 } 552 } else { 553 logger.addWarning("# Warning: Cannot lookup obfuscated method name (check your classpath settings)!"); 554 logger.addWarning("# method: " + getFullInName() + " / " + name + " / " + descriptor); 555 } 556 } 557 558 Md md = getMethod(name, descriptor); 560 if (md != null && !Modifier.isPrivate(md.getModifiers())) { 561 return md.getObfName(); 562 } 563 else { 564 return null; 565 } 566 } 567 568 569 570 public String getFieldOutNameUp(String name) { 571 for (Iterator iter = nameListUps.iterator(); iter.hasNext(); ) { 573 NameListUp nlu = (NameListUp) iter.next(); 574 if (null != nlu) { 575 String superOutName = nlu.getFieldOutNameUp(name); 576 if (superOutName != null) { 577 return superOutName; 578 } 579 } else { 580 logger.addWarning("# Warning: Cannot lookup output field name (check your classpath settings)!"); 581 logger.addWarning("# field: " + getFullInName() + " / " + name); 582 } 583 } 584 585 Fd fd = getField(name); 587 if (fd != null && !Modifier.isPrivate(fd.getModifiers())) { 588 return fd.getOutName(); 589 } 590 else { 591 return null; 592 } 593 } 594 595 596 597 public String getFieldObfNameUp(String name) { 598 for (Iterator iter = nameListUps.iterator(); iter.hasNext(); ) { 600 NameListUp nlu = (NameListUp) iter.next(); 601 if (null != nlu) { 602 String superObfName = nlu.getFieldObfNameUp(name); 603 if (superObfName != null) { 604 return superObfName; 605 } 606 } else { 607 logger.addWarning("# Warning: Cannot lookup obfuscated field name (check your classpath settings)!"); 608 logger.addWarning("# field: " + getFullInName() + " / " + name); 609 } 610 } 611 612 Fd fd = getField(name); 614 if (fd != null && !Modifier.isPrivate(fd.getModifiers())) { 615 return fd.getObfName(); 616 } 617 else { 618 return null; 619 } 620 } 621 622 623 624 public String getMethodObfNameDown(Cl caller, String name, String descriptor) { 625 Md md = getMethod(name, descriptor); 627 if (md != null && md.isFixed()) { 628 return md.getOutName(); 629 } 630 631 String theObfName = null; 633 if (superClass != null) { 634 Cl superClassItem = getClassTree().getCl(superClass); 635 if (superClassItem != caller) { 636 NameListUp nl = superClassItem != null ? (NameListUp)superClassItem : getExtNameListUp(superClass); 637 if (null != nl) { 638 theObfName = nl.getMethodObfNameUp(name, descriptor); 639 if (theObfName != null) { 640 return theObfName; 641 } 642 } else { 643 logger.addWarning("# Warning: Cannot lookup method in super class (check your classpath settings)!"); 644 logger.addWarning("# Cl: " + caller.getFullInName() + " / " + name + " / " + descriptor); 645 } 646 } 647 for (int i = 0; i < superInterfaces.length; i++) { 648 Cl interfaceItem = getClassTree().getCl(superInterfaces[i]); 649 if (interfaceItem != caller) { 650 NameListUp nl = interfaceItem != null ? (NameListUp)interfaceItem : getExtNameListUp(superInterfaces[i]); 651 if (null != nl) { 652 theObfName = nl.getMethodObfNameUp(name, descriptor); 653 if (theObfName != null) { 654 return theObfName; 655 } 656 } else { 657 logger.addWarning("# Warning: Cannot lookup method in interfaces (check your classpath settings)!"); 658 logger.addWarning("# Cl: " + caller.getFullInName() + " / " + name + " / " + descriptor); 659 } 660 } 661 } 662 } 663 664 for (Iterator iter = nameListDowns.iterator(); iter.hasNext(); ) { 666 theObfName = ((NameListDown) iter.next()).getMethodObfNameDown(this, name, descriptor); 667 if (theObfName != null) { 668 return theObfName; 669 } 670 } 671 672 return null; 674 } 675 676 677 678 public String getFieldObfNameDown(Cl caller, String name) { 679 Fd fd = getField(name); 681 if (fd != null && fd.isFixed()) { 682 return fd.getOutName(); 683 } 684 685 String theObfName = null; 687 if (superClass != null) { 688 Cl superClassItem = getClassTree().getCl(superClass); 689 if (superClassItem != caller) { 690 NameListUp nl = superClassItem != null ? (NameListUp)superClassItem : getExtNameListUp(superClass); 691 if (nl != null) { 692 theObfName = nl.getFieldObfNameUp(name); 693 if (theObfName != null) { 694 return theObfName; 695 } 696 } else { 697 logger.addWarning("# Warning: Cannot lookup field in super class (check your classpath settings)!"); 698 logger.addWarning("# Cl: " + caller.getFullInName() + " / " + name); 699 } 700 } 701 for (int i = 0; i < superInterfaces.length; i++) { 702 Cl interfaceItem = getClassTree().getCl(superInterfaces[i]); 703 if (interfaceItem != caller) { 704 NameListUp nl = interfaceItem != null ? (NameListUp)interfaceItem : getExtNameListUp(superInterfaces[i]); 705 if (null != nl) { 706 theObfName = nl.getFieldObfNameUp(name); 707 if (theObfName != null) { 708 return theObfName; 709 } 710 } else { 711 logger.addWarning("# Warning: Cannot lookup field in interfaces (check your classpath settings)!"); 712 logger.addWarning("# Cl: " + caller.getFullInName() + " / " + name); 713 } 714 } 715 } 716 } 717 718 for (Iterator iter = nameListDowns.iterator(); iter.hasNext(); ) { 720 theObfName = ((NameListDown) iter.next()).getFieldObfNameDown(this, name); 721 if (theObfName != null) { 722 return theObfName; 723 } 724 } 725 726 return null; 728 } 729 730 731 private static Hashtable extNameListUpCache = new Hashtable(); 733 734 private NameListUp getExtNameListUp(String name) { 735 NameListUp nl = (NameListUp)extNameListUpCache.get(name); 736 if (nl == null) { 737 try { 738 nl = new ExtNameListUp(name); 739 extNameListUpCache.put(name, nl); 740 } catch (ClassNotFoundException cnfex) { 741 nl = null; 742 } 743 } 744 return nl; 745 } 746 747 class ExtNameListUp implements NameListUp { 749 private Class extClass; 751 private Method[] methods = null; 752 753 public ExtNameListUp(String name) 755 throws ClassNotFoundException { 756 extClass = Class.forName(Tools.translate(name), false, getClass().getClassLoader()); 757 } 758 759 760 public ExtNameListUp(Class extClass) { 762 this.extClass = extClass; 763 } 764 765 766 public String getMethodObfNameUp(String name, String descriptor) { 768 return getMethodOutNameUp(name, descriptor); 769 } 770 771 772 public String getMethodOutNameUp(String name, String descriptor) { 774 if (methods == null) { 776 methods = getAllDeclaredMethods(extClass); 777 Vector pruned = new Vector(); 778 for (int i = 0; i < methods.length; i++) { 779 int modifiers = methods[i].getModifiers(); 780 if (!Modifier.isPrivate(modifiers)) { 781 pruned.addElement(methods[i]); 782 } 783 } 784 methods = new Method[pruned.size()]; 785 for (int i = 0; i < methods.length; i++) { 786 methods[i] = (Method)pruned.elementAt(i); 787 } 788 } 789 790 nextMethod: 792 for (int i = 0; i < methods.length; i++) { 793 if (name.equals(methods[i].getName())) { 794 String [] paramAndReturnNames = Tools.parseDescriptor(descriptor); 795 Class [] paramTypes = methods[i].getParameterTypes(); 796 Class returnType = methods[i].getReturnType(); 797 if (paramAndReturnNames.length == paramTypes.length + 1) { 798 for (int j = 0; j < paramAndReturnNames.length - 1; j++) { 799 if (!paramAndReturnNames[j].equals(paramTypes[j].getName())) { 800 continue nextMethod; 801 } 802 } 803 String returnName = returnType.getName(); 804 if (!paramAndReturnNames[paramAndReturnNames.length - 1].equals(returnName)) { 805 continue nextMethod; 806 } 807 808 return name; 810 } 811 } 812 } 813 814 return null; 816 } 817 818 819 public String getFieldObfNameUp(String name) { 821 return getFieldOutNameUp(name); 822 } 823 824 825 public String getFieldOutNameUp(String name) { 827 Field field = getAllDeclaredField(extClass, name); 829 if (field != null) { 830 int modifiers = field.getModifiers(); 832 if (!Modifier.isPrivate(modifiers)) { 833 return name; 834 } 835 } 836 837 return null; 839 } 840 841 842 private Method[] getAllDeclaredMethods(Class theClass) { 844 Vector ma = new Vector(); 845 int length = 0; 846 847 Method[] allPubMethods = theClass.getMethods(); 849 ma.addElement(allPubMethods); 850 length += allPubMethods.length; 851 852 while (theClass != null) { 855 Method[] methods = theClass.getDeclaredMethods(); 856 ma.addElement(methods); 857 length += methods.length; 858 theClass = theClass.getSuperclass(); 859 } 860 861 Method[] allMethods = new Method[length]; 863 int pos = 0; 864 for (Iterator iter = ma.iterator(); iter.hasNext(); ) { 865 Method[] methods = (Method[]) iter.next(); 866 System.arraycopy(methods, 0, allMethods, pos, methods.length); 867 pos += methods.length; 868 } 869 return allMethods; 870 } 871 872 873 private Field getAllDeclaredField(Class theClass, String name) { 875 Class origClass = theClass; 876 877 while (theClass != null) { 879 Field field = null; 880 try { 881 field = theClass.getDeclaredField(name); 882 } catch (Exception e) { 883 field = null; 884 } 885 if (field != null) { 886 return field; 887 } 888 theClass = theClass.getSuperclass(); 889 } 890 891 try { 894 return origClass.getField(name); 895 } catch (Exception e) { 896 return null; 897 } 898 } 899 } 900 901 902 903 904 909 public void setSerializable(boolean serializable) { 910 this.isSerializableClass = serializable; 911 } 912 913 914 919 public boolean isSerializable() { 920 return isSerializableClass; 921 } 922 923 924 925 926 930 public void setRemoteClass(boolean rmic) { 931 this.isRemoteClass = rmic; 932 } 933 934 935 940 public boolean isRemoteClass() { 941 return isRemoteClass; 942 } 943 944 945 946 947 951 public boolean isBeingObfuscated() { 952 TreeItem ti = this; 953 while (null != ti) { 954 if (!ti.getInName().equals(ti.getOutName())) { 955 return true; 956 } 957 ti = ti.getParent(); 958 } 959 return false; 960 } 961 962 963 964 965 968 public String [] getSuperInterfaces() { 969 return superInterfaces; 970 } 971 972 973 974 975 978 public String getSuperclass() { 979 return superClass; 980 } 981 } 982 | Popular Tags |