View Javadoc
1   package org.apache.maven.plugins.assembly.format;
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.commons.io.input.ReaderInputStream;
23  import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
24  import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
25  import org.apache.maven.plugins.assembly.utils.LineEndings;
26  import org.apache.maven.plugins.assembly.utils.LineEndingsUtils;
27  import org.apache.maven.shared.filtering.MavenFilteringException;
28  import org.apache.maven.shared.filtering.MavenReaderFilterRequest;
29  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
30  import org.codehaus.plexus.components.io.resources.PlexusIoResource;
31  
32  import java.io.IOException;
33  import java.io.InputStream;
34  import java.io.InputStreamReader;
35  import java.io.Reader;
36  import java.util.LinkedHashSet;
37  import java.util.List;
38  import java.util.Properties;
39  import java.util.Set;
40  
41  /**
42   *
43   */
44  public class ReaderFormatter
45  {
46      private static Reader createReaderFilter( Reader source, String escapeString, List<String> delimiters,
47                                                AssemblerConfigurationSource configSource, boolean isPropertiesFile,
48                                                Properties additionalProperties )
49          throws IOException
50      {
51          try
52          {
53  
54              MavenReaderFilterRequest filterRequest =
55                  new MavenReaderFilterRequest( source, true, configSource.getProject(), configSource.getFilters(),
56                                                isPropertiesFile, configSource.getMavenSession(), additionalProperties );
57              
58              filterRequest.setEscapeString( escapeString );
59  
60              // if these are NOT set, just use the defaults, which are '${*}' and '@'.
61              if ( delimiters != null && !delimiters.isEmpty() )
62              {
63                  LinkedHashSet<String> delims = new LinkedHashSet<>();
64                  for ( String delim : delimiters )
65                  {
66                      if ( delim == null )
67                      {
68                          // FIXME: ${filter:*} could also trigger this condition. Need a better long-term solution.
69                          delims.add( "${*}" );
70                      }
71                      else
72                      {
73                          delims.add( delim );
74                      }
75                  }
76  
77                  filterRequest.setDelimiters( delims );
78              }
79              else
80              {
81                  filterRequest.setDelimiters( filterRequest.getDelimiters() );
82              }
83  
84              filterRequest.setInjectProjectBuildFilters( configSource.isIncludeProjectBuildFilters() );
85              return configSource.getMavenReaderFilter().filter( filterRequest );
86          }
87          catch ( MavenFilteringException e )
88          {
89              IOException ioe = new IOException( "Error filtering file '" + source + "': " + e.getMessage(), e );
90              throw ioe;
91          }
92      }
93  
94  
95      private static boolean isForbiddenFiletypes( PlexusIoResource plexusIoResource )
96      {
97          String fileName = plexusIoResource.getName().toLowerCase();
98          return ( fileName.endsWith( ".zip" ) || fileName.endsWith( ".jar" ) );
99      }
100 
101     private static void checkifFileTypeIsAppropriateForLineEndingTransformation( PlexusIoResource plexusIoResource )
102         throws IOException
103     {
104         if ( isForbiddenFiletypes( plexusIoResource ) )
105         {
106             throw new IOException( "Cannot transform line endings on this kind of file: " + plexusIoResource.getName()
107                                        + "\nDoing so is more or less guaranteed to destroy the file, and it indicates"
108                                        + " a problem with your assembly descriptor."
109                                        + "\nThis error message is new as of 2.5.3. "
110                                        + "\nEarlier versions of assembly-plugin will silently destroy your file. "
111                                        + "Fix your descriptor" );
112         }
113 
114     }
115 
116     public static InputStreamTransformer getFileSetTransformers( final AssemblerConfigurationSource configSource,
117                                                                  final boolean isFiltered,
118                                                                  final Set<String> nonFilteredFileExtensions,
119                                                                  String fileSetLineEnding )
120         throws AssemblyFormattingException
121     {
122         final LineEndings lineEndingToUse = LineEndingsUtils.getLineEnding( fileSetLineEnding );
123 
124         final boolean transformLineEndings = !LineEndings.keep.equals( lineEndingToUse );
125 
126         if ( transformLineEndings || isFiltered )
127         {
128             return new InputStreamTransformer()
129             {
130                 @Override
131                 public InputStream transform( PlexusIoResource plexusIoResource,
132                                               InputStream inputStream )
133                     throws IOException
134                 {
135                     final String fileName = plexusIoResource.getName();
136                     for ( String extension : nonFilteredFileExtensions )
137                     {
138                         if ( fileName.endsWith( '.' + extension ) )
139                         {
140                             return inputStream;
141                         }
142                     }
143                     
144                     InputStream result = inputStream;
145                     if ( isFiltered )
146                     {
147                         boolean isPropertyFile = AssemblyFileUtils.isPropertyFile( plexusIoResource.getName() );
148                         final String encoding = isPropertyFile ? "ISO-8859-1" : configSource.getEncoding();
149 
150                         Reader source = encoding != null
151                             ? new InputStreamReader( inputStream, encoding )
152                             : new InputStreamReader( inputStream ); // wtf platform encoding ? TODO: Fix this
153                         Reader filtered =
154                             createReaderFilter( source, configSource.getEscapeString(), configSource.getDelimiters(),
155                                                 configSource, isPropertyFile, configSource.getAdditionalProperties() );
156                         result = encoding != null
157                             ? new ReaderInputStream( filtered, encoding )
158                             : new ReaderInputStream( filtered );
159                     }
160                     if ( transformLineEndings )
161                     {
162                         checkifFileTypeIsAppropriateForLineEndingTransformation( plexusIoResource );
163                         result = LineEndingsUtils.lineEndingConverter( result, lineEndingToUse );
164                     }
165                     return result;
166                 }
167             };
168         }
169         return null;
170     }
171 }