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 }