1
2
3
4
5
6
7
8 package au.com.acegi.xmlformat;
9
10 import java.io.File;
11 import java.io.IOException;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.List;
15
16 import org.apache.maven.plugin.AbstractMojo;
17 import org.apache.maven.plugin.MojoExecutionException;
18 import org.apache.maven.plugin.MojoFailureException;
19 import org.apache.maven.plugins.annotations.Parameter;
20 import org.codehaus.plexus.util.DirectoryScanner;
21 import org.dom4j.DocumentException;
22
23
24
25
26 @SuppressWarnings("DesignForExtension")
27 public abstract class AbstractXmlPlugin extends AbstractMojo {
28
29
30
31
32 @Parameter(property = "attributeQuoteChar", defaultValue = "\"")
33 @SuppressWarnings("PMD.ImmutableField")
34 private char attributeQuoteChar = '"';
35
36
37
38
39 @Parameter(defaultValue = ".", readonly = true, required = true, property = "project.basedir")
40 private File baseDirectory;
41
42
43
44
45 @Parameter(property = "encoding", defaultValue = "UTF-8")
46 @SuppressWarnings("PMD.ImmutableField")
47 private String encoding = "UTF-8";
48
49
50
51
52
53
54 @Parameter(property = "excludes")
55 private String[] excludes;
56
57
58
59
60 @Parameter(property = "expandEmptyElements", defaultValue = "false")
61 private boolean expandEmptyElements;
62
63
64
65
66
67 @Parameter(property = "includes")
68 private String[] includes;
69
70
71
72
73 @Parameter(property = "indentSize", defaultValue = "2")
74 private int indentSize;
75
76
77
78
79 @Parameter(property = "tabIndent", defaultValue = "false")
80 private boolean tabIndent;
81
82
83
84
85
86
87
88
89
90
91
92
93 @Parameter(property = "lineEnding", defaultValue = "LF")
94 @SuppressWarnings("PMD.ImmutableField")
95 private LineEnding lineEnding = LineEnding.LF;
96
97
98
99
100
101
102 @Parameter(property = "lineSeparator", defaultValue = "\n")
103 @SuppressWarnings("PMD.ImmutableField")
104 @Deprecated
105 private String lineSeparator = "\n";
106
107
108
109
110 @Parameter(property = "newLineAfterDeclaration", defaultValue = "false")
111 private boolean newLineAfterDeclaration;
112
113
114
115
116 @Parameter(property = "newLineAfterNTags", defaultValue = "0")
117 private int newLineAfterNTags;
118
119
120
121
122 @Parameter(property = "newlines", defaultValue = "true")
123 private boolean newlines;
124
125
126
127
128 @Parameter(property = "omitEncoding", defaultValue = "false")
129 private boolean omitEncoding;
130
131
132
133
134 @Parameter(property = "padText", defaultValue = "false")
135 private boolean padText;
136
137
138
139
140 @Parameter(property = "xml-format.skip", defaultValue = "false")
141 private boolean skip;
142
143
144
145
146
147 @Parameter(property = "skipTargetFolder", defaultValue = "true")
148 private boolean skipTargetFolder = true;
149
150
151
152
153 @Parameter(property = "suppressDeclaration", defaultValue = "false")
154 private boolean suppressDeclaration;
155
156
157
158
159 @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true)
160 private File targetDirectory;
161
162
163
164
165 @Parameter(property = "trimText", defaultValue = "true")
166 private boolean trimText;
167
168
169
170
171 @Parameter(property = "xhtml", defaultValue = "false")
172 private boolean xhtml;
173
174
175
176
177 @Parameter(property = "keepBlankLines", defaultValue = "false")
178 private boolean keepBlankLines;
179
180 @Override
181 public void execute() throws MojoExecutionException, MojoFailureException {
182 assert baseDirectory != null;
183 assert targetDirectory != null;
184
185 if (skip) {
186 getLog().info("[xml-format] Skipped");
187 return;
188 }
189
190 initializeIncludes();
191 initializeExcludes();
192
193 final XmlOutputFormat fmt = buildFormatter();
194
195 boolean success = true;
196 boolean neededFormatting = false;
197 for (final String inputName : find()) {
198 final File input = baseDirectory.toPath().resolve(inputName).toFile();
199 try {
200 neededFormatting |= processFile(input, fmt);
201 } catch (final DocumentException | IOException ex) {
202 success = false;
203 getLog().error("[xml-format] Error for " + input, ex);
204 }
205 }
206
207 if (!success) {
208 throw new MojoFailureException("[xml-format] Failed)");
209 }
210 afterAllProcessed(neededFormatting);
211 }
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 protected abstract boolean processFile(File input, XmlOutputFormat fmt) throws DocumentException, IOException;
229
230
231
232
233
234
235
236
237
238
239 protected abstract void afterAllProcessed(boolean neededFormatting) throws MojoExecutionException;
240
241 void setBaseDirectory(final File baseDirectory) {
242 this.baseDirectory = baseDirectory;
243 }
244
245 void setExcludes(final String... excludes) {
246 this.excludes = excludes == null ? null : Arrays.copyOf(excludes, excludes.length);
247 }
248
249 void setIncludes(final String... includes) {
250 this.includes = includes == null ? null : Arrays.copyOf(includes, includes.length);
251 }
252
253 void setSkip(final boolean skip) {
254 this.skip = skip;
255 }
256
257 void setSkipTargetFolder(final boolean skipTargetFolder) {
258 this.skipTargetFolder = skipTargetFolder;
259 }
260
261 void setTargetDirectory(final File targetDirectory) {
262 this.targetDirectory = targetDirectory;
263 }
264
265 private XmlOutputFormat buildFormatter() {
266 final XmlOutputFormat fmt = new XmlOutputFormat();
267 fmt.setAttributeQuoteCharacter(attributeQuoteChar);
268 fmt.setEncoding(encoding);
269 fmt.setExpandEmptyElements(expandEmptyElements);
270 if (tabIndent) {
271 fmt.setIndent("\t");
272 } else {
273 fmt.setIndentSize(indentSize);
274 }
275 fmt.setLineSeparator(determineLineSeparator());
276 fmt.setNewLineAfterDeclaration(newLineAfterDeclaration);
277 fmt.setNewLineAfterNTags(newLineAfterNTags);
278 fmt.setNewlines(newlines);
279 fmt.setOmitEncoding(omitEncoding);
280 fmt.setPadText(padText);
281 fmt.setSuppressDeclaration(suppressDeclaration);
282 fmt.setTrimText(trimText);
283 fmt.setXHTML(xhtml);
284 fmt.setKeepBlankLines(keepBlankLines);
285 return fmt;
286 }
287
288 private String determineLineSeparator() {
289 return "\n".equals(lineSeparator) ? lineEnding.getChars() : lineSeparator;
290 }
291
292 private String[] find() {
293 final DirectoryScanner dirScanner = new DirectoryScanner();
294 dirScanner.setBasedir(baseDirectory);
295 dirScanner.setIncludes(includes);
296
297 final List<String> exclude = new ArrayList<>(Arrays.asList(excludes));
298 if (skipTargetFolder && baseDirectory.equals(targetDirectory.getParentFile())) {
299 exclude.add(targetDirectory.getName() + "/**");
300 }
301 final String[] excluded = new String[exclude.size()];
302 dirScanner.setExcludes(exclude.toArray(excluded));
303
304 dirScanner.scan();
305 return dirScanner.getIncludedFiles();
306 }
307
308 private void initializeExcludes() {
309 if (excludes == null || excludes.length == 0) {
310 excludes = new String[0];
311 }
312 }
313
314 private void initializeIncludes() {
315 if (includes == null || includes.length == 0) {
316 includes = new String[] { "**/*.xml" };
317 }
318 }
319 }