src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/AbstractBuilder.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 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  */
  25 
  26 package com.sun.tools.doclets.internal.toolkit.builders;
  27 
  28 import java.io.*;
  29 import java.lang.reflect.*;
  30 import java.util.*;
  31 
  32 import com.sun.javadoc.PackageDoc;
  33 import com.sun.tools.doclets.internal.toolkit.*;
  34 import com.sun.tools.doclets.internal.toolkit.util.*;
  35 







  36 /**
  37  * The superclass for all builders.  A builder is a class that provides
  38  * the structure and content of API documentation.  A builder is completely
  39  * doclet independent which means that any doclet can use builders to
  40  * construct documentation, as long as it impelements the appropriate
  41  * writer interfaces.  For example, if a doclet wanted to use
  42  * {@link ConstantsSummaryBuilder} to build a constant summary, all it has to
  43  * do is implement the ConstantsSummaryWriter interface and pass it to the
  44  * builder using a WriterFactory.
  45  *
  46  *  <p><b>This is NOT part of any supported API.
  47  *  If you write code that depends on this, you do so at your own risk.
  48  *  This code and its internal interfaces are subject to change or
  49  *  deletion without notice.</b>
  50  *
  51  * @author Jamie Ho
  52  * @since 1.5
  53  */
  54 
  55 public abstract class AbstractBuilder {
  56     public static class Context {
  57         /**
  58          * The configuration used in this run of the doclet.
  59          */
  60         final Configuration configuration;
  61 
  62         /**
  63          * Keep track of which packages we have seen for
  64          * efficiency purposes.  We don't want to copy the
  65          * doc files multiple times for a single package.
  66          */
  67         final Set<PackageDoc> containingPackagesSeen;
  68 
  69         /**
  70          * Shared parser for the builder XML file
  71          */
  72         final LayoutParser layoutParser;
  73 
  74         Context(Configuration configuration,
  75                 Set<PackageDoc> containingPackagesSeen,
  76                 LayoutParser layoutParser) {
  77             this.configuration = configuration;
  78             this.containingPackagesSeen = containingPackagesSeen;
  79             this.layoutParser = layoutParser;
  80         }
  81     }
  82 
  83     /**
  84      * The configuration used in this run of the doclet.
  85      */
  86     protected final Configuration configuration;
  87 
  88     protected final Utils utils;
  89 
  90     /**
  91      * Keep track of which packages we have seen for
  92      * efficiency purposes.  We don't want to copy the
  93      * doc files multiple times for a single package.
  94      */
  95     protected final Set<PackageDoc> containingPackagesSeen;
  96 
  97     protected final LayoutParser layoutParser;
  98 
  99     /**
 100      * True if we want to print debug output.
 101      */
 102     protected static final boolean DEBUG = false;
 103 
 104     /**
 105      * Construct a Builder.
 106      * @param configuration the configuration used in this run
 107      *        of the doclet.
 108      */
 109     public AbstractBuilder(Context c) {
 110         this.configuration = c.configuration;
 111         this.utils = configuration.utils;
 112         this.containingPackagesSeen = c.containingPackagesSeen;
 113         this.layoutParser = c.layoutParser;
 114     }
 115 


 124      * Build the documentation.
 125      *
 126      * @throws IOException there was a problem writing the output.
 127      */
 128     public abstract void build() throws IOException;
 129 
 130     /**
 131      * Build the documentation, as specified by the given XML element.
 132      *
 133      * @param node the XML element that specifies which component to document.
 134      * @param contentTree content tree to which the documentation will be added
 135      */
 136     protected void build(XMLNode node, Content contentTree) {
 137         String component = node.name;
 138         try {
 139             invokeMethod("build" + component,
 140                     new Class<?>[]{XMLNode.class, Content.class},
 141                     new Object[]{node, contentTree});
 142         } catch (NoSuchMethodException e) {
 143             e.printStackTrace();
 144             configuration.root.printError("Unknown element: " + component);
 145             throw new DocletAbortException(e);
 146         } catch (InvocationTargetException e) {
 147             throw new DocletAbortException(e.getCause());
 148         } catch (Exception e) {
 149             e.printStackTrace();
 150             configuration.root.printError("Exception " +
 151                     e.getClass().getName() +
 152                     " thrown while processing element: " + component);
 153             throw new DocletAbortException(e);
 154         }
 155     }
 156 
 157     /**
 158      * Build the documentation, as specified by the children of the given XML element.
 159      *
 160      * @param node the XML element that specifies which components to document.
 161      * @param contentTree content tree to which the documentation will be added
 162      */
 163     protected void buildChildren(XMLNode node, Content contentTree) {
 164         for (XMLNode child : node.children)
 165             build(child, contentTree);
 166     }
 167 
 168     /**
 169      * Given the name and parameters, invoke the method in the builder.  This
 170      * method is required to invoke the appropriate build method as instructed
 171      * by the builder XML file.
 172      *
 173      * @param methodName   the name of the method that we would like to invoke.
 174      * @param paramClasses the types for each parameter.
 175      * @param params       the parameters of the method.
 176      */
 177     protected void invokeMethod(String methodName, Class<?>[] paramClasses,
 178             Object[] params)
 179     throws Exception {
 180         if (DEBUG) {
 181             configuration.root.printError("DEBUG: " + this.getClass().getName() + "." + methodName);

 182         }
 183         Method method = this.getClass().getMethod(methodName, paramClasses);
 184         method.invoke(this, params);
 185     }
 186 }
   1 /*
   2  * Copyright (c) 2003, 2015, 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  */
  25 
  26 package jdk.javadoc.internal.doclets.toolkit.builders;
  27 
  28 import java.io.*;
  29 import java.lang.reflect.*;
  30 import java.util.*;
  31 
  32 import javax.lang.model.element.PackageElement;


  33 
  34 import jdk.javadoc.internal.doclets.toolkit.Configuration;
  35 import jdk.javadoc.internal.doclets.toolkit.Content;
  36 import jdk.javadoc.internal.doclets.toolkit.util.DocletAbortException;
  37 import jdk.javadoc.internal.doclets.toolkit.util.Utils;
  38 
  39 import static javax.tools.Diagnostic.Kind.*;
  40 
  41 /**
  42  * The superclass for all builders.  A builder is a class that provides
  43  * the structure and content of API documentation.  A builder is completely
  44  * doclet independent which means that any doclet can use builders to
  45  * construct documentation, as long as it impelements the appropriate
  46  * writer interfaces.  For example, if a doclet wanted to use
  47  * {@link ConstantsSummaryBuilder} to build a constant summary, all it has to
  48  * do is implement the ConstantsSummaryWriter interface and pass it to the
  49  * builder using a WriterFactory.
  50  *
  51  *  <p><b>This is NOT part of any supported API.
  52  *  If you write code that depends on this, you do so at your own risk.
  53  *  This code and its internal interfaces are subject to change or
  54  *  deletion without notice.</b>
  55  *
  56  * @author Jamie Ho
  57  * @since 1.5
  58  */
  59 
  60 public abstract class AbstractBuilder {
  61     public static class Context {
  62         /**
  63          * The configuration used in this run of the doclet.
  64          */
  65         final Configuration configuration;
  66 
  67         /**
  68          * Keep track of which packages we have seen for
  69          * efficiency purposes.  We don't want to copy the
  70          * doc files multiple times for a single package.
  71          */
  72         final Set<PackageElement> containingPackagesSeen;
  73 
  74         /**
  75          * Shared parser for the builder XML file
  76          */
  77         final LayoutParser layoutParser;
  78 
  79         Context(Configuration configuration,
  80                 Set<PackageElement> containingPackagesSeen,
  81                 LayoutParser layoutParser) {
  82             this.configuration = configuration;
  83             this.containingPackagesSeen = containingPackagesSeen;
  84             this.layoutParser = layoutParser;
  85         }
  86     }
  87 
  88     /**
  89      * The configuration used in this run of the doclet.
  90      */
  91     protected final Configuration configuration;
  92 
  93     protected final Utils utils;
  94 
  95     /**
  96      * Keep track of which packages we have seen for
  97      * efficiency purposes.  We don't want to copy the
  98      * doc files multiple times for a single package.
  99      */
 100     protected final Set<PackageElement> containingPackagesSeen;
 101 
 102     protected final LayoutParser layoutParser;
 103 
 104     /**
 105      * True if we want to print debug output.
 106      */
 107     protected static final boolean DEBUG = false;
 108 
 109     /**
 110      * Construct a Builder.
 111      * @param configuration the configuration used in this run
 112      *        of the doclet.
 113      */
 114     public AbstractBuilder(Context c) {
 115         this.configuration = c.configuration;
 116         this.utils = configuration.utils;
 117         this.containingPackagesSeen = c.containingPackagesSeen;
 118         this.layoutParser = c.layoutParser;
 119     }
 120 


 129      * Build the documentation.
 130      *
 131      * @throws IOException there was a problem writing the output.
 132      */
 133     public abstract void build() throws IOException;
 134 
 135     /**
 136      * Build the documentation, as specified by the given XML element.
 137      *
 138      * @param node the XML element that specifies which component to document.
 139      * @param contentTree content tree to which the documentation will be added
 140      */
 141     protected void build(XMLNode node, Content contentTree) {
 142         String component = node.name;
 143         try {
 144             invokeMethod("build" + component,
 145                     new Class<?>[]{XMLNode.class, Content.class},
 146                     new Object[]{node, contentTree});
 147         } catch (NoSuchMethodException e) {
 148             e.printStackTrace();
 149             configuration.reporter.print(ERROR, "Unknown element: " + component);
 150             throw new DocletAbortException(e);
 151         } catch (InvocationTargetException e) {
 152             throw new DocletAbortException(e.getCause());
 153         } catch (Exception e) {
 154             e.printStackTrace();
 155             configuration.reporter.print(ERROR, "Exception " +
 156                     e.getClass().getName() +
 157                     " thrown while processing element: " + component);
 158             throw new DocletAbortException(e);
 159         }
 160     }
 161 
 162     /**
 163      * Build the documentation, as specified by the children of the given XML element.
 164      *
 165      * @param node the XML element that specifies which components to document.
 166      * @param contentTree content tree to which the documentation will be added
 167      */
 168     protected void buildChildren(XMLNode node, Content contentTree) {
 169         for (XMLNode child : node.children)
 170             build(child, contentTree);
 171     }
 172 
 173     /**
 174      * Given the name and parameters, invoke the method in the builder.  This
 175      * method is required to invoke the appropriate build method as instructed
 176      * by the builder XML file.
 177      *
 178      * @param methodName   the name of the method that we would like to invoke.
 179      * @param paramClasses the types for each parameter.
 180      * @param params       the parameters of the method.
 181      */
 182     protected void invokeMethod(String methodName, Class<?>[] paramClasses,
 183             Object[] params)
 184     throws Exception {
 185         if (DEBUG) {
 186             configuration.reporter.print(ERROR, "DEBUG: " +
 187                     this.getClass().getName() + "." + methodName);
 188         }
 189         Method method = this.getClass().getMethod(methodName, paramClasses);
 190         method.invoke(this, params);
 191     }
 192 }