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

Quick Search    Search Deep

Source code: com/puppycrawl/tools/checkstyle/api/FileContents.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.api;
20  
21  import org.apache.regexp.RE;
22  
23  import java.util.ArrayList;
24  import java.util.Collections;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.HashMap;
28  
29  /**
30   * Represents the contents of a file.
31   *
32   * @author Oliver Burn
33   * @version 1.0
34   */
35  public final class FileContents
36  {
37      /**
38       * the pattern to match a single line comment containing only the comment
39       * itself -- no code.
40       */
41      private static final String MATCH_SINGLELINE_COMMENT_PAT =
42          "^\\s*//.*$";
43      /** compiled regexp to match a single-line comment line */
44      private static final RE MATCH_SINGLELINE_COMMENT =
45          Utils.createRE(MATCH_SINGLELINE_COMMENT_PAT);
46  
47      /** the file name */
48      private final String mFilename;
49  
50      /** the lines */
51      private final String[] mLines;
52  
53      /** map of the Javadoc comments indexed on the last line of the comment.
54       * The hack is it assumes that there is only one Javadoc comment per line.
55       */
56      private final Map mJavadocComments = new HashMap();
57  
58      /** map of the C++ comments indexed on the first line of the comment. */
59      private final Map mCPlusPlusComments = new HashMap();
60      /**
61       * map of the C comments indexed on the first line of the comment to a
62       * list of comments on that line
63       */
64      private final Map mCComments = new HashMap();
65  
66      /**
67       * Creates a new <code>FileContents</code> instance.
68       *
69       * @param aFilename name of the file
70       * @param aLines the contents of the file
71       */
72      public FileContents(String aFilename, String[] aLines)
73      {
74          mFilename = aFilename;
75          mLines = aLines;
76      }
77  
78      /**
79       * Report the location of a C++ style comment.
80       * @param aStartLineNo the starting line number
81       * @param aStartColNo the starting column number
82       **/
83      public void reportCppComment(int aStartLineNo, int aStartColNo)
84      {
85          final String cmt = mLines[aStartLineNo - 1].substring(aStartColNo);
86          mCPlusPlusComments.put(new Integer(aStartLineNo), cmt);
87      }
88  
89      /**
90       * Returns a map of all the C++ style comments. The key is a line number,
91       * the value is the comment at the line.
92       * @return the Map of comments
93       */
94      public Map getCppComments()
95      {
96          return Collections.unmodifiableMap(mCPlusPlusComments);
97      }
98  
99      /**
100      * Report the location of a C-style comment.
101      * @param aStartLineNo the starting line number
102      * @param aStartColNo the starting column number
103      * @param aEndLineNo the ending line number
104      * @param aEndColNo the ending column number
105      **/
106     public void reportCComment(int aStartLineNo, int aStartColNo,
107                                int aEndLineNo, int aEndColNo)
108     {
109         final String[] cc = extractCComment(aStartLineNo, aStartColNo,
110                                             aEndLineNo, aEndColNo);
111 
112         // save the comment
113         final Integer key = new Integer(aStartLineNo);
114         if (mCComments.containsKey(key)) {
115             final List entries = (List) mCComments.get(key);
116             entries.add(cc);
117         }
118         else {
119             final List entries = new ArrayList();
120             entries.add(cc);
121             mCComments.put(key, entries);
122         }
123 
124         // Remember if possible Javadoc comment
125         if (mLines[aStartLineNo - 1].indexOf("/**", aStartColNo) != -1) {
126             mJavadocComments.put(new Integer(aEndLineNo - 1), cc);
127         }
128     }
129 
130     /**
131      * Returns a map of all C style comments. The key is the line number, the
132      * value is a list of C style comments at the line.
133      * @return the map of comments
134      */
135     public Map getCComments()
136     {
137         return Collections.unmodifiableMap(mCComments);
138     }
139 
140     /**
141      * Returns the specified C comment as a String array.
142      * @return C comment as a array
143      * @param aStartLineNo the starting line number
144      * @param aStartColNo the starting column number
145      * @param aEndLineNo the ending line number
146      * @param aEndColNo the ending column number
147      **/
148     private String[] extractCComment(int aStartLineNo, int aStartColNo,
149                                      int aEndLineNo, int aEndColNo)
150     {
151         String[] retVal;
152         if (aStartLineNo == aEndLineNo) {
153             retVal = new String[1];
154             retVal[0] = mLines[aStartLineNo - 1].substring(aStartColNo,
155                                                            aEndColNo + 1);
156         }
157         else {
158             retVal = new String[aEndLineNo - aStartLineNo + 1];
159             retVal[0] = mLines[aStartLineNo - 1].substring(aStartColNo);
160             for (int i = aStartLineNo; i < aEndLineNo; i++) {
161                 retVal[i - aStartLineNo + 1] = mLines[i];
162             }
163             retVal[retVal.length - 1] =
164                 mLines[aEndLineNo - 1].substring(0, aEndColNo + 1);
165         }
166         return retVal;
167     }
168 
169     /**
170      * Returns the Javadoc comment before the specified line.
171      * A return value of <code>null</code> means there is no such comment.
172      * @return the Javadoc comment, or <code>null</code> if none
173      * @param aLineNo the line number to check before
174      **/
175     public String[] getJavadocBefore(int aLineNo)
176     {
177         // Lines start at 1 to the callers perspective, so need to take off 2
178         int lineNo = aLineNo - 2;
179 
180         // skip blank lines
181         while ((lineNo > 0) && (lineIsBlank(lineNo) || lineIsComment(lineNo))) {
182             lineNo--;
183         }
184 
185         return (String[]) mJavadocComments.get(new Integer(lineNo));
186     }
187 
188     /** @return the lines in the file */
189     public String[] getLines()
190     {
191         return mLines;
192     }
193 
194     /** @return the name of the file */
195     public String getFilename()
196     {
197         return mFilename;
198     }
199 
200     /**
201      * Checks if the specified line is blank.
202      * @param aLineNo the line number to check
203      * @return if the specified line consists only of tabs and spaces.
204      **/
205     public boolean lineIsBlank(int aLineNo)
206     {
207         // possible improvement: avoid garbage creation in trim()
208         return "".equals(mLines[aLineNo].trim());
209     }
210 
211     /**
212      * Checks if the specified line is a single-line comment without code.
213      * @param aLineNo  the line number to check
214      * @return if the specified line consists of only a single line comment
215      *         without code.
216      **/
217     public boolean lineIsComment(int aLineNo)
218     {
219       return MATCH_SINGLELINE_COMMENT.match(mLines[aLineNo]);
220     }
221 
222 }