src/share/classes/com/sun/tools/javadoc/Start.java

changeset 1413
bdcef2ef52d2
parent 1411
467f4f754368
child 1797
019063968164
equal deleted inserted replaced
1412:400a4e8accd3 1413:bdcef2ef52d2
27 27
28 import java.io.File; 28 import java.io.File;
29 import java.io.FileNotFoundException; 29 import java.io.FileNotFoundException;
30 import java.io.IOException; 30 import java.io.IOException;
31 import java.io.PrintWriter; 31 import java.io.PrintWriter;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.Collections;
35
36 import javax.tools.JavaFileManager;
37 import javax.tools.JavaFileObject;
32 38
33 import com.sun.javadoc.*; 39 import com.sun.javadoc.*;
34 import com.sun.tools.javac.main.CommandLine; 40 import com.sun.tools.javac.main.CommandLine;
41 import com.sun.tools.javac.util.ClientCodeException;
35 import com.sun.tools.javac.util.Context; 42 import com.sun.tools.javac.util.Context;
36 import com.sun.tools.javac.util.List; 43 import com.sun.tools.javac.util.List;
37 import com.sun.tools.javac.util.ListBuffer; 44 import com.sun.tools.javac.util.ListBuffer;
38 import com.sun.tools.javac.util.Log; 45 import com.sun.tools.javac.util.Log;
39 import com.sun.tools.javac.util.Options; 46 import com.sun.tools.javac.util.Options;
67 private long defaultFilter = PUBLIC | PROTECTED; 74 private long defaultFilter = PUBLIC | PROTECTED;
68 75
69 private final Messager messager; 76 private final Messager messager;
70 77
71 private DocletInvoker docletInvoker; 78 private DocletInvoker docletInvoker;
79
80 /**
81 * In API mode, exceptions thrown while calling the doclet are
82 * propagated using ClientCodeException.
83 */
84 private boolean apiMode;
72 85
73 Start(String programName, 86 Start(String programName,
74 PrintWriter errWriter, 87 PrintWriter errWriter,
75 PrintWriter warnWriter, 88 PrintWriter warnWriter,
76 PrintWriter noticeWriter, 89 PrintWriter noticeWriter,
119 } 132 }
120 133
121 public Start(Context context) { 134 public Start(Context context) {
122 context.getClass(); // null check 135 context.getClass(); // null check
123 this.context = context; 136 this.context = context;
137 apiMode = true;
124 defaultDocletClassName = standardDocletClassName; 138 defaultDocletClassName = standardDocletClassName;
125 docletParentClassLoader = null; 139 docletParentClassLoader = null;
126 140
127 Log log = context.get(Log.logKey); 141 Log log = context.get(Log.logKey);
128 if (log instanceof Messager) 142 if (log instanceof Messager)
182 196
183 /** 197 /**
184 * Main program - external wrapper 198 * Main program - external wrapper
185 */ 199 */
186 int begin(String... argv) { 200 int begin(String... argv) {
201 boolean ok = begin(null, argv, Collections.<JavaFileObject> emptySet());
202 return ok ? 0 : 1;
203 }
204
205 public boolean begin(Class<?> docletClass, Iterable<String> options, Iterable<? extends JavaFileObject> fileObjects) {
206 Collection<String> opts = new ArrayList<String>();
207 for (String opt: options) opts.add(opt);
208 return begin(docletClass, opts.toArray(new String[opts.size()]), fileObjects);
209 }
210
211 private boolean begin(Class<?> docletClass, String[] options, Iterable<? extends JavaFileObject> fileObjects) {
187 boolean failed = false; 212 boolean failed = false;
188 213
189 try { 214 try {
190 failed = !parseAndExecute(argv); 215 failed = !parseAndExecute(docletClass, options, fileObjects);
191 } catch (Messager.ExitJavadoc exc) { 216 } catch (Messager.ExitJavadoc exc) {
192 // ignore, we just exit this way 217 // ignore, we just exit this way
193 } catch (OutOfMemoryError ee) { 218 } catch (OutOfMemoryError ee) {
194 messager.error(Messager.NOPOS, "main.out.of.memory"); 219 messager.error(Messager.NOPOS, "main.out.of.memory");
195 failed = true; 220 failed = true;
221 } catch (ClientCodeException e) {
222 // simply rethrow these exceptions, to be caught and handled by JavadocTaskImpl
223 throw e;
196 } catch (Error ee) { 224 } catch (Error ee) {
197 ee.printStackTrace(System.err); 225 ee.printStackTrace(System.err);
198 messager.error(Messager.NOPOS, "main.fatal.error"); 226 messager.error(Messager.NOPOS, "main.fatal.error");
199 failed = true; 227 failed = true;
200 } catch (Exception ee) { 228 } catch (Exception ee) {
205 messager.exitNotice(); 233 messager.exitNotice();
206 messager.flush(); 234 messager.flush();
207 } 235 }
208 failed |= messager.nerrors() > 0; 236 failed |= messager.nerrors() > 0;
209 failed |= rejectWarnings && messager.nwarnings() > 0; 237 failed |= rejectWarnings && messager.nwarnings() > 0;
210 return failed ? 1 : 0; 238 return !failed;
211 } 239 }
212 240
213 /** 241 /**
214 * Main program - internal 242 * Main program - internal
215 */ 243 */
216 private boolean parseAndExecute(String... argv) throws IOException { 244 private boolean parseAndExecute(
245 Class<?> docletClass,
246 String[] argv,
247 Iterable<? extends JavaFileObject> fileObjects) throws IOException {
217 long tm = System.currentTimeMillis(); 248 long tm = System.currentTimeMillis();
218 249
219 ListBuffer<String> javaNames = new ListBuffer<String>(); 250 ListBuffer<String> javaNames = new ListBuffer<String>();
220 251
221 // Preprocess @file arguments 252 // Preprocess @file arguments
227 } catch (IOException e) { 258 } catch (IOException e) {
228 e.printStackTrace(System.err); 259 e.printStackTrace(System.err);
229 exit(); 260 exit();
230 } 261 }
231 262
232 setDocletInvoker(argv); 263
264 JavaFileManager fileManager = context.get(JavaFileManager.class);
265 setDocletInvoker(docletClass, fileManager, argv);
233 266
234 compOpts = Options.instance(context); 267 compOpts = Options.instance(context);
235 268
236 // Parse arguments 269 // Parse arguments
237 for (int i = 0 ; i < argv.length ; i++) { 270 for (int i = 0 ; i < argv.length ; i++) {
285 javaNames.append(arg); 318 javaNames.append(arg);
286 } 319 }
287 } 320 }
288 compOpts.notifyListeners(); 321 compOpts.notifyListeners();
289 322
290 if (javaNames.isEmpty() && subPackages.isEmpty()) { 323 if (javaNames.isEmpty() && subPackages.isEmpty() && isEmpty(fileObjects)) {
291 usageError("main.No_packages_or_classes_specified"); 324 usageError("main.No_packages_or_classes_specified");
292 } 325 }
293 326
294 if (!docletInvoker.validOptions(options.toList())) { 327 if (!docletInvoker.validOptions(options.toList())) {
295 // error message already displayed 328 // error message already displayed
308 docLocale, 341 docLocale,
309 encoding, 342 encoding,
310 showAccess, 343 showAccess,
311 javaNames.toList(), 344 javaNames.toList(),
312 options.toList(), 345 options.toList(),
346 fileObjects,
313 breakiterator, 347 breakiterator,
314 subPackages.toList(), 348 subPackages.toList(),
315 excludedPackages.toList(), 349 excludedPackages.toList(),
316 docClasses, 350 docClasses,
317 // legacy? 351 // legacy?
332 } 366 }
333 367
334 return ok; 368 return ok;
335 } 369 }
336 370
337 private void setDocletInvoker(String[] argv) { 371 private <T> boolean isEmpty(Iterable<T> iter) {
372 return !iter.iterator().hasNext();
373 }
374
375 /**
376 * Init the doclet invoker.
377 * The doclet class may be given explicitly, or via the -doclet option in
378 * argv.
379 * If the doclet class is not given explicitly, it will be loaded from
380 * the file manager's DOCLET_PATH location, if available, or via the
381 * -doclet path option in argv.
382 * @param docletClass The doclet class. May be null.
383 * @param fileManager The file manager used to get the class loader to load
384 * the doclet class if required. May be null.
385 * @param argv Args containing -doclet and -docletpath, in case they are required.
386 */
387 private void setDocletInvoker(Class<?> docletClass, JavaFileManager fileManager, String[] argv) {
388 if (docletClass != null) {
389 docletInvoker = new DocletInvoker(messager, docletClass, apiMode);
390 // TODO, check no -doclet, -docletpath
391 return;
392 }
393
338 String docletClassName = null; 394 String docletClassName = null;
339 String docletPath = null; 395 String docletPath = null;
340 396
341 // Parse doclet specifying arguments 397 // Parse doclet specifying arguments
342 for (int i = 0 ; i < argv.length ; i++) { 398 for (int i = 0 ; i < argv.length ; i++) {
343 String arg = argv[i]; 399 String arg = argv[i];
344 if (arg.equals("-doclet")) { 400 if (arg.equals(ToolOption.DOCLET.opt)) {
345 oneArg(argv, i++); 401 oneArg(argv, i++);
346 if (docletClassName != null) { 402 if (docletClassName != null) {
347 usageError("main.more_than_one_doclet_specified_0_and_1", 403 usageError("main.more_than_one_doclet_specified_0_and_1",
348 docletClassName, argv[i]); 404 docletClassName, argv[i]);
349 } 405 }
350 docletClassName = argv[i]; 406 docletClassName = argv[i];
351 } else if (arg.equals("-docletpath")) { 407 } else if (arg.equals(ToolOption.DOCLETPATH.opt)) {
352 oneArg(argv, i++); 408 oneArg(argv, i++);
353 if (docletPath == null) { 409 if (docletPath == null) {
354 docletPath = argv[i]; 410 docletPath = argv[i];
355 } else { 411 } else {
356 docletPath += File.pathSeparator + argv[i]; 412 docletPath += File.pathSeparator + argv[i];
361 if (docletClassName == null) { 417 if (docletClassName == null) {
362 docletClassName = defaultDocletClassName; 418 docletClassName = defaultDocletClassName;
363 } 419 }
364 420
365 // attempt to find doclet 421 // attempt to find doclet
366 docletInvoker = new DocletInvoker(messager, 422 docletInvoker = new DocletInvoker(messager, fileManager,
367 docletClassName, docletPath, 423 docletClassName, docletPath,
368 docletParentClassLoader); 424 docletParentClassLoader,
425 apiMode);
369 } 426 }
370 427
371 /** 428 /**
372 * Set one arg option. 429 * Set one arg option.
373 * Error and exit if one argument is not provided. 430 * Error and exit if one argument is not provided.

mercurial