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.net.URI;
29  import java.nio.charset.Charset;
30  import java.nio.charset.UnsupportedCharsetException;
31  import java.util.ArrayList;
32  import java.util.List;
33  import java.util.Set;
34  import java.util.regex.Pattern;
35  
36  import com.puppycrawl.tools.checkstyle.PropertyType;
37  import com.puppycrawl.tools.checkstyle.XdocsPropertyType;
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      @XdocsPropertyType(PropertyType.STRING)
61      private Charset charset;
62  
63      
64  
65  
66  
67      protected abstract void postProcessHeaderLines();
68  
69      
70  
71  
72  
73  
74      protected List<String> getHeaderLines() {
75          return List.copyOf(readerLines);
76      }
77  
78      
79  
80  
81  
82  
83      public void setCharset(String charset) {
84          this.charset = createCharset(charset);
85      }
86  
87      
88  
89  
90  
91  
92  
93      public void setHeaderFile(URI uri) throws CheckstyleException {
94          if (uri == null) {
95              throw new CheckstyleException(
96                  "property 'headerFile' is missing or invalid in module "
97                      + getConfiguration().getName());
98          }
99  
100         headerFile = uri;
101     }
102 
103     
104 
105 
106 
107 
108     private void loadHeaderFile() throws CheckstyleException {
109         checkHeaderNotInitialized();
110         try (Reader headerReader = new InputStreamReader(new BufferedInputStream(
111                     headerFile.toURL().openStream()), charset)) {
112             loadHeader(headerReader);
113         }
114         catch (final IOException exc) {
115             throw new CheckstyleException(
116                     "unable to load header file " + headerFile, exc);
117         }
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 
140     private static Charset createCharset(String name) {
141         if (!Charset.isSupported(name)) {
142             final String message = "unsupported charset: '" + name + "'";
143             throw new UnsupportedCharsetException(message);
144         }
145         return Charset.forName(name);
146     }
147 
148     
149 
150 
151 
152 
153 
154 
155 
156     public void setHeader(String header) {
157         if (!CommonUtil.isBlank(header)) {
158             checkHeaderNotInitialized();
159 
160             final String headerExpandedNewLines = ESCAPED_LINE_FEED_PATTERN
161                     .matcher(header).replaceAll("\n");
162 
163             try (Reader headerReader = new StringReader(headerExpandedNewLines)) {
164                 loadHeader(headerReader);
165             }
166             catch (final IOException exc) {
167                 throw new IllegalArgumentException("unable to load header", exc);
168             }
169         }
170     }
171 
172     
173 
174 
175 
176 
177 
178     private void loadHeader(final Reader headerReader) throws IOException {
179         try (LineNumberReader lnr = new LineNumberReader(headerReader)) {
180             String line;
181             do {
182                 line = lnr.readLine();
183                 if (line != null) {
184                     readerLines.add(line);
185                 }
186             } while (line != null);
187             postProcessHeaderLines();
188         }
189     }
190 
191     @Override
192     protected final void finishLocalSetup() throws CheckstyleException {
193         if (headerFile != null) {
194             loadHeaderFile();
195         }
196     }
197 
198     @Override
199     public Set<String> getExternalResourceLocations() {
200         final Set<String> result;
201 
202         if (headerFile == null) {
203             result = Set.of();
204         }
205         else {
206             result = Set.of(headerFile.toASCIIString());
207         }
208 
209         return result;
210     }
211 
212 }