001: /*
002: * Copyright 1998-2005 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.formats.html;
027:
028: import com.sun.tools.doclets.internal.toolkit.*;
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: * Configure the output based on the command line options.
037: * <p>
038: * Also determine the length of the command line option. For example,
039: * for a option "-header" there will be a string argument associated, then the
040: * the length of option "-header" is two. But for option "-nohelp" no argument
041: * is needed so it's length is 1.
042: * </p>
043: * <p>
044: * Also do the error checking on the options used. For example it is illegal to
045: * use "-helpfile" option when already "-nohelp" option is used.
046: * </p>
047: *
048: * @author Robert Field.
049: * @author Atul Dambalkar.
050: * @author Jamie Ho
051: */
052: public class ConfigurationImpl extends Configuration {
053:
054: private static final ConfigurationImpl instance = new ConfigurationImpl();
055:
056: /**
057: * The build date. Note: For now, we will use
058: * a version number instead of a date.
059: */
060: public static final String BUILD_DATE = System
061: .getProperty("java.version");
062:
063: /**
064: * The name of the constant values file.
065: */
066: public static final String CONSTANTS_FILE_NAME = "constant-values.html";
067:
068: /**
069: * Argument for command line option "-header".
070: */
071: public String header = "";
072:
073: /**
074: * Argument for command line option "-packagesheader".
075: */
076: public String packagesheader = "";
077:
078: /**
079: * Argument for command line option "-footer".
080: */
081: public String footer = "";
082:
083: /**
084: * Argument for command line option "-doctitle".
085: */
086: public String doctitle = "";
087:
088: /**
089: * Argument for command line option "-windowtitle".
090: */
091: public String windowtitle = "";
092:
093: /**
094: * Argument for command line option "-top".
095: */
096: public String top = "";
097:
098: /**
099: * Argument for command line option "-bottom".
100: */
101: public String bottom = "";
102:
103: /**
104: * Argument for command line option "-helpfile".
105: */
106: public String helpfile = "";
107:
108: /**
109: * Argument for command line option "-stylesheetfile".
110: */
111: public String stylesheetfile = "";
112:
113: /**
114: * True if command line option "-nohelp" is used. Default value is false.
115: */
116: public boolean nohelp = false;
117:
118: /**
119: * True if command line option "-splitindex" is used. Default value is
120: * false.
121: */
122: public boolean splitindex = false;
123:
124: /**
125: * False if command line option "-noindex" is used. Default value is true.
126: */
127: public boolean createindex = true;
128:
129: /**
130: * True if command line option "-use" is used. Default value is false.
131: */
132: public boolean classuse = false;
133:
134: /**
135: * False if command line option "-notree" is used. Default value is true.
136: */
137: public boolean createtree = true;
138:
139: /**
140: * True if command line option "-nodeprecated" is used. Default value is
141: * false.
142: */
143: public boolean nodeprecatedlist = false;
144:
145: /**
146: * True if command line option "-nonavbar" is used. Default value is false.
147: */
148: public boolean nonavbar = false;
149:
150: /**
151: * True if command line option "-nooverview" is used. Default value is
152: * false
153: */
154: private boolean nooverview = false;
155:
156: /**
157: * True if command line option "-overview" is used. Default value is false.
158: */
159: public boolean overview = false;
160:
161: /**
162: * This is true if option "-overview" is used or option "-overview" is not
163: * used and number of packages is more than one.
164: */
165: public boolean createoverview = false;
166:
167: /**
168: * Unique Resource Handler for this package.
169: */
170: public final MessageRetriever standardmessage;
171:
172: /**
173: * First file to appear in the right-hand frame in the generated
174: * documentation.
175: */
176: public String topFile = "";
177:
178: /**
179: * The classdoc for the class file getting generated.
180: */
181: public ClassDoc currentcd = null; // Set this classdoc in the
182:
183: // ClassWriter.
184:
185: /**
186: * Constructor. Initialises resource for the
187: * {@link com.sun.tools.doclets.MessageRetriever}.
188: */
189: private ConfigurationImpl() {
190: standardmessage = new MessageRetriever(this ,
191: "com.sun.tools.doclets.formats.html.resources.standard");
192: }
193:
194: public static ConfigurationImpl getInstance() {
195: return instance;
196: }
197:
198: /**
199: * Return the build date for the doclet.
200: */
201: public String getDocletSpecificBuildDate() {
202: return BUILD_DATE;
203: }
204:
205: /**
206: * Depending upon the command line options provided by the user, set
207: * configure the output generation environment.
208: *
209: * @param options The array of option names and values.
210: */
211: public void setSpecificDocletOptions(String[][] options) {
212: for (int oi = 0; oi < options.length; ++oi) {
213: String[] os = options[oi];
214: String opt = os[0].toLowerCase();
215: if (opt.equals("-footer")) {
216: footer = os[1];
217: } else if (opt.equals("-header")) {
218: header = os[1];
219: } else if (opt.equals("-packagesheader")) {
220: packagesheader = os[1];
221: } else if (opt.equals("-doctitle")) {
222: doctitle = os[1];
223: } else if (opt.equals("-windowtitle")) {
224: windowtitle = os[1];
225: } else if (opt.equals("-top")) {
226: top = os[1];
227: } else if (opt.equals("-bottom")) {
228: bottom = os[1];
229: } else if (opt.equals("-helpfile")) {
230: helpfile = os[1];
231: } else if (opt.equals("-stylesheetfile")) {
232: stylesheetfile = os[1];
233: } else if (opt.equals("-charset")) {
234: charset = os[1];
235: } else if (opt.equals("-nohelp")) {
236: nohelp = true;
237: } else if (opt.equals("-splitindex")) {
238: splitindex = true;
239: } else if (opt.equals("-noindex")) {
240: createindex = false;
241: } else if (opt.equals("-use")) {
242: classuse = true;
243: } else if (opt.equals("-notree")) {
244: createtree = false;
245: } else if (opt.equals("-nodeprecatedlist")) {
246: nodeprecatedlist = true;
247: } else if (opt.equals("-nosince")) {
248: nosince = true;
249: } else if (opt.equals("-nonavbar")) {
250: nonavbar = true;
251: } else if (opt.equals("-nooverview")) {
252: nooverview = true;
253: } else if (opt.equals("-overview")) {
254: overview = true;
255: }
256: }
257: if (root.specifiedClasses().length > 0) {
258: Map map = new HashMap();
259: PackageDoc pd;
260: ClassDoc[] classes = root.classes();
261: for (int i = 0; i < classes.length; i++) {
262: pd = classes[i].containingPackage();
263: if (!map.containsKey(pd.name())) {
264: map.put(pd.name(), pd);
265: }
266: }
267: }
268: setCreateOverview();
269: setTopFile(root);
270: }
271:
272: /**
273: * Returns the "length" of a given option. If an option takes no
274: * arguments, its length is one. If it takes one argument, it's
275: * length is two, and so on. This method is called by JavaDoc to
276: * parse the options it does not recognize. It then calls
277: * {@link #validOptions(String[][], DocErrorReporter)} to
278: * validate them.
279: * <b>Note:</b><br>
280: * The options arrive as case-sensitive strings. For options that
281: * are not case-sensitive, use toLowerCase() on the option string
282: * before comparing it.
283: * </blockquote>
284: *
285: * @return number of arguments + 1 for a option. Zero return means
286: * option not known. Negative value means error occurred.
287: */
288: public int optionLength(String option) {
289: int result = -1;
290: if ((result = super .optionLength(option)) > 0) {
291: return result;
292: }
293: // otherwise look for the options we have added
294: option = option.toLowerCase();
295: if (option.equals("-nodeprecatedlist")
296: || option.equals("-noindex")
297: || option.equals("-notree") || option.equals("-nohelp")
298: || option.equals("-splitindex")
299: || option.equals("-serialwarn")
300: || option.equals("-use") || option.equals("-nonavbar")
301: || option.equals("-nooverview")) {
302: return 1;
303: } else if (option.equals("-help")) {
304: System.out.println(getText("doclet.usage"));
305: return 1;
306: } else if (option.equals("-footer") || option.equals("-header")
307: || option.equals("-packagesheader")
308: || option.equals("-doctitle")
309: || option.equals("-windowtitle")
310: || option.equals("-top") || option.equals("-bottom")
311: || option.equals("-helpfile")
312: || option.equals("-stylesheetfile")
313: || option.equals("-charset")
314: || option.equals("-overview")) {
315: return 2;
316: } else {
317: return 0;
318: }
319: }
320:
321: /**
322: * {@inheritDoc}
323: */
324: public boolean validOptions(String options[][],
325: DocErrorReporter reporter) {
326: boolean helpfile = false;
327: boolean nohelp = false;
328: boolean overview = false;
329: boolean nooverview = false;
330: boolean splitindex = false;
331: boolean noindex = false;
332: // check shared options
333: if (!generalValidOptions(options, reporter)) {
334: return false;
335: }
336: // otherwise look at our options
337: for (int oi = 0; oi < options.length; ++oi) {
338: String[] os = options[oi];
339: String opt = os[0].toLowerCase();
340: if (opt.equals("-helpfile")) {
341: if (nohelp == true) {
342: reporter.printError(getText(
343: "doclet.Option_conflict", "-helpfile",
344: "-nohelp"));
345: return false;
346: }
347: if (helpfile == true) {
348: reporter.printError(getText("doclet.Option_reuse",
349: "-helpfile"));
350: return false;
351: }
352: File help = new File(os[1]);
353: if (!help.exists()) {
354: reporter.printError(getText(
355: "doclet.File_not_found", os[1]));
356: return false;
357: }
358: helpfile = true;
359: } else if (opt.equals("-nohelp")) {
360: if (helpfile == true) {
361: reporter.printError(getText(
362: "doclet.Option_conflict", "-nohelp",
363: "-helpfile"));
364: return false;
365: }
366: nohelp = true;
367: } else if (opt.equals("-overview")) {
368: if (nooverview == true) {
369: reporter.printError(getText(
370: "doclet.Option_conflict", "-overview",
371: "-nooverview"));
372: return false;
373: }
374: if (overview == true) {
375: reporter.printError(getText("doclet.Option_reuse",
376: "-overview"));
377: return false;
378: }
379: overview = true;
380: } else if (opt.equals("-nooverview")) {
381: if (overview == true) {
382: reporter.printError(getText(
383: "doclet.Option_conflict", "-nooverview",
384: "-overview"));
385: return false;
386: }
387: nooverview = true;
388: } else if (opt.equals("-splitindex")) {
389: if (noindex == true) {
390: reporter.printError(getText(
391: "doclet.Option_conflict", "-splitindex",
392: "-noindex"));
393: return false;
394: }
395: splitindex = true;
396: } else if (opt.equals("-noindex")) {
397: if (splitindex == true) {
398: reporter.printError(getText(
399: "doclet.Option_conflict", "-noindex",
400: "-splitindex"));
401: return false;
402: }
403: noindex = true;
404: }
405: }
406: return true;
407: }
408:
409: /**
410: * {@inheritDoc}
411: */
412: public MessageRetriever getDocletSpecificMsg() {
413: return standardmessage;
414: }
415:
416: /**
417: * Decide the page which will appear first in the right-hand frame. It will
418: * be "overview-summary.html" if "-overview" option is used or no
419: * "-overview" but the number of packages is more than one. It will be
420: * "package-summary.html" of the respective package if there is only one
421: * package to document. It will be a class page(first in the sorted order),
422: * if only classes are provided on the command line.
423: *
424: * @param root Root of the program structure.
425: */
426: protected void setTopFile(RootDoc root) {
427: if (!checkForDeprecation(root)) {
428: return;
429: }
430: if (createoverview) {
431: topFile = "overview-summary.html";
432: } else {
433: if (packages.length == 1 && packages[0].name().equals("")) {
434: if (root.classes().length > 0) {
435: ClassDoc[] classarr = root.classes();
436: Arrays.sort(classarr);
437: ClassDoc cd = getValidClass(classarr);
438: topFile = DirectoryManager.getPathToClass(cd);
439: }
440: } else {
441: topFile = DirectoryManager.getPathToPackage(
442: packages[0], "package-summary.html");
443: }
444: }
445: }
446:
447: protected ClassDoc getValidClass(ClassDoc[] classarr) {
448: if (!nodeprecated) {
449: return classarr[0];
450: }
451: for (int i = 0; i < classarr.length; i++) {
452: if (classarr[i].tags("deprecated").length == 0) {
453: return classarr[i];
454: }
455: }
456: return null;
457: }
458:
459: protected boolean checkForDeprecation(RootDoc root) {
460: ClassDoc[] classarr = root.classes();
461: for (int i = 0; i < classarr.length; i++) {
462: if (isGeneratedDoc(classarr[i])) {
463: return true;
464: }
465: }
466: return false;
467: }
468:
469: /**
470: * Generate "overview.html" page if option "-overview" is used or number of
471: * packages is more than one. Sets {@link #createoverview} field to true.
472: */
473: protected void setCreateOverview() {
474: if ((overview || packages.length > 1) && !nooverview) {
475: createoverview = true;
476: }
477: }
478:
479: /**
480: * {@inheritDoc}
481: */
482: public WriterFactory getWriterFactory() {
483: return WriterFactoryImpl.getInstance();
484: }
485:
486: /**
487: * {@inheritDoc}
488: */
489: public Comparator getMemberComparator() {
490: return null;
491: }
492: }
|