Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/checks/design/FinalClassCheck.java


1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2003  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 com.puppycrawl.tools.checkstyle.api.Check;
22  import com.puppycrawl.tools.checkstyle.api.DetailAST;
23  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
24  import java.util.Stack;
25  
26  /**
27   * <p>
28   * Checks that class which has only private ctors
29   * is declared as final.
30   * </p>
31   * <p>
32   * An example of how to configure the check is:
33   * </p>
34   * <pre>
35   * &lt;module name="FinalClass"/&gt;
36   * </pre>
37   * @author o_sukhodolsky
38   */
39  public class FinalClassCheck
40      extends Check
41  {
42      /** keeps ClassDesc objects for stack of declared classes */
43      private final Stack mClasses = new Stack();
44  
45      /** @see Check */
46      public int[] getDefaultTokens()
47      {
48          return new int[]{TokenTypes.CLASS_DEF, TokenTypes.CTOR_DEF};
49      }
50  
51      /** @see Check */
52      public void visitToken(DetailAST aAST)
53      {
54          final DetailAST modifiers = aAST.findFirstToken(TokenTypes.MODIFIERS);
55  
56          if (aAST.getType() == TokenTypes.CLASS_DEF) {
57              final boolean isFinal = (modifiers != null)
58                      && modifiers.branchContains(TokenTypes.FINAL);
59              final boolean isAbstract = (modifiers != null)
60                      && modifiers.branchContains(TokenTypes.ABSTRACT);
61              mClasses.push(new ClassDesc(isFinal, isAbstract));
62          }
63          else {
64              final ClassDesc desc = (ClassDesc) mClasses.peek();
65              if ((modifiers != null)
66                  && modifiers.branchContains(TokenTypes.LITERAL_PRIVATE))
67              {
68                  desc.reportPrivateCtor();
69              }
70              else {
71                  desc.reportNonPrivateCtor();
72              }
73          }
74      }
75  
76      /** @see Check */
77      public void leaveToken(DetailAST aAST)
78      {
79          if (aAST.getType() != TokenTypes.CLASS_DEF) {
80              return;
81          }
82  
83          final ClassDesc desc = (ClassDesc) mClasses.pop();
84          if (!desc.isDeclaredAsFinal()
85              && !desc.isDeclaredAsAbstract()
86              && desc.hasPrivateCtor()
87              && !desc.hasNonPrivateCtor())
88          {
89              final String className =
90                  aAST.findFirstToken(TokenTypes.IDENT).getText();
91              log(aAST.getLineNo(), "final.class", className);
92          }
93      }
94  
95      /** maintains information about class' ctors */
96      private static final class ClassDesc
97      {
98          /** is class declared as final */
99          private final boolean mDeclaredAsFinal;
100 
101         /** is class declared as abstract */
102         private final boolean mDeclaredAsAbstract;
103 
104         /** does class have non-provate ctors */
105         private boolean mHasNonPrivateCtor;
106 
107         /** does class have private ctors */
108         private boolean mHasPrivateCtor;
109 
110         /**
111          *  create a new ClassDesc instance.
112          *  @param aDeclaredAsFinal indicates if the
113          *         class declared as final
114          *  @param aDeclaredAsAbstract indicates if the
115          *         class declared as abstract
116          */
117         ClassDesc(boolean aDeclaredAsFinal, boolean aDeclaredAsAbstract)
118         {
119             mDeclaredAsFinal = aDeclaredAsFinal;
120             mDeclaredAsAbstract = aDeclaredAsAbstract;
121         }
122 
123         /** adds private ctor. */
124         void reportPrivateCtor()
125         {
126             mHasPrivateCtor = true;
127         }
128 
129         /** adds non-private ctor. */
130         void reportNonPrivateCtor()
131         {
132             mHasNonPrivateCtor = true;
133         }
134 
135         /**
136          *  does class have private ctors.
137          *  @return true if class has private ctors
138          */
139         boolean hasPrivateCtor()
140         {
141             return mHasPrivateCtor;
142         }
143 
144         /**
145          *  does class have non-private ctors.
146          *  @return true if class has non-private ctors
147          */
148         boolean hasNonPrivateCtor()
149         {
150             return mHasNonPrivateCtor;
151         }
152 
153         /**
154          *  is class declared as final.
155          *  @return true if class is declared as final
156          */
157         boolean isDeclaredAsFinal()
158         {
159             return mDeclaredAsFinal;
160         }
161 
162         /**
163          *  is class declared as abstract.
164          *  @return true if class is declared as final
165          */
166         boolean isDeclaredAsAbstract()
167         {
168             return mDeclaredAsAbstract;
169         }
170 
171         /**
172          * Returns a string representation of the object.
173          * @return a string representation of the object
174          */
175         public String toString()
176         {
177             return this.getClass().getName()
178                 + "["
179                 + "final=" + mDeclaredAsFinal
180                 + " abstract=" + mDeclaredAsAbstract
181                 + " pctor=" + mHasPrivateCtor
182                 + " ctor=" + mHasNonPrivateCtor
183                 + "]";
184         }
185     }
186 }