0N/A/*
553N/A * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
553N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
553N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
553N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
553N/A * or visit www.oracle.com if you need additional information or have any
553N/A * questions.
0N/A */
0N/A
0N/Apackage com.sun.tools.doclets.internal.toolkit.util;
0N/A
0N/Aimport com.sun.javadoc.*;
0N/Aimport com.sun.tools.doclets.internal.toolkit.taglets.*;
0N/Aimport java.util.*;
0N/A
0N/A/**
0N/A * Search for the requested documentation. Inherit documentation if necessary.
0N/A *
0N/A * @author Jamie Ho
0N/A * @since 1.5
0N/A */
0N/Apublic class DocFinder {
0N/A
0N/A /**
0N/A * The class that encapsulates the input.
0N/A */
0N/A public static class Input {
0N/A /**
0N/A * The method to search documentation from.
0N/A */
0N/A public MethodDoc method = null;
0N/A /**
0N/A * The taglet to search for documentation on behalf of. Null if we want
0N/A * to search for overall documentation.
0N/A */
0N/A public InheritableTaglet taglet = null;
0N/A
0N/A /**
0N/A * The id of the tag to retrieve documentation for.
0N/A */
0N/A public String tagId = null;
0N/A
0N/A /**
0N/A * The tag to retrieve documentation for. This is only used for the
0N/A * inheritDoc tag.
0N/A */
0N/A public Tag tag = null;
0N/A
0N/A /**
0N/A * True if we only want to search for the first sentence.
0N/A */
0N/A public boolean isFirstSentence = false;
0N/A
0N/A /**
0N/A * True if we are looking for documentation to replace the inheritDocTag.
0N/A */
0N/A public boolean isInheritDocTag = false;
0N/A
0N/A /**
0N/A * Used to distinguish between type variable param tags and regular
0N/A * param tags.
0N/A */
0N/A public boolean isTypeVariableParamTag = false;
0N/A
0N/A public Input() {}
0N/A
0N/A public Input(MethodDoc method, InheritableTaglet taglet, Tag tag,
0N/A boolean isFirstSentence, boolean isInheritDocTag) {
0N/A this.method = method;
0N/A this.taglet = taglet;
0N/A this.tag = tag;
0N/A this.isFirstSentence = isFirstSentence;
0N/A this.isInheritDocTag = isInheritDocTag;
0N/A }
0N/A
0N/A public Input(MethodDoc method, InheritableTaglet taglet, String tagId) {
0N/A this.method = method;
0N/A this.taglet = taglet;
0N/A this.tagId = tagId;
0N/A }
0N/A
0N/A public Input(MethodDoc method, InheritableTaglet taglet, String tagId,
0N/A boolean isTypeVariableParamTag) {
0N/A this.method = method;
0N/A this.taglet = taglet;
0N/A this.tagId = tagId;
0N/A this.isTypeVariableParamTag = isTypeVariableParamTag;
0N/A }
0N/A
0N/A public Input(MethodDoc method, InheritableTaglet taglet) {
0N/A this.method = method;
0N/A this.taglet = taglet;
0N/A }
0N/A
0N/A public Input(MethodDoc method) {
0N/A this.method = method;
0N/A }
0N/A
0N/A public Input(MethodDoc method, boolean isFirstSentence) {
0N/A this.method = method;
0N/A this.isFirstSentence = isFirstSentence;
0N/A }
0N/A
0N/A public Input copy() {
0N/A Input clone = new Input();
0N/A clone.method = this.method;
0N/A clone.taglet = this.taglet;
0N/A clone.tagId = this.tagId;
0N/A clone.tag = this.tag;
0N/A clone.isFirstSentence = this.isFirstSentence;
0N/A clone.isInheritDocTag = this.isInheritDocTag;
0N/A clone.isTypeVariableParamTag = this.isTypeVariableParamTag;
0N/A return clone;
0N/A
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * The class that encapsulates the output.
0N/A */
0N/A public static class Output {
0N/A /**
0N/A * The tag that holds the documentation. Null if documentation
0N/A * is not held by a tag.
0N/A */
0N/A public Tag holderTag;
0N/A
0N/A /**
0N/A * The Doc object that holds the documentation.
0N/A */
0N/A public Doc holder;
0N/A
0N/A /**
0N/A * The inherited documentation.
0N/A */
0N/A public Tag[] inlineTags = new Tag[] {};
0N/A
0N/A /**
0N/A * False if documentation could not be inherited.
0N/A */
0N/A public boolean isValidInheritDocTag = true;
0N/A
0N/A /**
0N/A * When automatically inheriting throws tags, you sometime must inherit
0N/A * more than one tag. For example if the method declares that it throws
0N/A * IOException and the overidden method has throws tags for IOException and
0N/A * ZipException, both tags would be inherited because ZipException is a
0N/A * subclass of IOException. This subclass of DocFinder.Output allows
0N/A * multiple tag inheritence.
0N/A */
73N/A public List<Tag> tagList = new ArrayList<Tag>();
0N/A }
0N/A
0N/A /**
0N/A * Search for the requested comments in the given method. If it does not
0N/A * have comments, return documentation from the overriden method if possible.
0N/A * If the overriden method does not exist or does not have documentation to
0N/A * inherit, search for documentation to inherit from implemented methods.
0N/A *
0N/A * @param input the input object used to perform the search.
0N/A *
0N/A * @return an Output object representing the documentation that was found.
0N/A */
0N/A public static Output search(Input input) {
0N/A Output output = new Output();
0N/A if (input.isInheritDocTag) {
0N/A //Do nothing because "method" does not have any documentation.
0N/A //All it has it {@inheritDoc}.
0N/A } else if (input.taglet == null) {
0N/A //We want overall documentation.
0N/A output.inlineTags = input.isFirstSentence ?
0N/A input.method.firstSentenceTags() :
0N/A input.method.inlineTags();
0N/A output.holder = input.method;
0N/A } else {
0N/A input.taglet.inherit(input, output);
0N/A }
0N/A
0N/A if (output.inlineTags != null && output.inlineTags.length > 0) {
0N/A return output;
0N/A }
0N/A output.isValidInheritDocTag = false;
0N/A Input inheritedSearchInput = input.copy();
0N/A inheritedSearchInput.isInheritDocTag = false;
0N/A if (input.method.overriddenMethod() != null) {
0N/A inheritedSearchInput.method = input.method.overriddenMethod();
0N/A output = search(inheritedSearchInput);
0N/A output.isValidInheritDocTag = true;
0N/A if (output != null && output.inlineTags.length > 0) {
0N/A return output;
0N/A }
0N/A }
0N/A //NOTE: When we fix the bug where ClassDoc.interfaceTypes() does
0N/A // not pass all implemented interfaces, we will use the
0N/A // appropriate method here.
0N/A MethodDoc[] implementedMethods =
0N/A (new ImplementedMethods(input.method, null)).build(false);
0N/A for (int i = 0; i < implementedMethods.length; i++) {
0N/A inheritedSearchInput.method = implementedMethods[i];
0N/A output = search(inheritedSearchInput);
0N/A output.isValidInheritDocTag = true;
0N/A if (output != null && output.inlineTags.length > 0) {
0N/A return output;
0N/A }
0N/A }
0N/A return output;
0N/A }
0N/A}