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