1 package org.ashkelon; 2 7 8 import java.io.Serializable ; 9 import java.sql.Connection ; 10 import java.sql.PreparedStatement ; 11 import java.sql.ResultSet ; 12 import java.sql.SQLException ; 13 import java.util.ArrayList ; 14 import java.util.Comparator ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.LinkedList ; 18 import java.util.List ; 19 import java.util.Map ; 20 21 import org.ashkelon.db.DBMgr; 22 import org.ashkelon.db.DBUtils; 23 import org.ashkelon.db.PKManager; 24 import org.ashkelon.util.JDocUtil; 25 import org.ashkelon.util.Logger; 26 import org.ashkelon.util.StringUtils; 27 import org.ashkelon.util.TreeNode; 28 29 import com.sun.javadoc.ClassDoc; 30 import com.sun.javadoc.ConstructorDoc; 31 import com.sun.javadoc.FieldDoc; 32 import com.sun.javadoc.MethodDoc; 33 34 41 public class ClassType implements Comparator , JDoc, Serializable 42 { 43 private int classType; 44 private String qualifiedName; 45 private String name; 46 private JPackage jPackage; 47 private ClassType superClass; 48 private String superClassName; 49 private boolean isAbstract; 50 private String version; 51 private DocInfo doc; 52 53 private boolean isStatic; 54 private boolean isFinal; 55 private int accessibility; 56 private String modifiers; 57 58 private List authors; 59 private List interfaces; 60 61 private List fields; 62 private List constructors; 63 private List methods; 64 65 private String containingClassName; 66 private ClassType containingClass; 67 private List innerClasses; 68 private API api; 69 70 private int id; 71 private boolean idSet = false; 72 73 private boolean storePackage = false; 74 75 private int level; 78 private static String SEQUENCE = "CLASSTYPE_SEQ"; 79 private static String TABLENAME = "CLASSTYPE"; 80 81 82 public static final int ORDINARY_CLASS = 1; 83 84 public static final int INTERFACE = 2; 85 86 public static final int EXCEPTION_CLASS = 3; 87 88 public static final int ERROR_CLASS = 4; 89 90 public static final String [] CLASSTYPES = {"ordinaryClass", "interface", "exception", "errorClass"}; 91 92 private transient Logger log; 93 94 public ClassType(String qualifiedName) 95 { 96 setQualifiedName(qualifiedName); 97 setName(JDocUtil.unqualify(qualifiedName)); 98 99 setAuthors(new ArrayList ()); 100 setInterfaces(new ArrayList ()); 101 102 setFields(new ArrayList ()); 103 setConstructors(new ArrayList ()); 104 setMethods(new ArrayList ()); 105 106 setSuperClassName(""); 107 108 setContainingClassName(""); 109 setInnerClasses(new ArrayList ()); 110 111 Logger.getInstance().debug("qualified name: "+qualifiedName); 112 113 if (qualifiedName.indexOf(".") > -1) 118 setPackage(new JPackage(qualifiedName.substring(0, qualifiedName.lastIndexOf(".")))); 119 120 setDoc(new DocInfo()); 121 122 log = Logger.getInstance(); 123 } 124 125 public ClassType(ClassDoc classdoc, API api) 126 { 127 this.api = api; 128 setName(classdoc.name()); 129 setQualifiedName(classdoc.qualifiedTypeName()); 130 131 setDoc(new DocInfo(classdoc)); 132 133 ClassDoc superClass = classdoc.superclass(); 134 if (superClass == null) 135 setSuperClassName(""); 136 else 137 setSuperClassName(superClass.qualifiedName()); 138 139 ClassDoc containingClass = classdoc.containingClass(); 140 if (containingClass == null) 141 setContainingClassName(""); 142 else 143 setContainingClassName(containingClass.qualifiedName()); 144 145 146 setAbstract(classdoc.isAbstract()); 147 String version = JDocUtil.getTagText(classdoc.tags("@version")); 148 if (version == null) 149 version = ""; 150 setVersion(version); 151 setClassType(getClassType(classdoc)); 152 153 setStatic(classdoc.isStatic()); 154 setFinal(classdoc.isFinal()); 155 setAccessibility(JDocUtil.getAccessibility(classdoc)); 156 String modifiers = classdoc.modifiers(); 157 if (modifiers.endsWith(" interface")) 158 { 159 modifiers = modifiers.substring(0, modifiers.indexOf(" interface")); 160 } 161 setModifiers(modifiers); 162 163 authors = new ArrayList (); 164 addAuthors(classdoc); 165 166 interfaces = new ArrayList (); 167 addInterfaces(classdoc.interfaces()); 168 169 fields = new ArrayList (); 170 addFields(classdoc.fields()); 171 172 constructors = new ArrayList (); 173 addConstructors(classdoc.constructors()); 174 175 methods = new ArrayList (); 176 addMethods(classdoc.methods()); 177 178 innerClasses = new ArrayList (); 179 addInnerClasses(classdoc.innerClasses()); 180 } 181 182 public ClassType(ClassDoc classdoc, JPackage jp, API api) 183 { 184 this(classdoc, api); 185 if (jp == null) 186 { 187 jp = new JPackage(classdoc.containingPackage(), false, api); 188 storePackage = true; 189 } 190 setPackage(jp); 191 } 192 193 public int getId(Connection conn) throws SQLException 194 { 195 if (!idSet) 196 { 197 id = PKManager.getInstance().nextVal(SEQUENCE); 199 idSet = true; 200 } 201 return id; 202 } 203 204 public int getId() 205 { 206 return id; 207 } 208 209 public void setId(int id) 210 { 211 this.id = id; 212 idSet = true; 213 } 214 215 public void store(Connection conn) throws SQLException 216 { 217 if (storePackage) 218 { 219 getPackage().store(conn); 221 } 222 223 Map fieldInfo = new HashMap (20); 224 fieldInfo.put("ID", new Integer (getId(conn))); 225 fieldInfo.put("TYPE", new Integer (getClassType())); 226 fieldInfo.put("QUALIFIEDNAME", StringUtils.truncate(getQualifiedName(), 150)); 227 fieldInfo.put("NAME", StringUtils.truncate(getName(), 100)); 228 fieldInfo.put("SUPERCLASSNAME", StringUtils.truncate(getSuperClassName(), 150)); 229 230 fieldInfo.put("CONTAININGCLASSNAME", StringUtils.truncate(getContainingClassName(), 150)); 231 232 int boolvalue = isAbstract() ? 1 : 0; 234 fieldInfo.put("ISABSTRACT", new Integer (boolvalue)); 235 236 fieldInfo.put("VERSION", StringUtils.truncate(getVersion(), 100)); 237 fieldInfo.put("DOCID", new Integer (getDoc().getId(conn))); 238 fieldInfo.put("PACKAGEID", new Integer (getPackage().getId(conn))); 239 240 boolvalue = isStatic() ? 1 : 0; 242 fieldInfo.put("ISSTATIC", new Integer (boolvalue)); 243 244 boolvalue = isFinal() ? 1 : 0; 246 fieldInfo.put("ISFINAL", new Integer (boolvalue)); 247 248 fieldInfo.put("ACCESSIBILITY", new Integer (getAccessibility())); 249 fieldInfo.put("MODIFIER", StringUtils.truncate(getModifiers(), 31)); 250 DBUtils.insert(conn, TABLENAME, fieldInfo); 251 252 getDoc().store(conn); 253 254 storeClassAuthors(conn); 255 storeInterfaces(conn); 256 storeSuperClass(conn); 257 258 for (int i=0; i<fields.size(); i++) 259 { 260 ((FieldMember) fields.get(i)).store(conn); 261 } 262 for (int i=0; i<constructors.size(); i++) 263 { 264 ((ConstructorMember) constructors.get(i)).store(conn); 265 } 266 for (int i=0; i<methods.size(); i++) 267 { 268 ((MethodMember) methods.get(i)).store(conn); 269 } 270 271 for (int i=0; i<innerClasses.size(); i++) 272 { 273 ((ClassType) innerClasses.get(i)).store(conn); 274 } 275 } 276 277 public void storeClassAuthors(Connection conn) throws SQLException 278 { 279 Map fieldInfo = new HashMap (5); 280 fieldInfo.put("CLASSID", new Integer (getId(conn))); 281 Author author = null; 282 for (int i=0; i<authors.size(); i++) 283 { 284 author = (Author) authors.get(i); 285 author.store(conn); 286 287 fieldInfo.put("AUTHORID", new Integer (author.getId(conn))); 288 DBUtils.insert(conn, "CLASS_AUTHOR", fieldInfo); 289 } 290 } 291 292 public void storeInterfaces(Connection conn) throws SQLException 293 { 294 Map fieldInfo = new HashMap (5); 295 fieldInfo.put("CLASSID", new Integer (getId(conn))); 296 String interface_name = ""; 297 for (int i=0; i<interfaces.size(); i++) 298 { 299 interface_name = ((ClassType) interfaces.get(i)).getQualifiedName(); 300 fieldInfo.put("NAME", StringUtils.truncate(interface_name, 150)); 301 DBUtils.insert(conn, "IMPL_INTERFACE", fieldInfo); 302 } 303 } 304 305 public void storeSuperClass(Connection conn) throws SQLException 306 { 307 if (StringUtils.isBlank(getSuperClassName())) 308 return; 309 Map fieldInfo = new HashMap (3); 310 fieldInfo.put("CLASSID", new Integer (getId(conn))); 311 fieldInfo.put("NAME", StringUtils.truncate(getSuperClassName(), 150)); 312 DBUtils.insert(conn, "SUPERCLASS", fieldInfo); 313 } 314 315 316 320 public static boolean delete(Connection conn, String className) throws SQLException 321 { 322 String sql = DBMgr.getInstance().getStatement("getclsanddocid"); 324 325 PreparedStatement pstmt = conn.prepareStatement(sql); 326 pstmt.setString(1, className); 327 ResultSet rset = pstmt.executeQuery(); 328 329 if (!rset.next()) 330 return false; 331 332 int classid = rset.getInt(1); 333 int classdocid = rset.getInt(2); 334 rset.close(); 335 pstmt.close(); 336 337 deleteInnerClasses(conn, className); 338 339 delete(conn, classid, classdocid); 340 return true; 341 } 342 343 public static void delete(Connection conn, int classid, int class_docid) throws SQLException 344 { 345 deleteFields(conn, classid); 346 deleteMethods(conn, classid); 347 deleteConstructors(conn, classid); 348 349 deleteInterfaces(conn, classid); 350 deleteSuperClass(conn, classid); 351 deleteClassAuthors(conn, classid); 352 353 DocInfo.delete(conn, class_docid); 354 355 String [][] params = {{"IMPL_INTERFACE", "interfaceid"}, 357 {"SUPERCLASS", "superclassid"}, 358 {"FIELD", "typeid"}, 359 {"METHOD", "returntypeid"}, 360 {"THROWNEXCEPTION", "exceptionid"}, 361 {"PARAMETER", "typeid"}, 362 {"REFERENCE", "refdoc_id"}}; 363 364 String sql = ""; 365 PreparedStatement pstmt; 366 for (int i=0; i<params.length; i++) 367 { 368 sql = "update " + params[i][0] + " set " + params[i][1] + " = null where " + params[i][1] + " = ?"; 369 Logger.getInstance().debug(sql); 370 pstmt = conn.prepareStatement(sql); 371 pstmt.setInt(1, classid); 372 pstmt.executeUpdate(); 373 pstmt.close(); 374 } 375 376 HashMap constraint = new HashMap (); 378 constraint.put("ID", new Integer (classid)); 379 DBUtils.delete(conn, TABLENAME, constraint); 380 } 381 382 public static void deleteFields(Connection conn, int classid) throws SQLException 383 { 384 String sql = DBMgr.getInstance().getStatement("getfieldanddocid"); 385 386 PreparedStatement pstmt = conn.prepareStatement(sql); 387 pstmt.setInt(1, classid); 388 ResultSet rset = pstmt.executeQuery(); 389 390 while (rset.next()) 391 { 392 FieldMember.delete(conn, rset.getInt(1), rset.getInt(2)); 393 } 394 395 rset.close(); 396 pstmt.close(); 397 } 398 399 public static void deleteMethods(Connection conn, int classid) throws SQLException 400 { 401 String sql = DBMgr.getInstance().getStatement("getmethodanddocid"); 402 403 PreparedStatement pstmt = conn.prepareStatement(sql); 404 pstmt.setInt(1, classid); 405 ResultSet rset = pstmt.executeQuery(); 406 407 while (rset.next()) 408 { 409 MethodMember.delete(conn, rset.getInt(1), rset.getInt(2)); 410 } 411 412 rset.close(); 413 pstmt.close(); 414 } 415 416 public static void deleteConstructors(Connection conn, int classid) throws SQLException 417 { 418 String sql = DBMgr.getInstance().getStatement("getconstranddocid"); 419 420 PreparedStatement pstmt = conn.prepareStatement(sql); 421 pstmt.setInt(1, classid); 422 ResultSet rset = pstmt.executeQuery(); 423 424 while (rset.next()) 425 { 426 ConstructorMember.delete(conn, rset.getInt(1), rset.getInt(2)); 427 } 428 429 rset.close(); 430 pstmt.close(); 431 } 432 433 public static void deleteClassAuthors(Connection conn, int classid) throws SQLException 434 { 435 String sql = DBMgr.getInstance().getStatement("deleteclassauthor"); 436 PreparedStatement pstmt = conn.prepareStatement(sql); 437 pstmt.setInt(1, classid); 438 pstmt.executeUpdate(); 439 pstmt.close(); 440 } 441 442 public static void deleteInterfaces(Connection conn, int classid) throws SQLException 443 { 444 String sql = DBMgr.getInstance().getStatement("deleteinterfaces"); 445 PreparedStatement pstmt = conn.prepareStatement(sql); 446 pstmt.setInt(1, classid); 447 pstmt.executeUpdate(); 448 pstmt.close(); 449 } 450 451 public static void deleteSuperClass(Connection conn, int classid) throws SQLException 452 { 453 String sql = DBMgr.getInstance().getStatement("deletesuperclass"); 454 PreparedStatement pstmt = conn.prepareStatement(sql); 455 pstmt.setInt(1, classid); 456 pstmt.executeUpdate(); 457 pstmt.close(); 458 } 459 460 public static void deleteInnerClasses(Connection conn, String containingClassName) throws SQLException 461 { 462 String sql = DBMgr.getInstance().getStatement("deleteinnercls"); 463 PreparedStatement pstmt = conn.prepareStatement(sql); 464 pstmt.setString(1, containingClassName); 465 pstmt.executeUpdate(); 466 pstmt.close(); 467 } 468 469 470 public boolean isInterface() 471 { 472 return (getClassType() == INTERFACE); 473 } 474 public boolean isClass() 475 { 476 return (getClassType() == ORDINARY_CLASS); 477 } 478 public boolean isException() 479 { 480 return (getClassType() == EXCEPTION_CLASS); 481 } 482 public boolean isError() 483 { 484 return (getClassType() == ERROR_CLASS); 485 } 486 487 public boolean isInnerClass() 488 { 489 return !StringUtils.isBlank(getContainingClassName()); 490 } 491 492 493 public int getClassType() { return classType; } 495 public void setClassType(int classType) { this.classType = classType; } 496 497 public String getClassTypeName() 498 { 499 int clsType = getClassType(); 500 if (clsType > CLASSTYPES.length || clsType <= 0) 501 { 502 return "unknown"; 503 } 504 return CLASSTYPES[clsType-1]; 505 } 506 507 public String getQualifiedName() { return qualifiedName; } 508 public void setQualifiedName(String qualifiedName) 509 { 510 this.qualifiedName = StringUtils.avoidNull(qualifiedName); 512 } 513 514 public String getName() { return name; } 516 public void setName(String name) 517 { 518 this.name = StringUtils.avoidNull(name); 519 } 520 521 public DocInfo getDoc() { return doc; } 522 public void setDoc(DocInfo doc) { this.doc = doc; } 523 524 public JPackage getPackage() { return jPackage; } 525 public void setPackage(JPackage jPackage) { this.jPackage = jPackage; } 526 527 public ClassType getSuperClass() { return superClass; } 528 public void setSuperClass(ClassType superClass) { this.superClass = superClass; } 529 530 531 public String getSuperClassName() { return superClassName; } 532 public void setSuperClassName(String superClassName) 533 { 534 this.superClassName = StringUtils.avoidNull(superClassName); 535 } 536 537 public String getContainingClassName() { return containingClassName; } 538 public void setContainingClassName(String containingClassName) 539 { 540 this.containingClassName = StringUtils.avoidNull(containingClassName); 541 } 542 543 public ClassType getContainingClass() { return containingClass; } 544 public void setContainingClass(ClassType containingClass) { this.containingClass = containingClass; } 545 546 547 public boolean isAbstract() { return isAbstract; } 548 public void setAbstract(boolean isAbstract) { this.isAbstract = isAbstract; } 549 550 public String getVersion() { return version; } 551 public void setVersion(String version) 552 { 553 this.version = StringUtils.avoidNull(version); 554 } 555 556 public boolean isStatic() { return isStatic; } 557 public void setStatic(boolean isStatic) { this.isStatic = isStatic; } 558 559 public boolean isFinal() { return isFinal; } 560 public void setFinal(boolean isFinal) { this.isFinal = isFinal; } 561 562 public int getAccessibility() { return accessibility; } 563 public void setAccessibility(int accessibility) { this.accessibility = accessibility; } 564 565 public String getModifiers() { return modifiers; } 566 public void setModifiers(String modifiers) { this.modifiers = modifiers; } 567 568 public void addAuthors(ClassDoc classdoc) 569 { 570 String [] names = JDocUtil.getTagList(classdoc.tags("@author")); 571 addAuthors(names); 572 } 573 574 public void addAuthors(String [] names) 575 { 576 for (int i=0; i<names.length; i++) 578 { 579 addAuthor(names[i]); 580 } 581 } 582 583 public void addAuthor(String authorName) 584 { 585 addAuthor(new Author(authorName)); 586 } 587 588 public void addAuthor(Author author) 589 { 590 authors.add(author); 591 author.addClass(this); 592 } 593 594 public List getAuthors() { return authors; } 595 public void setAuthors(List authors) { this.authors = authors; } 596 597 598 public void addInterfaces(ClassDoc[] impl_interfaces) 599 { 600 for (int i=0; i<impl_interfaces.length; i++) 601 { 602 addInterface(impl_interfaces[i].qualifiedName()); 603 } 604 } 605 606 public void addInterface(String qualifiedName) 607 { 608 if (StringUtils.isBlank(qualifiedName)) return; 609 interfaces.add(new ClassType(qualifiedName)); 610 } 611 612 public List getInterfaces() { return interfaces; } 613 public void setInterfaces(List interfaces) { this.interfaces = interfaces; } 614 615 616 public void addFields(FieldDoc[] fielddocs) 617 { 618 for (int i=0; i<fielddocs.length; i++) 620 { 621 addField(new FieldMember(fielddocs[i], this)); 622 } 623 } 624 625 public void addField(FieldMember fldMember) 626 { 627 fields.add(fldMember); 628 } 629 630 public void addConstructors(ConstructorDoc[] constructordocs) 631 { 632 for (int i=0; i<constructordocs.length; i++) 634 { 635 addConstructor(new ConstructorMember(constructordocs[i], this)); 636 } 637 } 638 639 public void addConstructor(ConstructorMember constr) 640 { 641 constructors.add(constr); 642 } 643 644 public void addMethods(MethodDoc[] methoddocs) 645 { 646 for (int i=0; i<methoddocs.length; i++) 648 { 649 addMethod(new MethodMember(methoddocs[i], this)); 650 } 651 } 652 653 public void addMethod(MethodMember method) 654 { 655 methods.add(method); 656 } 657 658 public List getFields() { return fields; } 659 public void setFields(List fields) { this.fields = fields; } 660 661 public List getConstructors() { return constructors; } 662 public void setConstructors(List constructors) { this.constructors = constructors; } 663 664 public List getMethods() { return methods; } 665 public void setMethods(List methods) { this.methods = methods; } 666 667 public boolean hasFields() { return !fields.isEmpty(); } 668 public boolean hasConstructors() { return !constructors.isEmpty(); } 669 public boolean hasMethods() { return !methods.isEmpty(); } 670 671 public boolean hasInnerClasses() { return !innerClasses.isEmpty(); } 672 673 public int getLevel() { return level; } 674 public void setLevel(int level) { this.level = level; } 675 676 677 public void addInnerClass(ClassType innerClass) 678 { 679 innerClasses.add(innerClass); 680 } 681 682 public void addInnerClasses(ClassDoc[] innerClasses) 683 { 684 for (int i=0; i<innerClasses.length; i++) 685 { 686 addInnerClass(new ClassType(innerClasses[i], getPackage(), (api==null) ? getAPI() : api)); 687 } 688 } 689 690 public List getInnerClasses() { return innerClasses; } 691 public void setInnerClasses(List innerClasses) { this.innerClasses = innerClasses; } 692 693 694 697 public static int getClassType(ClassDoc classdoc) 698 { 699 if (classdoc.isOrdinaryClass()) 700 { 701 return ORDINARY_CLASS; 702 } 703 else if (classdoc.isError()) 704 { 705 return ERROR_CLASS; 706 } 707 else if (classdoc.isException()) 708 { 709 return EXCEPTION_CLASS; 710 } 711 else if (classdoc.isInterface()) 712 { 713 return INTERFACE; 714 } 715 else 716 { 717 return JDocUtil.UNKNOWN_TYPE; 719 } 720 } 721 722 private List getDescendentList(Connection conn) throws SQLException 723 { 724 String sql = DBMgr.getInstance().getStatement("getdescendents"); 725 726 PreparedStatement pstmt = conn.prepareStatement(sql); 727 pstmt.setInt(1, getId()); 728 ResultSet rset = pstmt.executeQuery(); 729 730 List classes = new ArrayList (); 731 732 ClassType c; 733 while(rset.next()) 734 { 735 c = new ClassType(rset.getString(2)); 736 c.setId(rset.getInt(1)); 737 c.setSuperClassName(rset.getString(3)); 738 c.setClassType(rset.getInt(4)); 739 c.getDoc().setSummaryDescription(rset.getString(5)); 740 classes.add(c); 741 log.debug(c.getQualifiedName()); 742 } 743 744 return classes; 745 } 746 747 public TreeNode getSuperclassesConstrained(Connection conn, ClassType root) throws SQLException 748 { 749 TreeNode rootnode = getSuperclasses(conn); 750 if (root.getQualifiedName().equals("java.lang.Object")) 751 return rootnode; 752 753 TreeNode childnode = rootnode.getOnlyChild(); 754 while (((ClassType) childnode.getValue()).getId() != root.getId()) 755 childnode = childnode.getOnlyChild(); 756 757 return childnode.getOnlyChild(); 758 } 759 760 public TreeNode getDescendents(Connection conn) throws SQLException 761 { 762 if (DBMgr.getInstance().getDbtype().equals("oracle")) 763 { 764 return getDescendentsOra(conn); 765 } 766 767 List descendents = getDescendentList(conn); 768 769 List clstreelist = new ArrayList (); 770 ClassType c; 771 772 for (int i=0; i<descendents.size(); i++) 773 { 774 c = (ClassType) descendents.get(i); 775 777 TreeNode clstree = c.getSuperclassesConstrained(conn, this); 778 779 clstreelist.add(clstree); 781 } 782 783 log.debug(clstreelist.size()+" little trees to merge"); 784 785 TreeNode clsNode = new TreeNode(this); 786 TreeNode clstree; 787 788 for (int i=0; i<clstreelist.size(); i++) 789 { 790 clstree = (TreeNode) clstreelist.get(i); 791 793 String key = ((ClassType) clstree.getValue()).getQualifiedName(); 794 796 TreeNode node = clsNode; 797 TreeNode targetnode = clstree; 798 String targetkey = key; 799 800 while(node.getChild(targetkey)!=null) 801 { 802 node = node.getChild(targetkey); 804 targetnode = targetnode.getOnlyChild(); 805 if (targetnode == null) 806 { 807 continue; 808 } 809 targetkey = ((ClassType) targetnode.getValue()).getQualifiedName(); 810 } 811 if (targetnode == null) 812 { 813 continue; 814 } 815 816 820 node.addChild(targetkey, targetnode); 821 822 861 862 } 865 866 return clsNode; 867 868 } 869 870 public TreeNode getDescendentsOra(Connection conn) throws SQLException 871 { 872 873 String sql = 874 " select " + 875 " id, qualifiedname, level, superclassname, type " + 876 " from CLASSTYPE " + 877 " start with qualifiedname=? " + 878 " connect by prior qualifiedname=superclassname " + 879 " order by level desc, type, qualifiedname "; 880 881 PreparedStatement pstmt = conn.prepareStatement(sql); 882 pstmt.setString(1, getQualifiedName()); 883 ResultSet rset = pstmt.executeQuery(); 884 885 List classes = new ArrayList (); 886 887 ClassType c; 888 while(rset.next()) 889 { 890 c = new ClassType(rset.getString(2)); 891 c.setId(rset.getInt(1)); 892 c.setLevel(rset.getInt(3)); 893 c.setSuperClassName(rset.getString(4)); 894 c.setClassType(rset.getInt(5)); 895 classes.add(c); 896 log.debug(c.getQualifiedName() + " " + c.getLevel()); 897 } 898 899 TreeNode root = ClassType.makeTree(classes); 900 return root; 901 } 902 903 904 910 public static TreeNode makeTree(List classTree) 911 { 912 Map children = new HashMap (); 913 Map parents = new HashMap (); 914 TreeNode root; 915 916 int level, prev = 0; 917 int startat = 0; 918 919 ClassType cls; 920 TreeNode clsNode; 921 922 for (int i=0; i<classTree.size(); i++) 923 { 924 cls = (ClassType) classTree.get(i); 925 level = cls.getLevel(); 926 clsNode = new TreeNode(cls); 927 928 if (i==0) { prev = level; } 929 930 if (level != prev) 931 { 932 startat++; 933 934 if (startat >= 2) 935 { 936 TreeNode child; 937 ClassType childClass; 938 String supercls; 939 TreeNode parent = null; 940 941 Iterator itr = children.values().iterator(); 942 while (itr.hasNext()) 943 { 944 child = (TreeNode) itr.next(); 945 childClass = (ClassType) child.getValue(); 946 supercls = childClass.getSuperClassName(); 947 parent = (TreeNode) parents.get(supercls); 948 if (parent != null) 949 parent.addChild(childClass.getQualifiedName(), child); 950 } 951 } 952 953 children = parents; 954 parents = new HashMap (); 955 } 956 957 parents.put(cls.getQualifiedName(), clsNode); 958 959 prev = level; 960 } 961 962 ClassType rootClass = (ClassType) classTree.get(classTree.size()-1); 963 root = new TreeNode(rootClass); 964 965 root.setChildren(children); 966 return root; 967 968 } 969 970 971 public static TreeNode makeStupidTree(List classTree) 972 { 973 Logger log = Logger.getInstance(); 974 975 TreeNode root = new TreeNode(classTree.get(0)); 976 TreeNode current = root; 977 978 int parentLevel = 1; 979 int nextLevel; 980 981 ClassType next; 982 TreeNode nextNode; 983 LinkedList lastChildren = new LinkedList (); 984 985 for (int i=1; i<classTree.size(); i++) 986 { 987 next = (ClassType) classTree.get(i); 988 nextLevel = next.getLevel(); 989 nextNode = new TreeNode(next); 990 991 if (nextLevel - parentLevel == 1) { 993 current.addChild(next.getQualifiedName(), nextNode); 994 if (!lastChildren.isEmpty()) lastChildren.removeLast(); 995 lastChildren.add(nextNode); 996 } 997 else if (nextLevel - parentLevel == 2) { 999 current = (TreeNode) lastChildren.getLast(); 1000 parentLevel++; 1001 current.addChild(next.getQualifiedName(), nextNode); 1002 lastChildren.add(nextNode); 1003 } 1004 else if (nextLevel <= parentLevel) { 1006 TreeNode saved = current; 1007 while (nextLevel <= parentLevel) 1008 { 1009 current = current.getParent(); 1010 if (!current.getChildren().isEmpty()) 1011 lastChildren.removeLast(); 1012 parentLevel--; 1013 1014 if (current == null) 1015 { 1016 log.debug("Iteration #: "+i); 1017 log.debug("Error Occurred"); 1018 log.debug("parentLevel: "+parentLevel); 1019 log.debug(saved.getValue().toString()); 1020 log.debug(TreeNode.printTree(saved, 0)); 1021 } 1023 } 1024 1025 current.addChild(next.getQualifiedName(), nextNode); 1026 lastChildren.add(nextNode); 1027 } 1028 } 1029 1030 return root; 1031 } 1032 1033 1034 public int compare(Object p1, Object p2) 1035 { 1036 ClassType t1, t2; 1037 t1 = (ClassType) p1; 1038 t2 = (ClassType) p2; 1039 return (t1.getClassType() - t2.getClassType()); 1040 } 1041 1042 public String toString() 1043 { 1044 return getQualifiedName(); 1045 } 1046 1047 1048 public static ClassType makeClassFor(Connection conn, int clsId, boolean fetchChildren) 1049 throws SQLException , ClassNotFoundException 1050 { 1051 1062 String sql = DBMgr.getInstance().getStatement("makeclass"); 1063 1064 PreparedStatement pstmt = conn.prepareStatement(sql); 1065 pstmt.setInt(1, clsId); 1066 ResultSet rset = pstmt.executeQuery(); 1067 1068 if (!rset.next()) throw new ClassNotFoundException ("No class found matching id "+clsId); 1069 1070 ClassType cls = new ClassType(rset.getString(2)); 1071 cls.setId(rset.getInt(1)); 1072 cls.setName(rset.getString(3)); 1073 cls.setSuperClassName(rset.getString(4)); 1074 cls.setVersion(rset.getString(5)); 1075 cls.setClassType(rset.getInt(6)); 1076 cls.getPackage().setId(rset.getInt(7)); 1077 cls.setModifiers(rset.getString(14)); 1078 cls.setStatic(rset.getBoolean(15)); 1079 cls.setFinal(rset.getBoolean(16)); 1080 cls.setAbstract(rset.getBoolean(17)); 1081 cls.setAccessibility(rset.getInt(18)); 1082 String containingClassName = rset.getString(19); 1083 if (!StringUtils.isBlank(containingClassName)) 1084 { 1085 cls.setContainingClassName(containingClassName); 1086 cls.setContainingClass(new ClassType(containingClassName)); 1087 cls.getContainingClass().setId(rset.getInt(20)); 1088 } 1089 1090 cls.getPackage().setName(rset.getString(21)); 1091 cls.getPackage().setAPI(new API(rset.getString(22))); 1092 cls.getAPI().setId(rset.getInt(23)); 1093 1094 int superid = rset.getInt(8); 1095 if (superid > 0) 1096 { 1097 cls.setSuperClass(new ClassType(cls.getSuperClassName())); 1098 cls.getSuperClass().setId(superid); 1099 } 1100 1101 cls.setDoc(new DocInfo(rset.getString(10), rset.getString(11), rset.getString(12))); 1102 cls.getDoc().setId(rset.getInt(13)); 1103 cls.getDoc().setDescription(rset.getString(9)); 1104 1105 rset.close(); 1106 pstmt.close(); 1107 1108 if (fetchChildren) 1109 { 1110 cls.fetchAuthors(conn); 1111 cls.fetchInterfaces(conn); 1112 cls.fetchMembers(conn); 1113 cls.fetchInnerClasses(conn); 1114 cls.getDoc().fetchRefs(conn); 1115 } 1116 1117 return cls; 1118 } 1119 1120 1121 public static void main(String args[]) 1122 { 1123 DBMgr mgr = DBMgr.getInstance(); 1124 Logger log = Logger.getInstance(); 1125 log.setTraceLevel(Logger.DEBUG); 1126 1127 Connection conn = null; 1128 try 1129 { 1130 conn = mgr.getConnection(); 1131 1132 ClassType cls = ClassType.makeClassFor(conn, 114, false); 1133 TreeNode root = cls.getSuperclasses(conn); 1135 String treetext = TreeNode.printTree(root, 0); 1136 log.debug(treetext); 1137 1138 mgr.releaseConnection(conn); 1139 } 1140 catch (SQLException ex) 1141 { 1142 DBUtils.logSQLException(ex); 1143 } 1144 catch (ClassNotFoundException ex) 1145 { 1146 log.error(ex.getMessage()); 1147 } 1148 finally 1149 { 1150 if (conn!=null) 1151 mgr.releaseConnection(conn); 1152 } 1153 } 1154 1155 1156 public void fetchInnerClasses(Connection conn) throws SQLException , ClassNotFoundException 1157 { 1158 String sql = "select id from CLASSTYPE c where containingclassname=? order by name"; 1159 PreparedStatement pstmt = conn.prepareStatement(sql); 1160 pstmt.setString(1, getQualifiedName()); 1161 ResultSet rset = pstmt.executeQuery(); 1162 1163 while (rset.next()) 1164 addInnerClass(makeClassFor(conn, rset.getInt(1), false)); 1165 1166 rset.close(); 1167 pstmt.close(); 1168 } 1169 1170 public void fetchAuthors(Connection conn) throws SQLException 1171 { 1172 String sql = 1173 " select AUTHOR.id, AUTHOR.name " + 1174 " from AUTHOR, CLASS_AUTHOR ca " + 1175 " where ca.classid=? and ca.authorid=AUTHOR.id " + 1176 " order by AUTHOR.name "; 1177 1178 PreparedStatement pstmt = conn.prepareStatement(sql); 1179 pstmt.setInt(1, getId()); 1180 ResultSet rset = pstmt.executeQuery(); 1181 1182 Author author = null; 1183 while (rset.next()) 1184 { 1185 author = new Author(rset.getString(2)); 1186 author.setId(rset.getInt(1)); 1187 addAuthor(author); 1188 } 1189 1190 rset.close(); 1191 pstmt.close(); 1192 } 1193 1194 public void fetchInterfaces(Connection conn) throws SQLException 1195 { 1196 String sql = 1197 " select ii.name, ii.interfaceid " + 1198 " from IMPL_INTERFACE ii " + 1199 " where ii.classid=? " + 1200 " order by ii.name "; 1201 1202 PreparedStatement pstmt = conn.prepareStatement(sql); 1203 pstmt.setInt(1, getId()); 1204 ResultSet rset = pstmt.executeQuery(); 1205 ClassType ii; 1206 int iid; 1207 1208 while (rset.next()) 1209 { 1210 ii = new ClassType(rset.getString(1)); 1211 iid = rset.getInt(2); 1212 if (iid > 0) 1213 ii.setId(iid); 1214 interfaces.add(ii); 1215 } 1216 1217 rset.close(); 1218 pstmt.close(); 1219 } 1220 1221 1222 public void fetchMembers(Connection conn) throws SQLException 1223 { 1224 int FIELDS = 0; int TABLES = 1; int CONDITIONS = 2; 1225 1226 String [][] memberInfo = 1227 { 1228 {" , f.typename, f.typedimension, f.typeid ", " , FIELD f ", " and m.id=f.id "}, 1229 {" , ex.signature ", " , EXECMEMBER ex ", " and m.id=ex.id "}, 1230 {" , ex.signature , meth.isabstract, meth.returntypename, meth.returntypedimension, meth.returntypeid ", 1231 " , EXECMEMBER ex , METHOD meth ", 1232 " and m.id=ex.id and m.id=meth.id "} 1233 }; 1234 1235 PreparedStatement pstmt = null; 1236 ResultSet rset = null; 1237 1238 String [] sql = {"", "", ""}; 1239 for (int memberType=0; memberType<sql.length; memberType++) 1240 { 1241 sql[memberType] = 1242 " select m.id, m.qualifiedname, m.type, " + 1243 " m.isstatic, m.isfinal, m.accessibility, m.modifier, " + 1244 " d.summarydescription, d.since, d.deprecated " + 1245 memberInfo[memberType][FIELDS] + 1246 " from CLASSTYPE c, MEMBER m, DOC d " + 1247 memberInfo[memberType][TABLES] + 1248 " where c.id=? and m.type=? and m.classid=c.id and m.docid=d.id " + 1249 memberInfo[memberType][CONDITIONS] + 1250 " order by m.type, m.name " ; 1251 1252 log.debug("member sql statement:\n\t" + sql[memberType]); 1253 1254 pstmt = conn.prepareStatement(sql[memberType]); 1255 pstmt.setInt(1, getId()); 1256 pstmt.setInt(2, memberType+1); 1257 rset = pstmt.executeQuery(); 1258 1259 Member member = null; 1260 DocInfo doc; 1261 1262 while (rset.next()) 1263 { 1264 doc = new DocInfo(rset.getString(8), rset.getString(9), rset.getString(10)); 1265 1266 switch (memberType+1) 1267 { 1268 case Member.METHOD_MEMBER: 1269 { 1270 member = new MethodMember(rset.getString(2), rset.getString(11)); 1271 member.setId(rset.getInt(1)); 1272 member.setDoc(doc); 1273 member.setMemberType(rset.getInt(3)); 1274 member.setStatic(rset.getBoolean(4)); 1275 member.setFinal(rset.getBoolean(5)); 1276 member.setAccessibility(rset.getInt(6)); 1277 member.setModifiers(rset.getString(7)); 1278 1279 MethodMember mm = (MethodMember) member; 1280 mm.setAbstract(rset.getBoolean(12)); 1281 mm.setReturnTypeName(rset.getString(13)); 1282 mm.setReturnTypeDimension(rset.getInt(14)); 1283 int typeid = rset.getInt(15); 1284 if (typeid > 0) 1285 { 1286 mm.setReturnType(new ClassType(mm.getReturnTypeName())); 1287 mm.getReturnType().setId(typeid); 1288 } 1289 addMethod(mm); 1290 break; 1291 } case Member.FIELD_MEMBER: 1293 { 1294 member = new FieldMember(rset.getString(2), rset.getString(11)); 1295 member.setId(rset.getInt(1)); 1296 member.setDoc(doc); 1297 member.setMemberType(rset.getInt(3)); 1298 member.setStatic(rset.getBoolean(4)); 1299 member.setFinal(rset.getBoolean(5)); 1300 member.setAccessibility(rset.getInt(6)); 1301 member.setModifiers(rset.getString(7)); 1302 FieldMember fm = (FieldMember) member; 1303 fm.setTypeDimension(rset.getInt(12)); 1304 int typeid = rset.getInt(13); 1305 if (typeid > 0) 1306 { 1307 fm.setType(new ClassType(fm.getTypeName())); 1308 fm.getType().setId(typeid); 1309 } 1310 addField((FieldMember) member); 1311 break; 1312 } case Member.CONSTRUCTOR_MEMBER: 1314 { 1315 member = new ConstructorMember(rset.getString(2), rset.getString(11)); 1316 member.setId(rset.getInt(1)); 1317 member.setDoc(doc); 1318 member.setMemberType(rset.getInt(3)); 1319 member.setStatic(rset.getBoolean(4)); 1320 member.setFinal(rset.getBoolean(5)); 1321 member.setAccessibility(rset.getInt(6)); 1322 member.setModifiers(rset.getString(7)); 1323 ConstructorMember cm = (ConstructorMember) member; 1324 addConstructor(cm); 1325 break; 1326 } } } 1330 rset.close(); 1331 1332 } 1334 if (pstmt != null) pstmt.close(); 1335 1336 } 1338 1339 public TreeNode getSuperclasses(Connection conn) throws SQLException 1340 { 1341 if (!DBMgr.getInstance().getDbtype().equals("oracle")) 1342 { 1343 String sql = 1344 "select a.superclassid, c.qualifiedname, a.hierarchy, c.superclassname, c.type " + 1345 " from CLASS_ANCESTORS a, CLASSTYPE c " + 1346 " where a.classid=? and a.superclassid=c.id " + 1347 " order by a.hierarchy, c.type, c.qualifiedname"; 1348 PreparedStatement pstmt = conn.prepareStatement(sql); 1349 pstmt.setInt(1, getId()); 1350 ResultSet rset = pstmt.executeQuery(); 1351 1352 LinkedList classTree = new LinkedList (); 1353 this.setLevel(0); 1354 classTree.add(this); 1355 1356 ClassType tree_cls; 1357 int numLevels = 1; 1358 int level = 0; 1359 int num_returned = 0; 1360 1361 while(rset.next()) 1362 { 1363 num_returned++; 1364 tree_cls = new ClassType(rset.getString(2)); 1365 tree_cls.setId(rset.getInt(1)); 1366 level = rset.getInt(3) + 1; 1367 tree_cls.setSuperClassName(rset.getString(4)); 1368 tree_cls.setClassType(rset.getInt(5)); 1369 1370 numLevels = (level>numLevels) ? level : numLevels; 1371 tree_cls.setLevel(level); 1372 1373 classTree.add(tree_cls); 1374 } 1375 1376 rset.close(); 1377 pstmt.close(); 1378 1379 for (int j=0; j<num_returned; j++) 1380 { 1381 tree_cls = (ClassType) classTree.get(j); 1382 tree_cls.setLevel(numLevels - tree_cls.getLevel() + 1); 1383 } 1384 1385 ClassType top = (ClassType) classTree.getLast(); 1386 if (!StringUtils.isBlank(top.getSuperClassName())) 1387 { 1388 if (num_returned == 0) 1389 { 1390 top.setLevel(2); 1391 } 1392 tree_cls = new ClassType(top.getSuperClassName()); 1393 tree_cls.setLevel(1); 1394 classTree.add(tree_cls); 1395 } 1396 1397 return ClassType.makeTree(classTree); 1398 1399 } 1400 1401 1405 String sql = 1406 " select " + 1407 " id, qualifiedname, level, superclassname, type " + 1408 " from CLASSTYPE " + 1409 " start with qualifiedname=? " + 1410 " connect by qualifiedname=prior superclassname " + 1411 " order by level desc, type, qualifiedname" ; 1412 1413 PreparedStatement pstmt = conn.prepareStatement(sql); 1414 pstmt.setString(1, getQualifiedName()); 1415 ResultSet rset = pstmt.executeQuery(); 1416 1417 LinkedList classTree = new LinkedList (); 1418 1419 ClassType tree_cls; 1420 int numLevels = 1; 1421 int level = 0; 1422 int num_returned = 0; 1423 1424 while(rset.next()) 1425 { 1426 num_returned++; 1427 tree_cls = new ClassType(rset.getString(2)); 1428 tree_cls.setId(rset.getInt(1)); 1429 level = rset.getInt(3); 1430 tree_cls.setSuperClassName(rset.getString(4)); 1431 tree_cls.setClassType(rset.getInt(5)); 1432 numLevels = (level>numLevels) ? level : numLevels; 1433 tree_cls.setLevel(level); 1434 classTree.addFirst(tree_cls); 1435 } 1436 1437 rset.close(); 1438 pstmt.close(); 1439 1440 for (int j=0; j<num_returned; j++) 1441 { 1442 tree_cls = (ClassType) classTree.get(j); 1443 tree_cls.setLevel(numLevels - tree_cls.getLevel() + 1); 1444 log.debug("level: "+tree_cls.getLevel()); 1445 } 1446 1447 return ClassType.makeTree(classTree); 1448 } 1449 1450 public String getSummaryDescription() { return getDoc().getSummaryDescription(); } 1451 public String getDescription() { return getDoc().getDescription(); } 1452 public String getSince() { return getDoc().getSince(); } 1453 public String getDeprecatedDescr() { return getDoc().getDeprecated(); } 1454 public boolean isDeprecated() { return getDoc().isDeprecated(); } 1455 public List getReferences() { return getDoc().getReferences(); } 1456 1457 public API getAPI() { return getPackage().getAPI(); } 1458 1459 public String getStyle() { return getClassTypeName(); } 1460 1461} 1462 | Popular Tags |