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