1 23 package org.hammurapi; 24 25 import java.io.File ; 26 import java.io.FileInputStream ; 27 import java.io.FileOutputStream ; 28 import java.io.IOException ; 29 import java.text.SimpleDateFormat ; 30 import java.util.Collection ; 31 import java.util.Date ; 32 import java.util.HashSet ; 33 import java.util.Iterator ; 34 import java.util.LinkedList ; 35 import java.util.List ; 36 import java.util.Set ; 37 import java.util.zip.ZipEntry ; 38 import java.util.zip.ZipOutputStream ; 39 40 import javax.xml.parsers.DocumentBuilderFactory ; 41 import javax.xml.parsers.FactoryConfigurationError ; 42 import javax.xml.parsers.ParserConfigurationException ; 43 import javax.xml.transform.TransformerException ; 44 45 import org.apache.commons.cli.CommandLine; 46 import org.apache.commons.cli.CommandLineParser; 47 import org.apache.commons.cli.HelpFormatter; 48 import org.apache.commons.cli.Option; 49 import org.apache.commons.cli.OptionBuilder; 50 import org.apache.commons.cli.Options; 51 import org.apache.commons.cli.ParseException; 52 import org.apache.commons.cli.PosixParser; 53 import org.apache.tools.ant.BuildException; 54 import org.apache.tools.ant.DirectoryScanner; 55 import org.apache.tools.ant.Project; 56 import org.apache.tools.ant.Task; 57 import org.apache.tools.ant.types.FileSet; 58 import org.apache.tools.ant.types.Path; 59 import org.w3c.dom.Document ; 60 import org.w3c.dom.Element ; 61 62 import com.pavelvlasov.xml.dom.DOMUtils; 63 64 81 public class HammurapiArchiver extends Task { 82 static final String DATE_FORMAT="yyyy/MM/dd HH:mm:ss"; 83 84 private Boolean force; 85 86 91 public void setForce(boolean force) { 92 this.force=force ? Boolean.TRUE : Boolean.FALSE; 93 } 94 95 private Boolean forceOnWarnings; 96 97 101 public void setForceOnWarnings(boolean forceOnWarnings) { 102 this.forceOnWarnings=forceOnWarnings ? Boolean.TRUE : Boolean.FALSE; 103 } 104 105 private String title; 106 107 112 public void setTitle(String title) { 113 this.title=title; 114 } 115 116 private File output; 117 118 123 public void setOutput(File output) { 124 this.output=output; 125 } 126 127 132 private Path classPath; 133 134 public void setClassPath(Path classPath) { 135 if (this.classPath == null) { 136 this.classPath = classPath; 137 } else { 138 this.classPath.append(classPath); 139 } 140 } 141 142 private Date baseLine; 143 144 149 public void setBaseLine(Date baseLine) { 150 this.baseLine=baseLine; 151 } 152 153 private String hostId; 154 155 159 public void setHostId(String hostId) { 160 this.hostId=hostId; 161 } 162 163 private String baselining; 165 166 public void setBaselining(String baselining){ 167 this.baselining=baselining; 168 } 169 170 174 public Path createClasspath() { 175 if (classPath == null) { 176 classPath = new Path(project); 177 } 178 return classPath.createPath(); 179 } 180 181 private String uniquilize(String name, Set names) { 182 int idx=name.lastIndexOf('.'); 183 String newName = name; 184 String ext=""; 185 if (idx!=-1) { 186 ext=name.substring(idx); 187 name=name.substring(0, idx); 188 } 189 190 for (int i=0; names.contains(newName.toLowerCase()); i++) { 191 newName=name+"_"+Integer.toString(i, Character.MAX_RADIX)+ext; 192 } 193 names.add(newName.toLowerCase()); 194 return newName; 195 } 196 197 private int zipFile(File in, ZipOutputStream out, String entryName) throws IOException { 198 if (in.isFile()) { 199 log("Zipping file "+in.getAbsolutePath()+" as "+entryName, Project.MSG_VERBOSE); 200 out.putNextEntry(new ZipEntry (entryName)); 201 byte[] buf=new byte[4096]; 202 int l; 203 FileInputStream fis=new FileInputStream (in); 204 while ((l=fis.read(buf))!=-1) { 205 out.write(buf, 0, l); 206 } 207 fis.close(); 208 out.closeEntry(); 209 return 1; 210 } else if (in.isDirectory()) { 211 int ret=0; 212 File [] entries=in.listFiles(); 213 if (entries!=null && entries.length>0) { 214 log("Zipping directory "+in.getAbsolutePath()+" as "+entryName+"/", Project.MSG_VERBOSE); 215 out.putNextEntry(new ZipEntry (entryName+"/")); 216 for (int i=0; i<entries.length; i++) { 217 ret+=zipFile(entries[i], out, entryName+"/"+entries[i].getName()); 218 } 219 out.closeEntry(); 220 } 221 return ret; 222 } 223 224 return 0; 225 } 226 227 public void execute() throws BuildException { 228 try { 229 ZipOutputStream zos=new ZipOutputStream (new FileOutputStream (output)); 230 Set entryNames=new HashSet (); 231 232 Document config=DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); 233 Element root=config.createElement("hammurapi-archive"); 234 config.appendChild(root); 235 236 if (force!=null) { 237 root.setAttribute("force", force.booleanValue() ? "yes" : "no"); 238 } 239 240 if (forceOnWarnings!=null) { 241 root.setAttribute("force-on-warnings", forceOnWarnings.booleanValue() ? "yes" : "no"); 242 } 243 244 if (title!=null) { 245 root.setAttribute("title", title); 246 } 247 248 if (reviewDescription!=null) { 249 root.setAttribute("review-description", reviewDescription); 250 } 251 252 if (baseLine!=null) { 253 root.setAttribute("baseline", new SimpleDateFormat (DATE_FORMAT).format(baseLine)); 254 } 255 256 if (hostId!=null) { 257 root.setAttribute("host-id", hostId); 258 } 259 260 if (baselining!=null) { 262 root.setAttribute("baselining", baselining); 263 } 264 265 Element classPathElement=config.createElement("classpath"); 266 root.appendChild(classPathElement); 267 268 if (classPath!=null) { 269 String [] path=classPath.list(); 270 for (int i=0; i<path.length; i++) { 271 File cpEntry=new File (path[i]); 272 if (cpEntry.exists() && (cpEntry.isFile() || cpEntry.isDirectory())) { 273 String name=uniquilize("lib/"+cpEntry.getName(), entryNames); 274 if (zipFile(cpEntry, zos, name)>0) { 275 Element pathElement=config.createElement("path"); 276 classPathElement.appendChild(pathElement); 277 pathElement.appendChild(config.createTextNode(name)); 278 } 279 } else { 280 log("Classpath entry "+cpEntry.getAbsolutePath()+" does not exist", Project.MSG_VERBOSE); 281 } 282 } 283 } 284 285 Element sourcesElement=config.createElement("sources"); 286 root.appendChild(sourcesElement); 287 288 Iterator it=srcFileSets.iterator(); 289 while (it.hasNext()) { 290 HammurapiFileSet fs=(HammurapiFileSet) it.next(); 291 fs.setDefaultIncludes(); 292 DirectoryScanner scanner=fs.getDirectoryScanner(project); 293 String name=uniquilize("source/"+scanner.getBasedir().getName(), entryNames); 294 Element sourceElement=config.createElement("source"); 295 sourcesElement.appendChild(sourceElement); 296 sourceElement.appendChild(config.createTextNode(name)); 297 String [] files=scanner.getIncludedFiles(); 298 for (int i=0; i<files.length; i++) { 299 zipFile(new File (scanner.getBasedir(), files[i]), zos, name+"/"+files[i].replace(File.separatorChar, '/')); 300 } 301 } 302 303 306 it=srcFiles.iterator(); 307 while (it.hasNext()) { 308 String name=uniquilize("source/source", entryNames); 309 File file = (File ) it.next(); 310 String entryName = name+"/"+file.getName(); 311 Element sourceElement=config.createElement("source"); 312 sourcesElement.appendChild(sourceElement); 313 sourceElement.appendChild(config.createTextNode(entryName)); 314 zipFile(file, zos, entryName); 315 } 316 317 ZipEntry configEntry=new ZipEntry ("config.xml"); 318 zos.putNextEntry(configEntry); 319 DOMUtils.serialize(config, zos); 320 zos.closeEntry(); 321 322 zos.close(); 323 } catch (IOException e) { 324 throw new BuildException(e.getMessage(), e); 325 } catch (ParserConfigurationException e) { 326 throw new BuildException(e.getMessage(), e); 327 } catch (FactoryConfigurationError e) { 328 throw new BuildException(e.getMessage(), e); 329 } catch (TransformerException e) { 330 throw new BuildException(e.getMessage(), e); 331 } 332 } 333 334 338 public FileSet createSrc() { 339 FileSet ret=new HammurapiFileSet("**/*.java"); 340 srcFileSets.add(ret); 341 return ret; 342 } 343 344 private List srcFileSets = new LinkedList (); 345 346 private Collection srcFiles=new LinkedList (); 347 348 private static void printHelpAndExit(Options options) { 349 HelpFormatter formatter=new HelpFormatter(); 350 formatter.printHelp("Usage: har [options] <output file> <source files/dirs>", options, false); 351 System.exit(1); 352 } 353 354 358 public static void main(String [] args) { 359 System.out.println("Hammurapi 3 Copyright (C) 2004 Hammurapi Group"); 360 361 Options options=new Options(); 362 363 Option classPathOption=OptionBuilder 364 .withArgName("classpath") 365 .hasArg() 366 .withDescription("ClassPath") 367 .isRequired(false) 368 .create("c"); 369 370 options.addOption(classPathOption); 371 372 Option hostIdOption=OptionBuilder 373 .withArgName("hostId") 374 .hasArg() 375 .withDescription("Host id") 376 .isRequired(false) 377 .create("H"); 378 379 options.addOption(hostIdOption); 380 381 Option titleOption=OptionBuilder 382 .withArgName("title") 383 .hasArg() 384 .withDescription("Report title") 385 .isRequired(false) 386 .create("T"); 387 388 options.addOption(titleOption); 389 390 Option baseLineOption=OptionBuilder 391 .withDescription("Baseline date") 392 .withArgName("date") 393 .hasArg() 394 .isRequired(false) 395 .create("n"); 396 397 options.addOption(baseLineOption); 398 399 Option forceOption=OptionBuilder 400 .withDescription("Force reviews on unchanged files") 401 .isRequired(false) 402 .create("f"); 403 404 options.addOption(forceOption); 405 406 Option forceOnWarningsOption=OptionBuilder 407 .withDescription("Do not force reviews of files with warnings") 408 .isRequired(false) 409 .create("k"); 410 411 options.addOption(forceOnWarningsOption); 412 413 Option descriptionOption=OptionBuilder 414 .withDescription("Review description") 415 .withArgName("description") 416 .hasArg() 417 .isRequired(false) 418 .create("y"); 419 options.addOption(descriptionOption); 420 421 Option baseliningOption=OptionBuilder 423 .withArgName("off|on|set") 424 .hasArg() 425 .withDescription("Baselining mode") 426 .isRequired(false) 427 .create("B"); 428 429 options.addOption(descriptionOption); 430 431 Option helpOption=OptionBuilder.withDescription("Print this message").isRequired(false).create("h"); 432 options.addOption(helpOption); 433 434 CommandLineParser parser=new PosixParser(); 435 CommandLine line=null; 436 try { 437 line=parser.parse(options, args); 438 } catch (ParseException e) { 439 System.err.println(e.getMessage()); 440 System.err.flush(); 441 printHelpAndExit(options); 442 } 443 444 if (line.hasOption("h")) { 445 printHelpAndExit(options); 446 } 447 448 HammurapiArchiver task=new HammurapiArchiver(); 449 Project project = new Project(); 450 task.setProject(project); 451 project.setCoreLoader(task.getClass().getClassLoader()); 452 453 String [] values=line.getOptionValues('c'); 454 for (int i=0; values!=null && i<values.length; i++) { 455 task.createClasspath().append(new Path(project, values[i])); 456 } 457 458 String [] largs=line.getArgs(); 459 if (largs.length==0) { 460 System.out.println("Output file has to be provided"); 461 printHelpAndExit(options); 462 } 463 464 if (line.hasOption('f')) { 465 task.setForce(true); 466 } 467 468 if (line.hasOption('k')) { 469 task.setForceOnWarnings(false); 470 } 471 472 if (line.hasOption('n')) { 473 task.setBaseLine(new Date (line.getOptionValue('n'))); 474 } 475 476 if (line.hasOption('H')) { 477 task.setHostId(line.getOptionValue('H')); 478 } 479 480 if (line.hasOption('y')) { 481 task.setReviewDescription(line.getOptionValue('y')); 482 } 483 484 if (line.hasOption('T')) { 485 task.setTitle(line.getOptionValue('T')); 486 } 487 488 if (line.hasOption('B')) { 490 task.setBaselining(line.getOptionValue('B')); 491 } 492 493 task.setOutput(new File (largs[0])); 494 495 for (int i=1; i<largs.length; i++) { 496 File file = new File (largs[i]); 497 if (file.isFile()) { 498 task.srcFiles.add(file); 499 } else if (file.isDirectory()) { 500 task.createSrc().setDir(file); 501 } 502 } 503 504 task.setTaskName("har"); 505 506 try { 507 task.execute(); 508 System.exit(0); 509 } catch (Exception e) { 510 e.printStackTrace(); 511 System.exit(2); 512 } 513 } 514 515 private String reviewDescription; 516 517 521 public void setReviewDescription(String reviewDescription) { 522 this.reviewDescription=reviewDescription; 523 } 524 525 } 526 | Popular Tags |