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/HideUtilityClassConstructorCheck.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.TokenTypes;
23  import com.puppycrawl.tools.checkstyle.api.DetailAST;
24  
25  /**
26   * Make sure that utility classes (classes that contain only static methods)
27   * do not have a public constructor.
28   * <p>
29   * Rationale: Instantiating utility classes does not make sense.
30   * A common mistake is forgetting to hide the default constructor.
31   * </p>
32   *
33   * @author lkuehne
34   * @version $Revision: 1.4 $
35   */
36  public class HideUtilityClassConstructorCheck extends Check
37  {
38      /** @see Check */
39      public int[] getDefaultTokens()
40      {
41          return new int[] {TokenTypes.CLASS_DEF};
42      }
43  
44      /** @see Check */
45      public void visitToken(DetailAST aAST)
46      {
47          DetailAST objBlock = aAST.findFirstToken(TokenTypes.OBJBLOCK);
48          DetailAST child = (DetailAST) objBlock.getFirstChild();
49          boolean hasMethod = false;
50          boolean hasNonStaticMethod = false;
51          boolean hasDefaultCtor = true;
52          boolean hasPublicCtor = false;
53  
54          while (child != null) {
55              if (child.getType() == TokenTypes.METHOD_DEF) {
56                  hasMethod = true;
57                  final DetailAST modifiers =
58                      child.findFirstToken(TokenTypes.MODIFIERS);
59                  if (!modifiers.branchContains(TokenTypes.LITERAL_STATIC)) {
60                      hasNonStaticMethod = true;
61                  }
62              }
63              if (child.getType() == TokenTypes.CTOR_DEF) {
64                  hasDefaultCtor = false;
65                  final DetailAST modifiers =
66                      child.findFirstToken(TokenTypes.MODIFIERS);
67                  if (!modifiers.branchContains(TokenTypes.LITERAL_PRIVATE)
68                      && !modifiers.branchContains(TokenTypes.LITERAL_PROTECTED))
69                  {
70                      // treat package visible as public
71                      // for the purpose of this Check
72                      hasPublicCtor = true;
73                  }
74  
75              }
76              child = (DetailAST) child.getNextSibling();
77          }
78  
79          final boolean hasAccessibleCtor = (hasDefaultCtor || hasPublicCtor);
80  
81          // figure out if class extends java.lang.object directly
82          // keep it simple for now and get a 99% solution
83          // TODO: check for "extends java.lang.Object" and "extends Object"
84          // consider "import org.omg.CORBA.*"
85          final DetailAST extendsClause =
86                  aAST.findFirstToken(TokenTypes.EXTENDS_CLAUSE);
87          final boolean extendsJLO = // J.Lo even made it into in our sources :-)
88                  extendsClause.getFirstChild() == null;
89  
90          if (extendsJLO
91                  && hasMethod && !hasNonStaticMethod && hasAccessibleCtor)
92          {
93              log(aAST.getLineNo(), aAST.getColumnNo(),
94                  "Utility classes should not have "
95                  + "a public or default constructor.");
96          }
97      }
98  }