Wed, 27 Apr 2016 01:34:52 +0800
Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/langtools/
changeset: 2573:53ca196be1ae
tag: jdk8u25-b17
1 /*
2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.doclets.formats.html;
28 import java.net.*;
29 import java.util.*;
31 import javax.tools.JavaFileManager;
33 import com.sun.javadoc.*;
34 import com.sun.tools.doclets.formats.html.markup.ContentBuilder;
35 import com.sun.tools.doclets.internal.toolkit.*;
36 import com.sun.tools.doclets.internal.toolkit.util.*;
37 import com.sun.tools.doclint.DocLint;
38 import com.sun.tools.javac.file.JavacFileManager;
39 import com.sun.tools.javac.util.Context;
40 import com.sun.tools.javac.util.StringUtils;
41 import com.sun.tools.javadoc.RootDocImpl;
43 /**
44 * Configure the output based on the command line options.
45 * <p>
46 * Also determine the length of the command line option. For example,
47 * for a option "-header" there will be a string argument associated, then the
48 * the length of option "-header" is two. But for option "-nohelp" no argument
49 * is needed so it's length is 1.
50 * </p>
51 * <p>
52 * Also do the error checking on the options used. For example it is illegal to
53 * use "-helpfile" option when already "-nohelp" option is used.
54 * </p>
55 *
56 * <p><b>This is NOT part of any supported API.
57 * If you write code that depends on this, you do so at your own risk.
58 * This code and its internal interfaces are subject to change or
59 * deletion without notice.</b>
60 *
61 * @author Robert Field.
62 * @author Atul Dambalkar.
63 * @author Jamie Ho
64 * @author Bhavesh Patel (Modified)
65 */
66 public class ConfigurationImpl extends Configuration {
68 /**
69 * The build date. Note: For now, we will use
70 * a version number instead of a date.
71 */
72 public static final String BUILD_DATE = System.getProperty("java.version");
74 /**
75 * Argument for command line option "-header".
76 */
77 public String header = "";
79 /**
80 * Argument for command line option "-packagesheader".
81 */
82 public String packagesheader = "";
84 /**
85 * Argument for command line option "-footer".
86 */
87 public String footer = "";
89 /**
90 * Argument for command line option "-doctitle".
91 */
92 public String doctitle = "";
94 /**
95 * Argument for command line option "-windowtitle".
96 */
97 public String windowtitle = "";
99 /**
100 * Argument for command line option "-top".
101 */
102 public String top = "";
104 /**
105 * Argument for command line option "-bottom".
106 */
107 public String bottom = "";
109 /**
110 * Argument for command line option "-helpfile".
111 */
112 public String helpfile = "";
114 /**
115 * Argument for command line option "-stylesheetfile".
116 */
117 public String stylesheetfile = "";
119 /**
120 * Argument for command line option "-Xdocrootparent".
121 */
122 public String docrootparent = "";
124 /**
125 * True if command line option "-nohelp" is used. Default value is false.
126 */
127 public boolean nohelp = false;
129 /**
130 * True if command line option "-splitindex" is used. Default value is
131 * false.
132 */
133 public boolean splitindex = false;
135 /**
136 * False if command line option "-noindex" is used. Default value is true.
137 */
138 public boolean createindex = true;
140 /**
141 * True if command line option "-use" is used. Default value is false.
142 */
143 public boolean classuse = false;
145 /**
146 * False if command line option "-notree" is used. Default value is true.
147 */
148 public boolean createtree = true;
150 /**
151 * True if command line option "-nodeprecated" is used. Default value is
152 * false.
153 */
154 public boolean nodeprecatedlist = false;
156 /**
157 * True if command line option "-nonavbar" is used. Default value is false.
158 */
159 public boolean nonavbar = false;
161 /**
162 * True if command line option "-nooverview" is used. Default value is
163 * false
164 */
165 private boolean nooverview = false;
167 /**
168 * True if command line option "-overview" is used. Default value is false.
169 */
170 public boolean overview = false;
172 /**
173 * This is true if option "-overview" is used or option "-overview" is not
174 * used and number of packages is more than one.
175 */
176 public boolean createoverview = false;
178 /**
179 * Collected set of doclint options
180 */
181 public Set<String> doclintOpts = new LinkedHashSet<String>();
183 /**
184 * Unique Resource Handler for this package.
185 */
186 public final MessageRetriever standardmessage;
188 /**
189 * First file to appear in the right-hand frame in the generated
190 * documentation.
191 */
192 public DocPath topFile = DocPath.empty;
194 /**
195 * The classdoc for the class file getting generated.
196 */
197 public ClassDoc currentcd = null; // Set this classdoc in the ClassWriter.
199 /**
200 * Constructor. Initializes resource for the
201 * {@link com.sun.tools.doclets.internal.toolkit.util.MessageRetriever MessageRetriever}.
202 */
203 public ConfigurationImpl() {
204 standardmessage = new MessageRetriever(this,
205 "com.sun.tools.doclets.formats.html.resources.standard");
206 }
208 private final String versionRBName = "com.sun.tools.javadoc.resources.version";
209 private ResourceBundle versionRB;
211 /**
212 * Return the build date for the doclet.
213 */
214 @Override
215 public String getDocletSpecificBuildDate() {
216 if (versionRB == null) {
217 try {
218 versionRB = ResourceBundle.getBundle(versionRBName);
219 } catch (MissingResourceException e) {
220 return BUILD_DATE;
221 }
222 }
224 try {
225 return versionRB.getString("release");
226 } catch (MissingResourceException e) {
227 return BUILD_DATE;
228 }
229 }
231 /**
232 * Depending upon the command line options provided by the user, set
233 * configure the output generation environment.
234 *
235 * @param options The array of option names and values.
236 */
237 @Override
238 public void setSpecificDocletOptions(String[][] options) {
239 for (int oi = 0; oi < options.length; ++oi) {
240 String[] os = options[oi];
241 String opt = StringUtils.toLowerCase(os[0]);
242 if (opt.equals("-footer")) {
243 footer = os[1];
244 } else if (opt.equals("-header")) {
245 header = os[1];
246 } else if (opt.equals("-packagesheader")) {
247 packagesheader = os[1];
248 } else if (opt.equals("-doctitle")) {
249 doctitle = os[1];
250 } else if (opt.equals("-windowtitle")) {
251 windowtitle = os[1].replaceAll("\\<.*?>", "");
252 } else if (opt.equals("-top")) {
253 top = os[1];
254 } else if (opt.equals("-bottom")) {
255 bottom = os[1];
256 } else if (opt.equals("-helpfile")) {
257 helpfile = os[1];
258 } else if (opt.equals("-stylesheetfile")) {
259 stylesheetfile = os[1];
260 } else if (opt.equals("-charset")) {
261 charset = os[1];
262 } else if (opt.equals("-xdocrootparent")) {
263 docrootparent = os[1];
264 } else if (opt.equals("-nohelp")) {
265 nohelp = true;
266 } else if (opt.equals("-splitindex")) {
267 splitindex = true;
268 } else if (opt.equals("-noindex")) {
269 createindex = false;
270 } else if (opt.equals("-use")) {
271 classuse = true;
272 } else if (opt.equals("-notree")) {
273 createtree = false;
274 } else if (opt.equals("-nodeprecatedlist")) {
275 nodeprecatedlist = true;
276 } else if (opt.equals("-nonavbar")) {
277 nonavbar = true;
278 } else if (opt.equals("-nooverview")) {
279 nooverview = true;
280 } else if (opt.equals("-overview")) {
281 overview = true;
282 } else if (opt.equals("-xdoclint")) {
283 doclintOpts.add(null);
284 } else if (opt.startsWith("-xdoclint:")) {
285 doclintOpts.add(opt.substring(opt.indexOf(":") + 1));
286 }
287 }
288 if (root.specifiedClasses().length > 0) {
289 Map<String,PackageDoc> map = new HashMap<String,PackageDoc>();
290 PackageDoc pd;
291 ClassDoc[] classes = root.classes();
292 for (int i = 0; i < classes.length; i++) {
293 pd = classes[i].containingPackage();
294 if(! map.containsKey(pd.name())) {
295 map.put(pd.name(), pd);
296 }
297 }
298 }
299 setCreateOverview();
300 setTopFile(root);
302 if (root instanceof RootDocImpl) {
303 ((RootDocImpl) root).initDocLint(doclintOpts, tagletManager.getCustomTagNames());
304 }
305 }
307 /**
308 * Returns the "length" of a given option. If an option takes no
309 * arguments, its length is one. If it takes one argument, it's
310 * length is two, and so on. This method is called by JavaDoc to
311 * parse the options it does not recognize. It then calls
312 * {@link #validOptions(String[][], DocErrorReporter)} to
313 * validate them.
314 * <b>Note:</b><br>
315 * The options arrive as case-sensitive strings. For options that
316 * are not case-sensitive, use toLowerCase() on the option string
317 * before comparing it.
318 * </blockquote>
319 *
320 * @return number of arguments + 1 for a option. Zero return means
321 * option not known. Negative value means error occurred.
322 */
323 public int optionLength(String option) {
324 int result = -1;
325 if ((result = super.optionLength(option)) > 0) {
326 return result;
327 }
328 // otherwise look for the options we have added
329 option = StringUtils.toLowerCase(option);
330 if (option.equals("-nodeprecatedlist") ||
331 option.equals("-noindex") ||
332 option.equals("-notree") ||
333 option.equals("-nohelp") ||
334 option.equals("-splitindex") ||
335 option.equals("-serialwarn") ||
336 option.equals("-use") ||
337 option.equals("-nonavbar") ||
338 option.equals("-nooverview") ||
339 option.equals("-xdoclint") ||
340 option.startsWith("-xdoclint:")) {
341 return 1;
342 } else if (option.equals("-help")) {
343 // Uugh: first, this should not be hidden inside optionLength,
344 // and second, we should not be writing directly to stdout.
345 // But we have no access to a DocErrorReporter, which would
346 // allow use of reporter.printNotice
347 System.out.println(getText("doclet.usage"));
348 return 1;
349 } else if (option.equals("-x")) {
350 // Uugh: first, this should not be hidden inside optionLength,
351 // and second, we should not be writing directly to stdout.
352 // But we have no access to a DocErrorReporter, which would
353 // allow use of reporter.printNotice
354 System.out.println(getText("doclet.X.usage"));
355 return 1;
356 } else if (option.equals("-footer") ||
357 option.equals("-header") ||
358 option.equals("-packagesheader") ||
359 option.equals("-doctitle") ||
360 option.equals("-windowtitle") ||
361 option.equals("-top") ||
362 option.equals("-bottom") ||
363 option.equals("-helpfile") ||
364 option.equals("-stylesheetfile") ||
365 option.equals("-charset") ||
366 option.equals("-overview") ||
367 option.equals("-xdocrootparent")) {
368 return 2;
369 } else {
370 return 0;
371 }
372 }
374 /**
375 * {@inheritDoc}
376 */
377 @Override
378 public boolean validOptions(String options[][],
379 DocErrorReporter reporter) {
380 boolean helpfile = false;
381 boolean nohelp = false;
382 boolean overview = false;
383 boolean nooverview = false;
384 boolean splitindex = false;
385 boolean noindex = false;
386 // check shared options
387 if (!generalValidOptions(options, reporter)) {
388 return false;
389 }
390 // otherwise look at our options
391 for (int oi = 0; oi < options.length; ++oi) {
392 String[] os = options[oi];
393 String opt = StringUtils.toLowerCase(os[0]);
394 if (opt.equals("-helpfile")) {
395 if (nohelp == true) {
396 reporter.printError(getText("doclet.Option_conflict",
397 "-helpfile", "-nohelp"));
398 return false;
399 }
400 if (helpfile == true) {
401 reporter.printError(getText("doclet.Option_reuse",
402 "-helpfile"));
403 return false;
404 }
405 DocFile help = DocFile.createFileForInput(this, os[1]);
406 if (!help.exists()) {
407 reporter.printError(getText("doclet.File_not_found", os[1]));
408 return false;
409 }
410 helpfile = true;
411 } else if (opt.equals("-nohelp")) {
412 if (helpfile == true) {
413 reporter.printError(getText("doclet.Option_conflict",
414 "-nohelp", "-helpfile"));
415 return false;
416 }
417 nohelp = true;
418 } else if (opt.equals("-xdocrootparent")) {
419 try {
420 new URL(os[1]);
421 } catch (MalformedURLException e) {
422 reporter.printError(getText("doclet.MalformedURL", os[1]));
423 return false;
424 }
425 } else if (opt.equals("-overview")) {
426 if (nooverview == true) {
427 reporter.printError(getText("doclet.Option_conflict",
428 "-overview", "-nooverview"));
429 return false;
430 }
431 if (overview == true) {
432 reporter.printError(getText("doclet.Option_reuse",
433 "-overview"));
434 return false;
435 }
436 overview = true;
437 } else if (opt.equals("-nooverview")) {
438 if (overview == true) {
439 reporter.printError(getText("doclet.Option_conflict",
440 "-nooverview", "-overview"));
441 return false;
442 }
443 nooverview = true;
444 } else if (opt.equals("-splitindex")) {
445 if (noindex == true) {
446 reporter.printError(getText("doclet.Option_conflict",
447 "-splitindex", "-noindex"));
448 return false;
449 }
450 splitindex = true;
451 } else if (opt.equals("-noindex")) {
452 if (splitindex == true) {
453 reporter.printError(getText("doclet.Option_conflict",
454 "-noindex", "-splitindex"));
455 return false;
456 }
457 noindex = true;
458 } else if (opt.startsWith("-xdoclint:")) {
459 if (opt.contains("/")) {
460 reporter.printError(getText("doclet.Option_doclint_no_qualifiers"));
461 return false;
462 }
463 if (!DocLint.isValidOption(
464 opt.replace("-xdoclint:", DocLint.XMSGS_CUSTOM_PREFIX))) {
465 reporter.printError(getText("doclet.Option_doclint_invalid_arg"));
466 return false;
467 }
468 }
469 }
470 return true;
471 }
473 /**
474 * {@inheritDoc}
475 */
476 @Override
477 public MessageRetriever getDocletSpecificMsg() {
478 return standardmessage;
479 }
481 /**
482 * Decide the page which will appear first in the right-hand frame. It will
483 * be "overview-summary.html" if "-overview" option is used or no
484 * "-overview" but the number of packages is more than one. It will be
485 * "package-summary.html" of the respective package if there is only one
486 * package to document. It will be a class page(first in the sorted order),
487 * if only classes are provided on the command line.
488 *
489 * @param root Root of the program structure.
490 */
491 protected void setTopFile(RootDoc root) {
492 if (!checkForDeprecation(root)) {
493 return;
494 }
495 if (createoverview) {
496 topFile = DocPaths.OVERVIEW_SUMMARY;
497 } else {
498 if (packages.length == 1 && packages[0].name().equals("")) {
499 if (root.classes().length > 0) {
500 ClassDoc[] classarr = root.classes();
501 Arrays.sort(classarr);
502 ClassDoc cd = getValidClass(classarr);
503 topFile = DocPath.forClass(cd);
504 }
505 } else {
506 topFile = DocPath.forPackage(packages[0]).resolve(DocPaths.PACKAGE_SUMMARY);
507 }
508 }
509 }
511 protected ClassDoc getValidClass(ClassDoc[] classarr) {
512 if (!nodeprecated) {
513 return classarr[0];
514 }
515 for (int i = 0; i < classarr.length; i++) {
516 if (classarr[i].tags("deprecated").length == 0) {
517 return classarr[i];
518 }
519 }
520 return null;
521 }
523 protected boolean checkForDeprecation(RootDoc root) {
524 ClassDoc[] classarr = root.classes();
525 for (int i = 0; i < classarr.length; i++) {
526 if (isGeneratedDoc(classarr[i])) {
527 return true;
528 }
529 }
530 return false;
531 }
533 /**
534 * Generate "overview.html" page if option "-overview" is used or number of
535 * packages is more than one. Sets {@link #createoverview} field to true.
536 */
537 protected void setCreateOverview() {
538 if ((overview || packages.length > 1) && !nooverview) {
539 createoverview = true;
540 }
541 }
543 /**
544 * {@inheritDoc}
545 */
546 @Override
547 public WriterFactory getWriterFactory() {
548 return new WriterFactoryImpl(this);
549 }
551 /**
552 * {@inheritDoc}
553 */
554 @Override
555 public Comparator<ProgramElementDoc> getMemberComparator() {
556 return null;
557 }
559 /**
560 * {@inheritDoc}
561 */
562 @Override
563 public Locale getLocale() {
564 if (root instanceof RootDocImpl)
565 return ((RootDocImpl)root).getLocale();
566 else
567 return Locale.getDefault();
568 }
570 /**
571 * {@inheritDoc}
572 */
573 @Override
574 public JavaFileManager getFileManager() {
575 if (fileManager == null) {
576 if (root instanceof RootDocImpl)
577 fileManager = ((RootDocImpl) root).getFileManager();
578 else
579 fileManager = new JavacFileManager(new Context(), false, null);
580 }
581 return fileManager;
582 }
584 private JavaFileManager fileManager;
586 @Override
587 public boolean showMessage(SourcePosition pos, String key) {
588 if (root instanceof RootDocImpl) {
589 return pos == null || ((RootDocImpl) root).showTagMessages();
590 }
591 return true;
592 }
594 @Override
595 public Content newContent() {
596 return new ContentBuilder();
597 }
598 }