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