KickJava   Java API By Example, From Geeks To Geeks.

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


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.AbstractFormatCheck;
25 import com.puppycrawl.tools.checkstyle.checks.CheckUtils;
26
27 import java.util.HashSet JavaDoc;
28 import java.util.Set JavaDoc;
29
30 /**
31  * <p>
32  * Checks that particular class are never used as types in variable
33  * declarations, return values or parameters. Includes
34  * a pattern check that by default disallows abstract classes.
35  * </p>
36  * <p>
37  * Rationale:
38  * Helps reduce coupling on concrete classes. In addition abstract
39  * classes should be thought of a convenience base class
40  * implementations of interfaces and as such are not types themsleves.
41  * </p>
42  * @author <a HREF="mailto:simon@redhillconsulting.com.au">Simon Harris</a>
43  */

44 public final class IllegalTypeCheck extends AbstractFormatCheck
45 {
46     /** Default value of pattern for illegal class name. */
47     private static final String JavaDoc DEFAULT_FORMAT = "^(.*[\\.])?Abstract.*$";
48     /** Abstract classes legal by default. */
49     private static final String JavaDoc[] DEFAULT_LEGAL_ABSTRACT_NAMES = {};
50     /** Types illegal by default. */
51     private static final String JavaDoc[] DEFAULT_ILLEGAL_TYPES = {
52         "GregorianCalendar",
53         "Hashtable",
54         "HashSet",
55         "HashMap",
56         "ArrayList",
57         "LinkedList",
58         "LinkedHashMap",
59         "LinkedHashSet",
60         "TreeSet",
61         "TreeMap",
62         "Vector",
63         "java.util.GregorianCalendar",
64         "java.util.Hashtable",
65         "java.util.HashSet",
66         "java.util.HashMap",
67         "java.util.ArrayList",
68         "java.util.LinkedList",
69         "java.util.LinkedHashMap",
70         "java.util.LinkedHashSet",
71         "java.util.TreeSet",
72         "java.util.TreeMap",
73         "java.util.Vector",
74     };
75
76     /** Default ignored method names. */
77     private static final String JavaDoc[] DEFAULT_IGNORED_METHOD_NAMES = {
78         "getInitialContext",
79         "getEnvironment",
80     };
81
82     /** illegal classes. */
83     private final Set JavaDoc mIllegalClassNames = new HashSet JavaDoc();
84     /** legal abstract classes. */
85     private final Set JavaDoc mLegalAbstractClassNames = new HashSet JavaDoc();
86     /** methods which should be ignored. */
87     private final Set JavaDoc mIgnoredMethodNames = new HashSet JavaDoc();
88
89     /** Creates new instance of the check. */
90     public IllegalTypeCheck()
91     {
92         super(DEFAULT_FORMAT);
93         setIllegalClassNames(DEFAULT_ILLEGAL_TYPES);
94         setLegalAbstractClassNames(DEFAULT_LEGAL_ABSTRACT_NAMES);
95         setIgnoredMethodNames(DEFAULT_IGNORED_METHOD_NAMES);
96     }
97
98     /** {@inheritDoc} */
99     public int[] getDefaultTokens()
100     {
101         return new int[] {
102             TokenTypes.VARIABLE_DEF,
103             TokenTypes.PARAMETER_DEF,
104             TokenTypes.METHOD_DEF,
105         };
106     }
107
108     /** {@inheritDoc} */
109     public void visitToken(DetailAST aAST)
110     {
111         switch (aAST.getType()) {
112         case TokenTypes.METHOD_DEF:
113             visitMethodDef(aAST);
114             break;
115         case TokenTypes.VARIABLE_DEF:
116             visitVariableDef(aAST);
117             break;
118         case TokenTypes.PARAMETER_DEF:
119             visitParameterDef(aAST);
120             break;
121         default:
122             throw new IllegalStateException JavaDoc(aAST.toString());
123         }
124     }
125
126     /**
127      * Checks return type of a given method.
128      * @param aAST method for check.
129      */

130     private void visitMethodDef(DetailAST aAST)
131     {
132         if (isCheckedMethod(aAST)) {
133             checkClassName(aAST);
134         }
135     }
136
137     /**
138      * Checks type of parameters.
139      * @param aAST parameter list for check.
140      */

141     private void visitParameterDef(DetailAST aAST)
142     {
143         final DetailAST grandParentAST = aAST.getParent().getParent();
144
145         if ((grandParentAST.getType() == TokenTypes.METHOD_DEF)
146             && isCheckedMethod(grandParentAST))
147         {
148             checkClassName(aAST);
149         }
150     }
151
152     /**
153      * Checks type of given variable.
154      * @param aAST variable to check.
155      */

156     private void visitVariableDef(DetailAST aAST)
157     {
158         checkClassName(aAST);
159     }
160
161     /**
162      * Checks type of given method, parameter or variable.
163      * @param aAST node to check.
164      */

165     private void checkClassName(DetailAST aAST)
166     {
167         final DetailAST type = aAST.findFirstToken(TokenTypes.TYPE);
168         final FullIdent ident = CheckUtils.createFullType(type);
169
170         if (isMatchingClassName(ident.getText())) {
171             log(ident.getLineNo(), ident.getColumnNo(),
172                 "illegal.type", ident.getText());
173         }
174     }
175
176     /**
177      * @param aClassName class name to check.
178      * @return true if given class name is one of illegal classes
179      * or if it matches to abstract class names pattern.
180      */

181     private boolean isMatchingClassName(String JavaDoc aClassName)
182     {
183         return mIllegalClassNames.contains(aClassName)
184             || (!mLegalAbstractClassNames.contains(aClassName)
185                 && getRegexp().matcher(aClassName).find());
186     }
187
188     /**
189      * @param aAST method def to check.
190      * @return true if we should check this method.
191      */

192     private boolean isCheckedMethod(DetailAST aAST)
193     {
194         final String JavaDoc methodName =
195             aAST.findFirstToken(TokenTypes.IDENT).getText();
196         return !mIgnoredMethodNames.contains(methodName);
197     }
198
199     /**
200      * Set the list of illegal variable types.
201      * @param aClassNames array of illegal variable types
202      */

203     public void setIllegalClassNames(String JavaDoc[] aClassNames)
204     {
205         mIllegalClassNames.clear();
206         for (int i = 0; i < aClassNames.length; i++) {
207             final String JavaDoc name = aClassNames[i];
208             mIllegalClassNames.add(name);
209             final int lastDot = name.lastIndexOf(".");
210             if ((lastDot > 0) && (lastDot < (name.length() - 1))) {
211                 final String JavaDoc shortName =
212                     name.substring(name.lastIndexOf(".") + 1);
213                 mIllegalClassNames.add(shortName);
214             }
215         }
216     }
217
218     /**
219      * Get the list of illegal variable types.
220      * @return array of illegal variable types
221      */

222     public String JavaDoc[] getIllegalClassNames()
223     {
224         return (String JavaDoc[]) mIllegalClassNames.toArray(new String JavaDoc[0]);
225     }
226
227     /**
228      * Set the list of ignore method names.
229      * @param aMethodNames array of ignored method names
230      */

231     public void setIgnoredMethodNames(String JavaDoc[] aMethodNames)
232     {
233         mIgnoredMethodNames.clear();
234         for (int i = 0; i < aMethodNames.length; i++) {
235             mIgnoredMethodNames.add(aMethodNames[i]);
236         }
237     }
238
239     /**
240      * Get the list of ignored method names.
241      * @return array of ignored method names
242      */

243     public String JavaDoc[] getIgnoredMethodNames()
244     {
245         return (String JavaDoc[]) mIgnoredMethodNames.toArray(new String JavaDoc[0]);
246     }
247
248     /**
249      * Set the list of legal abstract class names.
250      * @param aClassNames array of legal abstract class names
251      */

252     public void setLegalAbstractClassNames(String JavaDoc[] aClassNames)
253     {
254         mLegalAbstractClassNames.clear();
255         for (int i = 0; i < aClassNames.length; i++) {
256             mLegalAbstractClassNames.add(aClassNames[i]);
257         }
258     }
259
260     /**
261      * Get the list of legal abstract class names.
262      * @return array of legal abstract class names
263      */

264     public String JavaDoc[] getLegalAbstractClassNames()
265     {
266         return (String JavaDoc[]) mLegalAbstractClassNames.toArray(new String JavaDoc[0]);
267     }
268 }
269
Popular Tags