001 /*
002 * Copyright 2003-2008 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
026 package com.sun.tools.doclets.internal.toolkit;
027
028 import com.sun.tools.doclets.internal.toolkit.builders.*;
029 import com.sun.tools.doclets.internal.toolkit.util.*;
030 import com.sun.javadoc.*;
031 import java.util.*;
032 import java.io.*;
033
034 /**
035 * An abstract implementation of a Doclet.
036 *
037 * This code is not part of an API.
038 * It is implementation that is subject to change.
039 * Do not use it as an API.
040 *
041 * @author Jamie Ho
042 */
043 public abstract class AbstractDoclet {
044
045 /**
046 * The global configuration information for this run.
047 */
048 public Configuration configuration;
049
050 /**
051 * The only doclet that may use this toolkit is {@value}
052 */
053 private static final String TOOLKIT_DOCLET_NAME = new
054 com.sun.tools.doclets.formats.html.HtmlDoclet().getClass().getName();
055
056 /**
057 * Verify that the only doclet that is using this toolkit is
058 * {@value #TOOLKIT_DOCLET_NAME}.
059 */
060 private boolean isValidDoclet(AbstractDoclet doclet) {
061 if (! doclet.getClass().getName().equals(TOOLKIT_DOCLET_NAME)) {
062 configuration.message.error("doclet.Toolkit_Usage_Violation",
063 TOOLKIT_DOCLET_NAME);
064 return false;
065 }
066 return true;
067 }
068
069 /**
070 * The method that starts the execution of the doclet.
071 *
072 * @param doclet the doclet to start the execution for.
073 * @param root the {@link RootDoc} that points to the source to document.
074 * @return true if the doclet executed without error. False otherwise.
075 */
076 public boolean start(AbstractDoclet doclet, RootDoc root) {
077 configuration = configuration();
078 configuration.root = root;
079 if (! isValidDoclet(doclet)) {
080 return false;
081 }
082 try {
083 doclet.startGeneration(root);
084 } catch (Exception exc) {
085 exc.printStackTrace();
086 return false;
087 }
088 return true;
089 }
090
091 /**
092 * Indicate that this doclet supports the 1.5 language features.
093 * @return JAVA_1_5, indicating that the new features are supported.
094 */
095 public static LanguageVersion languageVersion() {
096 return LanguageVersion.JAVA_1_5;
097 }
098
099
100 /**
101 * Create the configuration instance and returns it.
102 * @return the configuration of the doclet.
103 */
104 public abstract Configuration configuration();
105
106 /**
107 * Start the generation of files. Call generate methods in the individual
108 * writers, which will in turn genrate the documentation files. Call the
109 * TreeWriter generation first to ensure the Class Hierarchy is built
110 * first and then can be used in the later generation.
111 *
112 * @see com.sun.javadoc.RootDoc
113 */
114 private void startGeneration(RootDoc root) throws Exception {
115 if (root.classes().length == 0) {
116 configuration.message.
117 error("doclet.No_Public_Classes_To_Document");
118 return;
119 }
120 configuration.setOptions();
121 configuration.getDocletSpecificMsg().notice("doclet.build_version",
122 configuration.getDocletSpecificBuildDate());
123 ClassTree classtree = new ClassTree(configuration, configuration.nodeprecated);
124
125 generateClassFiles(root, classtree);
126 if (configuration.sourcepath != null && configuration.sourcepath.length() > 0) {
127 StringTokenizer pathTokens = new StringTokenizer(configuration.sourcepath,
128 String.valueOf(File.pathSeparatorChar));
129 boolean first = true;
130 while(pathTokens.hasMoreTokens()){
131 Util.copyDocFiles(configuration,
132 pathTokens.nextToken() + File.separator,
133 DocletConstants.DOC_FILES_DIR_NAME, first);
134 first = false;
135 }
136 }
137
138 PackageListWriter.generate(configuration);
139 generatePackageFiles(classtree);
140
141 generateOtherFiles(root, classtree);
142 configuration.tagletManager.printReport();
143 }
144
145 /**
146 * Generate additional documentation that is added to the API documentation.
147 *
148 * @param root the RootDoc of source to document.
149 * @param classtree the data structure representing the class tree.
150 */
151 protected void generateOtherFiles(RootDoc root, ClassTree classtree) throws Exception {
152 BuilderFactory builderFactory = configuration.getBuilderFactory();
153 AbstractBuilder constantsSummaryBuilder = builderFactory.getConstantsSummaryBuider();
154 constantsSummaryBuilder.build();
155 AbstractBuilder serializedFormBuilder = builderFactory.getSerializedFormBuilder();
156 serializedFormBuilder.build();
157 }
158
159 /**
160 * Generate the package documentation.
161 *
162 * @param classtree the data structure representing the class tree.
163 */
164 protected abstract void generatePackageFiles(ClassTree classtree) throws Exception;
165
166 /**
167 * Generate the class documentation.
168 *
169 * @param classtree the data structure representing the class tree.
170 */
171 protected abstract void generateClassFiles(ClassDoc[] arr, ClassTree classtree);
172
173 /**
174 * Iterate through all classes and construct documentation for them.
175 *
176 * @param root the RootDoc of source to document.
177 * @param classtree the data structure representing the class tree.
178 */
179 protected void generateClassFiles(RootDoc root, ClassTree classtree) {
180 generateClassFiles(classtree);
181 PackageDoc[] packages = root.specifiedPackages();
182 for (int i = 0; i < packages.length; i++) {
183 generateClassFiles(packages[i].allClasses(), classtree);
184 }
185 }
186
187 /**
188 * Generate the class files for single classes specified on the command line.
189 *
190 * @param classtree the data structure representing the class tree.
191 */
192 private void generateClassFiles(ClassTree classtree) {
193 String[] packageNames = configuration.classDocCatalog.packageNames();
194 for (int packageNameIndex = 0; packageNameIndex < packageNames.length;
195 packageNameIndex++) {
196 generateClassFiles(configuration.classDocCatalog.allClasses(
197 packageNames[packageNameIndex]), classtree);
198 }
199 }
200 }