1 23 package org.hammurapi; 24 25 import java.io.File ; 26 import java.io.FileNotFoundException ; 27 import java.io.IOException ; 28 import java.io.InputStreamReader ; 29 import java.net.InetAddress ; 30 import java.sql.SQLException ; 31 import java.text.SimpleDateFormat ; 32 import java.util.Collection ; 33 import java.util.Date ; 34 import java.util.Iterator ; 35 import java.util.LinkedList ; 36 import java.util.List ; 37 38 import org.apache.commons.cli.CommandLine; 39 import org.apache.commons.cli.CommandLineParser; 40 import org.apache.commons.cli.Option; 41 import org.apache.commons.cli.OptionBuilder; 42 import org.apache.commons.cli.Options; 43 import org.apache.commons.cli.ParseException; 44 import org.apache.commons.cli.PosixParser; 45 import org.apache.tools.ant.AntClassLoader; 46 import org.apache.tools.ant.BuildException; 47 import org.apache.tools.ant.DirectoryScanner; 48 import org.apache.tools.ant.Project; 49 import org.hammurapi.results.CompositeResults; 50 import org.hammurapi.results.persistent.jdbc.ResultsFactory; 51 import org.hammurapi.results.persistent.jdbc.ResultsFactoryConfig; 52 import org.w3c.dom.Element ; 53 54 import com.pavelvlasov.ant.ConnectionEntry; 55 import com.pavelvlasov.config.Component; 56 import com.pavelvlasov.config.ConfigurationException; 57 import com.pavelvlasov.jsel.JselException; 58 import com.pavelvlasov.jsel.Repository; 59 import com.pavelvlasov.jsel.RevisionMapper; 60 import com.pavelvlasov.jsel.impl.DbRepositoryImpl; 61 import com.pavelvlasov.jsel.impl.RepositoryConfig; 62 import com.pavelvlasov.jsel.impl.WarningSink; 63 import com.pavelvlasov.logging.AntLogger; 64 import com.pavelvlasov.logging.Logger; 65 import com.pavelvlasov.metrics.MeasurementCategoryFactory; 66 import com.pavelvlasov.metrics.TimeIntervalCategory; 67 import com.pavelvlasov.persistence.CompositeStorage; 68 import com.pavelvlasov.persistence.FileStorage; 69 import com.pavelvlasov.persistence.MemoryStorage; 70 import com.pavelvlasov.render.RenderingException; 71 import com.pavelvlasov.review.SimpleSourceMarker; 72 import com.pavelvlasov.review.SourceMarker; 73 import com.pavelvlasov.review.SourceMarkerComparator; 74 import com.pavelvlasov.sql.ConnectionPerThreadDataSource; 75 import com.pavelvlasov.sql.DataAccessObject; 76 import com.pavelvlasov.sql.JdbcStorage; 77 import com.pavelvlasov.sql.SQLProcessor; 78 import com.pavelvlasov.sql.Transaction; 79 import com.pavelvlasov.sql.hypersonic.HypersonicServerDataSource; 80 import com.pavelvlasov.sql.hypersonic.HypersonicStandaloneDataSource; 81 import com.pavelvlasov.sql.hypersonic.HypersonicTmpDataSource; 82 import com.pavelvlasov.util.VisitorStack; 83 import com.pavelvlasov.util.VisitorStackSource; 84 85 116 public class HammurapiTask extends TaskBase { 117 118 123 public class ViolationFilterVisitor { 124 public void visit(Repository repo) throws ConfigurationException { 125 Iterator vfit=violationFilters.iterator(); 127 while (vfit.hasNext()) { 128 Object vf=vfit.next(); 129 if (vf instanceof Component) { 130 ((Component) vf).start(); 131 } 132 } 133 } 134 135 public void leave(Repository repo) throws ConfigurationException { 136 Iterator vfit=violationFilters.iterator(); 138 while (vfit.hasNext()) { 139 Object vf=vfit.next(); 140 if (vf instanceof Component) { 141 ((Component) vf).stop(); 142 } 143 } 144 } 145 } 146 147 private static final TimeIntervalCategory tic=MeasurementCategoryFactory.getTimeIntervalCategory(HammurapiTask.class); 148 149 private boolean wrap=false; 150 151 private boolean cleanup=true; 152 boolean skipIntactPackages=false; 153 154 private boolean forceOnWaivers; 155 156 162 public void setCleanup(boolean cleanup) { 163 this.cleanup = cleanup; 164 } 165 166 174 public void setSkipIntactPackages(boolean skipIntactPackages) { 175 this.skipIntactPackages = skipIntactPackages; 176 } 177 178 183 public void setForceOnWaivers(boolean forceOnWaivers) { 184 this.forceOnWaivers=forceOnWaivers; 185 } 186 187 boolean isForceOnWaivers() { 188 return forceOnWaivers; 189 } 190 191 private Date baseLine; 192 193 198 public void setBaseLine(Date baseLine) { 199 this.baseLine=baseLine; 200 } 201 202 private String hostId; 203 204 public void execute() throws BuildException { 205 long started=System.currentTimeMillis(); 206 207 if (!suppressLogo) { 208 log("Hammurapi 3 Copyright (C) 2004 Hammurapi Group"); 209 } 210 211 File archiveTmpDir=processArchive(); 212 213 try { 214 Logger logger=new AntLogger(this); 215 216 final VisitorStack[] visitorStack={null}; 217 final VisitorStackSource visitorStackSource=new VisitorStackSource() { 218 public VisitorStack getVisitorStack() { 219 return visitorStack[0]; 220 } 221 }; 222 223 final SessionImpl reviewSession=new SessionImpl(); 224 225 InspectorSet inspectorSet=new InspectorSet( 226 new InspectorContextFactory() { 227 public InspectorContext newContext(InspectorDescriptor descriptor, Logger logger) { 228 return new InspectorContextImpl( 229 descriptor, 230 logger, 231 visitorStackSource, 232 reviewSession, 233 violationFilters); 234 } 235 }, 236 logger); 237 238 if (embeddedInspectors) { 239 log("Loading embedded inspectors", Project.MSG_VERBOSE); 240 loadEmbeddedInspectors(inspectorSet); 241 } 242 243 log("Loading inspectors", Project.MSG_VERBOSE); 244 Iterator it=inspectors.iterator(); 245 while (it.hasNext()) { 246 Object o=it.next(); 247 if (o instanceof InspectorSource) { 248 ((InspectorSource) o).loadInspectors(inspectorSet); 249 } else { 250 InspectorEntry inspectorEntry = (InspectorEntry) o; 251 inspectorSet.addDescriptor(inspectorEntry); 252 inspectorSet.addInspectorSourceInfo( 253 new InspectorSourceInfo( 254 "Inline inspector "+inspectorEntry.getName(), 255 "Build file: "+inspectorEntry.getLocation().toString(), 256 "")); 257 } 258 } 259 260 log("Inspectors loaded: "+inspectorSet.size(), Project.MSG_VERBOSE); 261 262 log("Loading waivers", Project.MSG_VERBOSE); 263 Date now=new Date (); 264 WaiverSet waiverSet=new WaiverSet(); 265 it=waivers.iterator(); 266 while (it.hasNext()) { 267 ((WaiverSource) it.next()).loadWaivers(waiverSet,now); 268 } 269 270 log("Waivers loaded: "+waiverSet.size(), Project.MSG_VERBOSE); 271 272 log("Loading listeners", Project.MSG_VERBOSE); 273 List listeners=new LinkedList (); 274 it=listenerEntries.iterator(); 275 while (it.hasNext()) { 276 listeners.add(((ListenerEntry) it.next()).getObject(null)); 277 } 278 279 listeners.addAll(outputs); 281 listeners.add(new ReviewToLogListener(project)); 282 283 log("Loading source files", Project.MSG_VERBOSE); 284 285 RepositoryConfig config=new RepositoryConfig(); 286 if (classPath!=null) { 287 log("Loading class files to repository", Project.MSG_DEBUG); 288 config.setClassLoader(new AntClassLoader(project, classPath, false)); 289 reviewSession.setClassPath(classPath.list()); 290 } 291 292 config.setLogger(logger); 293 config.setCalculateDependencies(calculateDependencies); 294 config.setStoreSource(storeSource); 295 config.setEncoding(getEncoding()); 296 297 it=srcFileSets.iterator(); 298 while (it.hasNext()) { 299 HammurapiFileSet fs=(HammurapiFileSet) it.next(); 300 fs.setDefaultIncludes(); 301 DirectoryScanner scanner=fs.getDirectoryScanner(project); 302 config.addFile(scanner.getBasedir(), scanner.getIncludedFiles()); 303 } 304 305 308 it=srcFiles.iterator(); 309 while (it.hasNext()) { 310 config.addFile((File ) it.next()); 311 } 312 313 config.setName(title); 314 315 if (revisionMapper!=null) { 316 config.setRevisionMapper((RevisionMapper) revisionMapper.getObject(null)); 317 } 318 319 ConnectionPerThreadDataSource dataSource = createDataSource(reviewSession); 320 321 reviewSession.setDatasource(dataSource); 322 323 final LinkedList repoWarnings=new LinkedList (); 324 config.setWarningSink(new WarningSink() { 325 public void consume(final String source, final String message) { 326 repoWarnings.add(new Violation() { 327 public String getMessage() { 328 return message; 329 } 330 331 public InspectorDescriptor getDescriptor() { 332 return null; 333 } 334 335 SourceMarker sm=new SimpleSourceMarker(0,0,source,null); 336 337 public SourceMarker getSource() { 338 return sm; 339 } 340 341 public int compareTo(Object obj) { 342 if (obj instanceof Violation) { 343 Violation v=(Violation) obj; 344 int c=SourceMarkerComparator._compare(getSource(), v.getSource()); 345 return c==0 ? getMessage().compareTo(v.getMessage()) : c; 346 } 347 348 return hashCode()-obj.hashCode(); 349 } 350 }); 351 } 352 }); 353 354 config.setDataSource(dataSource); 355 final SQLProcessor sqlProcessor=new SQLProcessor(dataSource, null); 356 sqlProcessor.setTimeIntervalCategory(tic); 357 358 DbRepositoryImpl repositoryImpl = new DbRepositoryImpl(config); 359 Repository repository = wrap ? (Repository) repositoryImpl.getProxy() : repositoryImpl; 360 361 363 ResultsFactoryConfig rfConfig=new ResultsFactoryConfig(); 364 rfConfig.setInspectorSet(inspectorSet); 365 rfConfig.setName(title); 366 rfConfig.setReportNumber(repository.getScanNumber()); 367 rfConfig.setRepository(repository); 368 rfConfig.setSqlProcessor(sqlProcessor); 369 rfConfig.setHostId(hostId); 370 rfConfig.setBaseLine(baseLine); 371 rfConfig.setDescription(reviewDescription); 372 373 try { 374 rfConfig.setHostName(InetAddress.getLocalHost().getHostName()); 375 } catch (Exception e) { 376 log("Cannot resolve host name: "+e); 377 } 378 379 CompositeStorage storage=new CompositeStorage(); 380 storage.addStorage("jdbc", new JdbcStorage(sqlProcessor)); 381 storage.addStorage("file", new FileStorage(new File (System.getProperties().getProperty("java.io.tmpdir")))); 382 storage.addStorage("memory", new MemoryStorage()); 383 384 rfConfig.setStorage(storage); 385 rfConfig.setWaiverSet(waiverSet); 386 387 ResultsFactory resultsFactory=new ResultsFactory(rfConfig); 388 resultsFactory.install(); 389 390 CompositeResults summary=org.hammurapi.results.ResultsFactory.getInstance().newCompositeResults(title); 391 org.hammurapi.results.ResultsFactory.getInstance().setSummary(summary); 392 org.hammurapi.results.ResultsFactory.pushThreadResults(summary); 393 394 Collection inspectorsPerSe=new LinkedList (inspectorSet.getInspectors()); 395 reviewSession.setInspectors(inspectorSet); 396 Iterator inspectorsIt=inspectorsPerSe.iterator(); 397 log("Inspectors mapping", Project.MSG_VERBOSE); 398 while (inspectorsIt.hasNext()) { 399 Inspector inspector=(Inspector) inspectorsIt.next(); 400 log("\t"+inspector.getContext().getDescriptor().getName()+" -> "+inspector.getClass().getName(), Project.MSG_VERBOSE); 401 } 402 403 it=listeners.iterator(); 405 while (it.hasNext()) { 406 ((Listener) it.next()).onBegin(inspectorSet); 407 } 408 409 Iterator vfit=violationFilters.iterator(); 410 while (vfit.hasNext()) { 411 Object vf=vfit.next(); 412 if (vf instanceof DataAccessObject) { 413 ((DataAccessObject) vf).setSQLProcessor(sqlProcessor); 414 } 415 } 416 417 ResultsCollector collector = new ResultsCollector(this, inspectorSet, waiverSet, summary, listeners); 418 inspectorsPerSe.add(collector); 419 420 while (!repoWarnings.isEmpty()) { 422 collector.getSummary().addWarning((Violation) repoWarnings.removeFirst()); 423 } 424 425 log("Reviewing", Project.MSG_VERBOSE); 426 427 inspectorsPerSe.add(new ViolationFilterVisitor()); 428 429 SimpleReviewEngine rengine = new SimpleReviewEngine(inspectorsPerSe, this); 430 reviewSession.setVisitor(rengine.getVisitor()); 431 visitorStack[0]=rengine.getVisitorStack(); 432 433 rengine.review(repository); 434 435 writeWaiverStubs(waiverSet.getRejectedRequests()); 436 437 ResultsFactory.getInstance().commit(System.currentTimeMillis()-started); 438 439 if (cleanup) { 440 repositoryImpl.cleanupOldScans(); 441 resultsFactory.cleanupOldReports(); 442 } 443 444 repositoryImpl.stop(); 445 reviewSession.shutdown(); 446 resultsFactory.shutdown(); 447 dataSource.shutdown(); 448 449 451 if (hadExceptions) { 452 throw new BuildException("There have been exceptions during execution. Check log output."); 453 } 454 } catch (JselException e) { 455 throw new BuildException(e); 456 } catch (HammurapiException e) { 457 throw new BuildException(e); 458 } catch (ConfigurationException e) { 459 throw new BuildException(e); 460 } catch (FileNotFoundException e) { 461 throw new BuildException(e); 462 } catch (ClassNotFoundException e) { 463 throw new BuildException(e); 464 } catch (IOException e) { 465 throw new BuildException(e); 466 } catch (SQLException e) { 467 throw new BuildException(e); 468 } catch (RenderingException e) { 469 throw new BuildException(e); 470 } finally { 471 if (archiveTmpDir!=null) { 472 deleteFile(archiveTmpDir); 473 } 474 } 475 } 476 477 487 private ConnectionPerThreadDataSource createDataSource(final SessionImpl reviewSession) throws ClassNotFoundException , IOException , SQLException { 488 ConnectionPerThreadDataSource dataSource; 489 if (database==null && server==null && connection==null) { 490 dataSource = new HypersonicTmpDataSource(DbRepositoryImpl.HYPERSONIC_INIT_SCRIPT); 491 SQLProcessor sqlProcessor=new SQLProcessor(dataSource, null); 492 sqlProcessor.setTimeIntervalCategory(tic); 493 sqlProcessor.executeScript(new InputStreamReader (getClass().getClassLoader().getResourceAsStream(ResultsFactory.HYPERSONIC_INIT_SCRIPT))); 494 495 reviewSession.scheduleInitDb(); 496 } else if (database!=null && server==null && connection==null) { 497 reviewSession.setDbProperty("type", "Hypersonic"); 498 499 dataSource = new HypersonicStandaloneDataSource( 500 database.getAbsolutePath(), 501 new Transaction() { 502 503 public boolean execute(SQLProcessor processor) throws SQLException { 504 processor.setTimeIntervalCategory(tic); 505 try { 506 processor.executeScript(new InputStreamReader (getClass().getClassLoader().getResourceAsStream(DbRepositoryImpl.HYPERSONIC_INIT_SCRIPT))); 507 processor.executeScript(new InputStreamReader (getClass().getClassLoader().getResourceAsStream(ResultsFactory.HYPERSONIC_INIT_SCRIPT))); 508 } catch (IOException e) { 509 throw new BuildException("Cannot initialize database", e); 510 } 511 512 reviewSession.scheduleInitDb(); 513 return true; 514 } 515 }); 516 } else if (database==null && server!=null && connection==null) { 517 dataSource=new HypersonicServerDataSource(server.getHost(), server.getUser(), server.getPassword(), null); 518 } else if (database==null && server==null && connection!=null) { 519 dataSource=connection.getDataSource(); 520 } else { 521 throw new BuildException("server nested element, connection nested element and database attribute are mutually exclusive"); 522 } 523 return dataSource; 524 } 525 526 530 public void setHostId(String hostId) { 531 this.hostId=hostId; 532 } 533 534 private ServerEntry server; 535 536 private ConnectionEntry connection; 537 538 private boolean calculateDependencies; 539 private boolean storeSource; 540 541 545 public static void main(String [] args) { 546 System.out.println("Hammurapi 3 Copyright (C) 2004 Hammurapi Group"); 547 548 Options options=new Options(); 549 550 populateOptions(options); 551 552 CommandLineParser parser=new PosixParser(); 553 CommandLine line=null; 554 try { 555 line=parser.parse(options, args); 556 } catch (ParseException e) { 557 System.err.println(e.getMessage()); 558 System.err.flush(); 559 printHelpAndExit(options); 560 } 561 562 if (line.hasOption("h")) { 563 printHelpAndExit(options); 564 } 565 566 HammurapiTask task=new HammurapiTask(); 567 Project project = new Project(); 568 task.setProject(project); 569 project.setCoreLoader(task.getClass().getClassLoader()); 570 571 task.configure(options, line); 572 573 task.suppressLogo=true; 574 575 task.setTaskName("hammurapi"); 576 577 try { 578 task.execute(); 579 System.exit(0); 580 } catch (Exception e) { 581 e.printStackTrace(); 582 System.exit(2); 583 } 584 } 585 586 592 protected void configure(Options options, CommandLine line) { 593 super.configure(options, line); 594 595 if (line.hasOption('z')) { 596 setCalculateDependencies(true); 597 } 598 599 if (line.hasOption('b')) { 600 setStoreSource(true); 601 } 602 603 if (line.hasOption('n')) { 604 setBaseLine(new Date (line.getOptionValue('n'))); 605 } 606 607 611 if (line.hasOption('H')) { 612 setHostId(line.getOptionValue('H')); 613 } 614 615 if (line.hasOption('L')) { 616 ConnectionEntry ce=new ConnectionEntry(); 617 ce.setDriverClass(line.getOptionValue('L')); 618 ce.setUrl(line.getOptionValue('N')); 619 ce.setUser(line.getOptionValue('j')); 620 ce.setPassword(line.getOptionValue('p')); 621 addConnection(ce); 622 } 623 624 if (line.hasOption('R')) { 625 addServer(new ServerEntry(line.getOptionValue('R'), line.getOptionValue('j'), line.getOptionValue('p'))); 626 } 627 628 if (line.hasOption('F')) { 629 setForceOnWaivers(false); 630 } 631 632 } 634 635 662 665 protected static void populateOptions(Options options) { 666 TaskBase.populateOptions(options); 667 668 Option hostIdOption=OptionBuilder 669 .withArgName("hostId") 670 .hasArg() 671 .withDescription("Host id") 672 .isRequired(false) 673 .create("H"); 674 675 options.addOption(hostIdOption); 676 677 685 687 Option serverOption=OptionBuilder 688 .withDescription("Database server name") 689 .withArgName("database server") 690 .hasArg() 691 .isRequired(false) 692 .create("R"); 693 694 options.addOption(serverOption); 695 696 Option driverClassOption=OptionBuilder 697 .withDescription("Database driver class") 698 .withArgName("class name") 699 .hasArg() 700 .isRequired(false) 701 .create("L"); 702 703 options.addOption(driverClassOption); 704 705 Option connectionUrlOption=OptionBuilder 706 .withDescription("Database connection URL") 707 .withArgName("url") 708 .hasArg() 709 .isRequired(false) 710 .create("N"); 711 712 options.addOption(connectionUrlOption); 713 714 Option userOption=OptionBuilder 715 .withDescription("Database user") 716 .withArgName("user name") 717 .hasArg() 718 .isRequired(false) 719 .create("j"); 720 721 options.addOption(userOption); 722 723 Option passwordOption=OptionBuilder 724 .withDescription("Database password") 725 .withArgName("password") 726 .hasArg() 727 .isRequired(false) 728 .create("p"); 729 730 options.addOption(passwordOption); 731 732 Option baseLineOption=OptionBuilder 733 .withDescription("Baseline date") 734 .withArgName("date") 735 .hasArg() 736 .isRequired(false) 737 .create("n"); 738 739 options.addOption(baseLineOption); 740 741 Option calculateDependenciesOption=OptionBuilder 742 .withDescription("Calculate dependencies") 743 .isRequired(false) 744 .create("z"); 745 746 options.addOption(calculateDependenciesOption); 747 748 Option storeSourceOption=OptionBuilder 749 .withDescription("Store source") 750 .isRequired(false) 751 .create("b"); 752 753 options.addOption(storeSourceOption); 754 755 Option forceOnWaiversOption=OptionBuilder 756 .withDescription("Do not force reviews on waivers") 757 .isRequired(false) 758 .create("F"); 759 760 options.addOption(forceOnWaiversOption); 761 762 } 763 764 770 public void setCalculateDependencies(boolean calculateDependencies) { 771 this.calculateDependencies=calculateDependencies; 772 } 773 774 779 public void setStoreSource(boolean storeSource) { 780 this.storeSource=storeSource; 781 } 782 783 788 public void addServer(ServerEntry server) { 789 this.server=server; 790 } 791 792 798 public void addConnection(ConnectionEntry connection) { 799 this.connection=connection; 800 } 801 802 806 protected void setAttributes(Element config) { 807 super.setAttributes(config); 808 if (config.hasAttribute("host-id")) { 809 setHostId(config.getAttribute("host-id")); 810 } 811 if (config.hasAttribute("baseline")) { 812 try { 813 setBaseLine(new SimpleDateFormat (HammurapiArchiver.DATE_FORMAT).parse(config.getAttribute("baseline"))); 814 } catch (java.text.ParseException e) { 815 throw new BuildException("Cannot parse baseline date", e); 816 } 817 } 818 } 819 } 820 | Popular Tags |