View Javadoc
1   package org.codehaus.mojo.taglist.beans;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.BufferedReader;
23  import java.io.File;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.Reader;
28  import java.nio.file.Files;
29  import java.util.Collection;
30  import java.util.HashMap;
31  import java.util.Map;
32  import java.util.TreeSet;
33  
34  /**
35   * Report for a file.
36   *
37   * @author <a href="mailto:bellingard.NO-SPAM@gmail.com">Fabrice Bellingard </a>
38   */
39  public class FileReport implements Comparable<FileReport> {
40  
41      /**
42       * The file being analyzed.
43       */
44      private final File file;
45  
46      /**
47       * The character encoding of the source file
48       */
49      private final String encoding;
50  
51      /**
52       * The name of the class corresponding to this file.
53       */
54      private String className;
55  
56      /**
57       * Pair values of a line number and a comment. Map of [Integer,String].
58       */
59      private final Map<Integer, String> tagListing;
60  
61      /**
62       * The package identification string.
63       */
64      private static final String PACKAGE_STR = "package";
65  
66      /**
67       * Constructor.
68       *
69       * @param file The file to analyze.
70       * @param encoding the file encoding to use for the report.
71       */
72      public FileReport(File file, String encoding) {
73          this.file = file;
74          this.encoding = encoding;
75          this.tagListing = new HashMap<>();
76      }
77  
78      /**
79       * Adds a new entry to the list of tags found for this file report.
80       *
81       * @param comment the comment string containing the 'todo'.
82       * @param lineIndex the line number of the comment (or first line if multi-lined).
83       */
84      public void addComment(String comment, int lineIndex) {
85          tagListing.put(lineIndex, comment);
86      }
87  
88      /**
89       * Returns the path corresponding to the analyzed class, for instance:
90       * org/apache/maven/plugins/taglist/beans/FileReport.
91       *
92       * @return the file path.
93       */
94      public String getClassNameWithSlash() {
95          return className.replace('.', '/');
96      }
97  
98      /**
99       * Access an input reader that uses the current file encoding.
100      *
101      * @param fileToRead the file to open in the reader.
102      * @throws IOException the IO exception.
103      * @return a reader with the current file encoding.
104      */
105     private Reader getReader(File fileToRead) throws IOException {
106         InputStream in = Files.newInputStream(fileToRead.toPath());
107         return (encoding == null) ? new InputStreamReader(in) : new InputStreamReader(in, encoding);
108     }
109 
110     /**
111      * Returns the complete name of the analyzed class, for instance: org.codehaus.mojo.taglist.beans.FileReport.
112      *
113      * @return the full class name.
114      */
115     public String getClassName() {
116         if (className != null) {
117             return className;
118         }
119         // need to compute it (only once)
120         String packageName = null;
121         try (BufferedReader reader = new BufferedReader(getReader(file))) {
122             String currentLine = reader.readLine();
123             if (currentLine != null) {
124                 currentLine = currentLine.trim();
125             }
126             while (currentLine != null) {
127                 if (currentLine.startsWith(PACKAGE_STR)) {
128                     packageName = currentLine
129                             .substring(PACKAGE_STR.length())
130                             .trim()
131                             .replaceAll(";", "")
132                             .trim();
133                     break;
134                 }
135                 String nextLine = reader.readLine();
136                 if (nextLine == null) {
137                     currentLine = nextLine;
138                 } else {
139                     currentLine = nextLine.trim();
140                 }
141             }
142         } catch (IOException e) {
143             packageName = "unknown";
144         }
145 
146         className = packageName + "." + file.getName().replaceAll("\\.java$", "");
147 
148         return className;
149     }
150 
151     /**
152      * Returns the list of the comment line indexes.
153      *
154      * @return Collection of Integer.
155      */
156     public Collection<Integer> getLineIndexes() {
157         return new TreeSet<>(tagListing.keySet());
158     }
159 
160     /**
161      * Returns the comment for the corresponding line index.
162      *
163      * @param lineIndex the index of the line.
164      * @return the comment.
165      */
166     public String getComment(Integer lineIndex) {
167         return tagListing.get(lineIndex);
168     }
169 
170     /**
171      * {@inheritDoc}
172      *
173      * @see Comparable#compareTo(Object)
174      */
175     public int compareTo(FileReport o) {
176         if (o != null) {
177             return this.getClassName().compareTo(o.getClassName());
178         } else {
179             return 0;
180         }
181     }
182 
183     /**
184      * {@inheritDoc}
185      *
186      * @see Object#equals(Object)
187      */
188     public boolean equals(Object r) {
189         // In Java 5 the PriorityQueue.remove method uses the
190         // compareTo method, while in Java 6 it uses the equals method.
191         if (!(r instanceof FileReport)) {
192             return false;
193         }
194         return (this.compareTo((FileReport) r) == 0);
195     }
196 
197     /**
198      * {@inheritDoc}
199      *
200      * @see Object#hashCode()
201      */
202     public int hashCode() {
203         assert false : "hashCode not designed";
204         return 1; // any arbitrary constant will do
205     }
206 }