30 import java.lang.reflect.Method; |
30 import java.lang.reflect.Method; |
31 import java.lang.reflect.Modifier; |
31 import java.lang.reflect.Modifier; |
32 import java.net.URL; |
32 import java.net.URL; |
33 import java.net.URLClassLoader; |
33 import java.net.URLClassLoader; |
34 |
34 |
|
35 import javax.tools.DocumentationTool; |
|
36 import javax.tools.JavaFileManager; |
|
37 |
35 import com.sun.javadoc.*; |
38 import com.sun.javadoc.*; |
|
39 import com.sun.tools.javac.file.Locations; |
|
40 import com.sun.tools.javac.util.ClientCodeException; |
36 import com.sun.tools.javac.util.List; |
41 import com.sun.tools.javac.util.List; |
37 import static com.sun.javadoc.LanguageVersion.*; |
42 import static com.sun.javadoc.LanguageVersion.*; |
38 |
43 |
39 |
44 |
40 /** |
45 /** |
54 private final String docletClassName; |
59 private final String docletClassName; |
55 |
60 |
56 private final ClassLoader appClassLoader; |
61 private final ClassLoader appClassLoader; |
57 |
62 |
58 private final Messager messager; |
63 private final Messager messager; |
|
64 |
|
65 /** |
|
66 * In API mode, exceptions thrown while calling the doclet are |
|
67 * propagated using ClientCodeException. |
|
68 */ |
|
69 private final boolean apiMode; |
59 |
70 |
60 private static class DocletInvokeException extends Exception { |
71 private static class DocletInvokeException extends Exception { |
61 private static final long serialVersionUID = 0; |
72 private static final long serialVersionUID = 0; |
62 } |
73 } |
63 |
74 |
69 } else { |
80 } else { |
70 return path1 + File.pathSeparator + path2; |
81 return path1 + File.pathSeparator + path2; |
71 } |
82 } |
72 } |
83 } |
73 |
84 |
74 public DocletInvoker(Messager messager, |
85 public DocletInvoker(Messager messager, Class<?> docletClass, boolean apiMode) { |
|
86 this.messager = messager; |
|
87 this.docletClass = docletClass; |
|
88 docletClassName = docletClass.getName(); |
|
89 appClassLoader = null; |
|
90 this.apiMode = apiMode; |
|
91 } |
|
92 |
|
93 public DocletInvoker(Messager messager, JavaFileManager fileManager, |
75 String docletClassName, String docletPath, |
94 String docletClassName, String docletPath, |
76 ClassLoader docletParentClassLoader) { |
95 ClassLoader docletParentClassLoader, |
|
96 boolean apiMode) { |
77 this.messager = messager; |
97 this.messager = messager; |
78 this.docletClassName = docletClassName; |
98 this.docletClassName = docletClassName; |
79 |
99 this.apiMode = apiMode; |
80 // construct class loader |
100 |
81 String cpString = null; // make sure env.class.path defaults to dot |
101 if (fileManager != null && fileManager.hasLocation(DocumentationTool.Location.DOCLET_PATH)) { |
82 |
102 appClassLoader = fileManager.getClassLoader(DocumentationTool.Location.DOCLET_PATH); |
83 // do prepends to get correct ordering |
103 } else { |
84 cpString = appendPath(System.getProperty("env.class.path"), cpString); |
104 // construct class loader |
85 cpString = appendPath(System.getProperty("java.class.path"), cpString); |
105 String cpString = null; // make sure env.class.path defaults to dot |
86 cpString = appendPath(docletPath, cpString); |
106 |
87 URL[] urls = com.sun.tools.javac.file.Locations.pathToURLs(cpString); |
107 // do prepends to get correct ordering |
88 if (docletParentClassLoader == null) |
108 cpString = appendPath(System.getProperty("env.class.path"), cpString); |
89 appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName)); |
109 cpString = appendPath(System.getProperty("java.class.path"), cpString); |
90 else |
110 cpString = appendPath(docletPath, cpString); |
91 appClassLoader = new URLClassLoader(urls, docletParentClassLoader); |
111 URL[] urls = Locations.pathToURLs(cpString); |
|
112 if (docletParentClassLoader == null) |
|
113 appClassLoader = new URLClassLoader(urls, getDelegationClassLoader(docletClassName)); |
|
114 else |
|
115 appClassLoader = new URLClassLoader(urls, docletParentClassLoader); |
|
116 } |
92 |
117 |
93 // attempt to find doclet |
118 // attempt to find doclet |
94 Class<?> dc = null; |
119 Class<?> dc = null; |
95 try { |
120 try { |
96 dc = appClassLoader.loadClass(docletClassName); |
121 dc = appClassLoader.loadClass(docletClassName); |
278 throw new DocletInvokeException(); |
303 throw new DocletInvokeException(); |
279 } |
304 } |
280 ClassLoader savedCCL = |
305 ClassLoader savedCCL = |
281 Thread.currentThread().getContextClassLoader(); |
306 Thread.currentThread().getContextClassLoader(); |
282 try { |
307 try { |
283 Thread.currentThread().setContextClassLoader(appClassLoader); |
308 if (appClassLoader != null) // will be null if doclet class provided via API |
|
309 Thread.currentThread().setContextClassLoader(appClassLoader); |
284 return meth.invoke(null , params); |
310 return meth.invoke(null , params); |
285 } catch (IllegalArgumentException exc) { |
311 } catch (IllegalArgumentException exc) { |
286 messager.error(Messager.NOPOS, "main.internal_error_exception_thrown", |
312 messager.error(Messager.NOPOS, "main.internal_error_exception_thrown", |
287 docletClassName, methodName, exc.toString()); |
313 docletClassName, methodName, exc.toString()); |
288 throw new DocletInvokeException(); |
314 throw new DocletInvokeException(); |
294 messager.error(Messager.NOPOS, "main.internal_error_exception_thrown", |
320 messager.error(Messager.NOPOS, "main.internal_error_exception_thrown", |
295 docletClassName, methodName, exc.toString()); |
321 docletClassName, methodName, exc.toString()); |
296 throw new DocletInvokeException(); |
322 throw new DocletInvokeException(); |
297 } catch (InvocationTargetException exc) { |
323 } catch (InvocationTargetException exc) { |
298 Throwable err = exc.getTargetException(); |
324 Throwable err = exc.getTargetException(); |
|
325 if (apiMode) |
|
326 throw new ClientCodeException(err); |
299 if (err instanceof java.lang.OutOfMemoryError) { |
327 if (err instanceof java.lang.OutOfMemoryError) { |
300 messager.error(Messager.NOPOS, "main.out.of.memory"); |
328 messager.error(Messager.NOPOS, "main.out.of.memory"); |
301 } else { |
329 } else { |
302 messager.error(Messager.NOPOS, "main.exception_thrown", |
330 messager.error(Messager.NOPOS, "main.exception_thrown", |
303 docletClassName, methodName, exc.toString()); |
331 docletClassName, methodName, exc.toString()); |
304 exc.getTargetException().printStackTrace(); |
332 exc.getTargetException().printStackTrace(); |
305 } |
333 } |
306 throw new DocletInvokeException(); |
334 throw new DocletInvokeException(); |
307 } finally { |
335 } finally { |