langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java
changeset 37938 42baa89d2156
parent 37858 7c04fcb12bd4
child 37939 3eb8c2a89b77
equal deleted inserted replaced
37858:7c04fcb12bd4 37938:42baa89d2156
     1 /*
       
     2  * Copyright (c) 1997, 2013, 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.javadoc;
       
    27 
       
    28 import java.io.DataInputStream;
       
    29 import java.io.IOException;
       
    30 import java.io.InputStream;
       
    31 import java.text.CollationKey;
       
    32 import java.util.regex.Matcher;
       
    33 import java.util.regex.Pattern;
       
    34 
       
    35 import javax.tools.FileObject;
       
    36 
       
    37 import com.sun.javadoc.*;
       
    38 import com.sun.source.util.TreePath;
       
    39 import com.sun.tools.javac.tree.JCTree;
       
    40 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
       
    41 import com.sun.tools.javac.util.Position;
       
    42 
       
    43 /**
       
    44  * abstract base class of all Doc classes.  Doc item's are representations
       
    45  * of java language constructs (class, package, method,...) which have
       
    46  * comments and have been processed by this run of javadoc.  All Doc items
       
    47  * are unique, that is, they are == comparable.
       
    48  *
       
    49  *  <p><b>This is NOT part of any supported API.
       
    50  *  If you write code that depends on this, you do so at your own risk.
       
    51  *  This code and its internal interfaces are subject to change or
       
    52  *  deletion without notice.</b>
       
    53  *
       
    54  * @since 1.2
       
    55  * @author Robert Field
       
    56  * @author Atul M Dambalkar
       
    57  * @author Neal Gafter (rewrite)
       
    58  */
       
    59 public abstract class DocImpl implements Doc, Comparable<Object> {
       
    60 
       
    61     /**
       
    62      * Doc environment
       
    63      */
       
    64     protected final DocEnv env;   //### Rename this everywhere to 'docenv' ?
       
    65 
       
    66     /**
       
    67      * Back pointer to the tree node for this doc item.
       
    68      * May be null if there is no associated tree.
       
    69      */
       
    70     protected TreePath treePath;
       
    71 
       
    72     /**
       
    73      *  The complex comment object, lazily initialized.
       
    74      */
       
    75     private Comment comment;
       
    76 
       
    77     /**
       
    78      * The cached sort key, to take care of Natural Language Text sorting.
       
    79      */
       
    80     private CollationKey collationkey = null;
       
    81 
       
    82     /**
       
    83      *  Raw documentation string.
       
    84      */
       
    85     protected String documentation;  // Accessed in PackageDocImpl, RootDocImpl
       
    86 
       
    87     /**
       
    88      * Cached first sentence.
       
    89      */
       
    90     private Tag[] firstSentence;
       
    91 
       
    92     /**
       
    93      * Cached inline tags.
       
    94      */
       
    95     private Tag[] inlineTags;
       
    96 
       
    97     /**
       
    98      * Constructor.
       
    99      */
       
   100     DocImpl(DocEnv env, TreePath treePath) {
       
   101         this.treePath = treePath;
       
   102         this.documentation = getCommentText(treePath);
       
   103         this.env = env;
       
   104     }
       
   105 
       
   106     private static String getCommentText(TreePath p) {
       
   107         if (p == null)
       
   108             return null;
       
   109 
       
   110         JCCompilationUnit topLevel = (JCCompilationUnit) p.getCompilationUnit();
       
   111         JCTree tree = (JCTree) p.getLeaf();
       
   112         return topLevel.docComments.getCommentText(tree);
       
   113     }
       
   114 
       
   115     /**
       
   116      * So subclasses have the option to do lazy initialization of
       
   117      * "documentation" string.
       
   118      */
       
   119     protected String documentation() {
       
   120         if (documentation == null) documentation = "";
       
   121         return documentation;
       
   122     }
       
   123 
       
   124     /**
       
   125      * For lazy initialization of comment.
       
   126      */
       
   127     Comment comment() {
       
   128         if (comment == null) {
       
   129             String d = documentation();
       
   130             if (env.doclint != null
       
   131                     && treePath != null
       
   132                     && env.shouldCheck(treePath.getCompilationUnit())
       
   133                     && d.equals(getCommentText(treePath))) {
       
   134                 env.doclint.scan(treePath);
       
   135             }
       
   136             comment = new Comment(this, d);
       
   137         }
       
   138         return comment;
       
   139     }
       
   140 
       
   141     /**
       
   142      * Return the text of the comment for this doc item.
       
   143      * TagImpls have been removed.
       
   144      */
       
   145     public String commentText() {
       
   146         return comment().commentText();
       
   147     }
       
   148 
       
   149     /**
       
   150      * Return all tags in this Doc item.
       
   151      *
       
   152      * @return an array of TagImpl containing all tags on this Doc item.
       
   153      */
       
   154     public Tag[] tags() {
       
   155         return comment().tags();
       
   156     }
       
   157 
       
   158     /**
       
   159      * Return tags of the specified kind in this Doc item.
       
   160      *
       
   161      * @param tagname name of the tag kind to search for.
       
   162      * @return an array of TagImpl containing all tags whose 'kind()'
       
   163      * matches 'tagname'.
       
   164      */
       
   165     public Tag[] tags(String tagname) {
       
   166         return comment().tags(tagname);
       
   167     }
       
   168 
       
   169     /**
       
   170      * Return the see also tags in this Doc item.
       
   171      *
       
   172      * @return an array of SeeTag containing all &#64;see tags.
       
   173      */
       
   174     public SeeTag[] seeTags() {
       
   175         return comment().seeTags();
       
   176     }
       
   177 
       
   178     public Tag[] inlineTags() {
       
   179         if (inlineTags == null) {
       
   180             inlineTags = Comment.getInlineTags(this, commentText());
       
   181         }
       
   182         return inlineTags;
       
   183     }
       
   184 
       
   185     public Tag[] firstSentenceTags() {
       
   186         if (firstSentence == null) {
       
   187             //Parse all sentences first to avoid duplicate warnings.
       
   188             inlineTags();
       
   189             try {
       
   190                 env.setSilent(true);
       
   191                 firstSentence = Comment.firstSentenceTags(this, commentText());
       
   192             } finally {
       
   193                 env.setSilent(false);
       
   194             }
       
   195         }
       
   196         return firstSentence;
       
   197     }
       
   198 
       
   199     /**
       
   200      * Utility for subclasses which read HTML documentation files.
       
   201      */
       
   202     String readHTMLDocumentation(InputStream input, FileObject filename) throws IOException {
       
   203         byte[] filecontents = new byte[input.available()];
       
   204         try {
       
   205             DataInputStream dataIn = new DataInputStream(input);
       
   206             dataIn.readFully(filecontents);
       
   207         } finally {
       
   208             input.close();
       
   209         }
       
   210         String encoding = env.getEncoding();
       
   211         String rawDoc = (encoding!=null)
       
   212             ? new String(filecontents, encoding)
       
   213             : new String(filecontents);
       
   214         Pattern bodyPat = Pattern.compile("(?is).*<body\\b[^>]*>(.*)</body\\b.*");
       
   215         Matcher m = bodyPat.matcher(rawDoc);
       
   216         if (m.matches()) {
       
   217             return m.group(1);
       
   218         } else {
       
   219             String key = rawDoc.matches("(?is).*<body\\b.*")
       
   220                     ? "javadoc.End_body_missing_from_html_file"
       
   221                     : "javadoc.Body_missing_from_html_file";
       
   222             env.error(SourcePositionImpl.make(filename, Position.NOPOS, null), key);
       
   223             return "";
       
   224         }
       
   225     }
       
   226 
       
   227     /**
       
   228      * Return the full unprocessed text of the comment.  Tags
       
   229      * are included as text.  Used mainly for store and retrieve
       
   230      * operations like internalization.
       
   231      */
       
   232     public String getRawCommentText() {
       
   233         return documentation();
       
   234     }
       
   235 
       
   236     /**
       
   237      * Set the full unprocessed text of the comment.  Tags
       
   238      * are included as text.  Used mainly for store and retrieve
       
   239      * operations like internalization.
       
   240      */
       
   241     public void setRawCommentText(String rawDocumentation) {
       
   242         treePath = null;
       
   243         documentation = rawDocumentation;
       
   244         comment = null;
       
   245     }
       
   246 
       
   247     /**
       
   248      * Set the full unprocessed text of the comment and tree path.
       
   249      */
       
   250     void setTreePath(TreePath treePath) {
       
   251         this.treePath = treePath;
       
   252         documentation = getCommentText(treePath);
       
   253         comment = null;
       
   254     }
       
   255 
       
   256     /**
       
   257      * return a key for sorting.
       
   258      */
       
   259     CollationKey key() {
       
   260         if (collationkey == null) {
       
   261             collationkey = generateKey();
       
   262         }
       
   263         return collationkey;
       
   264     }
       
   265 
       
   266     /**
       
   267      * Generate a key for sorting.
       
   268      * <p>
       
   269      * Default is name().
       
   270      */
       
   271     CollationKey generateKey() {
       
   272         String k = name();
       
   273         // System.out.println("COLLATION KEY FOR " + this + " is \"" + k + "\"");
       
   274         return env.doclocale.collator.getCollationKey(k);
       
   275     }
       
   276 
       
   277     /**
       
   278      * Returns a string representation of this Doc item.
       
   279      */
       
   280     @Override
       
   281     public String toString() {
       
   282         return qualifiedName();
       
   283     }
       
   284 
       
   285     /**
       
   286      * Returns the name of this Doc item.
       
   287      *
       
   288      * @return  the name
       
   289      */
       
   290     public abstract String name();
       
   291 
       
   292     /**
       
   293      * Returns the qualified name of this Doc item.
       
   294      *
       
   295      * @return  the name
       
   296      */
       
   297     public abstract String qualifiedName();
       
   298 
       
   299     /**
       
   300      * Compares this Object with the specified Object for order.  Returns a
       
   301      * negative integer, zero, or a positive integer as this Object is less
       
   302      * than, equal to, or greater than the given Object.
       
   303      * <p>
       
   304      * Included so that Doc item are java.lang.Comparable.
       
   305      *
       
   306      * @param   obj the {@code Object} to be compared.
       
   307      * @return  a negative integer, zero, or a positive integer as this Object
       
   308      *          is less than, equal to, or greater than the given Object.
       
   309      * @exception ClassCastException the specified Object's type prevents it
       
   310      *            from being compared to this Object.
       
   311      */
       
   312     public int compareTo(Object obj) {
       
   313         // System.out.println("COMPARE \"" + this + "\" to \"" + obj + "\" = " + key().compareTo(((DocImpl)obj).key()));
       
   314         return key().compareTo(((DocImpl)obj).key());
       
   315     }
       
   316 
       
   317     /**
       
   318      * Is this Doc item a field?  False until overridden.
       
   319      *
       
   320      * @return true if it represents a field
       
   321      */
       
   322     public boolean isField() {
       
   323         return false;
       
   324     }
       
   325 
       
   326     /**
       
   327      * Is this Doc item an enum constant?  False until overridden.
       
   328      *
       
   329      * @return true if it represents an enum constant
       
   330      */
       
   331     public boolean isEnumConstant() {
       
   332         return false;
       
   333     }
       
   334 
       
   335     /**
       
   336      * Is this Doc item a constructor?  False until overridden.
       
   337      *
       
   338      * @return true if it represents a constructor
       
   339      */
       
   340     public boolean isConstructor() {
       
   341         return false;
       
   342     }
       
   343 
       
   344     /**
       
   345      * Is this Doc item a method (but not a constructor or annotation
       
   346      * type element)?
       
   347      * False until overridden.
       
   348      *
       
   349      * @return true if it represents a method
       
   350      */
       
   351     public boolean isMethod() {
       
   352         return false;
       
   353     }
       
   354 
       
   355     /**
       
   356      * Is this Doc item an annotation type element?
       
   357      * False until overridden.
       
   358      *
       
   359      * @return true if it represents an annotation type element
       
   360      */
       
   361     public boolean isAnnotationTypeElement() {
       
   362         return false;
       
   363     }
       
   364 
       
   365     /**
       
   366      * Is this Doc item a interface (but not an annotation type)?
       
   367      * False until overridden.
       
   368      *
       
   369      * @return true if it represents a interface
       
   370      */
       
   371     public boolean isInterface() {
       
   372         return false;
       
   373     }
       
   374 
       
   375     /**
       
   376      * Is this Doc item a exception class?  False until overridden.
       
   377      *
       
   378      * @return true if it represents a exception
       
   379      */
       
   380     public boolean isException() {
       
   381         return false;
       
   382     }
       
   383 
       
   384     /**
       
   385      * Is this Doc item a error class?  False until overridden.
       
   386      *
       
   387      * @return true if it represents a error
       
   388      */
       
   389     public boolean isError() {
       
   390         return false;
       
   391     }
       
   392 
       
   393     /**
       
   394      * Is this Doc item an enum type?  False until overridden.
       
   395      *
       
   396      * @return true if it represents an enum type
       
   397      */
       
   398     public boolean isEnum() {
       
   399         return false;
       
   400     }
       
   401 
       
   402     /**
       
   403      * Is this Doc item an annotation type?  False until overridden.
       
   404      *
       
   405      * @return true if it represents an annotation type
       
   406      */
       
   407     public boolean isAnnotationType() {
       
   408         return false;
       
   409     }
       
   410 
       
   411     /**
       
   412      * Is this Doc item an ordinary class (i.e. not an interface,
       
   413      * annotation type, enumeration, exception, or error)?
       
   414      * False until overridden.
       
   415      *
       
   416      * @return true if it represents an ordinary class
       
   417      */
       
   418     public boolean isOrdinaryClass() {
       
   419         return false;
       
   420     }
       
   421 
       
   422     /**
       
   423      * Is this Doc item a class
       
   424      * (and not an interface or annotation type)?
       
   425      * This includes ordinary classes, enums, errors and exceptions.
       
   426      * False until overridden.
       
   427      *
       
   428      * @return true if it represents a class
       
   429      */
       
   430     public boolean isClass() {
       
   431         return false;
       
   432     }
       
   433 
       
   434     /**
       
   435      * return true if this Doc is include in the active set.
       
   436      */
       
   437     public abstract boolean isIncluded();
       
   438 
       
   439     /**
       
   440      * Return the source position of the entity, or null if
       
   441      * no position is available.
       
   442      */
       
   443     public SourcePosition position() { return null; }
       
   444 }