1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.assembly.filter;
20
21 import javax.inject.Named;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.io.OutputStreamWriter;
27 import java.io.Reader;
28 import java.io.StringWriter;
29 import java.io.Writer;
30 import java.nio.charset.StandardCharsets;
31 import java.nio.file.Files;
32 import java.util.ArrayList;
33 import java.util.Collections;
34 import java.util.Date;
35 import java.util.List;
36
37 import org.apache.commons.io.IOUtils;
38 import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
39 import org.codehaus.plexus.archiver.Archiver;
40 import org.codehaus.plexus.archiver.ArchiverException;
41 import org.codehaus.plexus.archiver.UnArchiver;
42 import org.codehaus.plexus.components.io.fileselectors.FileInfo;
43
44
45
46
47 @Named("file-aggregator")
48 public class SimpleAggregatingDescriptorHandler implements ContainerDescriptorHandler {
49
50
51 @SuppressWarnings("FieldCanBeLocal")
52 private final String commentChars = "#";
53
54 private final StringWriter aggregateWriter = new StringWriter();
55
56 private final List<String> filenames = new ArrayList<>();
57
58
59
60 private String filePattern;
61
62 private String outputPath;
63
64 private boolean overrideFilterAction;
65
66 @Override
67 public void finalizeArchiveCreation(final Archiver archiver) {
68 checkConfig();
69
70 if (outputPath.endsWith("/")) {
71 throw new ArchiverException("Cannot write aggregated properties to a directory. "
72 + "You must specify a file name in the outputPath configuration for this"
73 + " handler. (handler: " + getClass().getName());
74 }
75
76 if (outputPath.startsWith("/")) {
77 outputPath = outputPath.substring(1);
78 }
79
80 final File temp = writePropertiesFile();
81
82 overrideFilterAction = true;
83
84 archiver.addFile(temp, outputPath);
85
86 overrideFilterAction = false;
87 }
88
89 private File writePropertiesFile() {
90 File f;
91 try {
92 f = Files.createTempFile("maven-assembly-plugin", "tmp").toFile();
93 f.deleteOnExit();
94
95 try (Writer writer = getWriter(f)) {
96 writer.write(commentChars + " Aggregated on " + new Date() + " from: ");
97
98 for (final String filename : filenames) {
99 writer.write("\n" + commentChars + " " + filename);
100 }
101
102 writer.write("\n\n");
103 writer.write(aggregateWriter.toString());
104 }
105 } catch (final IOException e) {
106 throw new ArchiverException(
107 "Error adding aggregated properties to finalize archive creation. Reason: " + e.getMessage(), e);
108 }
109
110 return f;
111 }
112
113 private Writer getWriter(File f) throws IOException {
114 Writer writer;
115 writer = AssemblyFileUtils.isPropertyFile(f)
116 ? new OutputStreamWriter(Files.newOutputStream(f.toPath()), StandardCharsets.ISO_8859_1)
117 : new OutputStreamWriter(Files.newOutputStream(f.toPath()));
118 return writer;
119 }
120
121 @Override
122 public void finalizeArchiveExtraction(final UnArchiver unarchiver) {}
123
124 @Override
125 public List<String> getVirtualFiles() {
126 checkConfig();
127
128 return Collections.singletonList(outputPath);
129 }
130
131 @Override
132 public boolean isSelected(final FileInfo fileInfo) throws IOException {
133 checkConfig();
134
135 if (overrideFilterAction) {
136 return true;
137 }
138
139 String name = AssemblyFileUtils.normalizeFileInfo(fileInfo);
140
141 if (fileInfo.isFile() && name.matches(filePattern)) {
142 readProperties(fileInfo);
143 filenames.add(name);
144
145 return false;
146 }
147
148 return true;
149 }
150
151 private void checkConfig() {
152 if (filePattern == null || outputPath == null) {
153 throw new IllegalStateException(
154 "You must configure filePattern and outputPath in your containerDescriptorHandler declaration.");
155 }
156 }
157
158 private void readProperties(final FileInfo fileInfo) throws IOException {
159 try (StringWriter writer = new StringWriter();
160 Reader reader = AssemblyFileUtils.isPropertyFile(fileInfo.getName())
161 ? new InputStreamReader(fileInfo.getContents(), StandardCharsets.ISO_8859_1)
162 : new InputStreamReader(fileInfo.getContents()))
163 {
164 IOUtils.copy(reader, writer);
165 final String content = writer.toString();
166 aggregateWriter.write("\n");
167 aggregateWriter.write(content);
168 }
169 }
170
171 @SuppressWarnings("UnusedDeclaration")
172 public String getFilePattern() {
173 return filePattern;
174 }
175
176 @SuppressWarnings("UnusedDeclaration")
177 public void setFilePattern(final String filePattern) {
178 this.filePattern = filePattern;
179 }
180
181 @SuppressWarnings("UnusedDeclaration")
182 public String getOutputPath() {
183 return outputPath;
184 }
185
186 @SuppressWarnings("UnusedDeclaration")
187 public void setOutputPath(final String outputPath) {
188 this.outputPath = outputPath;
189 }
190 }