View Javadoc
1   package org.apache.maven.plugins.assembly.filter;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   * @version $Id: SimpleAggregatingDescriptorHandler.html 1016737 2017-08-13 12:01:54Z khmarbaise $
49   */
50  @Component( role = ContainerDescriptorHandler.class, hint = "file-aggregator", instantiationStrategy = "per-lookup" )
51  public class SimpleAggregatingDescriptorHandler
52      implements ContainerDescriptorHandler, LogEnabled
53  {
54  
55      // component configuration.
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      // calculated, temporary values.
65  
66      private String filePattern;
67  
68      private String outputPath;
69  
70      private boolean overrideFilterAction;
71  
72      // injected by the container.
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 ) ); // Still platform encoding
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() ); // platform encoding
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 }