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/HeaderCheck.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  
20  package com.puppycrawl.tools.checkstyle.checks;
21  
22  import java.io.FileReader;
23  import java.io.IOException;
24  import java.io.LineNumberReader;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  
28  import com.puppycrawl.tools.checkstyle.api.Check;
29  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
30  import com.puppycrawl.tools.checkstyle.api.DetailAST;
31  
32  import org.apache.commons.beanutils.ConversionException;
33  
34  /**
35   * <p>
36   * Checks the header of the source against a fixed header file.
37   * </p>
38   * <p>
39   * Rationale: In most projects each file must have a fixed header,
40   * since usually the header contains copyright information.
41   * </p>
42   * <p> The header contents are specified in the file identified by property
43   * headerFile.
44   * </p>
45   * <p>Property ignoreLines specifies the line numbers to ignore when
46   * matching lines in a header file.
47   * The property type is a comma-separated list of integers and defaults to an
48   * empty list.
49   * </p>
50   *
51   * <p>This property is very useful for supporting headers that contain copyright
52   * dates. For example, consider the following header:</p>
53   *
54   * <pre>
55   * line 1: ////////////////////////////////////////////////////////////////////
56   * line 2: // checkstyle:
57   * line 3: // Checks Java source code for adherence to a set of rules.
58   * line 4: // Copyright (C) 2001  Oliver Burn
59   * line 5: ////////////////////////////////////////////////////////////////////
60   * </pre>
61   *
62   * <p>Since the year information will change over time, you can tell checkstyle
63   * to ignore line 4 by setting property ignoreLines to <strong>4</strong>.</p>
64   * <p>
65   * An example of how to configure the check to use header file
66   * &quot;java.header&quot; and ignore lines 2, 3, and 4 is:
67   * </p>
68   * <pre>
69   * &lt;module name="Header"&gt;
70   *    &lt;property name="headerFile" value="java.header"/&gt;
71   *    &lt;property name="ignoreLines" value="2, 3, 4"/&gt;
72   * &lt;/module&gt;
73   * </pre>
74   * @author Lars Kühne
75   */
76  public class HeaderCheck
77      extends Check
78  {
79      /** empty array to avoid instantiations */
80      private static final int[] EMPTY_INT_ARRAY = new int[0];
81  
82      /** the lines of the header file */
83      private String[] mHeaderLines;
84  
85      /** the header lines to ignore in the check, sorted */
86      private int[] mIgnoreLines = EMPTY_INT_ARRAY;
87  
88      /** @see com.puppycrawl.tools.checkstyle.api.Check */
89      public int[] getDefaultTokens()
90      {
91          return new int[0];
92      }
93  
94      /**
95       * Checks that required args were specified.
96       * @see com.puppycrawl.tools.checkstyle.api.AutomaticBean#finishLocalSetup
97       */
98      protected final void finishLocalSetup() throws CheckstyleException
99      {
100         if (mHeaderLines == null) {
101             throw new CheckstyleException(
102                     "property 'headerFile' is missing or invalid in module "
103                     + getConfiguration().getName());
104         }
105     }
106 
107     /** @see com.puppycrawl.tools.checkstyle.api.Check */
108     public void beginTree(DetailAST aRootAST)
109     {
110 
111         final String[] lines = getLines();
112 
113         if (mHeaderLines.length > lines.length) {
114             log(1, "header.missing");
115         }
116         else {
117             for (int i = 0; i < mHeaderLines.length; i++) {
118                 // skip lines we are meant to ignore
119                 if (isIgnoreLine(i + 1)) {
120                     continue;
121                 }
122 
123                 if (!isMatch(i)) {
124                     log(i + 1, "header.mismatch", mHeaderLines[i]);
125                     break; // stop checking
126                 }
127             }
128         }
129     }
130 
131     /**
132      * @param aLineNo a line number
133      * @return if <code>aLineNo</code> is one of the ignored header lines.
134      */
135     private boolean isIgnoreLine(int aLineNo)
136     {
137         return (Arrays.binarySearch(mIgnoreLines, aLineNo) >= 0);
138     }
139 
140     /**
141      * Checks if a code line matches the required header line.
142      * @param aLineNumber the linenumber to check against the header
143      * @return true if and only if the line matches the required header line
144      */
145     protected boolean isMatch(int aLineNumber)
146     {
147         final String[] lines = getLines();
148         return mHeaderLines[aLineNumber].equals(lines[aLineNumber]);
149     }
150 
151     /**
152      * Set the header file to check against.
153      * @param aFileName the file that contains the header to check against.
154      * @throws ConversionException if the file cannot be loaded
155      */
156     public void setHeaderFile(String aFileName)
157         throws ConversionException
158     {
159         // Handle empty param
160         if ((aFileName == null) || (aFileName.trim().length() == 0)) {
161             return;
162         }
163 
164         // load the file
165         try {
166             final LineNumberReader lnr =
167                     new LineNumberReader(new FileReader(aFileName));
168             final ArrayList lines = new ArrayList();
169             while (true) {
170                 final String l = lnr.readLine();
171                 if (l == null) {
172                     break;
173                 }
174                 lines.add(l);
175             }
176             mHeaderLines = (String[]) lines.toArray(new String[0]);
177         }
178         catch (IOException ex) {
179             throw new ConversionException(
180                     "unable to load header file " + aFileName, ex);
181         }
182 
183     }
184 
185     /**
186      * Set the lines numbers to ignore in the header check.
187      * @param aList comma separated list of line numbers to ignore in header.
188      */
189     public void setIgnoreLines(int[] aList)
190     {
191         if (aList == null || aList.length == 0) {
192             mIgnoreLines = EMPTY_INT_ARRAY;
193             return;
194         }
195 
196         mIgnoreLines = new int[aList.length];
197         System.arraycopy(aList, 0, mIgnoreLines, 0, aList.length);
198         Arrays.sort(mIgnoreLines);
199     }
200 
201     /**
202      * Return the header lines to check against.
203      * @return the header lines to check against.
204      */
205     protected String[] getHeaderLines()
206     {
207         return mHeaderLines;
208     }
209 }