001: /*
002: * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: package com.sun.tools.doclets.formats.html;
026:
027: import com.sun.tools.doclets.internal.toolkit.*;
028: import com.sun.tools.doclets.internal.toolkit.builders.*;
029: import com.sun.tools.doclets.internal.toolkit.util.*;
030:
031: import com.sun.javadoc.*;
032: import java.util.*;
033: import java.io.*;
034:
035: /**
036: * The class with "start" method, calls individual Writers.
037: *
038: * @author Atul M Dambalkar
039: * @author Robert Field
040: * @author Jamie Ho
041: *
042: */
043: public class HtmlDoclet extends AbstractDoclet {
044:
045: /**
046: * The global configuration information for this run.
047: */
048: public ConfigurationImpl configuration = (ConfigurationImpl) configuration();
049:
050: /**
051: * The "start" method as required by Javadoc.
052: *
053: * @param root the root of the documentation tree.
054: * @see com.sun.javadoc.RootDoc
055: * @return true if the doclet ran without encountering any errors.
056: */
057: public static boolean start(RootDoc root) {
058: HtmlDoclet doclet = new HtmlDoclet();
059: return doclet.start(doclet, root);
060: }
061:
062: /**
063: * Create the configuration instance.
064: * Override this method to use a different
065: * configuration.
066: */
067: public Configuration configuration() {
068: return ConfigurationImpl.getInstance();
069: }
070:
071: /**
072: * Start the generation of files. Call generate methods in the individual
073: * writers, which will in turn genrate the documentation files. Call the
074: * TreeWriter generation first to ensure the Class Hierarchy is built
075: * first and then can be used in the later generation.
076: *
077: * For new format.
078: *
079: * @see com.sun.javadoc.RootDoc
080: */
081: protected void generateOtherFiles(RootDoc root, ClassTree classtree)
082: throws Exception {
083: super .generateOtherFiles(root, classtree);
084: if (configuration.linksource) {
085: if (configuration.destDirName.length() > 0) {
086: SourceToHTMLConverter
087: .convertRoot(
088: configuration,
089: root,
090: configuration.destDirName
091: + File.separator
092: + DocletConstants.SOURCE_OUTPUT_DIR_NAME);
093: } else {
094: SourceToHTMLConverter.convertRoot(configuration, root,
095: DocletConstants.SOURCE_OUTPUT_DIR_NAME);
096: }
097: }
098:
099: if (configuration.topFile.length() == 0) {
100: configuration.standardmessage
101: .error("doclet.No_Non_Deprecated_Classes_To_Document");
102: return;
103: }
104: boolean nodeprecated = configuration.nodeprecated;
105: String configdestdir = configuration.destDirName;
106: String confighelpfile = configuration.helpfile;
107: String configstylefile = configuration.stylesheetfile;
108: performCopy(configdestdir, confighelpfile);
109: performCopy(configdestdir, configstylefile);
110: Util.copyResourceFile(configuration, "inherit.gif", false);
111: // do early to reduce memory footprint
112: if (configuration.classuse) {
113: ClassUseWriter.generate(configuration, classtree);
114: }
115: IndexBuilder indexbuilder = new IndexBuilder(configuration,
116: nodeprecated);
117:
118: if (configuration.createtree) {
119: TreeWriter.generate(configuration, classtree);
120: }
121: if (configuration.createindex) {
122: if (configuration.splitindex) {
123: SplitIndexWriter.generate(configuration, indexbuilder);
124: } else {
125: SingleIndexWriter.generate(configuration, indexbuilder);
126: }
127: }
128:
129: if (!(configuration.nodeprecatedlist || nodeprecated)) {
130: DeprecatedListWriter.generate(configuration);
131: }
132:
133: AllClassesFrameWriter.generate(configuration, new IndexBuilder(
134: configuration, nodeprecated, true));
135:
136: FrameOutputWriter.generate(configuration);
137:
138: if (configuration.createoverview) {
139: PackageIndexWriter.generate(configuration);
140: }
141: if (configuration.helpfile.length() == 0
142: && !configuration.nohelp) {
143: HelpWriter.generate(configuration);
144: }
145: if (configuration.stylesheetfile.length() == 0) {
146: StylesheetWriter.generate(configuration);
147: }
148: }
149:
150: /**
151: * {@inheritDoc}
152: */
153: protected void generateClassFiles(ClassDoc[] arr,
154: ClassTree classtree) {
155: Arrays.sort(arr);
156: for (int i = 0; i < arr.length; i++) {
157: if (!(configuration.isGeneratedDoc(arr[i]) && arr[i]
158: .isIncluded())) {
159: continue;
160: }
161: ClassDoc prev = (i == 0) ? null : arr[i - 1];
162: ClassDoc curr = arr[i];
163: ClassDoc next = (i + 1 == arr.length) ? null : arr[i + 1];
164: try {
165: if (curr.isAnnotationType()) {
166: AbstractBuilder annotationTypeBuilder = configuration
167: .getBuilderFactory()
168: .getAnnotationTypeBuilder(
169: (AnnotationTypeDoc) curr, prev,
170: next);
171: annotationTypeBuilder.build();
172: } else {
173: AbstractBuilder classBuilder = configuration
174: .getBuilderFactory().getClassBuilder(curr,
175: prev, next, classtree);
176: classBuilder.build();
177: }
178: } catch (Exception e) {
179: e.printStackTrace();
180: throw new DocletAbortException();
181: }
182: }
183: }
184:
185: /**
186: * {@inheritDoc}
187: */
188: protected void generatePackageFiles(ClassTree classtree)
189: throws Exception {
190: PackageDoc[] packages = configuration.packages;
191: if (packages.length > 1) {
192: PackageIndexFrameWriter.generate(configuration);
193: }
194: PackageDoc prev = null, next;
195: for (int i = 0; i < packages.length; i++) {
196: PackageFrameWriter.generate(configuration, packages[i]);
197: next = (i + 1 < packages.length && packages[i + 1].name()
198: .length() > 0) ? packages[i + 1] : null;
199: //If the next package is unnamed package, skip 2 ahead if possible
200: next = (i + 2 < packages.length && next == null) ? packages[i + 2]
201: : next;
202: AbstractBuilder packageSummaryBuilder = configuration
203: .getBuilderFactory().getPackageSummaryBuilder(
204: packages[i], prev, next);
205: packageSummaryBuilder.build();
206: if (configuration.createtree) {
207: PackageTreeWriter.generate(configuration, packages[i],
208: prev, next, configuration.nodeprecated);
209: }
210: prev = packages[i];
211: }
212: }
213:
214: /**
215: * Check for doclet added options here.
216: *
217: * @return number of arguments to option. Zero return means
218: * option not known. Negative value means error occurred.
219: */
220: public static int optionLength(String option) {
221: // Construct temporary configuration for check
222: return (ConfigurationImpl.getInstance()).optionLength(option);
223: }
224:
225: /**
226: * Check that options have the correct arguments here.
227: * <P>
228: * This method is not required and will default gracefully
229: * (to true) if absent.
230: * <P>
231: * Printing option related error messages (using the provided
232: * DocErrorReporter) is the responsibility of this method.
233: *
234: * @return true if the options are valid.
235: */
236: public static boolean validOptions(String options[][],
237: DocErrorReporter reporter) {
238: // Construct temporary configuration for check
239: return (ConfigurationImpl.getInstance()).validOptions(options,
240: reporter);
241: }
242:
243: private void performCopy(String configdestdir, String filename) {
244: try {
245: String destdir = (configdestdir.length() > 0) ? configdestdir
246: + File.separatorChar
247: : "";
248: if (filename.length() > 0) {
249: File helpstylefile = new File(filename);
250: String parent = helpstylefile.getParent();
251: String helpstylefilename = (parent == null) ? filename
252: : filename.substring(parent.length() + 1);
253: File desthelpfile = new File(destdir
254: + helpstylefilename);
255: if (!desthelpfile.getCanonicalPath().equals(
256: helpstylefile.getCanonicalPath())) {
257: configuration.message.notice((SourcePosition) null,
258: "doclet.Copying_File_0_To_File_1",
259: helpstylefile.toString(), desthelpfile
260: .toString());
261: Util.copyFile(desthelpfile, helpstylefile);
262: }
263: }
264: } catch (IOException exc) {
265: configuration.message.error((SourcePosition) null,
266: "doclet.perform_copy_exception_encountered", exc
267: .toString());
268: throw new DocletAbortException();
269: }
270: }
271: }
|