KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > puppycrawl > tools > checkstyle > checks > design > VisibilityModifierCheck


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.design;
20
21 import java.util.HashSet JavaDoc;
22 import java.util.Set JavaDoc;
23 import java.util.regex.Pattern JavaDoc;
24 import java.util.regex.PatternSyntaxException JavaDoc;
25
26 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
27 import com.puppycrawl.tools.checkstyle.api.Check;
28 import com.puppycrawl.tools.checkstyle.api.DetailAST;
29 import com.puppycrawl.tools.checkstyle.api.Utils;
30 import com.puppycrawl.tools.checkstyle.api.ScopeUtils;
31 import org.apache.commons.beanutils.ConversionException;
32
33 import antlr.collections.AST;
34
35 /**
36  * Checks visibility of class members. Only static final members may be public,
37  * other class members must be private unless allowProtected/Package is set.
38  * <p>
39  * Public members are not flagged if the name matches the public
40  * member regular expression (contains "^serialVersionUID$" by
41  * default).
42  * </p>
43  * Rationale: Enforce encapsulation.
44  *
45  * @author lkuehne
46  */

47 public class VisibilityModifierCheck
48     extends Check
49 {
50     /** whether protected members are allowed */
51     private boolean mProtectedAllowed;
52
53     /** whether package visible members are allowed */
54     private boolean mPackageAllowed;
55
56     /**
57      * pattern for public members that should be ignored. Note:
58      * Earlier versions of checkstyle used ^f[A-Z][a-zA-Z0-9]*$ as the
59      * default to allow CMP for EJB 1.1 with the default settings.
60      * With EJB 2.0 it is not longer necessary to have public access
61      * for persistent fields.
62      */

63     private String JavaDoc mPublicMemberFormat = "^serialVersionUID$";
64
65     /** regexp for public members that should be ignored */
66     private Pattern JavaDoc mPublicMemberPattern;
67
68     /** Create an instance. */
69     public VisibilityModifierCheck()
70     {
71         setPublicMemberPattern(mPublicMemberFormat);
72     }
73
74     /** @return whether protected members are allowed */
75     public boolean isProtectedAllowed()
76     {
77         return mProtectedAllowed;
78     }
79
80     /**
81      * Set whether protected members are allowed.
82      * @param aProtectedAllowed whether protected members are allowed
83      */

84     public void setProtectedAllowed(boolean aProtectedAllowed)
85     {
86         mProtectedAllowed = aProtectedAllowed;
87     }
88
89     /** @return whether package visible members are allowed */
90     public boolean isPackageAllowed()
91     {
92         return mPackageAllowed;
93     }
94
95     /**
96      * Set whether package visible members are allowed.
97      * @param aPackageAllowed whether package visible members are allowed
98      */

99     public void setPackageAllowed(boolean aPackageAllowed)
100     {
101         mPackageAllowed = aPackageAllowed;
102     }
103
104     /**
105      * Set the pattern for public members to ignore.
106      * @param aPattern pattern for public members to ignore.
107      */

108     public void setPublicMemberPattern(String JavaDoc aPattern)
109     {
110         try {
111             mPublicMemberPattern = Utils.getPattern(aPattern);
112             mPublicMemberFormat = aPattern;
113         }
114         catch (final PatternSyntaxException JavaDoc e) {
115             throw new ConversionException("unable to parse " + aPattern, e);
116         }
117     }
118
119     /**
120      * @return the regexp for public members to ignore.
121      */

122     private Pattern JavaDoc getPublicMemberRegexp()
123     {
124         return mPublicMemberPattern;
125     }
126
127     /** {@inheritDoc} */
128     public int[] getDefaultTokens()
129     {
130         return new int[] {TokenTypes.VARIABLE_DEF};
131     }
132
133     /** {@inheritDoc} */
134     public void visitToken(DetailAST aAST)
135     {
136         if ((aAST.getType() != TokenTypes.VARIABLE_DEF)
137             || (aAST.getParent().getType() != TokenTypes.OBJBLOCK))
138         {
139             return;
140         }
141
142         final DetailAST varNameAST = getVarNameAST(aAST);
143         final String JavaDoc varName = varNameAST.getText();
144         final boolean inInterfaceOrAnnotationBlock =
145             ScopeUtils.inInterfaceOrAnnotationBlock(aAST);
146         final Set JavaDoc mods = getModifiers(aAST);
147         final String JavaDoc declaredScope = getVisibilityScope(mods);
148         final String JavaDoc variableScope =
149              inInterfaceOrAnnotationBlock ? "public" : declaredScope;
150
151         if (!("private".equals(variableScope)
152                 || inInterfaceOrAnnotationBlock // implicitly static and final
153
|| (mods.contains("static") && mods.contains("final"))
154                 || ("package".equals(variableScope) && isPackageAllowed())
155                 || ("protected".equals(variableScope) && isProtectedAllowed())
156                 || ("public".equals(variableScope)
157                    && getPublicMemberRegexp().matcher(varName).find())))
158         {
159             log(varNameAST.getLineNo(), varNameAST.getColumnNo(),
160                     "variable.notPrivate", varName);
161         }
162     }
163
164     /**
165      * Returns the variable name in a VARIABLE_DEF AST.
166      * @param aVariableDefAST an AST where type == VARIABLE_DEF AST.
167      * @return the variable name in aVariableDefAST
168      */

169     private DetailAST getVarNameAST(DetailAST aVariableDefAST)
170     {
171         AST ast = aVariableDefAST.getFirstChild();
172         while (ast != null) {
173             final AST nextSibling = ast.getNextSibling();
174             if (ast.getType() == TokenTypes.TYPE) {
175                 return (DetailAST) nextSibling;
176             }
177             ast = nextSibling;
178         }
179         return null;
180     }
181
182     /**
183      * Returns the set of modifier Strings for a VARIABLE_DEF AST.
184      * @param aVariableDefAST AST for a vraiable definition
185      * @return the set of modifier Strings for variableDefAST
186      */

187     private Set JavaDoc getModifiers(DetailAST aVariableDefAST)
188     {
189         final AST modifiersAST = aVariableDefAST.getFirstChild();
190         if (modifiersAST.getType() != TokenTypes.MODIFIERS) {
191             throw new IllegalStateException JavaDoc("Strange parse tree");
192         }
193         final Set JavaDoc retVal = new HashSet JavaDoc();
194         AST modifier = modifiersAST.getFirstChild();
195         while (modifier != null) {
196             retVal.add(modifier.getText());
197             modifier = modifier.getNextSibling();
198         }
199         return retVal;
200
201     }
202
203     /**
204      * Returns the visibility scope specified with a set of modifiers.
205      * @param aModifiers the set of modifier Strings
206      * @return one of "public", "private", "protected", "package"
207      */

208     private String JavaDoc getVisibilityScope(Set JavaDoc aModifiers)
209     {
210         final String JavaDoc[] explicitModifiers = {"public", "private", "protected"};
211         for (int i = 0; i < explicitModifiers.length; i++) {
212             final String JavaDoc candidate = explicitModifiers[i];
213             if (aModifiers.contains(candidate)) {
214                 return candidate;
215             }
216         }
217         return "package";
218     }
219 }
220
Popular Tags