src/share/classes/com/sun/tools/doclets/internal/toolkit/util/SourceToHTMLConverter.java

Tue, 25 May 2010 15:54:51 -0700

author
ohair
date
Tue, 25 May 2010 15:54:51 -0700
changeset 554
9d9f26857129
parent 229
03bcd66bd8e7
permissions
-rw-r--r--

6943119: Rebrand source copyright notices
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 2001, 2009, 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  */
    26 package com.sun.tools.doclets.internal.toolkit.util;
    28 import java.io.*;
    29 import java.util.*;
    30 import javax.tools.FileObject;
    32 import com.sun.javadoc.*;
    33 import com.sun.tools.doclets.internal.toolkit.*;
    35 /**
    36  * Converts Java Source Code to HTML.
    37  *
    38  * This code is not part of an API.
    39  * It is implementation that is subject to change.
    40  * Do not use it as an API
    41  *
    42  * @author Jamie Ho
    43  * @since 1.4
    44  */
    45 public class SourceToHTMLConverter {
    47     /**
    48      * The background color.
    49      */
    50     protected static final String BGCOLOR = "white";
    52     /**
    53      * The line number color.
    54      */
    55     protected static final String LINE_NO_COLOR = "green";
    57     /**
    58      * The number of trailing blank lines at the end of the page.
    59      * This is inserted so that anchors at the bottom of small pages
    60      * can be reached.
    61      */
    62     protected static final int NUM_BLANK_LINES = 60;
    65     /**
    66      * Source is converted to HTML using static methods below.
    67      */
    68     private SourceToHTMLConverter() {}
    70     /**
    71      * Convert the Classes in the given RootDoc to an HTML.
    72      * @param configuration the configuration.
    73      * @param rd the RootDoc to convert.
    74      * @param outputdir the name of the directory to output to.
    75      */
    76     public static void convertRoot(Configuration configuration, RootDoc rd, String outputdir) {
    77         if (rd == null || outputdir == null) {
    78             return;
    79         }
    80         PackageDoc[] pds = rd.specifiedPackages();
    81         for (int i = 0; i < pds.length; i++) {
    82             convertPackage(configuration, pds[i], outputdir);
    83         }
    84         ClassDoc[] cds = rd.specifiedClasses();
    85         for (int i = 0; i < cds.length; i++) {
    86             convertClass(configuration, cds[i],
    87                 getPackageOutputDir(outputdir, cds[i].containingPackage()));
    88         }
    89     }
    91     /**
    92      * Convert the Classes in the given Package to an HTML.
    93      * @param configuration the configuration.
    94      * @param pd the Package to convert.
    95      * @param outputdir the name of the directory to output to.
    96      */
    97     public static void convertPackage(Configuration configuration, PackageDoc pd, String outputdir) {
    98         if (pd == null || outputdir == null) {
    99             return;
   100         }
   101         String classOutputdir = getPackageOutputDir(outputdir, pd);
   102         ClassDoc[] cds = pd.allClasses();
   103         for (int i = 0; i < cds.length; i++) {
   104             convertClass(configuration, cds[i], classOutputdir);
   105         }
   106     }
   108     /**
   109      * Return the directory write output to for the given package.
   110      * @param outputDir the directory to output to.
   111      * @param pd the Package to generate output for.
   112      */
   113     private static String getPackageOutputDir(String outputDir, PackageDoc pd) {
   114         return outputDir + File.separator +
   115             DirectoryManager.getDirectoryPath(pd) + File.separator;
   116     }
   118     /**
   119      * Convert the given Class to an HTML.
   120      * @param configuration the configuration.
   121      * @param cd the class to convert.
   122      * @param outputdir the name of the directory to output to.
   123      */
   124     public static void convertClass(Configuration configuration, ClassDoc cd, String outputdir) {
   125         if (cd == null || outputdir == null) {
   126             return;
   127         }
   128         try {
   129             SourcePosition sp = cd.position();
   130             if (sp == null)
   131                 return;
   132             Reader r;
   133             // temp hack until we can update SourcePosition API.
   134             if (sp instanceof com.sun.tools.javadoc.SourcePositionImpl) {
   135                 FileObject fo = ((com.sun.tools.javadoc.SourcePositionImpl) sp).fileObject();
   136                 if (fo == null)
   137                     return;
   138                 r = fo.openReader(true);
   139             } else {
   140                 File file = sp.file();
   141                 if (file == null)
   142                     return;
   143                 r = new FileReader(file);
   144             }
   145             LineNumberReader reader = new LineNumberReader(r);
   146             int lineno = 1;
   147             String line;
   148             StringBuffer output = new StringBuffer();
   149             try {
   150                 while ((line = reader.readLine()) != null) {
   151                     output.append(formatLine(line, configuration.sourcetab, lineno));
   152                     lineno++;
   153                 }
   154             } finally {
   155                 reader.close();
   156             }
   157             output = addLineNumbers(output.toString());
   158             output.insert(0, getHeader(configuration));
   159             output.append(getFooter());
   160             writeToFile(output.toString(), outputdir, cd.name(), configuration);
   161         } catch (Exception e){
   162             e.printStackTrace();
   163         }
   164     }
   166     /**
   167      * Write the output to the file.
   168      * @param output the string to output.
   169      * @param outputDir the directory to output to.
   170      * @param className the name of the class that I am converting to HTML.
   171      * @param configuration the Doclet configuration to pass notices to.
   172      */
   173     private static void writeToFile(String output, String outputDir, String className, Configuration configuration) throws IOException {
   174         File dir = new File(outputDir);
   175         dir.mkdirs();
   176         File newFile = new File(dir, className + ".html");
   177         configuration.message.notice("doclet.Generating_0", newFile.getPath());
   178         FileOutputStream fout = new FileOutputStream(newFile);
   179         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fout));
   180         bw.write(output);
   181         bw.close();
   182         fout.close();
   183     }
   185     /**
   186      * Given a <code>String</code>, add line numbers.
   187      * @param s the text to add line numbers to.
   188      *
   189      * @return the string buffer with the line numbering for each line.
   190      */
   191     private static StringBuffer addLineNumbers(String s) {
   192         StringBuffer sb = new StringBuffer();
   193         StringTokenizer st = new StringTokenizer(s, "\n", true);
   194         int lineno = 1;
   195         String current;
   196         while(st.hasMoreTokens()){
   197             current = st.nextToken();
   198             sb.append(current.equals("\n") ?
   199                     getHTMLLineNo(lineno) + current :
   200                     getHTMLLineNo(lineno) + current + st.nextToken());
   201             lineno++;
   202         }
   203         return sb;
   204     }
   206     /**
   207      * Get the header.
   208      * @param configuration the Doclet configuration
   209      * @return the header to the output file
   210      */
   211     protected static String getHeader(Configuration configuration) {
   212         StringBuffer result = new StringBuffer("<HTML lang=\"" + configuration.getLocale().getLanguage() + "\">" + DocletConstants.NL);
   213         result.append("<BODY BGCOLOR=\""+ BGCOLOR + "\">" + DocletConstants.NL);
   214         result.append("<PRE>" + DocletConstants.NL);
   215         return result.toString();
   216     }
   218     /**
   219      * Get the footer
   220      * @return the footer to the output file
   221      */
   222     protected static String getFooter() {
   223         StringBuffer footer = new StringBuffer();
   224         for (int i = 0; i < NUM_BLANK_LINES; i++) {
   225             footer.append(DocletConstants.NL);
   226         }
   227         footer.append("</PRE>" + DocletConstants.NL + "</BODY>" +
   228             DocletConstants.NL + "</HTML>" + DocletConstants.NL);
   229         return footer.toString();
   230     }
   232     /**
   233      * Get the HTML for the lines.
   234      * @param lineno The line number
   235      * @return the HTML code for the line
   236      */
   237     protected static String getHTMLLineNo(int lineno) {
   238         StringBuffer result = new StringBuffer("<FONT color=\"" + LINE_NO_COLOR
   239             + "\">");
   240         if (lineno < 10) {
   241             result.append("00" + ((new Integer(lineno)).toString()));
   242         } else if (lineno < 100) {
   243             result.append("0" + ((new Integer(lineno)).toString()));
   244         } else {
   245             result.append((new Integer(lineno)).toString());
   246         }
   247         result.append("</FONT>    ");
   248         return result.toString();
   249     }
   251     /**
   252      * Format a given line of source. <br>
   253      * Note:  In the future, we will add special colors for constructs in the
   254      * language.
   255      * @param line the string to format.
   256      * @param tabLength the number of spaces for each tab.
   257      * @param currentLineNo the current number.
   258      */
   259     protected static String formatLine(String line, int tabLength, int currentLineNo) {
   260         if (line == null) {
   261             return null;
   262         }
   263         StringBuffer lineBuffer = new StringBuffer(Util.escapeHtmlChars(line));
   264         //Insert an anchor for the line
   265         lineBuffer.append("<a name=\"line." + Integer.toString(currentLineNo) + "\"></a>");
   266         lineBuffer.append(DocletConstants.NL);
   267         Util.replaceTabs(tabLength, lineBuffer);
   268         return lineBuffer.toString();
   269     }
   271     /**
   272      * Given an array of <code>Doc</code>s, add to the given <code>HashMap</code> the
   273      * line numbers and anchors that should be inserted in the output at those lines.
   274      * @param docs the array of <code>Doc</code>s to add anchors for.
   275      * @param hash the <code>HashMap</code> to add to.
   276      */
   277     protected static void addToHash(Doc[] docs, HashMap<Integer,String> hash) {
   278         if(docs == null) {
   279             return;
   280         }
   281         for(int i = 0; i < docs.length; i++) {
   282             hash.put(docs[i].position().line(), getAnchor(docs[i]));
   283         }
   284     }
   286     /**
   287      * Given a <code>Doc</code>, return an anchor for it.
   288      * @param d the <code>Doc</code> to check.
   289      * @return an anchor of the form &lt;a name="my_name">&lt;/a>
   290      */
   291     protected static String getAnchor(Doc d) {
   292         return "    <a name=\"" + getAnchorName(d) + "\"></a>";
   293     }
   295     /**
   296      * Given a <code>Doc</code>, return an anchor name for it.
   297      * @param d the <code>Doc</code> to check.
   298      * @return the name of the anchor.
   299      */
   300     public static String getAnchorName(Doc d) {
   301         return "line." + d.position().line();
   302     }
   303 }

mercurial