提交 5e89ded1 编写于 作者: J jjg

8001664: refactor javadoc to use abstraction to handle files

Reviewed-by: darcy
上级 f4fd0524
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
package com.sun.tools.doclets.formats.html; package com.sun.tools.doclets.formats.html;
import java.io.*;
import java.net.*; import java.net.*;
import java.util.*; import java.util.*;
...@@ -46,6 +45,11 @@ import com.sun.tools.doclets.internal.toolkit.util.*; ...@@ -46,6 +45,11 @@ import com.sun.tools.doclets.internal.toolkit.util.*;
* use "-helpfile" option when already "-nohelp" option is used. * use "-helpfile" option when already "-nohelp" option is used.
* </p> * </p>
* *
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @author Robert Field. * @author Robert Field.
* @author Atul Dambalkar. * @author Atul Dambalkar.
* @author Jamie Ho * @author Jamie Ho
...@@ -362,7 +366,7 @@ public class ConfigurationImpl extends Configuration { ...@@ -362,7 +366,7 @@ public class ConfigurationImpl extends Configuration {
"-helpfile")); "-helpfile"));
return false; return false;
} }
File help = new File(os[1]); DocFile help = DocFile.createFileForInput(this, os[1]);
if (!help.exists()) { if (!help.exists()) {
reporter.printError(getText("doclet.File_not_found", os[1])); reporter.printError(getText("doclet.File_not_found", os[1]));
return false; return false;
......
...@@ -104,15 +104,12 @@ public class HtmlDoclet extends AbstractDoclet { ...@@ -104,15 +104,12 @@ public class HtmlDoclet extends AbstractDoclet {
return; return;
} }
boolean nodeprecated = configuration.nodeprecated; boolean nodeprecated = configuration.nodeprecated;
String configdestdir = configuration.destDirName; performCopy(configuration.helpfile);
String confighelpfile = configuration.helpfile; performCopy(configuration.stylesheetfile);
String configstylefile = configuration.stylesheetfile; copyResourceFile("background.gif");
performCopy(configdestdir, confighelpfile); copyResourceFile("tab.gif");
performCopy(configdestdir, configstylefile); copyResourceFile("titlebar.gif");
Util.copyResourceFile(configuration, "background.gif", false); copyResourceFile("titlebar_end.gif");
Util.copyResourceFile(configuration, "tab.gif", false);
Util.copyResourceFile(configuration, "titlebar.gif", false);
Util.copyResourceFile(configuration, "titlebar_end.gif", false);
// do early to reduce memory footprint // do early to reduce memory footprint
if (configuration.classuse) { if (configuration.classuse) {
ClassUseWriter.generate(configuration, classtree); ClassUseWriter.generate(configuration, classtree);
...@@ -149,8 +146,8 @@ public class HtmlDoclet extends AbstractDoclet { ...@@ -149,8 +146,8 @@ public class HtmlDoclet extends AbstractDoclet {
// If a stylesheet file is not specified, copy the default stylesheet // If a stylesheet file is not specified, copy the default stylesheet
// and replace newline with platform-specific newline. // and replace newline with platform-specific newline.
if (configuration.stylesheetfile.length() == 0) { if (configuration.stylesheetfile.length() == 0) {
Util.copyFile(configuration, "stylesheet.css", DocPaths.RESOURCES, DocFile f = DocFile.createFileForOutput(configuration, DocPaths.STYLESHEET);
DocPath.empty, false, true); f.copyResource(DocPaths.RESOURCES.resolve(DocPaths.STYLESHEET), false, true);
} }
} }
...@@ -251,29 +248,33 @@ public class HtmlDoclet extends AbstractDoclet { ...@@ -251,29 +248,33 @@ public class HtmlDoclet extends AbstractDoclet {
return (ConfigurationImpl.getInstance()).validOptions(options, reporter); return (ConfigurationImpl.getInstance()).validOptions(options, reporter);
} }
private void performCopy(String configdestdir, String filename) { /**
* Copy a file in the resources directory to the destination directory.
* @param resource The name of the resource file to copy
*/
private void copyResourceFile(String resource) {
DocPath p = DocPaths.RESOURCES.resolve(resource);
DocFile f = DocFile.createFileForOutput(configuration, p);
f.copyResource(p, false, false);
}
private void performCopy(String filename) {
if (filename.isEmpty())
return;
try { try {
String destdir = (configdestdir.length() > 0) ? DocFile fromfile = DocFile.createFileForInput(configuration, filename);
configdestdir + File.separatorChar: ""; DocPath path = DocPath.create(fromfile.getName());
if (filename.length() > 0) { DocFile toFile = DocFile.createFileForOutput(configuration, path);
File helpstylefile = new File(filename); if (toFile.isSameFile(fromfile))
String parent = helpstylefile.getParent(); return;
String helpstylefilename = (parent == null)?
filename: configuration.message.notice((SourcePosition) null,
filename.substring(parent.length() + 1); "doclet.Copying_File_0_To_File_1",
File desthelpfile = new File(destdir + helpstylefilename); fromfile.toString(), path.getPath());
if (!desthelpfile.getCanonicalPath().equals( toFile.copyFile(fromfile);
helpstylefile.getCanonicalPath())) {
configuration.message.
notice((SourcePosition) null,
"doclet.Copying_File_0_To_File_1",
helpstylefile.toString(), desthelpfile.toString());
Util.copyFile(desthelpfile, helpstylefile);
}
}
} catch (IOException exc) { } catch (IOException exc) {
configuration.message. configuration.message.error((SourcePosition) null,
error((SourcePosition) null,
"doclet.perform_copy_exception_encountered", "doclet.perform_copy_exception_encountered",
exc.toString()); exc.toString());
throw new DocletAbortException(); throw new DocletAbortException();
......
...@@ -723,7 +723,8 @@ public class HtmlDocletWriter extends HtmlDocWriter { ...@@ -723,7 +723,8 @@ public class HtmlDocletWriter extends HtmlDocWriter {
if (helpfile.isEmpty()) { if (helpfile.isEmpty()) {
helpfilenm = DocPaths.HELP_DOC; helpfilenm = DocPaths.HELP_DOC;
} else { } else {
helpfilenm = DocPath.create(new File(helpfile).getName()); DocFile file = DocFile.createFileForInput(configuration, helpfile);
helpfilenm = DocPath.create(file.getName());
} }
Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm), Content linkContent = getHyperLink(pathToRoot.resolve(helpfilenm),
helpLabel, "", ""); helpLabel, "", "");
...@@ -1671,12 +1672,13 @@ public class HtmlDocletWriter extends HtmlDocWriter { ...@@ -1671,12 +1672,13 @@ public class HtmlDocletWriter extends HtmlDocWriter {
* @return an HtmlTree for the lINK tag which provides the stylesheet location * @return an HtmlTree for the lINK tag which provides the stylesheet location
*/ */
public HtmlTree getStyleSheetProperties() { public HtmlTree getStyleSheetProperties() {
String filename = configuration.stylesheetfile; String stylesheetfile = configuration.stylesheetfile;
DocPath stylesheet; DocPath stylesheet;
if (filename.length() > 0) { if (stylesheetfile.isEmpty()) {
stylesheet = DocPath.create(new File(filename).getName());
} else {
stylesheet = DocPaths.STYLESHEET; stylesheet = DocPaths.STYLESHEET;
} else {
DocFile file = DocFile.createFileForInput(configuration, stylesheetfile);
stylesheet = DocPath.create(file.getName());
} }
HtmlTree link = HtmlTree.LINK("stylesheet", "text/css", HtmlTree link = HtmlTree.LINK("stylesheet", "text/css",
pathToRoot.resolve(stylesheet).getPath(), pathToRoot.resolve(stylesheet).getPath(),
......
...@@ -26,11 +26,13 @@ ...@@ -26,11 +26,13 @@
package com.sun.tools.doclets.formats.html; package com.sun.tools.doclets.formats.html;
import java.io.*; import java.io.*;
import javax.tools.FileObject; import javax.tools.FileObject;
import com.sun.javadoc.*; import com.sun.javadoc.*;
import com.sun.tools.doclets.formats.html.markup.*;
import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.*;
import com.sun.tools.doclets.internal.toolkit.util.*; import com.sun.tools.doclets.internal.toolkit.util.*;
import com.sun.tools.doclets.formats.html.markup.*;
/** /**
* Converts Java Source Code to HTML. * Converts Java Source Code to HTML.
...@@ -95,8 +97,7 @@ public class SourceToHTMLConverter { ...@@ -95,8 +97,7 @@ public class SourceToHTMLConverter {
// package files to HTML. // package files to HTML.
if (!(configuration.nodeprecated && if (!(configuration.nodeprecated &&
(Util.isDeprecated(cds[i]) || Util.isDeprecated(cds[i].containingPackage())))) (Util.isDeprecated(cds[i]) || Util.isDeprecated(cds[i].containingPackage()))))
convertClass(configuration, cds[i], convertClass(configuration, cds[i], outputdir);
getPackageOutputDir(outputdir, cds[i].containingPackage()));
} }
} }
...@@ -109,10 +110,9 @@ public class SourceToHTMLConverter { ...@@ -109,10 +110,9 @@ public class SourceToHTMLConverter {
*/ */
public static void convertPackage(ConfigurationImpl configuration, PackageDoc pd, public static void convertPackage(ConfigurationImpl configuration, PackageDoc pd,
DocPath outputdir) { DocPath outputdir) {
if (pd == null || outputdir == null) { if (pd == null) {
return; return;
} }
DocPath classOutputdir = getPackageOutputDir(outputdir, pd);
ClassDoc[] cds = pd.allClasses(); ClassDoc[] cds = pd.allClasses();
for (int i = 0; i < cds.length; i++) { for (int i = 0; i < cds.length; i++) {
// If -nodeprecated option is set and the class is marked as deprecated, // If -nodeprecated option is set and the class is marked as deprecated,
...@@ -120,21 +120,10 @@ public class SourceToHTMLConverter { ...@@ -120,21 +120,10 @@ public class SourceToHTMLConverter {
// containing package deprecation since it is already check in // containing package deprecation since it is already check in
// the calling method above. // the calling method above.
if (!(configuration.nodeprecated && Util.isDeprecated(cds[i]))) if (!(configuration.nodeprecated && Util.isDeprecated(cds[i])))
convertClass(configuration, cds[i], classOutputdir); convertClass(configuration, cds[i], outputdir);
} }
} }
/**
* Return the directory write output to for the given package.
*
* @param outputDir the directory to output to.
* @param pd the Package to generate output for.
* @return the package output directory as a String.
*/
private static DocPath getPackageOutputDir(DocPath outputDir, PackageDoc pd) {
return outputDir.resolve(DocPath.forPackage(pd));
}
/** /**
* Convert the given Class to an HTML. * Convert the given Class to an HTML.
* *
...@@ -144,7 +133,7 @@ public class SourceToHTMLConverter { ...@@ -144,7 +133,7 @@ public class SourceToHTMLConverter {
*/ */
public static void convertClass(ConfigurationImpl configuration, ClassDoc cd, public static void convertClass(ConfigurationImpl configuration, ClassDoc cd,
DocPath outputdir) { DocPath outputdir) {
if (cd == null || outputdir == null) { if (cd == null) {
return; return;
} }
try { try {
...@@ -184,8 +173,8 @@ public class SourceToHTMLConverter { ...@@ -184,8 +173,8 @@ public class SourceToHTMLConverter {
addBlankLines(pre); addBlankLines(pre);
Content div = HtmlTree.DIV(HtmlStyle.sourceContainer, pre); Content div = HtmlTree.DIV(HtmlStyle.sourceContainer, pre);
body.addContent(div); body.addContent(div);
writeToFile(body, outputdir, cd.name(), configuration); writeToFile(body, outputdir.resolve(DocPath.forClass(cd)), configuration);
} catch (Exception e){ } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
...@@ -194,12 +183,11 @@ public class SourceToHTMLConverter { ...@@ -194,12 +183,11 @@ public class SourceToHTMLConverter {
* Write the output to the file. * Write the output to the file.
* *
* @param body the documentation content to be written to the file. * @param body the documentation content to be written to the file.
* @param outputDir the directory to output to. * @param path the path for the file.
* @param className the name of the class that I am converting to HTML.
* @param configuration the Doclet configuration to pass notices to. * @param configuration the Doclet configuration to pass notices to.
*/ */
private static void writeToFile(Content body, DocPath outputDir, private static void writeToFile(Content body, DocPath path,
String className, ConfigurationImpl configuration) throws IOException { ConfigurationImpl configuration) throws IOException {
Content htmlDocType = DocType.Transitional(); Content htmlDocType = DocType.Transitional();
Content head = new HtmlTree(HtmlTag.HEAD); Content head = new HtmlTree(HtmlTag.HEAD);
head.addContent(HtmlTree.TITLE(new StringContent( head.addContent(HtmlTree.TITLE(new StringContent(
...@@ -208,15 +196,15 @@ public class SourceToHTMLConverter { ...@@ -208,15 +196,15 @@ public class SourceToHTMLConverter {
Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(),
head, body); head, body);
Content htmlDocument = new HtmlDocument(htmlDocType, htmlTree); Content htmlDocument = new HtmlDocument(htmlDocType, htmlTree);
File dir = outputDir.resolveAgainst(configuration.destDirName); configuration.message.notice("doclet.Generating_0", path.getPath());
dir.mkdirs(); DocFile df = DocFile.createFileForOutput(configuration, path);
File newFile = new File(dir, className + ".html"); Writer w = df.openWriter();
configuration.message.notice("doclet.Generating_0", newFile.getPath()); try {
FileOutputStream fout = new FileOutputStream(newFile); htmlDocument.write(w, true);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fout)); } finally {
bw.write(htmlDocument.toString()); w.close();
bw.close(); }
fout.close();
} }
/** /**
...@@ -229,7 +217,8 @@ public class SourceToHTMLConverter { ...@@ -229,7 +217,8 @@ public class SourceToHTMLConverter {
String filename = configuration.stylesheetfile; String filename = configuration.stylesheetfile;
DocPath stylesheet; DocPath stylesheet;
if (filename.length() > 0) { if (filename.length() > 0) {
stylesheet = DocPath.create(new File(filename).getName()); DocFile file = DocFile.createFileForInput(configuration, filename);
stylesheet = DocPath.create(file.getName());
} else { } else {
stylesheet = DocPaths.STYLESHEET; stylesheet = DocPaths.STYLESHEET;
} }
......
...@@ -156,7 +156,7 @@ public class HtmlWriter { ...@@ -156,7 +156,7 @@ public class HtmlWriter {
*/ */
public HtmlWriter(Configuration configuration, DocPath path) public HtmlWriter(Configuration configuration, DocPath path)
throws IOException, UnsupportedEncodingException { throws IOException, UnsupportedEncodingException {
writer = Util.genWriter(configuration, path); writer = DocFile.createFileForOutput(configuration, path).openWriter();
this.configuration = configuration; this.configuration = configuration;
this.memberDetailsListPrinted = false; this.memberDetailsListPrinted = false;
packageTableHeader = new String[] { packageTableHeader = new String[] {
......
...@@ -106,7 +106,7 @@ public abstract class AbstractDoclet { ...@@ -106,7 +106,7 @@ public abstract class AbstractDoclet {
/** /**
* Start the generation of files. Call generate methods in the individual * Start the generation of files. Call generate methods in the individual
* writers, which will in turn genrate the documentation files. Call the * writers, which will in turn generate the documentation files. Call the
* TreeWriter generation first to ensure the Class Hierarchy is built * TreeWriter generation first to ensure the Class Hierarchy is built
* first and then can be used in the later generation. * first and then can be used in the later generation.
* *
...@@ -124,17 +124,7 @@ public abstract class AbstractDoclet { ...@@ -124,17 +124,7 @@ public abstract class AbstractDoclet {
ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated); ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
generateClassFiles(root, classtree); generateClassFiles(root, classtree);
if (configuration.sourcepath != null && configuration.sourcepath.length() > 0) { Util.copyDocFiles(configuration, DocPaths.DOC_FILES);
StringTokenizer pathTokens = new StringTokenizer(configuration.sourcepath,
String.valueOf(File.pathSeparatorChar));
boolean first = true;
while(pathTokens.hasMoreTokens()){
Util.copyDocFiles(configuration,
new File(pathTokens.nextToken()),
DocPaths.DOC_FILES, first);
first = false;
}
}
PackageListWriter.generate(configuration); PackageListWriter.generate(configuration);
generatePackageFiles(classtree); generatePackageFiles(classtree);
......
...@@ -456,7 +456,7 @@ public abstract class Configuration { ...@@ -456,7 +456,7 @@ public abstract class Configuration {
tagletManager.addCustomTag(args[1], tagletpath); tagletManager.addCustomTag(args[1], tagletpath);
continue; continue;
} }
String[] tokens = Util.tokenize(args[1], String[] tokens = tokenize(args[1],
TagletManager.SIMPLE_TAGLET_OPT_SEPERATOR, 3); TagletManager.SIMPLE_TAGLET_OPT_SEPERATOR, 3);
if (tokens.length == 1) { if (tokens.length == 1) {
String tagName = args[1]; String tagName = args[1];
...@@ -480,6 +480,47 @@ public abstract class Configuration { ...@@ -480,6 +480,47 @@ public abstract class Configuration {
} }
} }
/**
* Given a string, return an array of tokens. The separator can be escaped
* with the '\' character. The '\' character may also be escaped by the
* '\' character.
*
* @param s the string to tokenize.
* @param separator the separator char.
* @param maxTokens the maximum number of tokens returned. If the
* max is reached, the remaining part of s is appended
* to the end of the last token.
*
* @return an array of tokens.
*/
private String[] tokenize(String s, char separator, int maxTokens) {
List<String> tokens = new ArrayList<String>();
StringBuilder token = new StringBuilder ();
boolean prevIsEscapeChar = false;
for (int i = 0; i < s.length(); i += Character.charCount(i)) {
int currentChar = s.codePointAt(i);
if (prevIsEscapeChar) {
// Case 1: escaped character
token.appendCodePoint(currentChar);
prevIsEscapeChar = false;
} else if (currentChar == separator && tokens.size() < maxTokens-1) {
// Case 2: separator
tokens.add(token.toString());
token = new StringBuilder();
} else if (currentChar == '\\') {
// Case 3: escape character
prevIsEscapeChar = true;
} else {
// Case 4: regular character
token.appendCodePoint(currentChar);
}
}
if (token.length() > 0) {
tokens.add(token.toString());
}
return tokens.toArray(new String[] {});
}
private void addToSet(Set<String> s, String str){ private void addToSet(Set<String> s, String str){
StringTokenizer st = new StringTokenizer(str, ":"); StringTokenizer st = new StringTokenizer(str, ":");
String current; String current;
...@@ -532,12 +573,12 @@ public abstract class Configuration { ...@@ -532,12 +573,12 @@ public abstract class Configuration {
String opt = os[0].toLowerCase(); String opt = os[0].toLowerCase();
if (opt.equals("-d")) { if (opt.equals("-d")) {
String destdirname = addTrailingFileSep(os[1]); String destdirname = addTrailingFileSep(os[1]);
File destDir = new File(destdirname); DocFile destDir = DocFile.createFileForDirectory(this, destdirname);
if (!destDir.exists()) { if (!destDir.exists()) {
//Create the output directory (in case it doesn't exist yet) //Create the output directory (in case it doesn't exist yet)
reporter.printNotice(getText("doclet.dest_dir_create", reporter.printNotice(getText("doclet.dest_dir_create",
destdirname)); destdirname));
(new File(destdirname)).mkdirs(); destDir.mkdirs();
} else if (!destDir.isDirectory()) { } else if (!destDir.isDirectory()) {
reporter.printError(getText( reporter.printError(getText(
"doclet.destination_directory_not_directory_0", "doclet.destination_directory_not_directory_0",
...@@ -711,7 +752,7 @@ public abstract class Configuration { ...@@ -711,7 +752,7 @@ public abstract class Configuration {
public InputStream getBuilderXML() throws FileNotFoundException { public InputStream getBuilderXML() throws FileNotFoundException {
return builderXMLPath == null ? return builderXMLPath == null ?
Configuration.class.getResourceAsStream(DEFAULT_BUILDER_XML) : Configuration.class.getResourceAsStream(DEFAULT_BUILDER_XML) :
new FileInputStream(new File(builderXMLPath)); DocFile.createFileForInput(this, builderXMLPath).openInputStream();
} }
/** /**
......
...@@ -140,10 +140,7 @@ public class AnnotationTypeBuilder extends AbstractBuilder { ...@@ -140,10 +140,7 @@ public class AnnotationTypeBuilder extends AbstractBuilder {
//Only copy doc files dir if the containing package is not //Only copy doc files dir if the containing package is not
//documented AND if we have not documented a class from the same //documented AND if we have not documented a class from the same
//package already. Otherwise, we are making duplicate copies. //package already. Otherwise, we are making duplicate copies.
Util.copyDocFiles(configuration, Util.copyDocFiles(configuration, containingPackage);
new File(Util.getPackageSourcePath(configuration, containingPackage),
DocPath.forPackage(annotationTypeDoc).getPath()),
DocPaths.DOC_FILES, true);
containingPackagesSeen.add(containingPackage.name()); containingPackagesSeen.add(containingPackage.name());
} }
} }
......
...@@ -266,10 +266,7 @@ public class ClassBuilder extends AbstractBuilder { ...@@ -266,10 +266,7 @@ public class ClassBuilder extends AbstractBuilder {
//Only copy doc files dir if the containing package is not //Only copy doc files dir if the containing package is not
//documented AND if we have not documented a class from the same //documented AND if we have not documented a class from the same
//package already. Otherwise, we are making duplicate copies. //package already. Otherwise, we are making duplicate copies.
Util.copyDocFiles(configuration, Util.copyDocFiles(configuration, containingPackage);
new File(Util.getPackageSourcePath(configuration, containingPackage),
DocPath.forPackage(classDoc).getPath()),
DocPaths.DOC_FILES, true);
containingPackagesSeen.add(containingPackage.name()); containingPackagesSeen.add(containingPackage.name());
} }
} }
......
...@@ -119,11 +119,7 @@ public class PackageSummaryBuilder extends AbstractBuilder { ...@@ -119,11 +119,7 @@ public class PackageSummaryBuilder extends AbstractBuilder {
packageWriter.addPackageFooter(contentTree); packageWriter.addPackageFooter(contentTree);
packageWriter.printDocument(contentTree); packageWriter.printDocument(contentTree);
packageWriter.close(); packageWriter.close();
Util.copyDocFiles( Util.copyDocFiles(configuration, packageDoc);
configuration,
Util.getPackageSourcePath(configuration, packageDoc),
DocPath.forPackage(packageDoc).resolve(DocPaths.DOC_FILES),
true);
} }
/** /**
......
...@@ -161,7 +161,7 @@ public class TagletManager { ...@@ -161,7 +161,7 @@ public class TagletManager {
* @param message the message retriever to print warnings. * @param message the message retriever to print warnings.
*/ */
public TagletManager(boolean nosince, boolean showversion, public TagletManager(boolean nosince, boolean showversion,
boolean showauthor, MessageRetriever message){ boolean showauthor, MessageRetriever message) {
overridenStandardTags = new HashSet<String>(); overridenStandardTags = new HashSet<String>();
potentiallyConflictingTags = new HashSet<String>(); potentiallyConflictingTags = new HashSet<String>();
standardTags = new HashSet<String>(); standardTags = new HashSet<String>();
...@@ -253,47 +253,17 @@ public class TagletManager { ...@@ -253,47 +253,17 @@ public class TagletManager {
* @param path the search path string * @param path the search path string
* @return the resulting array of directory and JAR file URLs * @return the resulting array of directory and JAR file URLs
*/ */
private static URL[] pathToURLs(String path) { private URL[] pathToURLs(String path) {
StringTokenizer st = new StringTokenizer(path, File.pathSeparator); Set<URL> urls = new LinkedHashSet<URL>();
URL[] urls = new URL[st.countTokens()]; for (String s: path.split(File.pathSeparator)) {
int count = 0; if (s.isEmpty()) continue;
while (st.hasMoreTokens()) { try {
URL url = fileToURL(new File(st.nextToken())); urls.add(new File(s).getAbsoluteFile().toURI().toURL());
if (url != null) { } catch (MalformedURLException e) {
urls[count++] = url; message.error("doclet.MalformedURL", s);
} }
} }
urls = Arrays.copyOf(urls, count); return urls.toArray(new URL[urls.size()]);
return urls;
}
/**
* Returns the directory or JAR file URL corresponding to the specified
* local file name.
*
* @param file the File object
* @return the resulting directory or JAR file URL, or null if unknown
*/
private static URL fileToURL(File file) {
String name;
try {
name = file.getCanonicalPath();
} catch (IOException e) {
name = file.getAbsolutePath();
}
name = name.replace(File.separatorChar, '/');
if (!name.startsWith("/")) {
name = "/" + name;
}
// If the file does not exist, then assume that it's a directory
if (!file.isFile()) {
name = name + "/";
}
try {
return new URL("file", "", name);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("file");
}
} }
......
/*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.doclets.internal.toolkit.util;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.tools.JavaFileManager.Location;
import javax.tools.StandardLocation;
import com.sun.tools.doclets.internal.toolkit.Configuration;
/**
* Abstraction for handling files, which may be specified directly
* (e.g. via a path on the command line) or relative to a Location.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @since 8
*/
public class DocFile {
/**
* The doclet configuration.
* Provides access to options such as docencoding, output directory, etc.
*/
private final Configuration configuration;
/**
* The location for this file. Maybe null if the file was created without
* a location or path.
*/
private final Location location;
/**
* The path relative to the (output) location. Maybe null if the file was
* created without a location or path.
*/
private final DocPath path;
/**
* The file object itself.
* This is temporary, until we create different subtypes of DocFile.
*/
private final File file;
/** Create a DocFile for a directory. */
public static DocFile createFileForDirectory(Configuration configuration, String file) {
return new DocFile(configuration, new File(file));
}
/** Create a DocFile for a file that will be opened for reading. */
public static DocFile createFileForInput(Configuration configuration, String file) {
return new DocFile(configuration, new File(file));
}
/** Create a DocFile for a file that will be opened for writing. */
public static DocFile createFileForOutput(Configuration configuration, DocPath path) {
return new DocFile(configuration, StandardLocation.CLASS_OUTPUT, path);
}
/**
* List the directories and files found in subdirectories along the
* elements of the given location.
* @param configuration the doclet configuration
* @param location currently, only {@link StandardLocation#SOURCE_PATH} is supported.
* @param path the subdirectory of the directories of the location for which to
* list files
*/
public static Iterable<DocFile> list(Configuration configuration, Location location, DocPath path) {
if (location != StandardLocation.SOURCE_PATH)
throw new IllegalArgumentException();
Set<DocFile> files = new LinkedHashSet<DocFile>();
for (String s : configuration.sourcepath.split(File.pathSeparator)) {
if (s.isEmpty())
continue;
File f = new File(s);
if (f.isDirectory()) {
f = new File(f, path.getPath());
if (f.exists())
files.add(new DocFile(configuration, f));
}
}
return files;
}
/** Create a DocFile for a given file. */
private DocFile(Configuration configuration, File file) {
this.configuration = configuration;
this.location = null;
this.path = null;
this.file = file;
}
/** Create a DocFile for a given location and relative path. */
private DocFile(Configuration configuration, Location location, DocPath path) {
this.configuration = configuration;
this.location = location;
this.path = path;
this.file = path.resolveAgainst(configuration.destDirName);
}
/** Open an input stream for the file. */
public InputStream openInputStream() throws FileNotFoundException {
return new BufferedInputStream(new FileInputStream(file));
}
/**
* Open an output stream for the file.
* The file must have been created with a location of
* {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path.
*/
public OutputStream openOutputStream() throws IOException, UnsupportedEncodingException {
if (location != StandardLocation.CLASS_OUTPUT)
throw new IllegalStateException();
createDirectoryForFile(file);
return new BufferedOutputStream(new FileOutputStream(file));
}
/**
* Open an writer for the file, using the encoding (if any) given in the
* doclet configuration.
* The file must have been created with a location of
* {@link StandardLocation#CLASS_OUTPUT} and a corresponding relative path.
*/
public Writer openWriter() throws IOException, UnsupportedEncodingException {
if (location != StandardLocation.CLASS_OUTPUT)
throw new IllegalStateException();
createDirectoryForFile(file);
FileOutputStream fos = new FileOutputStream(file);
if (configuration.docencoding == null) {
return new BufferedWriter(new OutputStreamWriter(fos));
} else {
return new BufferedWriter(new OutputStreamWriter(fos, configuration.docencoding));
}
}
/**
* Copy the contents of another file directly to this file.
*/
public void copyFile(DocFile fromFile) throws IOException {
if (location != StandardLocation.CLASS_OUTPUT)
throw new IllegalStateException();
createDirectoryForFile(file);
InputStream input = fromFile.openInputStream();
OutputStream output = openOutputStream();
try {
byte[] bytearr = new byte[1024];
int len;
while ((len = input.read(bytearr)) != -1) {
output.write(bytearr, 0, len);
}
} catch (FileNotFoundException exc) {
} catch (SecurityException exc) {
} finally {
input.close();
output.close();
}
}
/**
* Copy the contents of a resource file to this file.
* @param resource the path of the resource, relative to the package of this class
* @param overwrite whether or not to overwrite the file if it already exists
* @param replaceNewLine if false, the file is copied as a binary file;
* if true, the file is written line by line, using the platform line
* separator
*/
public void copyResource(DocPath resource, boolean overwrite, boolean replaceNewLine) {
if (location != StandardLocation.CLASS_OUTPUT)
throw new IllegalStateException();
if (file.exists() && !overwrite)
return;
createDirectoryForFile(file);
try {
InputStream in = Configuration.class.getResourceAsStream(resource.getPath());
if (in == null)
return;
OutputStream out = new FileOutputStream(file);
try {
if (!replaceNewLine) {
byte[] buf = new byte[2048];
int n;
while((n = in.read(buf))>0) out.write(buf,0,n);
} else {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer;
if (configuration.docencoding == null) {
writer = new BufferedWriter(new OutputStreamWriter(out));
} else {
writer = new BufferedWriter(new OutputStreamWriter(out,
configuration.docencoding));
}
try {
String line;
while ((line = reader.readLine()) != null) {
writer.write(line);
writer.write(DocletConstants.NL);
}
} finally {
reader.close();
writer.close();
}
}
} finally {
in.close();
out.close();
}
} catch (IOException e) {
e.printStackTrace(System.err);
throw new DocletAbortException();
}
}
/** Return true if the file can be read. */
public boolean canRead() {
return file.canRead();
}
/** Return true if the file can be written. */
public boolean canWrite() {
return file.canRead();
}
/** Return true if the file exists. */
public boolean exists() {
return file.exists();
}
/** Return the base name (last component) of the file name. */
public String getName() {
return file.getName();
}
/** Return the file system path for this file. */
public String getPath() {
return file.getPath();
}
/** Return true is file has an absolute path name. */
boolean isAbsolute() {
return file.isAbsolute();
}
/** Return true is file identifies a directory. */
public boolean isDirectory() {
return file.isDirectory();
}
/** Return true is file identifies a file. */
public boolean isFile() {
return file.isFile();
}
/** Return true if this file is the same as another. */
public boolean isSameFile(DocFile other) {
try {
return file.exists()
&& file.getCanonicalFile().equals(other.file.getCanonicalFile());
} catch (IOException e) {
return false;
}
}
/** If the file is a directory, list its contents. */
public Iterable<DocFile> list() {
List<DocFile> files = new ArrayList<DocFile>();
for (File f: file.listFiles()) {
files.add(new DocFile(configuration, f));
}
return files;
}
/** Create the file as a directory, including any parent directories. */
public boolean mkdirs() {
return file.mkdirs();
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(DocPath p) {
return resolve(p.getPath());
}
/**
* Derive a new file by resolving a relative path against this file.
* The new file will inherit the configuration and location of this file
* If this file has a path set, the new file will have a corresponding
* new path.
*/
public DocFile resolve(String p) {
if (location == null && path == null) {
return new DocFile(configuration, new File(file, p));
} else {
return new DocFile(configuration, location, path.resolve(p));
}
}
/**
* Resolve a relative file against the given output location.
* @param locn Currently, only SOURCE_OUTPUT is supported.
*/
public DocFile resolveAgainst(StandardLocation locn) {
if (locn != StandardLocation.CLASS_OUTPUT)
throw new IllegalArgumentException();
return new DocFile(configuration,
new File(configuration.destDirName, file.getPath()));
}
/**
* Given a path string create all the directories in the path. For example,
* if the path string is "java/applet", the method will create directory
* "java" and then "java/applet" if they don't exist. The file separator
* string "/" is platform dependent system property.
*
* @param path Directory path string.
*/
private void createDirectoryForFile(File file) {
File dir = file.getParentFile();
if (dir == null || dir.exists() || dir.mkdirs())
return;
configuration.message.error(
"doclet.Unable_to_create_directory_0", dir.getPath());
throw new DocletAbortException();
}
/** Return a string to identify the contents of this object,
* for debugging purposes.
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DocFile[");
if (location != null)
sb.append("locn:").append(location).append(",");
if (path != null)
sb.append("path:").append(path.getPath()).append(",");
sb.append("file:").append(file);
sb.append("]");
return sb.toString();
}
}
...@@ -28,6 +28,11 @@ package com.sun.tools.doclets.internal.toolkit.util; ...@@ -28,6 +28,11 @@ package com.sun.tools.doclets.internal.toolkit.util;
/** /**
* Standard DocPath objects. * Standard DocPath objects.
* *
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*
* @since 8 * @since 8
*/ */
public class DocPaths { public class DocPaths {
......
...@@ -30,6 +30,8 @@ import java.net.*; ...@@ -30,6 +30,8 @@ import java.net.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import javax.tools.StandardLocation;
import com.sun.javadoc.*; import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.*;
...@@ -177,7 +179,7 @@ public class Extern { ...@@ -177,7 +179,7 @@ public class Extern {
if (isUrl(pkglisturl)) { if (isUrl(pkglisturl)) {
readPackageListFromURL(url, toURL(pkglisturl)); readPackageListFromURL(url, toURL(pkglisturl));
} else { } else {
readPackageListFromFile(url, new File(pkglisturl)); readPackageListFromFile(url, DocFile.createFileForInput(configuration, pkglisturl));
} }
return true; return true;
} catch (Fault f) { } catch (Fault f) {
...@@ -247,16 +249,18 @@ public class Extern { ...@@ -247,16 +249,18 @@ public class Extern {
* @param path URL or directory path to the packages. * @param path URL or directory path to the packages.
* @param pkgListPath Path to the local "package-list" file. * @param pkgListPath Path to the local "package-list" file.
*/ */
private void readPackageListFromFile(String path, File pkgListPath) private void readPackageListFromFile(String path, DocFile pkgListPath)
throws Fault { throws Fault {
File file = new File(pkgListPath, "package-list"); DocFile file = pkgListPath.resolve(DocPaths.PACKAGE_LIST);
if (! (file.isAbsolute() || linkoffline)){ if (! (file.isAbsolute() || linkoffline)){
file = new File(configuration.destDirName, file.getPath()); file = file.resolveAgainst(StandardLocation.CLASS_OUTPUT);
} }
try { try {
if (file.exists() && file.canRead()) { if (file.exists() && file.canRead()) {
readPackageList(new FileInputStream(file), path, boolean pathIsRelative =
! ((new File(path)).isAbsolute() || isUrl(path))); !DocFile.createFileForInput(configuration, path).isAbsolute()
&& !isUrl(path);
readPackageList(file.openInputStream(), path, pathIsRelative);
} else { } else {
throw new Fault(configuration.getText("doclet.File_error", file.getPath()), null); throw new Fault(configuration.getText("doclet.File_error", file.getPath()), null);
} }
......
...@@ -52,7 +52,7 @@ public class PackageListWriter extends PrintWriter { ...@@ -52,7 +52,7 @@ public class PackageListWriter extends PrintWriter {
* @param configuration the current configuration of the doclet. * @param configuration the current configuration of the doclet.
*/ */
public PackageListWriter(Configuration configuration) throws IOException { public PackageListWriter(Configuration configuration) throws IOException {
super(Util.genWriter(configuration, DocPaths.PACKAGE_LIST)); super(DocFile.createFileForOutput(configuration, DocPaths.PACKAGE_LIST).openWriter());
this.configuration = configuration; this.configuration = configuration;
} }
......
/*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.doclets.internal.toolkit.util;
import java.io.File;
/**
* This class is used to represent a source path which can contain only
* directories no zip files. If a zip file is specified in the command line it
* will not get reflected in the SourcePath.
*
* This code is not part of an API.
* It is implementation that is subject to change.
* Do not use it as an API
*
* @author Atul M Dambalkar
*/
public class SourcePath {
private final char dirSeparator = File.pathSeparatorChar;
/**
* The original class path string
*/
private String pathstr;
/**
* List of source path entries. Each entry is a directory.
*/
private File[] sourcePath;
/**
* Build a source path from the specified path string on the command line.
*/
public SourcePath(String pathstr) {
init(pathstr);
}
/**
* Build a default source path from the path strings specified by
* the properties env.class.path.
*/
public SourcePath() {
init(System.getProperty("env.class.path"));
}
/**
* Initialize the SourcePath File array, which will contain only the
* directory names from the given path string.
*
* @param pathstr Path String.
*/
private void init(String pathstr) {
if (pathstr == null || pathstr.length() == 0) {
pathstr = ".";
}
int noOfFileSep = 0;
int index = 0;
this.pathstr = pathstr; // Save original class path string
// Count the number of path separators
while ((index = pathstr.indexOf(dirSeparator, index)) != -1) {
noOfFileSep++;
index++;
}
// Build the source path
File[] tempPath = new File[noOfFileSep + 1];
int tempPathIndex = 0;
int len = pathstr.length();
int sepPos = 0;
for (index = 0; index < len; index = sepPos + 1) {
sepPos = pathstr.indexOf(dirSeparator, index);
if (sepPos < 0) {
sepPos = len;
}
File file = new File(pathstr.substring(index, sepPos));
if (file.isDirectory()) {
tempPath[tempPathIndex++] = file;
} // if it is really a file, ignore it.
}
sourcePath = new File[tempPathIndex];
System.arraycopy((Object)tempPath, 0, (Object)sourcePath,
0, tempPathIndex);
}
/**
* Find the specified directory in the source path.
*
* @param p Name of the directory to be searched for in the source path.
* @return File Return the directory if found else return null.
*/
public File getDirectory(DocPath p) {
for (int i = 0; i < sourcePath.length; i++) {
File directoryNeeded = new File(sourcePath[i], p.getPath());
if (directoryNeeded.isDirectory()) {
return directoryNeeded;
}
}
return null;
}
/**
* Return original source path string.
*/
public String toString() {
return pathstr;
}
}
...@@ -30,6 +30,7 @@ import java.util.*; ...@@ -30,6 +30,7 @@ import java.util.*;
import com.sun.javadoc.*; import com.sun.javadoc.*;
import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.*;
import javax.tools.StandardLocation;
/** /**
* Utilities Class for Doclets. * Utilities Class for Doclets.
...@@ -191,32 +192,6 @@ public class Util { ...@@ -191,32 +192,6 @@ public class Util {
} }
} }
/**
* Copy source file to destination file.
*
* @throws SecurityException
* @throws IOException
*/
public static void copyFile(File destfile, File srcfile)
throws IOException {
byte[] bytearr = new byte[512];
int len = 0;
FileInputStream input = new FileInputStream(srcfile);
File destDir = destfile.getParentFile();
destDir.mkdirs();
FileOutputStream output = new FileOutputStream(destfile);
try {
while ((len = input.read(bytearr)) != -1) {
output.write(bytearr, 0, len);
}
} catch (FileNotFoundException exc) {
} catch (SecurityException exc) {
} finally {
input.close();
output.close();
}
}
/** /**
* Copy the given directory contents from the source package directory * Copy the given directory contents from the source package directory
* to the generated documentation directory. For example for a package * to the generated documentation directory. For example for a package
...@@ -230,210 +205,53 @@ public class Util { ...@@ -230,210 +205,53 @@ public class Util {
* @param dir The original directory name to copy from. * @param dir The original directory name to copy from.
* @param overwrite Overwrite files if true. * @param overwrite Overwrite files if true.
*/ */
public static void copyDocFiles(Configuration configuration, public static void copyDocFiles(Configuration configuration, PackageDoc pd) {
File path, DocPath dir, boolean overwrite) { copyDocFiles(configuration, DocPath.forPackage(pd).resolve(DocPaths.DOC_FILES));
if (checkCopyDocFilesErrors(configuration, path, dir)) {
return;
}
File srcdir = new File(path, dir.getPath());
File destdir = new File(configuration.docFileDestDirName, dir.getPath());
try {
createDirectory(configuration, destdir);
String[] files = srcdir.list();
for (int i = 0; i < files.length; i++) {
File srcfile = new File(srcdir, files[i]);
File destfile = new File(destdir, files[i]);
if (srcfile.isFile()) {
if (destfile.exists() && ! overwrite) {
configuration.message.warning((SourcePosition) null,
"doclet.Copy_Overwrite_warning",
srcfile.toString(), destdir.toString());
} else {
configuration.message.notice(
"doclet.Copying_File_0_To_Dir_1",
srcfile.toString(), destdir.toString());
Util.copyFile(destfile, srcfile);
}
} else if (srcfile.isDirectory()) {
if (configuration.copydocfilesubdirs
&& ! configuration.shouldExcludeDocFileDir(
srcfile.getName())){
copyDocFiles(configuration, path, dir.resolve(files[i]),
overwrite);
}
}
}
} catch (SecurityException exc) {
throw new DocletAbortException();
} catch (IOException exc) {
throw new DocletAbortException();
}
}
/**
* Given the parameters for copying doc-files, check for errors.
*
* @param configuration The configuration of the current doclet.
* @param path The relative path to the directory to be copied.
* @param dirName The original directory name to copy from.
*/
private static boolean checkCopyDocFilesErrors (Configuration configuration,
File path, DocPath dirName) {
if ((configuration.sourcepath == null || configuration.sourcepath.length() == 0) &&
(configuration.destDirName == null || configuration.destDirName.length() == 0)) {
//The destination path and source path are definitely equal.
return true;
}
File sourcePath, destPath = new File(configuration.destDirName);
StringTokenizer pathTokens = new StringTokenizer(
configuration.sourcepath == null ? "" : configuration.sourcepath,
File.pathSeparator);
//Check if the destination path is equal to the source path. If yes,
//do not copy doc-file directories.
while(pathTokens.hasMoreTokens()){
sourcePath = new File(pathTokens.nextToken());
if(destPath.equals(sourcePath)){
return true;
}
}
//Make sure the doc-file being copied exists.
File srcdir = new File(path, dirName.getPath());
if (! srcdir.exists()) {
return true;
}
return false;
}
/**
* Copy a file in the resources directory to the destination
* directory (if it is not there already). If
* <code>overwrite</code> is true and the destination file
* already exists, overwrite it.
*
* @param configuration Holds the destination directory and error message
* @param resourcefile The name of the resource file to copy
* @param overwrite A flag to indicate whether the file in the
* destination directory will be overwritten if
* it already exists.
*/
public static void copyResourceFile(Configuration configuration,
String resourcefile, boolean overwrite) {
copyFile(configuration, resourcefile, DocPaths.RESOURCES, DocPaths.RESOURCES,
overwrite, false);
} }
/** public static void copyDocFiles(Configuration configuration, DocPath dir) {
* Copy a file from a source directory to a destination directory
* (if it is not there already). If <code>overwrite</code> is true and
* the destination file already exists, overwrite it.
*
* @param configuration Holds the error message
* @param file The name of the file to copy
* @param source The source directory
* @param destination The destination directory where the file needs to be copied
* @param overwrite A flag to indicate whether the file in the
* destination directory will be overwritten if
* it already exists.
* @param replaceNewLine true if the newline needs to be replaced with platform-
* specific newline.
*/
public static void copyFile(Configuration configuration, String file, DocPath source,
DocPath destination, boolean overwrite, boolean replaceNewLine) {
copyFile(configuration, file, source.getPath(), destination.getPath(),
overwrite, replaceNewLine);
}
public static void copyFile(Configuration configuration, String file, String source,
String destination, boolean overwrite, boolean replaceNewLine) {
File destdir = configuration.destDirName.isEmpty() ?
(destination.isEmpty() ? null : new File(destination)) :
new File(configuration.destDirName, destination);
File destfile = (destdir == null) ? new File(file) : new File(destdir, file);
createDirectory(configuration, destfile.getParentFile());
if (destfile.exists() && (! overwrite)) return;
try { try {
InputStream in = Configuration.class.getResourceAsStream( boolean first = true;
source + '/' + file); for (DocFile f : DocFile.list(configuration, StandardLocation.SOURCE_PATH, dir)) {
if (in == null) return; if (!f.isDirectory()) {
OutputStream out = new FileOutputStream(destfile); continue;
try { }
if (!replaceNewLine) { DocFile srcdir = f;
byte[] buf = new byte[2048]; DocFile destdir = DocFile.createFileForOutput(configuration, dir);
int n; if (srcdir.isSameFile(destdir)) {
while((n = in.read(buf))>0) out.write(buf,0,n); continue;
} else { }
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
BufferedWriter writer; for (DocFile srcfile: srcdir.list()) {
if (configuration.docencoding == null) { DocFile destfile = destdir.resolve(srcfile.getName());
writer = new BufferedWriter(new OutputStreamWriter(out)); if (srcfile.isFile()) {
} else { if (destfile.exists() && !first) {
writer = new BufferedWriter(new OutputStreamWriter(out, configuration.message.warning((SourcePosition) null,
configuration.docencoding)); "doclet.Copy_Overwrite_warning",
} srcfile.getPath(), destdir.getPath());
try { } else {
String line; configuration.message.notice(
while ((line = reader.readLine()) != null) { "doclet.Copying_File_0_To_Dir_1",
writer.write(line); srcfile.getPath(), destdir.getPath());
writer.write(DocletConstants.NL); destfile.copyFile(srcfile);
}
} else if (srcfile.isDirectory()) {
if (configuration.copydocfilesubdirs
&& !configuration.shouldExcludeDocFileDir(srcfile.getName())) {
copyDocFiles(configuration, dir.resolve(srcfile.getName()));
} }
} finally {
reader.close();
writer.close();
} }
} }
} finally {
in.close();
out.close();
}
} catch (IOException ie) {
ie.printStackTrace(System.err);
throw new DocletAbortException();
}
}
/** first = false;
* Given a path string create all the directories in the path. For example,
* if the path string is "java/applet", the method will create directory
* "java" and then "java/applet" if they don't exist. The file separator
* string "/" is platform dependent system property.
*
* @param dir Directory path string.
*/
public static void createDirectory(Configuration configuration, File dir) {
if (dir == null) {
return;
}
if (dir.exists()) {
return;
} else {
if (dir.mkdirs()) {
return;
} else {
configuration.message.error(
"doclet.Unable_to_create_directory_0", dir.getPath());
throw new DocletAbortException();
} }
} catch (SecurityException exc) {
throw new DocletAbortException();
} catch (IOException exc) {
throw new DocletAbortException();
} }
} }
/**
* Given a PackageDoc, return the source path for that package.
* @param configuration The Configuration for the current Doclet.
* @param pkgDoc The package to search the path for.
* @return A string representing the path to the given package.
*/
public static File getPackageSourcePath(Configuration configuration,
PackageDoc pkgDoc) {
DocPath pkgPath = DocPath.forPackage(pkgDoc);
File pkgDir = new SourcePath(configuration.sourcepath).getDirectory(pkgPath);
if (pkgDir == null)
return null;
//Make sure that both paths are using the same separators.
String completePath = Util.replaceText(pkgDir.getPath(), File.separator, "/");
String pathForPkg = completePath.substring(0, completePath.lastIndexOf(pkgPath.getPath()));
return new File(pathForPkg);
}
/** /**
* We want the list of types in alphabetical order. However, types are not * We want the list of types in alphabetical order. However, types are not
* comparable. We need a comparator for now. * comparable. We need a comparator for now.
...@@ -638,31 +456,6 @@ public class Util { ...@@ -638,31 +456,6 @@ public class Util {
return rawString.trim(); return rawString.trim();
} }
/**
* Create the directory path for the file to be generated, construct
* FileOutputStream and OutputStreamWriter depending upon docencoding.
*
* @param path The directory path to be created for this file.
* @exception IOException Exception raised by the FileWriter is passed on
* to next level.
* @exception UnsupportedEncodingException Exception raised by the
* OutputStreamWriter is passed on to next level.
* @return Writer Writer for the file getting generated.
* @see java.io.FileOutputStream
* @see java.io.OutputStreamWriter
*/
public static Writer genWriter(Configuration configuration, DocPath path)
throws IOException, UnsupportedEncodingException {
File file = path.resolveAgainst(configuration.destDirName);
createDirectory(configuration, file.getParentFile());
FileOutputStream fos = new FileOutputStream(file);
if (configuration.docencoding == null) {
return new BufferedWriter(new OutputStreamWriter(fos));
} else {
return new BufferedWriter(new OutputStreamWriter(fos, configuration.docencoding));
}
}
/** /**
* Given an annotation, return true if it should be documented and false * Given an annotation, return true if it should be documented and false
* otherwise. * otherwise.
...@@ -682,47 +475,6 @@ public class Util { ...@@ -682,47 +475,6 @@ public class Util {
return false; return false;
} }
/**
* Given a string, return an array of tokens. The separator can be escaped
* with the '\' character. The '\' character may also be escaped by the
* '\' character.
*
* @param s the string to tokenize.
* @param separator the separator char.
* @param maxTokens the maxmimum number of tokens returned. If the
* max is reached, the remaining part of s is appended
* to the end of the last token.
*
* @return an array of tokens.
*/
public static String[] tokenize(String s, char separator, int maxTokens) {
List<String> tokens = new ArrayList<String>();
StringBuilder token = new StringBuilder ();
boolean prevIsEscapeChar = false;
for (int i = 0; i < s.length(); i += Character.charCount(i)) {
int currentChar = s.codePointAt(i);
if (prevIsEscapeChar) {
// Case 1: escaped character
token.appendCodePoint(currentChar);
prevIsEscapeChar = false;
} else if (currentChar == separator && tokens.size() < maxTokens-1) {
// Case 2: separator
tokens.add(token.toString());
token = new StringBuilder();
} else if (currentChar == '\\') {
// Case 3: escape character
prevIsEscapeChar = true;
} else {
// Case 4: regular character
token.appendCodePoint(currentChar);
}
}
if (token.length() > 0) {
tokens.add(token.toString());
}
return tokens.toArray(new String[] {});
}
/** /**
* Return true if this class is linkable and false if we can't link to the * Return true if this class is linkable and false if we can't link to the
* desired class. * desired class.
......
/* /*
* Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -77,17 +77,19 @@ public class TestDocFileDir extends JavadocTester { ...@@ -77,17 +77,19 @@ public class TestDocFileDir extends JavadocTester {
//Output dir = Input Dir //Output dir = Input Dir
private static final String[] ARGS1 = private static final String[] ARGS1 =
new String[] { new String[] {
"-d", BUG_ID + "-1", "-sourcepath", "-d", BUG_ID + "-1",
"blah" + String.valueOf(File.pathSeparatorChar) + "-sourcepath",
BUG_ID + "-1" + String.valueOf(File.pathSeparatorChar) + "blah" + File.pathSeparator + BUG_ID + "-1" + File.pathSeparator + "blah",
"blah", "pkg"}; "pkg"};
//Exercising -docfilessubdirs and -excludedocfilessubdir //Exercising -docfilessubdirs and -excludedocfilessubdir
private static final String[] ARGS2 = private static final String[] ARGS2 =
new String[] { new String[] {
"-d", BUG_ID + "-2", "-sourcepath", SRC_DIR, "-d", BUG_ID + "-2",
"-docfilessubdirs", "-excludedocfilessubdir", "-sourcepath", SRC_DIR,
"subdir-excluded1:subdir-excluded2", "pkg"}; "-docfilessubdirs",
"-excludedocfilessubdir", "subdir-excluded1:subdir-excluded2",
"pkg"};
//Output dir = "", Input dir = "" //Output dir = "", Input dir = ""
private static final String[] ARGS0 = private static final String[] ARGS0 =
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册