1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.checks.header;
21
22 import java.io.BufferedInputStream;
23 import java.io.IOException;
24 import java.io.InputStreamReader;
25 import java.io.LineNumberReader;
26 import java.io.Reader;
27 import java.io.StringReader;
28 import java.io.UnsupportedEncodingException;
29 import java.net.URI;
30 import java.nio.charset.Charset;
31 import java.nio.charset.StandardCharsets;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.Set;
36 import java.util.regex.Pattern;
37
38 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
39 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
40 import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder;
41 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
42
43
44
45
46
47 public abstract class AbstractHeaderCheck extends AbstractFileSetCheck
48 implements ExternalResourceHolder {
49
50
51 private static final Pattern ESCAPED_LINE_FEED_PATTERN = Pattern.compile("\\\\n");
52
53
54 private final List<String> readerLines = new ArrayList<>();
55
56
57 private URI headerFile;
58
59
60 private String charset = System.getProperty("file.encoding", StandardCharsets.UTF_8.name());
61
62
63
64
65
66 protected abstract void postProcessHeaderLines();
67
68
69
70
71
72 protected List<String> getHeaderLines() {
73 final List<String> copy = new ArrayList<>(readerLines);
74 return Collections.unmodifiableList(copy);
75 }
76
77
78
79
80
81
82 public void setCharset(String charset) throws UnsupportedEncodingException {
83 if (!Charset.isSupported(charset)) {
84 final String message = "unsupported charset: '" + charset + "'";
85 throw new UnsupportedEncodingException(message);
86 }
87 this.charset = charset;
88 }
89
90
91
92
93
94
95 public void setHeaderFile(URI uri) throws CheckstyleException {
96 if (uri == null) {
97 throw new CheckstyleException(
98 "property 'headerFile' is missing or invalid in module "
99 + getConfiguration().getName());
100 }
101
102 headerFile = uri;
103 }
104
105
106
107
108
109 private void loadHeaderFile() throws CheckstyleException {
110 checkHeaderNotInitialized();
111 try (Reader headerReader = new InputStreamReader(new BufferedInputStream(
112 headerFile.toURL().openStream()), charset)) {
113 loadHeader(headerReader);
114 }
115 catch (final IOException ex) {
116 throw new CheckstyleException(
117 "unable to load header file " + headerFile, ex);
118 }
119 }
120
121
122
123
124
125 private void checkHeaderNotInitialized() {
126 if (!readerLines.isEmpty()) {
127 throw new IllegalArgumentException(
128 "header has already been set - "
129 + "set either header or headerFile, not both");
130 }
131 }
132
133
134
135
136
137
138
139 public void setHeader(String header) {
140 if (!CommonUtil.isBlank(header)) {
141 checkHeaderNotInitialized();
142
143 final String headerExpandedNewLines = ESCAPED_LINE_FEED_PATTERN
144 .matcher(header).replaceAll("\n");
145
146 try (Reader headerReader = new StringReader(headerExpandedNewLines)) {
147 loadHeader(headerReader);
148 }
149 catch (final IOException ex) {
150 throw new IllegalArgumentException("unable to load header", ex);
151 }
152 }
153 }
154
155
156
157
158
159
160 private void loadHeader(final Reader headerReader) throws IOException {
161 try (LineNumberReader lnr = new LineNumberReader(headerReader)) {
162 String line;
163 do {
164 line = lnr.readLine();
165 if (line != null) {
166 readerLines.add(line);
167 }
168 } while (line != null);
169 postProcessHeaderLines();
170 }
171 }
172
173 @Override
174 protected final void finishLocalSetup() throws CheckstyleException {
175 if (headerFile != null) {
176 loadHeaderFile();
177 }
178 }
179
180 @Override
181 public Set<String> getExternalResourceLocations() {
182 final Set<String> result;
183
184 if (headerFile == null) {
185 result = Collections.emptySet();
186 }
187 else {
188 result = Collections.singleton(headerFile.toString());
189 }
190
191 return result;
192 }
193
194 }