KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > coding > RedundantThrowsCheck


1 ////////////////////////////////////////////////////////////////////////////////
2
// checkstyle: Checks Java source code for adherence to a set of rules.
3
// Copyright (C) 2001-2005 Oliver Burn
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
////////////////////////////////////////////////////////////////////////////////
19
package com.puppycrawl.tools.checkstyle.checks.coding;
20
21 import com.puppycrawl.tools.checkstyle.api.DetailAST;
22 import com.puppycrawl.tools.checkstyle.api.FullIdent;
23 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24 import com.puppycrawl.tools.checkstyle.checks.AbstractTypeAwareCheck;
25 import java.util.Iterator JavaDoc;
26 import java.util.LinkedList JavaDoc;
27 import java.util.List JavaDoc;
28
29 /**
30  * Checks for redundant exceptions declared in throws clause
31  * such as duplicates, unchecked exceptions or subclasses of
32  * another declared exception.
33  *
34  * <p>
35  * An example of how to configure the check is:
36  * </p>
37  * <pre>
38  * &lt;module name="RedundantThrows"&gt;
39  * &lt;property name=&quot;allowUnchecked&quot; value=&quot;true&quot;/&gt;
40  * &lt;property name=&quot;allowSubclasses&quot; value=&quot;true&quot;/&gt;
41  * &lt;/module&gt;
42  * </pre>
43  * @author o_sukhodolsky
44  */

45 public class RedundantThrowsCheck extends AbstractTypeAwareCheck
46 {
47     /**
48      * whether unchecked exceptions in throws
49      * are allowed or not
50      */

51     private boolean mAllowUnchecked;
52
53     /**
54      * whether subclass of another declared
55      * exception is allowed in throws clause
56      */

57     private boolean mAllowSubclasses;
58
59     /**
60      * Getter for allowUnchecked property.
61      * @param aAllowUnchecked whether unchecked excpetions in throws
62      * are allowed or not
63      */

64     public void setAllowUnchecked(boolean aAllowUnchecked)
65     {
66         mAllowUnchecked = aAllowUnchecked;
67     }
68
69     /**
70      * Getter for allowSubclasses property.
71      * @param aAllowSubclasses whether subclass of another declared
72      * exception is allowed in throws clause
73      */

74     public void setAllowSubclasses(boolean aAllowSubclasses)
75     {
76         mAllowSubclasses = aAllowSubclasses;
77     }
78
79     /** {@inheritDoc} */
80     public int[] getDefaultTokens()
81     {
82         return new int[] {
83             TokenTypes.PACKAGE_DEF,
84             TokenTypes.IMPORT,
85             TokenTypes.CLASS_DEF,
86             TokenTypes.ENUM_DEF,
87             TokenTypes.METHOD_DEF,
88             TokenTypes.CTOR_DEF,
89         };
90     }
91
92     /**
93      * Checks exceptions declared in throws for a method or constructor.
94      * @param aAST the tree node for the method or constructor.
95      */

96     protected final void processAST(DetailAST aAST)
97     {
98         final List JavaDoc knownExcs = new LinkedList JavaDoc();
99         final DetailAST throwsAST =
100             aAST.findFirstToken(TokenTypes.LITERAL_THROWS);
101         if (throwsAST != null) {
102             DetailAST child = (DetailAST) throwsAST.getFirstChild();
103             while (child != null) {
104                 if ((child.getType() == TokenTypes.IDENT)
105                     || (child.getType() == TokenTypes.DOT))
106                 {
107                     final FullIdent fi = FullIdent.createFullIdent(child);
108                     checkException(fi, knownExcs);
109                 }
110                 child = (DetailAST) child.getNextSibling();
111             }
112         }
113     }
114
115     /**
116      * Logs error if unable to load class information.
117      * @param aIdent class name for which we can no load class.
118      */

119     protected final void logLoadError(Token aIdent)
120     {
121         logLoadErrorImpl(aIdent.getLineNo(), aIdent.getColumnNo(),
122                          "redundant.throws.classInfo",
123                          new Object JavaDoc[] {aIdent.getText()});
124     }
125
126     /**
127      * Checks if an exception is already know (list of known
128      * exceptions contains it or its superclass) and it's not
129      * a superclass for some known exception and it's not
130      * an unchecked exception.
131      * If it's unknown then it will be added to ist of known exception.
132      * All subclasses of this exception will be deleted from known
133      * and the exception will be added instead.
134      *
135      * @param aExc <code>FullIdent</code> of exception to check
136      * @param aKnownExcs list of already known exception
137      */

138     private void checkException(FullIdent aExc, List JavaDoc aKnownExcs)
139     {
140         // Let's try to load class.
141
final ClassInfo newClassInfo =
142             createClassInfo(new Token(aExc), getCurrentClassName());
143
144         if (!mAllowUnchecked) {
145             if (isUnchecked(newClassInfo.getClazz())) {
146                 log(aExc.getLineNo(), aExc.getColumnNo(),
147                     "redundant.throws.unchecked", aExc.getText());
148             }
149         }
150
151         boolean shouldAdd = true;
152         for (final Iterator JavaDoc known = aKnownExcs.iterator(); known.hasNext();) {
153             final ClassInfo ci = (ClassInfo) known.next();
154             final Token fi = ci.getName();
155
156             if (ci.getClazz() == newClassInfo.getClazz()) {
157                 shouldAdd = false;
158                 log(aExc.getLineNo(), aExc.getColumnNo(),
159                     "redundant.throws.duplicate", aExc.getText());
160             }
161             else if (!mAllowSubclasses) {
162                 if (isSubclass(ci.getClazz(), newClassInfo.getClazz())) {
163                     known.remove();
164                     log(fi.getLineNo(), fi.getColumnNo(),
165                         "redundant.throws.subclass",
166                         fi.getText(), aExc.getText());
167                 }
168                 else if (isSubclass(newClassInfo.getClazz(), ci.getClazz())) {
169                     shouldAdd = false;
170                     log(aExc.getLineNo(), aExc.getColumnNo(),
171                         "redundant.throws.subclass",
172                         aExc.getText(), fi.getText());
173                 }
174             }
175         }
176
177         if (shouldAdd) {
178             aKnownExcs.add(newClassInfo);
179         }
180     }
181 }
182
Popular Tags