23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package jdk.javadoc.internal.doclets.toolkit.builders; |
26 package jdk.javadoc.internal.doclets.toolkit.builders; |
27 |
27 |
28 import java.io.*; |
|
29 import java.lang.reflect.*; |
28 import java.lang.reflect.*; |
30 import java.util.*; |
29 import java.util.*; |
31 |
30 |
32 import javax.lang.model.element.PackageElement; |
31 import javax.lang.model.element.PackageElement; |
33 |
32 |
34 import jdk.javadoc.internal.doclets.toolkit.Configuration; |
33 import jdk.javadoc.internal.doclets.toolkit.Configuration; |
35 import jdk.javadoc.internal.doclets.toolkit.Content; |
34 import jdk.javadoc.internal.doclets.toolkit.Content; |
|
35 import jdk.javadoc.internal.doclets.toolkit.DocletException; |
36 import jdk.javadoc.internal.doclets.toolkit.Messages; |
36 import jdk.javadoc.internal.doclets.toolkit.Messages; |
37 import jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException; |
37 import jdk.javadoc.internal.doclets.toolkit.Resources; |
|
38 import jdk.javadoc.internal.doclets.toolkit.util.InternalException; |
|
39 import jdk.javadoc.internal.doclets.toolkit.util.SimpleDocletException; |
38 import jdk.javadoc.internal.doclets.toolkit.util.Utils; |
40 import jdk.javadoc.internal.doclets.toolkit.util.Utils; |
39 |
41 |
40 import static javax.tools.Diagnostic.Kind.*; |
42 import static javax.tools.Diagnostic.Kind.*; |
41 |
43 |
42 /** |
44 /** |
128 public abstract String getName(); |
131 public abstract String getName(); |
129 |
132 |
130 /** |
133 /** |
131 * Build the documentation. |
134 * Build the documentation. |
132 * |
135 * |
133 * @throws IOException there was a problem writing the output. |
136 * @throws DocletException if there is a problem building the documentation |
134 */ |
137 */ |
135 public abstract void build() throws IOException; |
138 public abstract void build() throws DocletException; |
136 |
139 |
137 /** |
140 /** |
138 * Build the documentation, as specified by the given XML element. |
141 * Build the documentation, as specified by the given XML element. |
139 * |
142 * |
140 * @param node the XML element that specifies which component to document. |
143 * @param node the XML element that specifies which component to document. |
141 * @param contentTree content tree to which the documentation will be added |
144 * @param contentTree content tree to which the documentation will be added |
|
145 * @throws DocletException if there is a problem building the documentation |
142 */ |
146 */ |
143 protected void build(XMLNode node, Content contentTree) { |
147 protected void build(XMLNode node, Content contentTree) throws DocletException { |
144 String component = node.name; |
148 String component = node.name; |
145 try { |
149 try { |
146 invokeMethod("build" + component, |
150 String methodName = "build" + component; |
147 new Class<?>[]{XMLNode.class, Content.class}, |
151 if (DEBUG) { |
148 new Object[]{node, contentTree}); |
152 configuration.reporter.print(ERROR, |
|
153 "DEBUG: " + getClass().getName() + "." + methodName); |
|
154 } |
|
155 Method method = getClass().getMethod(methodName, XMLNode.class, Content.class); |
|
156 method.invoke(this, node, contentTree); |
|
157 |
149 } catch (NoSuchMethodException e) { |
158 } catch (NoSuchMethodException e) { |
150 e.printStackTrace(System.err); |
159 // Use SimpleDocletException instead of InternalException because there is nothing |
151 configuration.reporter.print(ERROR, "Unknown element: " + component); |
160 // informative about about the place the exception occurred, here in this method. |
152 throw new DocletAbortException(e); |
161 // The problem is either a misconfigured doclet.xml file or a missing method in the |
|
162 // user-supplied(?) doclet |
|
163 String message = resources.getText("doclet.builder.unknown.component", component); |
|
164 throw new SimpleDocletException(message, e); |
|
165 |
153 } catch (InvocationTargetException e) { |
166 } catch (InvocationTargetException e) { |
154 Throwable cause = e.getCause(); |
167 Throwable cause = e.getCause(); |
155 if (cause instanceof DocletAbortException) { |
168 if (cause instanceof DocletException) { |
156 throw (DocletAbortException) cause; |
169 throw (DocletException) cause; |
157 } else { |
170 } else { |
158 throw new DocletAbortException(e.getCause()); |
171 // use InternalException, so that a stacktrace showing the position of |
|
172 // the internal exception is generated |
|
173 String message = resources.getText("doclet.builder.exception.in.component", component, |
|
174 e.getCause()); |
|
175 throw new InternalException(message, e.getCause()); |
159 } |
176 } |
160 } catch (Exception e) { |
177 |
161 e.printStackTrace(System.err); |
178 } catch (ReflectiveOperationException e) { |
162 configuration.reporter.print(ERROR, "Exception " + |
179 // Use SimpleDocletException instead of InternalException because there is nothing |
163 e.getClass().getName() + |
180 // informative about about the place the exception occurred, here in this method. |
164 " thrown while processing element: " + component); |
181 // The problem is specific to the method being invoked, such as illegal access |
165 throw new DocletAbortException(e); |
182 // or illegal argument. |
|
183 String message = resources.getText("doclet.builder.exception.in.component", component, e); |
|
184 throw new SimpleDocletException(message, e.getCause()); |
166 } |
185 } |
167 } |
186 } |
168 |
187 |
169 /** |
188 /** |
170 * Build the documentation, as specified by the children of the given XML element. |
189 * Build the documentation, as specified by the children of the given XML element. |
171 * |
190 * |
172 * @param node the XML element that specifies which components to document. |
191 * @param node the XML element that specifies which components to document. |
173 * @param contentTree content tree to which the documentation will be added |
192 * @param contentTree content tree to which the documentation will be added |
|
193 * @throws DocletException if there is a problem while building the children |
174 */ |
194 */ |
175 protected void buildChildren(XMLNode node, Content contentTree) { |
195 protected void buildChildren(XMLNode node, Content contentTree) throws DocletException { |
176 for (XMLNode child : node.children) |
196 for (XMLNode child : node.children) |
177 build(child, contentTree); |
197 build(child, contentTree); |
178 } |
198 } |
179 |
|
180 /** |
|
181 * Given the name and parameters, invoke the method in the builder. This |
|
182 * method is required to invoke the appropriate build method as instructed |
|
183 * by the builder XML file. |
|
184 * |
|
185 * @param methodName the name of the method that we would like to invoke. |
|
186 * @param paramClasses the types for each parameter. |
|
187 * @param params the parameters of the method. |
|
188 */ |
|
189 protected void invokeMethod(String methodName, Class<?>[] paramClasses, |
|
190 Object[] params) |
|
191 throws Exception { |
|
192 if (DEBUG) { |
|
193 configuration.reporter.print(ERROR, "DEBUG: " + |
|
194 this.getClass().getName() + "." + methodName); |
|
195 } |
|
196 Method method = this.getClass().getMethod(methodName, paramClasses); |
|
197 method.invoke(this, params); |
|
198 } |
|
199 } |
199 } |