langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java
changeset 40587 1c355ea550ed
parent 40303 96a1226aca18
child 43261 d377e97291d8
equal deleted inserted replaced
40519:e17429a7e843 40587:1c355ea550ed
    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 /**
    89      * The configuration used in this run of the doclet.
    91      * The configuration used in this run of the doclet.
    90      */
    92      */
    91     protected final Configuration configuration;
    93     protected final Configuration configuration;
    92 
    94 
    93     protected final Messages messages;
    95     protected final Messages messages;
       
    96     protected final Resources resources;
    94     protected final Utils utils;
    97     protected final Utils utils;
    95 
    98 
    96     /**
    99     /**
    97      * Keep track of which packages we have seen for
   100      * Keep track of which packages we have seen for
    98      * efficiency purposes.  We don't want to copy the
   101      * efficiency purposes.  We don't want to copy the
   107      */
   110      */
   108     protected static final boolean DEBUG = false;
   111     protected static final boolean DEBUG = false;
   109 
   112 
   110     /**
   113     /**
   111      * Construct a Builder.
   114      * Construct a Builder.
   112      * @param configuration the configuration used in this run
   115      * @param c a context providing information used in this run of the doclet
   113      *        of the doclet.
       
   114      */
   116      */
   115     public AbstractBuilder(Context c) {
   117     public AbstractBuilder(Context c) {
   116         this.configuration = c.configuration;
   118         this.configuration = c.configuration;
   117         this.messages = configuration.getMessages();
   119         this.messages = configuration.getMessages();
       
   120         this.resources = configuration.getResources();
   118         this.utils = configuration.utils;
   121         this.utils = configuration.utils;
   119         this.containingPackagesSeen = c.containingPackagesSeen;
   122         this.containingPackagesSeen = c.containingPackagesSeen;
   120         this.layoutParser = c.layoutParser;
   123         this.layoutParser = c.layoutParser;
   121     }
   124     }
   122 
   125 
   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 }