aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.tools.doclets.formats.html.markup; aoqi@0: aoqi@0: import java.io.*; aoqi@0: import java.util.*; aoqi@0: aoqi@0: import com.sun.javadoc.*; aoqi@0: import com.sun.tools.doclets.formats.html.ConfigurationImpl; aoqi@0: import com.sun.tools.doclets.formats.html.SectionName; aoqi@0: import com.sun.tools.doclets.internal.toolkit.*; aoqi@0: import com.sun.tools.doclets.internal.toolkit.util.DocFile; aoqi@0: import com.sun.tools.doclets.internal.toolkit.util.DocLink; aoqi@0: import com.sun.tools.doclets.internal.toolkit.util.DocPath; aoqi@0: aoqi@0: aoqi@0: /** aoqi@0: * Class for the Html Format Code Generation specific to JavaDoc. aoqi@0: * This Class contains methods related to the Html Code Generation which aoqi@0: * are used by the Sub-Classes in the package com.sun.tools.doclets.standard aoqi@0: * and com.sun.tools.doclets.oneone. aoqi@0: * aoqi@0: *

This is NOT part of any supported API. aoqi@0: * If you write code that depends on this, you do so at your own risk. aoqi@0: * This code and its internal interfaces are subject to change or aoqi@0: * deletion without notice. aoqi@0: * aoqi@0: * @since 1.2 aoqi@0: * @author Atul M Dambalkar aoqi@0: * @author Robert Field aoqi@0: */ aoqi@0: public abstract class HtmlDocWriter extends HtmlWriter { aoqi@0: aoqi@0: public static final String CONTENT_TYPE = "text/html"; aoqi@0: aoqi@0: /** aoqi@0: * Constructor. Initializes the destination file name through the super aoqi@0: * class HtmlWriter. aoqi@0: * aoqi@0: * @param filename String file name. aoqi@0: */ aoqi@0: public HtmlDocWriter(Configuration configuration, DocPath filename) aoqi@0: throws IOException { aoqi@0: super(configuration, filename); aoqi@0: configuration.message.notice("doclet.Generating_0", aoqi@0: DocFile.createFileForOutput(configuration, filename).getPath()); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Accessor for configuration. aoqi@0: */ aoqi@0: public abstract Configuration configuration(); aoqi@0: aoqi@0: public Content getHyperLink(DocPath link, String label) { aoqi@0: return getHyperLink(link, new StringContent(label), false, "", "", ""); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get Html Hyper Link Content. aoqi@0: * aoqi@0: * @param where Position of the link in the file. Character '#' is not aoqi@0: * needed. aoqi@0: * @param label Tag for the link. aoqi@0: * @return a content tree for the hyper link aoqi@0: */ aoqi@0: public Content getHyperLink(String where, aoqi@0: Content label) { aoqi@0: return getHyperLink(getDocLink(where), label, "", ""); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get Html Hyper Link Content. aoqi@0: * aoqi@0: * @param sectionName The section name to which the link will be created. aoqi@0: * @param label Tag for the link. aoqi@0: * @return a content tree for the hyper link aoqi@0: */ aoqi@0: public Content getHyperLink(SectionName sectionName, aoqi@0: Content label) { aoqi@0: return getHyperLink(getDocLink(sectionName), label, "", ""); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get Html Hyper Link Content. aoqi@0: * aoqi@0: * @param sectionName The section name combined with where to which the link aoqi@0: * will be created. aoqi@0: * @param where The fragment combined with sectionName to which the link aoqi@0: * will be created. aoqi@0: * @param label Tag for the link. aoqi@0: * @return a content tree for the hyper link aoqi@0: */ aoqi@0: public Content getHyperLink(SectionName sectionName, String where, aoqi@0: Content label) { aoqi@0: return getHyperLink(getDocLink(sectionName, where), label, "", ""); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the link. aoqi@0: * aoqi@0: * @param where Position of the link in the file. aoqi@0: * @return a DocLink object for the hyper link aoqi@0: */ aoqi@0: public DocLink getDocLink(String where) { aoqi@0: return DocLink.fragment(getName(where)); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the link. aoqi@0: * aoqi@0: * @param sectionName The section name to which the link will be created. aoqi@0: * @return a DocLink object for the hyper link aoqi@0: */ aoqi@0: public DocLink getDocLink(SectionName sectionName) { aoqi@0: return DocLink.fragment(sectionName.getName()); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the link. aoqi@0: * aoqi@0: * @param sectionName The section name combined with where to which the link aoqi@0: * will be created. aoqi@0: * @param where The fragment combined with sectionName to which the link aoqi@0: * will be created. aoqi@0: * @return a DocLink object for the hyper link aoqi@0: */ aoqi@0: public DocLink getDocLink(SectionName sectionName, String where) { aoqi@0: return DocLink.fragment(sectionName.getName() + getName(where)); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Convert the name to a valid HTML name. aoqi@0: * aoqi@0: * @param name the name that needs to be converted to valid HTML name. aoqi@0: * @return a valid HTML name string. aoqi@0: */ aoqi@0: public String getName(String name) { aoqi@0: StringBuilder sb = new StringBuilder(); aoqi@0: char ch; aoqi@0: /* The HTML 4 spec at http://www.w3.org/TR/html4/types.html#h-6.2 mentions aoqi@0: * that the name/id should begin with a letter followed by other valid characters. aoqi@0: * The HTML 5 spec (draft) is more permissive on names/ids where the only restriction aoqi@0: * is that it should be at least one character long and should not contain spaces. aoqi@0: * The spec draft is @ http://www.w3.org/html/wg/drafts/html/master/dom.html#the-id-attribute. aoqi@0: * aoqi@0: * For HTML 4, we need to check for non-characters at the beginning of the name and aoqi@0: * substitute it accordingly, "_" and "$" can appear at the beginning of a member name. aoqi@0: * The method substitutes "$" with "Z:Z:D" and will prefix "_" with "Z:Z". aoqi@0: */ aoqi@0: for (int i = 0; i < name.length(); i++) { aoqi@0: ch = name.charAt(i); aoqi@0: switch (ch) { aoqi@0: case '(': aoqi@0: case ')': aoqi@0: case '<': aoqi@0: case '>': aoqi@0: case ',': aoqi@0: sb.append('-'); aoqi@0: break; aoqi@0: case ' ': aoqi@0: case '[': aoqi@0: break; aoqi@0: case ']': aoqi@0: sb.append(":A"); aoqi@0: break; aoqi@0: // Any appearance of $ needs to be substituted with ":D" and not with hyphen aoqi@0: // since a field name "P$$ and a method P(), both valid member names, can end aoqi@0: // up as "P--". A member name beginning with $ needs to be substituted with aoqi@0: // "Z:Z:D". aoqi@0: case '$': aoqi@0: if (i == 0) aoqi@0: sb.append("Z:Z"); aoqi@0: sb.append(":D"); aoqi@0: break; aoqi@0: // A member name beginning with _ needs to be prefixed with "Z:Z" since valid anchor aoqi@0: // names can only begin with a letter. aoqi@0: case '_': aoqi@0: if (i == 0) aoqi@0: sb.append("Z:Z"); aoqi@0: sb.append(ch); aoqi@0: break; aoqi@0: default: aoqi@0: sb.append(ch); aoqi@0: } aoqi@0: } aoqi@0: return sb.toString(); aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get Html hyperlink. aoqi@0: * aoqi@0: * @param link path of the file. aoqi@0: * @param label Tag for the link. aoqi@0: * @return a content tree for the hyper link aoqi@0: */ aoqi@0: public Content getHyperLink(DocPath link, Content label) { aoqi@0: return getHyperLink(link, label, "", ""); aoqi@0: } aoqi@0: aoqi@0: public Content getHyperLink(DocLink link, Content label) { aoqi@0: return getHyperLink(link, label, "", ""); aoqi@0: } aoqi@0: aoqi@0: public Content getHyperLink(DocPath link, aoqi@0: Content label, boolean strong, aoqi@0: String stylename, String title, String target) { aoqi@0: return getHyperLink(new DocLink(link), label, strong, aoqi@0: stylename, title, target); aoqi@0: } aoqi@0: aoqi@0: public Content getHyperLink(DocLink link, aoqi@0: Content label, boolean strong, aoqi@0: String stylename, String title, String target) { aoqi@0: Content body = label; aoqi@0: if (strong) { aoqi@0: body = HtmlTree.SPAN(HtmlStyle.typeNameLink, body); aoqi@0: } aoqi@0: if (stylename != null && stylename.length() != 0) { aoqi@0: HtmlTree t = new HtmlTree(HtmlTag.FONT, body); aoqi@0: t.addAttr(HtmlAttr.CLASS, stylename); aoqi@0: body = t; aoqi@0: } aoqi@0: HtmlTree l = HtmlTree.A(link.toString(), body); aoqi@0: if (title != null && title.length() != 0) { aoqi@0: l.addAttr(HtmlAttr.TITLE, title); aoqi@0: } aoqi@0: if (target != null && target.length() != 0) { aoqi@0: l.addAttr(HtmlAttr.TARGET, target); aoqi@0: } aoqi@0: return l; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get Html Hyper Link. aoqi@0: * aoqi@0: * @param link String name of the file. aoqi@0: * @param label Tag for the link. aoqi@0: * @param title String that describes the link's content for accessibility. aoqi@0: * @param target Target frame. aoqi@0: * @return a content tree for the hyper link. aoqi@0: */ aoqi@0: public Content getHyperLink(DocPath link, aoqi@0: Content label, String title, String target) { aoqi@0: return getHyperLink(new DocLink(link), label, title, target); aoqi@0: } aoqi@0: aoqi@0: public Content getHyperLink(DocLink link, aoqi@0: Content label, String title, String target) { aoqi@0: HtmlTree anchor = HtmlTree.A(link.toString(), label); aoqi@0: if (title != null && title.length() != 0) { aoqi@0: anchor.addAttr(HtmlAttr.TITLE, title); aoqi@0: } aoqi@0: if (target != null && target.length() != 0) { aoqi@0: anchor.addAttr(HtmlAttr.TARGET, target); aoqi@0: } aoqi@0: return anchor; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Get the name of the package, this class is in. aoqi@0: * aoqi@0: * @param cd ClassDoc. aoqi@0: */ aoqi@0: public String getPkgName(ClassDoc cd) { aoqi@0: String pkgName = cd.containingPackage().name(); aoqi@0: if (pkgName.length() > 0) { aoqi@0: pkgName += "."; aoqi@0: return pkgName; aoqi@0: } aoqi@0: return ""; aoqi@0: } aoqi@0: aoqi@0: public boolean getMemberDetailsListPrinted() { aoqi@0: return memberDetailsListPrinted; aoqi@0: } aoqi@0: aoqi@0: /** aoqi@0: * Print the frameset version of the Html file header. aoqi@0: * Called only when generating an HTML frameset file. aoqi@0: * aoqi@0: * @param title Title of this HTML document aoqi@0: * @param noTimeStamp If true, don't print time stamp in header aoqi@0: * @param frameset the frameset to be added to the HTML document aoqi@0: */ aoqi@0: public void printFramesetDocument(String title, boolean noTimeStamp, aoqi@0: Content frameset) throws IOException { aoqi@0: Content htmlDocType = DocType.FRAMESET; aoqi@0: Content htmlComment = new Comment(configuration.getText("doclet.New_Page")); aoqi@0: Content head = new HtmlTree(HtmlTag.HEAD); aoqi@0: head.addContent(getGeneratedBy(!noTimeStamp)); aoqi@0: if (configuration.charset.length() > 0) { aoqi@0: Content meta = HtmlTree.META("Content-Type", CONTENT_TYPE, aoqi@0: configuration.charset); aoqi@0: head.addContent(meta); aoqi@0: } aoqi@0: Content windowTitle = HtmlTree.TITLE(new StringContent(title)); aoqi@0: head.addContent(windowTitle); aoqi@0: head.addContent(getFramesetJavaScript()); aoqi@0: Content htmlTree = HtmlTree.HTML(configuration.getLocale().getLanguage(), aoqi@0: head, frameset); aoqi@0: Content htmlDocument = new HtmlDocument(htmlDocType, aoqi@0: htmlComment, htmlTree); aoqi@0: write(htmlDocument); aoqi@0: } aoqi@0: aoqi@0: protected Comment getGeneratedBy(boolean timestamp) { aoqi@0: String text = "Generated by javadoc"; // marker string, deliberately not localized aoqi@0: if (timestamp) { aoqi@0: Calendar calendar = new GregorianCalendar(TimeZone.getDefault()); aoqi@0: Date today = calendar.getTime(); aoqi@0: text += " ("+ configuration.getDocletSpecificBuildDate() + ") on " + today; aoqi@0: } aoqi@0: return new Comment(text); aoqi@0: } aoqi@0: }