1 package jdiff; 2 3 import com.sun.javadoc.*; 4 5 import java.util.*; 6 import java.io.*; 7 import java.lang.reflect.*; 8 9 16 public class RootDocToXML { 17 18 19 public RootDocToXML() { 20 } 21 22 28 public static boolean writeXML(RootDoc root) { 29 String tempFileName = outputFileName; 30 if (outputDirectory != null) { 31 tempFileName = outputDirectory; 32 if (!tempFileName.endsWith(JDiff.DIR_SEP)) 33 tempFileName += JDiff.DIR_SEP; 34 tempFileName += outputFileName; 35 } 36 37 try { 38 FileOutputStream fos = new FileOutputStream(tempFileName); 39 outputFile = new PrintWriter(fos); 40 System.out.println("JDiff: writing the API to file '" + tempFileName + "'..."); 41 if (root.specifiedPackages().length != 0) { 42 RootDocToXML apiWriter = new RootDocToXML(); 43 apiWriter.emitXMLHeader(); 44 apiWriter.logOptions(); 45 apiWriter.processPackages(root); 46 apiWriter.emitXMLFooter(); 47 } 48 outputFile.close(); 49 } catch(IOException e) { 50 System.out.println("IO Error while attempting to create " + tempFileName); 51 System.out.println("Error: " + e.getMessage()); 52 System.exit(1); 53 } 54 if (XMLToAPI.validateXML) { 57 writeXSD(); 58 } 59 return true; 60 } 61 62 65 public static void writeXSD() { 66 String xsdFileName = outputFileName; 67 if (outputDirectory == null) { 68 int idx = xsdFileName.lastIndexOf('\\'); 69 int idx2 = xsdFileName.lastIndexOf('/'); 70 if (idx == -1 && idx2 == -1) { 71 xsdFileName = ""; 72 } else if (idx == -1 && idx2 != -1) { 73 xsdFileName = xsdFileName.substring(0, idx2); 74 } else if (idx != -1 && idx2 == -1) { 75 xsdFileName = xsdFileName.substring(0, idx); 76 } else if (idx != -1 && idx2 != -1) { 77 int max = idx2 > idx ? idx2 : idx; 78 xsdFileName = xsdFileName.substring(0, max); 79 } 80 } else { 81 xsdFileName = outputDirectory; 82 if (!xsdFileName.endsWith(JDiff.DIR_SEP)) 83 xsdFileName += JDiff.DIR_SEP; 84 } 85 xsdFileName += "api.xsd"; 86 try { 87 FileOutputStream fos = new FileOutputStream(xsdFileName); 88 PrintWriter xsdFile = new PrintWriter(fos); 89 xsdFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>"); 91 xsdFile.println("<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">"); 92 xsdFile.println(""); 93 xsdFile.println("<xsd:annotation>"); 94 xsdFile.println(" <xsd:documentation>"); 95 xsdFile.println(" Schema for JDiff API representation."); 96 xsdFile.println(" </xsd:documentation>"); 97 xsdFile.println("</xsd:annotation>"); 98 xsdFile.println(); 99 xsdFile.println("<xsd:element name=\"api\" type=\"apiType\"/>"); 100 xsdFile.println(""); 101 xsdFile.println("<xsd:complexType name=\"apiType\">"); 102 xsdFile.println(" <xsd:sequence>"); 103 xsdFile.println(" <xsd:element name=\"package\" type=\"packageType\" minOccurs='1' maxOccurs='unbounded'/>"); 104 xsdFile.println(" </xsd:sequence>"); 105 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 106 xsdFile.println(" <xsd:attribute name=\"jdversion\" type=\"xsd:string\"/>"); 107 xsdFile.println("</xsd:complexType>"); 108 xsdFile.println(); 109 xsdFile.println("<xsd:complexType name=\"packageType\">"); 110 xsdFile.println(" <xsd:sequence>"); 111 xsdFile.println(" <xsd:choice maxOccurs='unbounded'>"); 112 xsdFile.println(" <xsd:element name=\"class\" type=\"classType\"/>"); 113 xsdFile.println(" <xsd:element name=\"interface\" type=\"classType\"/>"); 114 xsdFile.println(" </xsd:choice>"); 115 xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); 116 xsdFile.println(" </xsd:sequence>"); 117 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 118 xsdFile.println("</xsd:complexType>"); 119 xsdFile.println(); 120 xsdFile.println("<xsd:complexType name=\"classType\">"); 121 xsdFile.println(" <xsd:sequence>"); 122 xsdFile.println(" <xsd:element name=\"implements\" type=\"interfaceTypeName\" minOccurs='0' maxOccurs='unbounded'/>"); 123 xsdFile.println(" <xsd:element name=\"constructor\" type=\"constructorType\" minOccurs='0' maxOccurs='unbounded'/>"); 124 xsdFile.println(" <xsd:element name=\"method\" type=\"methodType\" minOccurs='0' maxOccurs='unbounded'/>"); 125 xsdFile.println(" <xsd:element name=\"field\" type=\"fieldType\" minOccurs='0' maxOccurs='unbounded'/>"); 126 xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); 127 xsdFile.println(" </xsd:sequence>"); 128 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 129 xsdFile.println(" <xsd:attribute name=\"extends\" type=\"xsd:string\" use='optional'/>"); 130 xsdFile.println(" <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>"); 131 xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); 132 xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); 133 xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); 134 xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); 135 xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); 136 xsdFile.println("</xsd:complexType>"); 137 xsdFile.println(); 138 xsdFile.println("<xsd:complexType name=\"interfaceTypeName\">"); 139 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 140 xsdFile.println("</xsd:complexType>"); 141 xsdFile.println(); 142 xsdFile.println("<xsd:complexType name=\"constructorType\">"); 143 xsdFile.println(" <xsd:sequence>"); 144 xsdFile.println(" <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>"); 145 xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); 146 xsdFile.println(" </xsd:sequence>"); 147 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 148 xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\" use='optional'/>"); 149 xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); 150 xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); 151 xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); 152 xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); 153 xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); 154 xsdFile.println("</xsd:complexType>"); 155 xsdFile.println(); 156 xsdFile.println("<xsd:complexType name=\"paramsType\">"); 157 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 158 xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>"); 159 xsdFile.println("</xsd:complexType>"); 160 xsdFile.println(); 161 xsdFile.println("<xsd:complexType name=\"exceptionType\">"); 162 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 163 xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>"); 164 xsdFile.println("</xsd:complexType>"); 165 xsdFile.println(); 166 xsdFile.println("<xsd:complexType name=\"methodType\">"); 167 xsdFile.println(" <xsd:sequence>"); 168 xsdFile.println(" <xsd:element name=\"param\" type=\"paramsType\" minOccurs='0' maxOccurs='unbounded'/>"); 169 xsdFile.println(" <xsd:element name=\"exception\" type=\"exceptionType\" minOccurs='0' maxOccurs='unbounded'/>"); 170 xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); 171 xsdFile.println(" </xsd:sequence>"); 172 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 173 xsdFile.println(" <xsd:attribute name=\"return\" type=\"xsd:string\" use='optional'/>"); 174 xsdFile.println(" <xsd:attribute name=\"abstract\" type=\"xsd:boolean\"/>"); 175 xsdFile.println(" <xsd:attribute name=\"native\" type=\"xsd:boolean\"/>"); 176 xsdFile.println(" <xsd:attribute name=\"synchronized\" type=\"xsd:boolean\"/>"); 177 xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); 178 xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); 179 xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); 180 xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); 181 xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); 182 xsdFile.println("</xsd:complexType>"); 183 xsdFile.println(); 184 xsdFile.println("<xsd:complexType name=\"fieldType\">"); 185 xsdFile.println(" <xsd:sequence>"); 186 xsdFile.println(" <xsd:element name=\"doc\" type=\"xsd:string\" minOccurs='0' maxOccurs='1'/>"); 187 xsdFile.println(" </xsd:sequence>"); 188 xsdFile.println(" <xsd:attribute name=\"name\" type=\"xsd:string\"/>"); 189 xsdFile.println(" <xsd:attribute name=\"type\" type=\"xsd:string\"/>"); 190 xsdFile.println(" <xsd:attribute name=\"transient\" type=\"xsd:boolean\"/>"); 191 xsdFile.println(" <xsd:attribute name=\"volatile\" type=\"xsd:boolean\"/>"); 192 xsdFile.println(" <xsd:attribute name=\"value\" type=\"xsd:string\" use='optional'/>"); 193 xsdFile.println(" <xsd:attribute name=\"src\" type=\"xsd:string\" use='optional'/>"); 194 xsdFile.println(" <xsd:attribute name=\"static\" type=\"xsd:boolean\"/>"); 195 xsdFile.println(" <xsd:attribute name=\"final\" type=\"xsd:boolean\"/>"); 196 xsdFile.println(" <xsd:attribute name=\"deprecated\" type=\"xsd:string\"/>"); 197 xsdFile.println(" <xsd:attribute name=\"visibility\" type=\"xsd:string\"/>"); 198 xsdFile.println("</xsd:complexType>"); 199 xsdFile.println(); 200 xsdFile.println("</xsd:schema>"); 201 xsdFile.close(); 202 } catch(IOException e) { 203 System.out.println("IO Error while attempting to create " + xsdFileName); 204 System.out.println("Error: " + e.getMessage()); 205 System.exit(1); 206 } 207 } 208 209 213 public void logOptions() { 214 outputFile.print("<!-- "); 215 outputFile.print(" Command line arguments = " + Options.cmdOptions); 216 outputFile.println(" -->"); 217 } 218 219 224 public void processPackages(RootDoc root) { 225 PackageDoc[] pd = root.specifiedPackages(); 226 for (int i = 0; pd != null && i < pd.length; i++) { 227 String pkgName = pd[i].name(); 228 229 if (!shownElement(pd[i], null)) 232 continue; 233 234 if (trace) System.out.println("PROCESSING PACKAGE: " + pkgName); 235 outputFile.println("<package name=\"" + pkgName + "\">"); 236 237 int tagCount = pd[i].tags().length; 238 if (trace) System.out.println("#tags: " + tagCount); 239 240 List classList = new LinkedList(Arrays.asList(pd[i].allClasses())); 241 Collections.sort(classList); 242 ClassDoc[] classes = new ClassDoc[classList.size()]; 243 classes = (ClassDoc[])classList.toArray(classes); 244 processClasses(classes, pkgName); 245 246 addPkgDocumentation(root, pd[i], 2); 247 248 outputFile.println("</package>"); 249 } 250 251 ClassDoc[] cd = root.specifiedClasses(); 255 if (!packagesOnly && cd != null && cd.length != 0) { 256 String pkgName = "anonymous"; 257 outputFile.println("<package name=\"" + pkgName + "\">"); 258 List classList = new LinkedList(Arrays.asList(cd)); 259 Collections.sort(classList); 260 ClassDoc[] classes = new ClassDoc[classList.size()]; 261 classes = (ClassDoc[])classList.toArray(classes); 262 processClasses(classes, pkgName); 263 outputFile.println("</package>"); 264 } 265 } 267 272 public void processClasses(ClassDoc[] cd, String pkgName) { 273 if (cd.length == 0) 274 return; 275 if (trace) System.out.println("PROCESSING CLASSES, number=" + cd.length); 276 for (int i = 0; i < cd.length; i++) { 277 String className = cd[i].name(); 278 if (trace) System.out.println("PROCESSING CLASS/IFC: " + className); 279 if (!shownElement(cd[i], classVisibilityLevel)) 281 continue; 282 boolean isInterface = false; 283 if (cd[i].isInterface()) 284 isInterface = true; 285 if (isInterface) { 286 outputFile.println(" <!-- start interface " + pkgName + "." + className + " -->"); 287 outputFile.print(" <interface name=\"" + className + "\""); 288 } else { 289 outputFile.println(" <!-- start class " + pkgName + "." + className + " -->"); 290 outputFile.print(" <class name=\"" + className + "\""); 291 } 292 ClassDoc parent = cd[i].superclass(); 294 if (parent != null) 295 outputFile.println(" extends=\"" + parent.qualifiedName() + "\""); 296 outputFile.println(" abstract=\"" + cd[i].isAbstract() + "\""); 297 addCommonModifiers(cd[i], 4); 298 outputFile.println(">"); 299 processInterfaces(cd[i].interfaces()); 301 processConstructors(cd[i].constructors()); 302 processMethods(cd[i], cd[i].methods()); 303 processFields(cd[i].fields()); 304 305 addDocumentation(cd[i], 4); 306 307 if (isInterface) { 308 outputFile.println(" </interface>"); 309 outputFile.println(" <!-- end interface " + pkgName + "." + className + " -->"); 310 } else { 311 outputFile.println(" </class>"); 312 outputFile.println(" <!-- end class " + pkgName + "." + className + " -->"); 313 } 314 321 } } 324 329 public void addCommonModifiers(ProgramElementDoc ped, int indent) { 330 addSourcePosition(ped, indent); 331 for (int i = 0; i < indent; i++) outputFile.print(" "); 333 outputFile.print("static=\"" + ped.isStatic() + "\""); 334 outputFile.print(" final=\"" + ped.isFinal() + "\""); 335 String visibility = null; 337 if (ped.isPublic()) 338 visibility = "public"; 339 else if (ped.isProtected()) 340 visibility = "protected"; 341 else if (ped.isPackagePrivate()) 342 visibility = "package"; 343 else if (ped.isPrivate()) 344 visibility = "private"; 345 outputFile.println(" visibility=\"" + visibility + "\""); 346 347 for (int i = 0; i < indent; i++) outputFile.print(" "); 349 boolean isDeprecated = false; 350 Tag[] ta = ((Doc)ped).tags("deprecated"); 351 if (ta.length != 0) { 352 isDeprecated = true; 353 } 354 if (ta.length > 1) { 355 System.out.println("JDiff: warning: multiple @deprecated tags found in comments for " + ped.name() + ". Using the first one only."); 356 System.out.println("Text is: " + ((Doc)ped).getRawCommentText()); 357 } 358 if (isDeprecated) { 359 String text = ta[0].text(); if (text != null && text.compareTo("") != 0) { 361 int idx = endOfFirstSentence(text); 362 if (idx == 0) { 363 outputFile.print("deprecated=\"deprecated, no comment\""); 365 } else { 366 String fs = null; 367 if (idx == -1) 368 fs = text; 369 else 370 fs = text.substring(0, idx+1); 371 String st = API.hideHTMLTags(fs); 372 outputFile.print("deprecated=\"" + st + "\""); 373 } 374 } else { 375 outputFile.print("deprecated=\"deprecated, no comment\""); 376 } 377 } else { 378 outputFile.print("deprecated=\"not deprecated\""); 379 } 380 381 } 383 388 public void addSourcePosition(ProgramElementDoc ped, int indent) { 389 if (!addSrcInfo) 390 return; 391 if (JDiff.javaVersion.startsWith("1.1") || 392 JDiff.javaVersion.startsWith("1.2") || 393 JDiff.javaVersion.startsWith("1.3")) { 394 return; } 396 try { 397 Class c = ProgramElementDoc.class; 399 Method m = c.getMethod("position", null); 400 Object sp = m.invoke(ped, null); 401 if (sp != null) { 402 for (int i = 0; i < indent; i++) outputFile.print(" "); 403 outputFile.println("src=\"" + sp + "\""); 404 } 405 } catch (NoSuchMethodException e2) { 406 System.err.println("Error: method \"position\" not found"); 407 e2.printStackTrace(); 408 } catch (IllegalAccessException e4) { 409 System.err.println("Error: class not permitted to be instantiated"); 410 e4.printStackTrace(); 411 } catch (InvocationTargetException e5) { 412 System.err.println("Error: method \"position\" could not be invoked"); 413 e5.printStackTrace(); 414 } catch (Exception e6) { 415 System.err.println("Error: "); 416 e6.printStackTrace(); 417 } 418 } 419 420 425 public void processInterfaces(ClassDoc[] ifaces) { 426 if (trace) System.out.println("PROCESSING INTERFACES, number=" + ifaces.length); 427 for (int i = 0; i < ifaces.length; i++) { 428 String ifaceName = ifaces[i].qualifiedName(); 429 if (trace) System.out.println("PROCESSING INTERFACE: " + ifaceName); 430 outputFile.println(" <implements name=\"" + ifaceName + "\"/>"); 431 } } 434 439 public void processConstructors(ConstructorDoc[] ct) { 440 if (trace) System.out.println("PROCESSING CONSTRUCTORS, number=" + ct.length); 441 for (int i = 0; i < ct.length; i++) { 442 String ctorName = ct[i].name(); 443 if (trace) System.out.println("PROCESSING CONSTRUCTOR: " + ctorName); 444 if (!shownElement(ct[i], memberVisibilityLevel)) 446 continue; 447 outputFile.print(" <constructor name=\"" + ctorName + "\""); 448 449 Parameter[] params = ct[i].parameters(); 450 boolean first = true; 451 if (params.length != 0) { 452 outputFile.print(" type=\""); 453 for (int j = 0; j < params.length; j++) { 454 if (!first) 455 outputFile.print(", "); 456 emitType(params[j].type()); 457 first = false; 458 } 459 outputFile.println("\""); 460 } else 461 outputFile.println(); 462 addCommonModifiers(ct[i], 6); 463 outputFile.println(">"); 464 465 processExceptions(ct[i].thrownExceptions()); 467 468 addDocumentation(ct[i], 6); 469 470 outputFile.println(" </constructor>"); 471 } } 474 479 public void processExceptions(ClassDoc[] cd) { 480 if (trace) System.out.println("PROCESSING EXCEPTIONS, number=" + cd.length); 481 for (int i = 0; i < cd.length; i++) { 482 String exceptionName = cd[i].name(); 483 if (trace) System.out.println("PROCESSING EXCEPTION: " + exceptionName); 484 outputFile.print(" <exception name=\"" + exceptionName + "\" type=\""); 485 emitType(cd[i]); 486 outputFile.println("\"/>"); 487 } } 490 495 public void processMethods(ClassDoc cd, MethodDoc[] md) { 496 if (trace) System.out.println("PROCESSING " +cd.name()+" METHODS, number = " + md.length); 497 for (int i = 0; i < md.length; i++) { 498 String methodName = md[i].name(); 499 if (trace) System.out.println("PROCESSING METHOD: " + methodName); 500 if (methodName.startsWith("<")) 502 continue; 503 if (!shownElement(md[i], memberVisibilityLevel)) 505 continue; 506 outputFile.print(" <method name=\"" + methodName + "\""); 507 com.sun.javadoc.Type retType = md[i].returnType(); 508 if (retType.qualifiedTypeName().compareTo("void") == 0) { 509 outputFile.println(); 511 } else { 512 outputFile.print(" return=\""); 513 emitType(retType); 514 outputFile.println("\""); 515 } 516 outputFile.print(" abstract=\"" + md[i].isAbstract() + "\""); 517 outputFile.print(" native=\"" + md[i].isNative() + "\""); 518 outputFile.println(" synchronized=\"" + md[i].isSynchronized() + "\""); 519 addCommonModifiers(md[i], 6); 520 outputFile.println(">"); 521 Parameter[] params = md[i].parameters(); 523 for (int j = 0; j < params.length; j++) { 524 outputFile.print(" <param name=\"" + params[j].name() + "\""); 525 outputFile.print(" type=\""); 526 emitType(params[j].type()); 527 outputFile.println("\"/>"); 528 } 529 530 processExceptions(md[i].thrownExceptions()); 532 533 addDocumentation(md[i], 6); 534 535 outputFile.println(" </method>"); 536 } } 539 544 public void processFields(FieldDoc[] fd) { 545 if (trace) System.out.println("PROCESSING FIELDS, number=" + fd.length); 546 for (int i = 0; i < fd.length; i++) { 547 String fieldName = fd[i].name(); 548 if (trace) System.out.println("PROCESSING FIELD: " + fieldName); 549 if (!shownElement(fd[i], memberVisibilityLevel)) 551 continue; 552 outputFile.print(" <field name=\"" + fieldName + "\""); 553 outputFile.print(" type=\""); 554 emitType(fd[i].type()); 555 outputFile.println("\""); 556 outputFile.print(" transient=\"" + fd[i].isTransient() + "\""); 557 outputFile.println(" volatile=\"" + fd[i].isVolatile() + "\""); 558 559 564 addCommonModifiers(fd[i], 6); 565 outputFile.println(">"); 566 567 addDocumentation(fd[i], 6); 568 569 outputFile.println(" </field>"); 570 571 } } 574 580 public void emitType(com.sun.javadoc.Type type) { 581 if (type == null) 582 return; 583 String name = type.qualifiedTypeName(); 584 if (name.startsWith("<<ambiguous>>")) 585 name = name.substring(13); 586 outputFile.print(name + type.dimension()); 587 } 588 589 592 public void emitXMLHeader() { 593 outputFile.println("<?xml version=\"1.0\" encoding=\"iso-8859-1\" standalone=\"no\"?>"); 594 outputFile.println("<!-- Generated by the JDiff Javadoc doclet -->"); 595 outputFile.println("<!-- (" + JDiff.jDiffLocation + ") -->"); 596 outputFile.println("<!-- on " + new Date() + " -->"); 597 outputFile.println(); 598 605 outputFile.println("<api"); 606 outputFile.println(" xmlns:xsi='" + baseURI + "/2001/XMLSchema-instance'"); 607 outputFile.println(" xsi:noNamespaceSchemaLocation='api.xsd'"); 608 outputFile.println(" name=\"" + apiIdentifier + "\""); 609 outputFile.println(" jdversion=\"" + JDiff.version + "\">"); 610 outputFile.println(); 611 } 612 613 616 public void emitXMLFooter() { 617 outputFile.println(); 618 outputFile.println("</api>"); 619 } 620 621 630 public boolean shownElement(Doc doc, String visLevel) { 631 if (doExclude && excludeTag != null && doc != null) { 634 String rct = doc.getRawCommentText(); 635 if (rct != null && rct.indexOf(excludeTag) != -1) { 636 return false; 637 } 638 } 639 if (visLevel == null) { 640 return true; 641 } 642 ProgramElementDoc ped = null; 643 if (doc instanceof ProgramElementDoc) { 644 ped = (ProgramElementDoc)doc; 645 } 646 if (visLevel.compareTo("private") == 0) 647 return true; 648 if (visLevel.compareTo("package") == 0) 650 return !ped.isPrivate(); 651 if (visLevel.compareTo("protected") == 0) 653 return !(ped.isPrivate() || ped.isPackagePrivate()); 654 if (visLevel.compareTo("public") == 0) 657 return ped.isPublic(); 658 return false; 659 } 661 666 public String stripNonPrintingChars(String s, Doc doc) { 667 if (!stripNonPrintables) 668 return s; 669 char[] sa = s.toCharArray(); 670 for (int i = 0; i < sa.length; i++) { 671 char c = sa[i]; 672 if (Character.isLetterOrDigit(c)) 675 continue; 676 if (c == ' ' || 678 c == '.' || 679 c == ',' || 680 c == '\r' || 681 c == '\t' || 682 c == '\n' || 683 c == '!' || 684 c == '?' || 685 c == ';' || 686 c == ':' || 687 c == '[' || 688 c == ']' || 689 c == '(' || 690 c == ')' || 691 c == '~' || 692 c == '@' || 693 c == '#' || 694 c == '$' || 695 c == '%' || 696 c == '^' || 697 c == '&' || 698 c == '*' || 699 c == '-' || 700 c == '=' || 701 c == '+' || 702 c == '_' || 703 c == '|' || 704 c == '\\' || 705 c == '/' || 706 c == '\'' || 707 c == '}' || 708 c == '{' || 709 c == '"' || 710 c == '<' || 711 c == '>' || 712 c == '`' 713 ) 714 continue; 715 733 sa[i] = '#'; 736 } 737 return new String (sa); 738 } 739 740 741 public boolean inRange(int val, int min, int max) { 742 if (val < min) 743 return false; 744 if (val > max) 745 return false; 746 return true; 747 } 748 749 759 public void addDocumentation(ProgramElementDoc ped, int indent) { 760 String rct = ((Doc)ped).getRawCommentText(); 761 if (rct != null) { 762 rct = stripNonPrintingChars(rct, (Doc)ped); 763 rct = rct.trim(); 764 if (rct.compareTo("") != 0 && 765 rct.indexOf(Comments.placeHolderText) == -1 && 766 rct.indexOf("InsertOtherCommentsHere") == -1) { 767 int idx = endOfFirstSentence(rct); 768 if (idx == 0) 769 return; 770 for (int i = 0; i < indent; i++) outputFile.print(" "); 771 outputFile.println("<doc>"); 772 for (int i = 0; i < indent; i++) outputFile.print(" "); 773 String firstSentence = null; 774 if (idx == -1) 775 firstSentence = rct; 776 else 777 firstSentence = rct.substring(0, idx+1); 778 boolean checkForAts = false; 779 if (checkForAts && firstSentence.indexOf("@") != -1 && 780 firstSentence.indexOf("@link") == -1) { 781 System.out.println("Warning: @ tag seen in comment: " + 782 firstSentence); 783 } 784 String firstSentenceNoTags = API.stuffHTMLTags(firstSentence); 785 outputFile.println(firstSentenceNoTags); 786 for (int i = 0; i < indent; i++) outputFile.print(" "); 787 outputFile.println("</doc>"); 788 } 789 } 790 } 791 792 804 public void addPkgDocumentation(RootDoc root, PackageDoc pd, int indent) { 805 String rct = null; 806 String filename = pd.name(); 807 try { 808 String srcLocation = null; 811 String [][] options = root.options(); 812 for (int opt = 0; opt < options.length; opt++) { 813 if ((options[opt][0]).compareTo("-sourcepath") == 0) { 814 srcLocation = options[opt][1]; 815 break; 816 } 817 } 818 filename = filename.replace('.', JDiff.DIR_SEP.charAt(0)); 819 if (srcLocation != null) { 820 if (srcLocation.startsWith("..")) { 822 String curDir = System.getProperty("user.dir"); 823 while (srcLocation.startsWith("..")) { 824 srcLocation = srcLocation.substring(3); 825 int idx = curDir.lastIndexOf(JDiff.DIR_SEP); 826 curDir = curDir.substring(0, idx+1); 827 } 828 srcLocation = curDir + srcLocation; 829 } 830 filename = srcLocation + JDiff.DIR_SEP + filename; 831 } 832 filename += JDiff.DIR_SEP + "package.htm"; 834 File f2 = new File(filename); 835 if (!f2.exists()) { 836 filename += "l"; 837 } 838 FileInputStream f = new FileInputStream(filename); 839 BufferedReader d = new BufferedReader(new InputStreamReader(f)); 840 String str = d.readLine(); 841 boolean inBody = false; 843 while(str != null) { 844 if (!inBody) { 845 if (str.toLowerCase().trim().startsWith("<body")) { 846 inBody = true; 847 } 848 str = d.readLine(); continue; } else { 851 if (str.toLowerCase().trim().startsWith("</body")) { 852 inBody = false; 853 continue; } 855 } 856 if (rct == null) 857 rct = str + "\n"; 858 else 859 rct += str + "\n"; 860 str = d.readLine(); 861 } 862 } catch(java.io.FileNotFoundException e) { 863 if (trace) 865 System.out.println("No package level documentation file at '" + filename + "'"); 866 } catch(java.io.IOException e) { 867 System.out.println("Error reading file \"" + filename + "\": " + e.getMessage()); 868 System.exit(5); 869 } 870 if (rct != null) { 871 rct = stripNonPrintingChars(rct, (Doc)pd); 872 rct = rct.trim(); 873 if (rct.compareTo("") != 0 && 874 rct.indexOf(Comments.placeHolderText) == -1 && 875 rct.indexOf("InsertOtherCommentsHere") == -1) { 876 int idx = endOfFirstSentence(rct); 877 if (idx == 0) 878 return; 879 for (int i = 0; i < indent; i++) outputFile.print(" "); 880 outputFile.println("<doc>"); 881 for (int i = 0; i < indent; i++) outputFile.print(" "); 882 String firstSentence = null; 883 if (idx == -1) 884 firstSentence = rct; 885 else 886 firstSentence = rct.substring(0, idx+1); 887 String firstSentenceNoTags = API.stuffHTMLTags(firstSentence); 888 outputFile.println(firstSentenceNoTags); 889 for (int i = 0; i < indent; i++) outputFile.print(" "); 890 outputFile.println("</doc>"); 891 } 892 } 893 } 894 895 906 public static int endOfFirstSentence(String text) { 907 return endOfFirstSentence(text, true); 908 } 909 910 921 public static int endOfFirstSentence(String text, boolean writingToXML) { 922 if (saveAllDocs && writingToXML) 923 return -1; 924 int textLen = text.length(); 925 if (textLen == 0) 926 return 0; 927 int index = -1; 928 int fromindex = 0; 930 int ellipsis = text.indexOf(". . ."); if (ellipsis != -1) 932 fromindex = ellipsis + 5; 933 int i = 0; 935 while (i < textLen && text.charAt(i) == ' ') { 936 i++; 937 } 938 if (text.charAt(i) == '@' && fromindex < textLen-1) 939 fromindex = i + 1; 940 index = minIndex(index, text.indexOf("? ", fromindex)); 942 index = minIndex(index, text.indexOf("?\t", fromindex)); 943 index = minIndex(index, text.indexOf("?\n", fromindex)); 944 index = minIndex(index, text.indexOf("?\r", fromindex)); 945 index = minIndex(index, text.indexOf("?\f", fromindex)); 946 index = minIndex(index, text.indexOf("! ", fromindex)); 947 index = minIndex(index, text.indexOf("!\t", fromindex)); 948 index = minIndex(index, text.indexOf("!\n", fromindex)); 949 index = minIndex(index, text.indexOf("!\r", fromindex)); 950 index = minIndex(index, text.indexOf("!\f", fromindex)); 951 index = minIndex(index, text.indexOf(". ", fromindex)); 952 index = minIndex(index, text.indexOf(".\t", fromindex)); 953 index = minIndex(index, text.indexOf(".\n", fromindex)); 954 index = minIndex(index, text.indexOf(".\r", fromindex)); 955 index = minIndex(index, text.indexOf(".\f", fromindex)); 956 index = minIndex(index, text.indexOf("@param", fromindex)); 957 index = minIndex(index, text.indexOf("@return", fromindex)); 958 index = minIndex(index, text.indexOf("@throw", fromindex)); 959 index = minIndex(index, text.indexOf("@serial", fromindex)); 960 index = minIndex(index, text.indexOf("@exception", fromindex)); 961 index = minIndex(index, text.indexOf("@deprecate", fromindex)); 962 index = minIndex(index, text.indexOf("@author", fromindex)); 963 index = minIndex(index, text.indexOf("@since", fromindex)); 964 index = minIndex(index, text.indexOf("@see", fromindex)); 965 index = minIndex(index, text.indexOf("@version", fromindex)); 966 if (doExclude && excludeTag != null) 967 index = minIndex(index, text.indexOf(excludeTag)); 968 index = minIndex(index, text.indexOf("@vtexclude", fromindex)); 969 index = minIndex(index, text.indexOf("@vtinclude", fromindex)); 970 index = minIndex(index, text.indexOf("<p>", 2)); index = minIndex(index, text.indexOf("<P>", 2)); index = minIndex(index, text.indexOf("<blockquote", 2)); index = minIndex(index, text.indexOf("<pre", fromindex)); if (index != -1 && 976 (text.charAt(index) == '@' || text.charAt(index) == '<')) { 977 if (index != 0) 978 index--; 979 } 980 981 994 return index; 995 } 996 997 1004 public static int minIndex(int i, int j) { 1005 if (i == -1) return j; 1006 if (j == -1) return i; 1007 return Math.min(i,j); 1008 } 1009 1010 1014 public static String outputFileName = null; 1015 1016 1020 public static String apiIdentifier = null; 1021 1022 1025 private static PrintWriter outputFile = null; 1026 1027 1031 public static String outputDirectory = null; 1032 1033 1037 public static String classVisibilityLevel = "protected"; 1038 1039 1044 public static String memberVisibilityLevel = "protected"; 1045 1046 1051 public static boolean saveAllDocs = true; 1052 1053 1057 public static boolean doExclude = false; 1058 1059 1062 public static String excludeTag = null; 1063 1064 1069 public static String baseURI = "http://www.w3.org"; 1070 1071 1075 static boolean stripNonPrintables = true; 1076 1077 1081 static boolean addSrcInfo = false; 1082 1083 1089 static boolean packagesOnly = false; 1090 1091 1092 private static boolean trace = false; 1093 1094} | Popular Tags |