1.1 --- a/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Wed Oct 17 16:43:26 2012 +0100 1.2 +++ b/src/share/classes/com/sun/tools/doclets/formats/html/HtmlDocletWriter.java Tue Oct 23 13:20:37 2012 -0700 1.3 @@ -55,32 +55,24 @@ 1.4 /** 1.5 * Relative path from the file getting generated to the destination 1.6 * directory. For example, if the file getting generated is 1.7 - * "java/lang/Object.html", then the relative path string is "../../". 1.8 + * "java/lang/Object.html", then the path to the root is "../..". 1.9 * This string can be empty if the file getting generated is in 1.10 * the destination directory. 1.11 */ 1.12 - public String relativePath = ""; 1.13 + public final DocPath pathToRoot; 1.14 1.15 /** 1.16 - * Same as relativepath, but normalized to never be empty or 1.17 - * end with a slash. 1.18 - */ 1.19 - public String relativepathNoSlash = ""; 1.20 - 1.21 - /** 1.22 - * Platform-dependent directory path from the current or the 1.23 + * Platform-independent path from the current or the 1.24 * destination directory to the file getting generated. 1.25 * Used when creating the file. 1.26 - * For example, if the file getting generated is 1.27 - * "java/lang/Object.html", then the path string is "java/lang". 1.28 */ 1.29 - public String path = ""; 1.30 + public final DocPath path; 1.31 1.32 /** 1.33 * Name of the file getting generated. If the file getting generated is 1.34 * "java/lang/Object.html", then the filename is "Object.html". 1.35 */ 1.36 - public String filename = ""; 1.37 + public final DocPath filename; 1.38 1.39 /** 1.40 * The display length used for indentation while generating the class page. 1.41 @@ -100,33 +92,15 @@ 1.42 /** 1.43 * Constructor to construct the HtmlStandardWriter object. 1.44 * 1.45 - * @param filename File to be generated. 1.46 + * @param path File to be generated. 1.47 */ 1.48 - public HtmlDocletWriter(ConfigurationImpl configuration, 1.49 - String filename) throws IOException { 1.50 - super(configuration, filename); 1.51 - this.configuration = configuration; 1.52 - this.filename = filename; 1.53 - } 1.54 - 1.55 - /** 1.56 - * Constructor to construct the HtmlStandardWriter object. 1.57 - * 1.58 - * @param path Platform-dependent {@link #path} used when 1.59 - * creating file. 1.60 - * @param filename Name of file to be generated. 1.61 - * @param relativePath Value for the variable {@link #relativePath}. 1.62 - */ 1.63 - public HtmlDocletWriter(ConfigurationImpl configuration, 1.64 - String path, String filename, 1.65 - String relativePath) throws IOException { 1.66 - super(configuration, path, filename); 1.67 + public HtmlDocletWriter(ConfigurationImpl configuration, DocPath path) 1.68 + throws IOException { 1.69 + super(configuration, path); 1.70 this.configuration = configuration; 1.71 this.path = path; 1.72 - this.relativePath = relativePath; 1.73 - this.relativepathNoSlash = 1.74 - DirectoryManager.getPathNoTrailingSlash(this.relativePath); 1.75 - this.filename = filename; 1.76 + this.pathToRoot = path.parent().invert(); 1.77 + this.filename = path.basename(); 1.78 } 1.79 1.80 /** 1.81 @@ -165,8 +139,9 @@ 1.82 int previndex = 0; 1.83 while (true) { 1.84 if (configuration.docrootparent.length() > 0) { 1.85 + final String docroot_parent = "{@docroot}/.."; 1.86 // Search for lowercase version of {@docRoot}/.. 1.87 - index = lowerHtml.indexOf("{@docroot}/..", previndex); 1.88 + index = lowerHtml.indexOf(docroot_parent, previndex); 1.89 // If next {@docRoot}/.. pattern not found, append rest of htmlstr and exit loop 1.90 if (index < 0) { 1.91 buf.append(htmlstr.substring(previndex)); 1.92 @@ -174,17 +149,18 @@ 1.93 } 1.94 // If next {@docroot}/.. pattern found, append htmlstr up to start of tag 1.95 buf.append(htmlstr.substring(previndex, index)); 1.96 - previndex = index + 13; // length for {@docroot}/.. string 1.97 + previndex = index + docroot_parent.length(); 1.98 // Insert docrootparent absolute path where {@docRoot}/.. was located 1.99 1.100 buf.append(configuration.docrootparent); 1.101 // Append slash if next character is not a slash 1.102 if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') { 1.103 - buf.append(DirectoryManager.URL_FILE_SEPARATOR); 1.104 + buf.append('/'); 1.105 } 1.106 } else { 1.107 + final String docroot = "{@docroot}"; 1.108 // Search for lowercase version of {@docRoot} 1.109 - index = lowerHtml.indexOf("{@docroot}", previndex); 1.110 + index = lowerHtml.indexOf(docroot, previndex); 1.111 // If next {@docRoot} tag not found, append rest of htmlstr and exit loop 1.112 if (index < 0) { 1.113 buf.append(htmlstr.substring(previndex)); 1.114 @@ -192,13 +168,12 @@ 1.115 } 1.116 // If next {@docroot} tag found, append htmlstr up to start of tag 1.117 buf.append(htmlstr.substring(previndex, index)); 1.118 - previndex = index + 10; // length for {@docroot} string 1.119 + previndex = index + docroot.length(); 1.120 // Insert relative path where {@docRoot} was located 1.121 - buf.append(relativepathNoSlash); 1.122 + buf.append(pathToRoot.isEmpty() ? "." : pathToRoot.getPath()); 1.123 // Append slash if next character is not a slash 1.124 - if (relativepathNoSlash.length() > 0 && previndex < htmlstr.length() && 1.125 - htmlstr.charAt(previndex) != '/') { 1.126 - buf.append(DirectoryManager.URL_FILE_SEPARATOR); 1.127 + if (previndex < htmlstr.length() && htmlstr.charAt(previndex) != '/') { 1.128 + buf.append('/'); 1.129 } 1.130 } 1.131 } 1.132 @@ -312,7 +287,7 @@ 1.133 */ 1.134 public Content getTargetPackageLink(PackageDoc pd, String target, 1.135 Content label) { 1.136 - return getHyperLink(pathString(pd, "package-summary.html"), "", label, "", target); 1.137 + return getHyperLink(pathString(pd, DocPaths.PACKAGE_SUMMARY), "", label, "", target); 1.138 } 1.139 1.140 /** 1.141 @@ -539,8 +514,8 @@ 1.142 * @return a content tree for the link 1.143 */ 1.144 protected Content getNavLinkContents() { 1.145 - Content linkContent = getHyperLink(relativePath + 1.146 - "overview-summary.html", "", overviewLabel, "", ""); 1.147 + Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_SUMMARY), 1.148 + "", overviewLabel, "", ""); 1.149 Content li = HtmlTree.LI(linkContent); 1.150 return li; 1.151 } 1.152 @@ -584,7 +559,7 @@ 1.153 * @param prev File name for the prev link 1.154 * @return a content tree for the link 1.155 */ 1.156 - public Content getNavLinkPrevious(String prev) { 1.157 + public Content getNavLinkPrevious(DocPath prev) { 1.158 Content li; 1.159 if (prev != null) { 1.160 li = HtmlTree.LI(getHyperLink(prev, "", prevLabel, "", "")); 1.161 @@ -601,7 +576,7 @@ 1.162 * @param next File name for the next link 1.163 * @return a content tree for the link 1.164 */ 1.165 - public Content getNavLinkNext(String next) { 1.166 + public Content getNavLinkNext(DocPath next) { 1.167 Content li; 1.168 if (next != null) { 1.169 li = HtmlTree.LI(getHyperLink(next, "", nextLabel, "", "")); 1.170 @@ -617,9 +592,9 @@ 1.171 * @param link File to be linked, "index.html" 1.172 * @return a content tree for the link 1.173 */ 1.174 - protected Content getNavShowLists(String link) { 1.175 - Content framesContent = getHyperLink(link + "?" + path + 1.176 - filename, "", framesLabel, "", "_top"); 1.177 + protected Content getNavShowLists(DocPath link) { 1.178 + Content framesContent = getHyperLink(link.getPath() + "?" + path.getPath(), 1.179 + "", framesLabel, "", "_top"); 1.180 Content li = HtmlTree.LI(framesContent); 1.181 return li; 1.182 } 1.183 @@ -630,7 +605,7 @@ 1.184 * @return a content tree for the link 1.185 */ 1.186 protected Content getNavShowLists() { 1.187 - return getNavShowLists(relativePath + "index.html"); 1.188 + return getNavShowLists(pathToRoot.resolve(DocPaths.INDEX)); 1.189 } 1.190 1.191 /** 1.192 @@ -639,7 +614,7 @@ 1.193 * @param link File to be linked 1.194 * @return a content tree for the link 1.195 */ 1.196 - protected Content getNavHideLists(String link) { 1.197 + protected Content getNavHideLists(DocPath link) { 1.198 Content noFramesContent = getHyperLink(link, "", noframesLabel, "", "_top"); 1.199 Content li = HtmlTree.LI(noFramesContent); 1.200 return li; 1.201 @@ -658,10 +633,10 @@ 1.202 PackageDoc[] packages = configuration.root.specifiedPackages(); 1.203 if (packages.length == 1 && configuration.root.specifiedClasses().length == 0) { 1.204 treeLinkContent = getHyperLink(pathString(packages[0], 1.205 - "package-tree.html"), "", treeLabel, 1.206 + DocPaths.PACKAGE_TREE), "", treeLabel, 1.207 "", ""); 1.208 } else { 1.209 - treeLinkContent = getHyperLink(relativePath + "overview-tree.html", 1.210 + treeLinkContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), 1.211 "", treeLabel, "", ""); 1.212 } 1.213 Content li = HtmlTree.LI(treeLinkContent); 1.214 @@ -675,7 +650,7 @@ 1.215 * @return a content tree for the link 1.216 */ 1.217 protected Content getNavLinkMainTree(String label) { 1.218 - Content mainTreeContent = getHyperLink(relativePath + "overview-tree.html", 1.219 + Content mainTreeContent = getHyperLink(pathToRoot.resolve(DocPaths.OVERVIEW_TREE), 1.220 new StringContent(label)); 1.221 Content li = HtmlTree.LI(mainTreeContent); 1.222 return li; 1.223 @@ -697,8 +672,8 @@ 1.224 * @return a content tree for the link 1.225 */ 1.226 protected Content getNavLinkDeprecated() { 1.227 - Content linkContent = getHyperLink(relativePath + 1.228 - "deprecated-list.html", "", deprecatedLabel, "", ""); 1.229 + Content linkContent = getHyperLink(pathToRoot.resolve(DocPaths.DEPRECATED_LIST), 1.230 + "", deprecatedLabel, "", ""); 1.231 Content li = HtmlTree.LI(linkContent); 1.232 return li; 1.233 } 1.234 @@ -711,8 +686,8 @@ 1.235 * @return a content tree for the link 1.236 */ 1.237 protected Content getNavLinkClassIndex() { 1.238 - Content allClassesContent = getHyperLink(relativePath + 1.239 - AllClassesFrameWriter.OUTPUT_FILE_NAME_NOFRAMES, "", 1.240 + Content allClassesContent = getHyperLink(pathToRoot.resolve( 1.241 + DocPaths.ALLCLASSES_NOFRAME), "", 1.242 allclassesLabel, "", ""); 1.243 Content li = HtmlTree.LI(allClassesContent); 1.244 return li; 1.245 @@ -724,9 +699,10 @@ 1.246 * @return a content tree for the link 1.247 */ 1.248 protected Content getNavLinkIndex() { 1.249 - Content linkContent = getHyperLink(relativePath +(configuration.splitindex? 1.250 - DirectoryManager.getPath("index-files") + fileseparator: "") + 1.251 - (configuration.splitindex?"index-1.html" : "index-all.html"), "", 1.252 + Content linkContent = getHyperLink(pathToRoot.resolve( 1.253 + (configuration.splitindex 1.254 + ? DocPaths.INDEX_FILES.resolve(DocPaths.indexN(1)) 1.255 + : DocPaths.INDEX_ALL)), "", 1.256 indexLabel, "", ""); 1.257 Content li = HtmlTree.LI(linkContent); 1.258 return li; 1.259 @@ -740,16 +716,14 @@ 1.260 * @return a content tree for the link 1.261 */ 1.262 protected Content getNavLinkHelp() { 1.263 - String helpfilenm = configuration.helpfile; 1.264 - if (helpfilenm.equals("")) { 1.265 - helpfilenm = "help-doc.html"; 1.266 + String helpfile = configuration.helpfile; 1.267 + DocPath helpfilenm; 1.268 + if (helpfile.isEmpty()) { 1.269 + helpfilenm = DocPaths.HELP_DOC; 1.270 } else { 1.271 - int lastsep; 1.272 - if ((lastsep = helpfilenm.lastIndexOf(File.separatorChar)) != -1) { 1.273 - helpfilenm = helpfilenm.substring(lastsep + 1); 1.274 - } 1.275 + helpfilenm = DocPath.create(new File(helpfile).getName()); 1.276 } 1.277 - Content linkContent = getHyperLink(relativePath + helpfilenm, "", 1.278 + Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm), "", 1.279 helpLabel, "", ""); 1.280 Content li = HtmlTree.LI(linkContent); 1.281 return li; 1.282 @@ -884,25 +858,13 @@ 1.283 } 1.284 1.285 /** 1.286 - * Return path to the class page for a classdoc. For example, the class 1.287 - * name is "java.lang.Object" and if the current file getting generated is 1.288 - * "java/io/File.html", then the path string to the class, returned is 1.289 - * "../../java/lang.Object.html". 1.290 - * 1.291 - * @param cd Class to which the path is requested. 1.292 - */ 1.293 - protected String pathToClass(ClassDoc cd) { 1.294 - return pathString(cd.containingPackage(), cd.name() + ".html"); 1.295 - } 1.296 - 1.297 - /** 1.298 * Return the path to the class page for a classdoc. Works same as 1.299 * {@link #pathToClass(ClassDoc)}. 1.300 * 1.301 * @param cd Class to which the path is requested. 1.302 * @param name Name of the file(doesn't include path). 1.303 */ 1.304 - protected String pathString(ClassDoc cd, String name) { 1.305 + protected DocPath pathString(ClassDoc cd, DocPath name) { 1.306 return pathString(cd.containingPackage(), name); 1.307 } 1.308 1.309 @@ -915,10 +877,8 @@ 1.310 * @param pd Package in which the file name is assumed to be. 1.311 * @param name File name, to which path string is. 1.312 */ 1.313 - protected String pathString(PackageDoc pd, String name) { 1.314 - StringBuilder buf = new StringBuilder(relativePath); 1.315 - buf.append(DirectoryManager.getPathToPackage(pd, name)); 1.316 - return buf.toString(); 1.317 + protected DocPath pathString(PackageDoc pd, DocPath name) { 1.318 + return pathToRoot.resolve(DocPath.forPackage(pd).resolve(name)); 1.319 } 1.320 1.321 /** 1.322 @@ -956,12 +916,12 @@ 1.323 } 1.324 } 1.325 if (included || pkg == null) { 1.326 - return getHyperLinkString(pathString(pkg, "package-summary.html"), 1.327 + return getHyperLinkString(pathString(pkg, DocPaths.PACKAGE_SUMMARY), 1.328 "", label, isStrong, style); 1.329 } else { 1.330 String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg)); 1.331 if (crossPkgLink != null) { 1.332 - return getHyperLinkString(crossPkgLink, "", label, isStrong, style); 1.333 + return getHyperLinkString(/*TEMP*/ DocPath.create(crossPkgLink), "", label, isStrong, style); 1.334 } else { 1.335 return label; 1.336 } 1.337 @@ -987,12 +947,12 @@ 1.338 } 1.339 } 1.340 if (included || pkg == null) { 1.341 - return getHyperLink(pathString(pkg, "package-summary.html"), 1.342 + return getHyperLink(pathString(pkg, DocPaths.PACKAGE_SUMMARY), 1.343 "", label); 1.344 } else { 1.345 String crossPkgLink = getCrossPackageLink(Util.getPackageName(pkg)); 1.346 if (crossPkgLink != null) { 1.347 - return getHyperLink(crossPkgLink, "", label); 1.348 + return getHyperLink(/*TEMP*/ DocPath.create(crossPkgLink), "", label); 1.349 } else { 1.350 return label; 1.351 } 1.352 @@ -1020,10 +980,10 @@ 1.353 //d must be a class doc since in has no containing class. 1.354 cd = (ClassDoc) doc; 1.355 } 1.356 - String href = relativePath + DocletConstants.SOURCE_OUTPUT_DIR_NAME 1.357 - + DirectoryManager.getDirectoryPath(cd.containingPackage()) 1.358 - + cd.name() + ".html#" + SourceToHTMLConverter.getAnchorName(doc); 1.359 - Content linkContent = getHyperLink(href, "", label, "", ""); 1.360 + DocPath href = pathToRoot 1.361 + .resolve(DocPaths.SOURCE_OUTPUT) 1.362 + .resolve(DocPath.forClass(cd)); 1.363 + Content linkContent = getHyperLink(href, SourceToHTMLConverter.getAnchorName(doc), label, "", ""); 1.364 htmltree.addContent(linkContent); 1.365 } 1.366 1.367 @@ -1085,7 +1045,7 @@ 1.368 //exists, but no way to determine if the external class exists. We just 1.369 //have to assume that it does. 1.370 return getHyperLinkString( 1.371 - configuration.extern.getExternalLink(packageName, relativePath, 1.372 + configuration.extern.getExternalLink(packageName, pathToRoot, 1.373 className + ".html?is-external=true"), 1.374 refMemName == null ? "" : refMemName, 1.375 label == null || label.length() == 0 ? defaultLabel : label, 1.376 @@ -1105,7 +1065,7 @@ 1.377 } 1.378 1.379 public String getCrossPackageLink(String pkgName) { 1.380 - return configuration.extern.getExternalLink(pkgName, relativePath, 1.381 + return configuration.extern.getExternalLink(pkgName, pathToRoot, 1.382 "package-summary.html?is-external=true"); 1.383 } 1.384 1.385 @@ -1321,7 +1281,7 @@ 1.386 String classCrossLink, packageCrossLink = getCrossPackageLink(refClassName); 1.387 if (packageCrossLink != null) { 1.388 //Package cross link found 1.389 - return getHyperLinkString(packageCrossLink, "", 1.390 + return getHyperLinkString(/*TEMP*/ DocPath.create(packageCrossLink), "", 1.391 (label.isEmpty() ? text : label), false); 1.392 } else if ((classCrossLink = getCrossClassLink(refClassName, 1.393 refMemName, label, false, "", !plain)) != null) { 1.394 @@ -1450,7 +1410,7 @@ 1.395 * @param doc the doc for which the comment tags will be generated 1.396 * @param tags the first sentence tags for the doc 1.397 * @param depr true if it is deprecated 1.398 - * @param first true if the first sentenge tags should be added 1.399 + * @param first true if the first sentence tags should be added 1.400 * @param htmltree the documentation tree to which the comment tags will be added 1.401 */ 1.402 private void addCommentTags(Doc doc, Tag[] tags, boolean depr, 1.403 @@ -1561,7 +1521,7 @@ 1.404 1.405 /** 1.406 * Suppose a piece of documentation has a relative link. When you copy 1.407 - * that documetation to another place such as the index or class-use page, 1.408 + * that documentation to another place such as the index or class-use page, 1.409 * that relative link will no longer work. We should redirect those links 1.410 * so that they will work again. 1.411 * <p> 1.412 @@ -1587,21 +1547,17 @@ 1.413 return text; 1.414 } 1.415 1.416 - String redirectPathFromRoot; 1.417 + DocPath redirectPathFromRoot; 1.418 if (doc instanceof ClassDoc) { 1.419 - redirectPathFromRoot = DirectoryManager.getDirectoryPath(((ClassDoc) doc).containingPackage()); 1.420 + redirectPathFromRoot = DocPath.forPackage(((ClassDoc) doc).containingPackage()); 1.421 } else if (doc instanceof MemberDoc) { 1.422 - redirectPathFromRoot = DirectoryManager.getDirectoryPath(((MemberDoc) doc).containingPackage()); 1.423 + redirectPathFromRoot = DocPath.forPackage(((MemberDoc) doc).containingPackage()); 1.424 } else if (doc instanceof PackageDoc) { 1.425 - redirectPathFromRoot = DirectoryManager.getDirectoryPath((PackageDoc) doc); 1.426 + redirectPathFromRoot = DocPath.forPackage((PackageDoc) doc); 1.427 } else { 1.428 return text; 1.429 } 1.430 1.431 - if (! redirectPathFromRoot.endsWith(DirectoryManager.URL_FILE_SEPARATOR)) { 1.432 - redirectPathFromRoot += DirectoryManager.URL_FILE_SEPARATOR; 1.433 - } 1.434 - 1.435 //Redirect all relative links. 1.436 int end, begin = text.toLowerCase().indexOf("<a"); 1.437 if(begin >= 0){ 1.438 @@ -1627,22 +1583,21 @@ 1.439 //might be missing '>' character because the href has an inline tag. 1.440 break; 1.441 } 1.442 - if(textBuff.substring(begin, end).indexOf("\"") != -1){ 1.443 + if (textBuff.substring(begin, end).indexOf("\"") != -1){ 1.444 begin = textBuff.indexOf("\"", begin) + 1; 1.445 end = textBuff.indexOf("\"", begin +1); 1.446 - if(begin == 0 || end == -1){ 1.447 + if (begin == 0 || end == -1){ 1.448 //Link is missing a quote. 1.449 break; 1.450 } 1.451 } 1.452 String relativeLink = textBuff.substring(begin, end); 1.453 - if(!(relativeLink.toLowerCase().startsWith("mailto:") || 1.454 - relativeLink.toLowerCase().startsWith("http:") || 1.455 - relativeLink.toLowerCase().startsWith("https:") || 1.456 - relativeLink.toLowerCase().startsWith("file:"))){ 1.457 - relativeLink = "{@"+(new DocRootTaglet()).getName() + "}" 1.458 - + redirectPathFromRoot 1.459 - + relativeLink; 1.460 + if (!(relativeLink.toLowerCase().startsWith("mailto:") || 1.461 + relativeLink.toLowerCase().startsWith("http:") || 1.462 + relativeLink.toLowerCase().startsWith("https:") || 1.463 + relativeLink.toLowerCase().startsWith("file:"))) { 1.464 + relativeLink = "{@"+(new DocRootTaglet()).getName() + "}/" 1.465 + + redirectPathFromRoot.resolve(relativeLink).getPath(); 1.466 textBuff.replace(begin, end, relativeLink); 1.467 } 1.468 begin = textBuff.toString().toLowerCase().indexOf("<a", begin + 1); 1.469 @@ -1715,17 +1670,15 @@ 1.470 */ 1.471 public HtmlTree getStyleSheetProperties() { 1.472 String filename = configuration.stylesheetfile; 1.473 + DocPath stylesheet; 1.474 if (filename.length() > 0) { 1.475 - File stylefile = new File(filename); 1.476 - String parent = stylefile.getParent(); 1.477 - filename = (parent == null)? 1.478 - filename: 1.479 - filename.substring(parent.length() + 1); 1.480 + stylesheet = DocPath.create(new File(filename).getName()); 1.481 } else { 1.482 - filename = "stylesheet.css"; 1.483 + stylesheet = DocPaths.STYLESHEET; 1.484 } 1.485 - filename = relativePath + filename; 1.486 - HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", filename, "Style"); 1.487 + HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", 1.488 + pathToRoot.resolve(stylesheet).getPath(), 1.489 + "Style"); 1.490 return link; 1.491 } 1.492