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