src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ValueTaglet.java

Tue, 14 May 2013 10:14:54 -0700

author
jjg
date
Tue, 14 May 2013 10:14:54 -0700
changeset 1743
6a5288a298fd
parent 1359
25e14ad23cef
child 1746
bd51ca92c013
permissions
-rw-r--r--

8012175: Convert TagletOutputImpl to use ContentBuilder instead of StringBuilder
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 2001, 2012, 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.taglets;
    28 import java.util.*;
    30 import com.sun.javadoc.*;
    31 import com.sun.tools.doclets.internal.toolkit.Configuration;
    32 import com.sun.tools.doclets.internal.toolkit.util.*;
    34 /**
    35  * An inline Taglet representing the value tag. This tag should only be used with
    36  * constant fields that have a value.  It is used to access the value of constant
    37  * fields.  This inline tag has an optional field name parameter.  If the name is
    38  * specified, the constant value is retrieved from the specified field.  A link
    39  * is also created to the specified field.  If a name is not specified, the value
    40  * is retrieved for the field that the inline tag appears on.  The name is specifed
    41  * in the following format:  [fully qualified class name]#[constant field name].
    42  *
    43  *  <p><b>This is NOT part of any supported API.
    44  *  If you write code that depends on this, you do so at your own risk.
    45  *  This code and its internal interfaces are subject to change or
    46  *  deletion without notice.</b>
    47  *
    48  * @author Jamie Ho
    49  * @since 1.4
    50  */
    52 public class ValueTaglet extends BaseInlineTaglet {
    54     /**
    55      * Construct a new ValueTaglet.
    56      */
    57     public ValueTaglet() {
    58         name = "value";
    59     }
    61     /**
    62      * Will return false because this inline tag may
    63      * only appear in Fields.
    64      * @return false since this is not a method.
    65      */
    66     public boolean inMethod() {
    67         return true;
    68     }
    70     /**
    71      * Will return false because this inline tag may
    72      * only appear in Fields.
    73      * @return false since this is not a method.
    74      */
    75     public boolean inConstructor() {
    76         return true;
    77     }
    79     /**
    80      * Will return false because this inline tag may
    81      * only appear in Fields.
    82      * @return false since this is not a method.
    83      */
    84     public boolean inOverview() {
    85         return true;
    86     }
    88     /**
    89      * Will return false because this inline tag may
    90      * only appear in Fields.
    91      * @return false since this is not a method.
    92      */
    93     public boolean inPackage() {
    94         return true;
    95     }
    97     /**
    98      * Will return false because this inline tag may
    99      * only appear in Fields.
   100      * @return false since this is not a method.
   101      */
   102     public boolean inType() {
   103         return true;
   104     }
   106     /**
   107      * Given the name of the field, return the corresponding FieldDoc.
   108      *
   109      * @param config the current configuration of the doclet.
   110      * @param tag the value tag.
   111      * @param name the name of the field to search for.  The name should be in
   112      * {@code <qualified class name>#<field name>} format. If the class name is omitted,
   113      * it is assumed that the field is in the current class.
   114      *
   115      * @return the corresponding FieldDoc. If the name is null or empty string,
   116      * return field that the value tag was used in.
   117      *
   118      * @throws DocletAbortException if the value tag does not specify a name to
   119      * a value field and it is not used within the comments of a valid field.
   120      */
   121     private FieldDoc getFieldDoc(Configuration config, Tag tag, String name) {
   122         if (name == null || name.length() == 0) {
   123             //Base case: no label.
   124             if (tag.holder() instanceof FieldDoc) {
   125                 return (FieldDoc) tag.holder();
   126             } else {
   127                 //This should never ever happen.
   128                 throw new DocletAbortException();
   129             }
   130         }
   131         StringTokenizer st = new StringTokenizer(name, "#");
   132         String memberName = null;
   133         ClassDoc cd = null;
   134         if (st.countTokens() == 1) {
   135             //Case 2:  @value in same class.
   136             Doc holder = tag.holder();
   137             if (holder instanceof MemberDoc) {
   138                 cd = ((MemberDoc) holder).containingClass();
   139             } else if (holder instanceof ClassDoc) {
   140                 cd = (ClassDoc) holder;
   141             }
   142             memberName = st.nextToken();
   143         } else {
   144             //Case 3: @value in different class.
   145             cd = config.root.classNamed(st.nextToken());
   146             memberName = st.nextToken();
   147         }
   148         if (cd == null) {
   149             return null;
   150         }
   151         FieldDoc[] fields = cd.fields();
   152         for (int i = 0; i < fields.length; i++) {
   153             if (fields[i].name().equals(memberName)) {
   154                 return fields[i];
   155             }
   156         }
   157         return null;
   158     }
   160     /**
   161      * {@inheritDoc}
   162      */
   163     public TagletOutput getTagletOutput(Tag tag, TagletWriter writer) {
   164         FieldDoc field = getFieldDoc(
   165             writer.configuration(), tag, tag.text());
   166         if (field == null) {
   167             //Reference is unknown.
   168             writer.getMsgRetriever().warning(tag.holder().position(),
   169                 "doclet.value_tag_invalid_reference", tag.text());
   170         } else if (field.constantValue() != null) {
   171             return writer.valueTagOutput(field,
   172                 Util.escapeHtmlChars(field.constantValueExpression()),
   173                 ! field.equals(tag.holder()));
   174         } else {
   175             //Referenced field is not a constant.
   176             writer.getMsgRetriever().warning(tag.holder().position(),
   177                 "doclet.value_tag_invalid_constant", field.name());
   178         }
   179         return writer.getOutputInstance();
   180     }
   181 }

mercurial