1 package org.ashkelon; 2 3 import java.io.BufferedReader ; 4 import java.io.FileNotFoundException ; 5 import java.io.FileReader ; 6 import java.io.IOException ; 7 import java.io.InputStream ; 8 import java.io.InputStreamReader ; 9 import java.sql.CallableStatement ; 10 import java.sql.Connection ; 11 import java.sql.PreparedStatement ; 12 import java.sql.ResultSet ; 13 import java.sql.SQLException ; 14 import java.sql.Statement ; 15 import java.util.Arrays ; 16 import java.util.Collection ; 17 import java.util.Iterator ; 18 import java.util.LinkedList ; 19 import java.util.List ; 20 21 import org.ashkelon.db.DBMgr; 22 import org.ashkelon.db.DBProc; 23 import org.ashkelon.db.DBUtils; 24 import org.ashkelon.db.PKManager; 25 import org.ashkelon.util.JDocUtil; 26 import org.ashkelon.util.Logger; 27 import org.ashkelon.util.StringUtils; 28 import org.exolab.castor.xml.MarshalException; 29 import org.exolab.castor.xml.ValidationException; 30 31 import com.sun.javadoc.ClassDoc; 32 import com.sun.javadoc.Doclet; 33 import com.sun.javadoc.PackageDoc; 34 import com.sun.javadoc.RootDoc; 35 36 39 public class Ashkelon extends Doclet 40 { 41 private RootDoc root = null; 42 private DBMgr dbmgr; 43 private Connection conn; 44 private Logger log; 45 private PKManager pkmgr; 46 private DBProc proc; 47 48 49 50 public static boolean start(RootDoc root) 51 { 52 Ashkelon ashkelon = new Ashkelon(root); 53 54 boolean verbose = StringUtils.getCommandLineOption("-verbose", root.options()); 55 boolean debug = StringUtils.getCommandLineOption("-debug", root.options()); 56 Logger log = Logger.getInstance(); 57 58 if (verbose) 59 log.setTraceLevel(Logger.VERBOSE); 60 if (debug) 61 log.setTraceLevel(Logger.DEBUG); 62 63 if (!ashkelon.init()) 64 return false; 65 66 ashkelon.doAdd(); 67 68 return ashkelon.finish(); 69 } 70 71 public Ashkelon() 72 { 73 log = Logger.getInstance(); 74 log.setPrefix("Ashkelon"); 75 } 76 77 public Ashkelon(RootDoc root) 78 { 79 this(); 80 this.root = root; 81 } 82 83 private boolean init() 84 { 85 dbmgr = DBMgr.getInstance(); 86 conn = null; 87 try 88 { 89 conn = dbmgr.getConnection(); 90 conn.setAutoCommit(false); 91 } catch (SQLException ex) 92 { 93 DBUtils.logSQLException(ex); 94 if (conn != null) 95 dbmgr.releaseConnection(conn); 96 return false; 97 } 98 pkmgr = PKManager.getInstance(); 99 proc = new DBProc(); 100 return true; 101 } 102 103 private boolean finish() 104 { 105 dbmgr.releaseConnection(conn); 106 pkmgr.save(); 107 return true; 108 } 109 110 protected void finalize() throws Throwable 111 { 112 root = null; 113 if (conn!=null) 114 dbmgr.releaseConnection(conn); 115 conn = null; 116 dbmgr = null; 117 log = null; 118 pkmgr = null; 119 } 120 121 private void doAdd() 122 { 123 long start = new java.util.Date ().getTime(); 124 125 boolean refsonly = StringUtils.getCommandLineOption("-refsonly", root.options()); 126 boolean norefs = StringUtils.getCommandLineOption("-norefs", root.options()); 127 128 String apifilename = StringUtils.getStringCommandLineOption("-api", root.options()); 129 130 API api = null; 131 if (!StringUtils.isBlank(apifilename)) 132 { 133 try 134 { 135 String sourcepath = StringUtils.getStringCommandLineOption("-sourcepath", root.options()); 136 api = new API().load(apifilename, sourcepath); 137 log.debug("api unmarshalled; name is: "+api.getName()); 138 } 139 catch (Exception ex) 140 { 141 log.error("Exception: "+ex.getMessage()); 142 } 143 } 144 145 if (api != null) 146 { 147 try 148 { 149 log.traceln("Storing api"); 150 api.store(conn); 151 conn.commit(); 152 } 153 catch (SQLException ex) 154 { 155 DBUtils.logSQLException(ex); 156 } 157 } 158 159 if(!refsonly) 160 { 161 try 162 { 163 proc.doAction(conn, "del_idx"); 165 } catch (SQLException ex) 166 { 167 log.verbose("no add/remove index optimizations during population for current db"); 168 } 169 170 PackageDoc[] packages = root.specifiedPackages(); 171 for (int i=0; i<packages.length; i++) 172 { 173 try 174 { 175 log.traceln("Processing package " + packages[i].name() + ".."); 176 new JPackage(packages[i], true, api).store(conn); 177 conn.commit(); 178 log.traceln("Package: " + packages[i].name() + " stored (committed)", Logger.VERBOSE); 179 } catch (SQLException ex) 180 { 181 log.error("Store (package: "+packages[i].name()+") failed!"); 182 DBUtils.logSQLException(ex); 183 log.error("Rolling back.."); 184 try 185 { 186 conn.rollback(); 187 } catch (SQLException inner_ex) 188 { 189 log.error("rollback failed!"); 190 } 191 } 192 } 193 194 ClassDoc[] classes = root.specifiedClasses(); 195 for (int i=0; i<classes.length; i++) 196 { 197 try 198 { 199 new ClassType(classes[i], null, api).store(conn); 200 conn.commit(); 201 log.traceln("Class: "+classes[i].qualifiedName()+" stored (committed)", Logger.VERBOSE); 202 } catch (SQLException ex) 203 { 204 log.error("Store (class: "+classes[i].qualifiedName()+") failed!"); 205 DBUtils.logSQLException(ex); 206 log.error("Rolling back.."); 207 try 208 { 209 conn.rollback(); 210 } catch (SQLException inner_ex) 211 { 212 log.error("rollback failed!"); 213 } 214 } 215 } 216 } 217 218 long addtime = new java.util.Date ().getTime() - start; 219 log.traceln("Add Time: "+addtime/1000+" seconds"); 220 221 if (!norefs) 222 { 223 log.traceln("Updating Internal References.."); 224 try 225 { 226 proc.doAction(conn, "add_idx"); 228 } catch (SQLException ex) 229 { 230 log.verbose("no add/remove index optimizations during population for current db"); 231 } 232 setInternalReferences(); 233 234 try 235 { 236 new AncestorPopulator(); } 238 catch (SQLException ex) 239 { 240 log.error("Failed to populate class ancestors table"); 241 DBUtils.logSQLException(ex); 242 } 243 } 244 245 long reftime = new java.util.Date ().getTime() - start - addtime; 246 log.traceln("Ref. Time: "+reftime/1000+" seconds"); 247 248 try 249 { 250 conn.commit(); 251 } 252 catch (SQLException ex) 253 { 254 log.error("jdbc commit failed"); 255 DBUtils.logSQLException(ex); 256 } 257 258 log.traceln("done"); 259 } 260 261 262 263 private void doRemove(String [] elements) 264 { 265 if (elements.length == 1 && elements[0].startsWith("@") && elements[0].endsWith(".xml")) 266 { 267 try 268 { 269 API api = new API().load(new FileReader (elements[0].substring(1))); 270 log.debug("api unmarshalled; name is: "+api.getName()); 271 api.delete(conn); 272 conn.commit(); 273 } 274 catch (Exception ex) 275 { 276 log.error("Exception: "+ex.getMessage()); 277 } 278 log.traceln("remove done"); 279 return; 280 } 281 282 if (elements.length == 1 && elements[0].startsWith("@")) 283 { 284 List elemList = JDocUtil.getPackageListFromFileName(elements[0]); 285 elements = (String []) elemList.toArray(elements); 286 } 287 for (int i=0; i<elements.length; i++) 288 { 289 log.traceln("Processing " + elements[i] + " for deletion.."); 290 try 291 { 292 boolean found = JPackage.delete(conn, elements[i]); if (found) 294 { 295 conn.commit(); 296 log.traceln("Package: " + elements[i] + " stored (committed)", Logger.VERBOSE); 297 } 298 else 299 { 300 found = ClassType.delete(conn, elements[i]); 301 if (found) 302 { 303 conn.commit(); 304 log.traceln("Class: " + elements[i] + " stored (committed)", Logger.VERBOSE); 305 } 306 else { 308 log.traceln("Element " + elements[i] + " not found in repository"); 309 } 310 } 311 } 312 catch (SQLException ex) 313 { 314 log.error("Failed to remove element " + elements[i]); 315 DBUtils.logSQLException(ex); 316 log.error("Rolling back.."); 317 try 318 { 319 conn.rollback(); 320 } catch (SQLException inner_ex) 321 { 322 log.error("rollback failed!"); 323 } 324 } 325 } 326 327 log.traceln("remove done"); 328 } 329 330 private void callStoredProc(String action) throws SQLException 331 { 332 String sql = "{call db_proc(?)}"; 333 CallableStatement cstmt = conn.prepareCall(sql); 334 cstmt.setString(1, action); 335 cstmt.executeUpdate(); 336 cstmt.close(); 337 conn.commit(); 338 } 339 340 341 public static int optionLength(String option) 342 { 343 if(option.equals("-norefs") || option.equals("-refsonly")) 344 return 1; 345 if (option.equals("-debug") || option.equals("-verbose")) 346 return 1; 347 if (option.equals("-api")) 348 return 2; 349 return 0; 350 } 351 352 private void setInternalReferences() 353 { 354 String [][] params = {{"FIELD", "typename", "typeid", "id"}, 355 {"METHOD", "returntypename", "returntypeid", "id"}, 356 {"IMPL_INTERFACE", "name", "interfaceid", "classid"}, 357 {"THROWNEXCEPTION", "name", "exceptionid", "throwerid"}, 358 {"PARAMETER", "typename", "typeid", "execmemberid"}, 359 {"SUPERCLASS", "name", "superclassid", "classid"} 360 }; 361 362 String sql = ""; 363 String sql2 = ""; 364 365 for (int i=0; i<params.length; i++) 366 { 367 log.traceln("\tProcessing " + params[i][0] + " references.."); 368 369 try 370 { 371 sql = " select " + params[i][0] + "." + params[i][3] + ", c.id, c.qualifiedname " + 372 " from " + params[i][0] + ", CLASSTYPE c " + 373 " where " + params[i][0] + "." + params[i][1] + " = c.qualifiedname and " + 374 params[i][0] + "." + params[i][2] + " is null"; 375 376 Statement stmt = conn.createStatement(); 377 ResultSet rset = stmt.executeQuery(sql); 378 379 String supplementary = ""; 380 if (i>=2) 381 supplementary = " and " + params[i][1] + "=? "; 382 383 sql2 = "update " + params[i][0] + " set " + params[i][2] + "=? " + 384 " where " + params[i][3] + "=?" + supplementary; 385 386 PreparedStatement pstmt = conn.prepareStatement(sql2); 387 388 while (rset.next()) 389 { 390 pstmt.clearParameters(); 391 pstmt.setInt(1, rset.getInt(2)); 392 pstmt.setInt(2, rset.getInt(1)); 393 if (!supplementary.equals("")) 394 pstmt.setString(3, rset.getString(3)); 395 pstmt.executeUpdate(); 396 } 397 398 pstmt.close(); 399 rset.close(); 400 401 stmt.close(); 402 403 conn.commit(); 404 log.traceln("Updated (committed) " + params[i][0] + " references", Logger.VERBOSE); 405 406 } catch (SQLException ex) 407 { 408 log.error("Internal Reference Update Failed!"); 409 DBUtils.logSQLException(ex); 410 log.error("Rolling back.."); 411 try 412 { 413 conn.rollback(); 414 } catch (SQLException inner_ex) 415 { 416 log.error("rollback failed!"); 417 } 418 } 419 420 } 422 423 try 424 { 425 String [][] params2 = {{"PACKAGE", "name"}, 426 {"CLASSTYPE", "qualifiedname"}, 427 {"MEMBER", "qualifiedname"}, 428 {"EXECMEMBER", "fullyqualifiedname"}}; 429 430 for (int i=0; i<params2.length; i++) 431 { 432 log.traceln("\tProcessing seetag " + params2[i][0] + " references.."); 433 434 sql = "select r.sourcedoc_id, " + params2[i][0] + ".id, " + 435 params2[i][0] + "." + params2[i][1] + 436 " from REFERENCE r, " + params2[i][0] + 437 " where r.refdoc_name = " + params2[i][0] + "." + params2[i][1] + 438 " and r.refdoc_id is null"; 439 440 Statement stmt = conn.createStatement(); 441 ResultSet rset = stmt.executeQuery(sql); 442 443 sql2 = "update REFERENCE set refdoc_id=? where sourcedoc_id=? and refdoc_name=?"; 444 445 PreparedStatement pstmt = conn.prepareStatement(sql2); 446 447 while (rset.next()) 448 { 449 pstmt.clearParameters(); 450 pstmt.setInt(1, rset.getInt(2)); 451 pstmt.setInt(2, rset.getInt(1)); 452 pstmt.setString(3, rset.getString(3)); 453 pstmt.executeUpdate(); 454 } 455 456 pstmt.close(); 457 458 rset.close(); 459 stmt.close(); 460 } 461 } catch (SQLException ex) 462 { 463 log.error("Internal Reference Update Failed!"); 464 DBUtils.logSQLException(ex); 465 log.error("Rolling back.."); 466 try 467 { 468 conn.rollback(); 469 } catch (SQLException inner_ex) 470 { 471 log.error("rollback failed!"); 472 } 473 } 474 } 475 476 477 private static void addCmd(String [] args) 478 { 479 String [] javadocargs = new String [args.length - 1]; 480 for (int i=1; i<args.length; i++) 481 javadocargs[i-1] = args[i]; 482 com.sun.tools.javadoc.Main.execute("ashkelon", "org.ashkelon.Ashkelon", args); 483 } 484 485 public static void addapiCmd(String [] args) 486 { 487 Logger log = Logger.getInstance(); 488 String apifilename = args[args.length-1].substring(1); log.debug("api file name: "+apifilename); 490 try 491 { 492 String sourcepath = extractSourcepath(args); 493 API api = new API().load(apifilename, sourcepath); 494 log.debug("api unmarshalled; name is: "+api.getName()); 495 LinkedList argslist = new LinkedList (Arrays.asList(args)); 496 argslist.removeLast(); 497 498 argslist.add("-api"); 499 argslist.add(apifilename); 500 501 Collection packagenames = api.getPackagenames(); 502 argslist.addAll(packagenames); 503 log.debug(StringUtils.join(argslist.toArray(), " ")); 504 String [] addlist = new String [argslist.size()]; 505 addCmd((String []) argslist.toArray(addlist)); 506 } 507 catch (FileNotFoundException ex) 508 { 509 log.error("File "+apifilename+" not found. Aborting"); 510 } 511 catch (MarshalException ex) 512 { 513 log.error("MarshalException: "+ex.getMessage()); 514 ex.printStackTrace(log.getWriter()); 515 } 516 catch (ValidationException ex) 517 { 518 log.error("ValidationException: "+ex.getMessage()); 519 ex.printStackTrace(log.getWriter()); 520 } 521 } 522 523 private static String extractSourcepath(String [] args) 524 { 525 for (int i=0; i<args.length; i++) 526 { 527 if ("-sourcepath".equals(args[i])) 528 { 529 return args[i+1]; 530 } 531 } 532 return "."; 533 } 534 535 private static void testCmd() 536 { 537 String [] javadocargs = new String [5]; 538 javadocargs[0] = "-doclet"; 539 javadocargs[1] = "org.ashkelon.Ashkelon"; 540 javadocargs[2] = "-sourcepath"; 541 javadocargs[3] = "c:\\jdk1.3\\src"; 542 javadocargs[4] = "java.util"; 544 com.sun.tools.javadoc.Main.main(javadocargs); 545 } 546 547 public static void resetCmd() 548 { 549 Logger log = Logger.getInstance(); 550 log.traceln("Please wait while all tables are reset.."); 551 Ashkelon ashkelon = new Ashkelon(); 552 ashkelon.init(); 553 try 554 { 555 560 ashkelon.proc.doAction(ashkelon.conn, "reset"); 562 } 563 catch (SQLException ex) 564 { 565 DBUtils.logSQLException(ex); 566 } 567 571 ashkelon.dbmgr.releaseConnection(ashkelon.conn); 573 log.traceln("..done"); 574 } 575 576 private void addSequences() 577 { 578 try 579 { 580 String seqs[] = {"PKG_SEQ", "CLASSTYPE_SEQ", "AUTHOR_SEQ", "DOC_SEQ", "MEMBER_SEQ"}; 581 for (int i=0; i<seqs.length; i++) 582 { 583 pkmgr.addSequence(conn, seqs[i], 100); 584 } 585 conn.commit(); 586 log.traceln("added (committed) ashkelon sequences to db"); 587 } catch (SQLException ex) 588 { 589 DBUtils.logSQLException(ex); 590 log.error("Rolling back.."); 591 try 592 { 593 conn.rollback(); 594 } catch (SQLException inner_ex) 595 { 596 log.error("rollback failed!"); 597 } 598 } 599 } 600 601 602 private static void printUsage() 603 { 604 Logger log = Logger.getInstance(); 605 try 606 { 607 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("org/ashkelon/Usage.txt"); 608 if (is == null) { return; } 609 BufferedReader br = new BufferedReader (new InputStreamReader (is)); 610 String line = ""; 611 while ((line = br.readLine()) != null) 612 log.traceln(line); 613 br.close(); 614 is.close(); 615 } catch (IOException ex) 616 { 617 log.error("Unable to print usage!"); 618 log.error("IOException: "+ex.getMessage()); 619 } 620 } 621 622 public static void updateRefsCmd() 623 { 624 Logger log = Logger.getInstance(); 625 Ashkelon ashkelon = new Ashkelon(); 626 ashkelon.init(); 627 ashkelon.setInternalReferences(); 628 try 629 { 630 new AncestorPopulator(); } 632 catch (SQLException ex) 633 { 634 log.error("Failed to populate class ancestors table"); 635 DBUtils.logSQLException(ex); 636 } 637 } 638 639 public static void listCmd() 640 { 641 Logger log = Logger.getInstance(); 642 log.setPrefix("list"); 643 Ashkelon ashkelon = new Ashkelon(); 644 645 if (!ashkelon.init()) 646 { 647 log.error("error occurred. exiting"); 648 return; 649 } 650 651 try 652 { 653 List names = Generic.listNames(ashkelon.conn, API.getTableName()); 654 Iterator i = names.iterator(); 655 while (i.hasNext()) 656 { 657 log.traceln("API: " + (String ) i.next()); 658 if (names.isEmpty()) 661 { 662 log.traceln("repository is empty"); 663 } 664 } 665 if (names.isEmpty()) 666 { 667 log.traceln("repository is empty"); 668 } 669 } catch (SQLException ex) 670 { 671 DBUtils.logSQLException(ex); 672 } 673 ashkelon.finish(); 674 } 675 676 public static void removeCmd(String args[]) 677 { 678 Logger log = Logger.getInstance(); 679 log.setPrefix("remove"); 680 681 Ashkelon ashkelon = new Ashkelon(); 682 ashkelon.init(); 683 String [] removeargs = new String [args.length - 1]; 684 for (int i=1; i<args.length; i++) 685 { 686 removeargs[i-1] = args[i]; 687 } 688 ashkelon.doRemove(removeargs); 689 ashkelon.finish(); 690 } 691 692 693 public static void main(String [] args) 695 { 696 698 Logger log = Logger.getInstance(); 699 700 if (args.length >=2) 701 { 702 if (args[1].equals("-verbose")) 703 { 704 log.setTraceLevel(Logger.VERBOSE); 705 } 706 else if (args[1].equals("-debug")) 707 { 708 log.setTraceLevel(Logger.DEBUG); 709 } 710 } 711 712 if (args.length == 0) 713 { 714 printUsage(); 715 return; 716 } 717 else if (args[0].equals("reset")) 718 { 719 resetCmd(); 720 return; 721 } 722 else if (args[0].equals("list")) 723 { 724 listCmd(); 725 return; 726 } 727 else if (args[0].equals("test")) 728 { 729 testCmd(); 730 return; 731 } 732 else if (args[0].equals("remove")) 733 { 734 if (args.length == 1) 735 printUsage(); 736 removeCmd(args); 737 return; 738 } 739 else if (args[0].equals("add")) 740 { 741 if (args.length == 1) 742 printUsage(); 743 String lastarg = args[args.length-1]; 744 if (lastarg != null && lastarg.startsWith("@") && lastarg.endsWith(".xml")) 745 addapiCmd(args); 746 else 747 addCmd(args); 748 return; 749 } 750 else if (args[0].equals("updaterefs")) 751 { 752 updateRefsCmd(); 753 } 754 else 755 { 756 printUsage(); 757 } 758 } 759 760 } 761 | Popular Tags |