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