001: /*
002: * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.doclets.internal.toolkit.util;
027:
028: import com.sun.javadoc.*;
029: import com.sun.tools.doclets.internal.toolkit.Configuration;
030: import java.util.*;
031:
032: /**
033: * For a given class method, build an array of interface methods which it
034: * implements.
035: *
036: * This code is not part of an API.
037: * It is implementation that is subject to change.
038: * Do not use it as an API
039: *
040: * @author Atul M Dambalkar
041: */
042: public class ImplementedMethods {
043:
044: private Map interfaces = new HashMap();
045: private List methlist = new ArrayList();
046: private Configuration configuration;
047: private final ClassDoc classdoc;
048: private final MethodDoc method;
049:
050: public ImplementedMethods(MethodDoc method,
051: Configuration configuration) {
052: this .method = method;
053: this .configuration = configuration;
054: classdoc = method.containingClass();
055: }
056:
057: /**
058: * Return the array of interface methods which the method passed in the
059: * constructor is implementing. The search/build order is as follows:
060: * <pre>
061: * 1. Search in all the immediate interfaces which this method's class is
062: * implementing. Do it recursively for the superinterfaces as well.
063: * 2. Traverse all the superclasses and search recursively in the
064: * interfaces which those superclasses implement.
065: *</pre>
066: *
067: * @return MethodDoc[] Array of implemented methods.
068: */
069: public MethodDoc[] build(boolean sort) {
070: buildImplementedMethodList(sort);
071: return (MethodDoc[]) methlist.toArray(new MethodDoc[methlist
072: .size()]);
073: }
074:
075: public MethodDoc[] build() {
076: return build(true);
077: }
078:
079: public Type getMethodHolder(MethodDoc methodDoc) {
080: return (Type) interfaces.get(methodDoc);
081: }
082:
083: /**
084: * Search for the method in the array of interfaces. If found check if it is
085: * overridden by any other subinterface method which this class
086: * implements. If it is not overidden, add it in the method list.
087: * Do this recursively for all the extended interfaces for each interface
088: * from the array passed.
089: */
090: private void buildImplementedMethodList(boolean sort) {
091: List intfacs = Util.getAllInterfaces(classdoc, configuration,
092: sort);
093: for (Iterator iter = intfacs.iterator(); iter.hasNext();) {
094: Type interfaceType = (Type) iter.next();
095: MethodDoc found = Util.findMethod(interfaceType
096: .asClassDoc(), method);
097: if (found != null) {
098: removeOverriddenMethod(found);
099: if (!overridingMethodFound(found)) {
100: methlist.add(found);
101: interfaces.put(found, interfaceType);
102: }
103: }
104: }
105: }
106:
107: /**
108: * Search in the method list and check if it contains a method which
109: * is overridden by the method as parameter. If found, remove the
110: * overridden method from the method list.
111: *
112: * @param method Is this method overriding a method in the method list.
113: */
114: private void removeOverriddenMethod(MethodDoc method) {
115: ClassDoc overriddenClass = method.overriddenClass();
116: if (overriddenClass != null) {
117: for (int i = 0; i < methlist.size(); i++) {
118: ClassDoc cd = ((MethodDoc) methlist.get(i))
119: .containingClass();
120: if (cd == overriddenClass
121: || overriddenClass.subclassOf(cd)) {
122: methlist.remove(i); // remove overridden method
123: return;
124: }
125: }
126: }
127: }
128:
129: /**
130: * Search in the already found methods' list and check if it contains
131: * a method which is overriding the method parameter or is the method
132: * parameter itself.
133: *
134: * @param method MethodDoc Method to be searched in the Method List for
135: * an overriding method.
136: */
137: private boolean overridingMethodFound(MethodDoc method) {
138: ClassDoc containingClass = method.containingClass();
139: for (int i = 0; i < methlist.size(); i++) {
140: MethodDoc listmethod = (MethodDoc) methlist.get(i);
141: if (containingClass == listmethod.containingClass()) {
142: // it's the same method.
143: return true;
144: }
145: ClassDoc cd = listmethod.overriddenClass();
146: if (cd == null) {
147: continue;
148: }
149: if (cd == containingClass || cd.subclassOf(containingClass)) {
150: return true;
151: }
152: }
153: return false;
154: }
155: }
|