1   package org.apache.maven.plugin.assembly.format;
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  import org.apache.commons.io.input.ReaderInputStream;
23  import org.apache.maven.plugin.assembly.AssemblerConfigurationSource;
24  import org.apache.maven.plugin.assembly.utils.AssemblyFileUtils;
25  import org.apache.maven.plugin.assembly.utils.LineEndings;
26  import org.apache.maven.plugin.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 javax.annotation.Nonnull;
33  import javax.annotation.Nullable;
34  import java.io.IOException;
35  import java.io.InputStream;
36  import java.io.InputStreamReader;
37  import java.io.Reader;
38  import java.util.LinkedHashSet;
39  import java.util.List;
40  
41  
42  
43  
44  public class ReaderFormatter
45  {
46      private static Reader createReaderFilter( @Nonnull Reader source, String escapeString, List<String> delimiters,
47                                                AssemblerConfigurationSource configSource, boolean isPropertiesFile )
48          throws IOException
49      {
50          try
51          {
52  
53              MavenReaderFilterRequest filterRequest =
54                  new MavenReaderFilterRequest( source, true, configSource.getProject(), configSource.getFilters(),
55                                                isPropertiesFile, null, configSource.getMavenSession(), null );
56              filterRequest.setEscapeString( escapeString );
57  
58              
59              if ( delimiters != null && !delimiters.isEmpty() )
60              {
61                  LinkedHashSet<String> delims = new LinkedHashSet<String>();
62                  for ( String delim : delimiters )
63                  {
64                      if ( delim == null )
65                      {
66                          
67                          delims.add( "${*}" );
68                      }
69                      else
70                      {
71                          delims.add( delim );
72                      }
73                  }
74  
75                  filterRequest.setDelimiters( delims );
76              }
77              else
78              {
79                  filterRequest.setDelimiters( filterRequest.getDelimiters() );
80              }
81  
82              filterRequest.setInjectProjectBuildFilters( configSource.isIncludeProjectBuildFilters() );
83              return configSource.getMavenReaderFilter().filter( filterRequest );
84          }
85          catch ( MavenFilteringException e )
86          {
87              IOException ioe = new IOException( "Error filtering file '" + source + "': " + e.getMessage() );
88              ioe.initCause( e ); 
89              throw ioe;
90          }
91      }
92  
93  
94      private static boolean isForbiddenFiletypes( PlexusIoResource plexusIoResource )
95          throws IOException
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     @Nullable
117     public static InputStreamTransformer getFileSetTransformers( final AssemblerConfigurationSource configSource,
118                                                                  final boolean isFiltered, String fileSetLineEnding )
119         throws AssemblyFormattingException
120     {
121         final LineEndings lineEndingToUse = LineEndingsUtils.getLineEnding( fileSetLineEnding );
122 
123         final boolean transformLineEndings = !LineEndings.keep.equals( lineEndingToUse );
124 
125         if ( transformLineEndings || isFiltered )
126         {
127             return new InputStreamTransformer()
128             {
129                 @Nonnull
130                 public InputStream transform( @Nonnull PlexusIoResource plexusIoResource,
131                                               @Nonnull InputStream inputStream )
132                     throws IOException
133                 {
134                     InputStream result = inputStream;
135                     if ( isFiltered )
136                     {
137                         boolean isPropertyFile = AssemblyFileUtils.isPropertyFile( plexusIoResource.getName() );
138                         final String encoding = isPropertyFile ? "ISO-8859-1" : configSource.getEncoding();
139 
140                         Reader source = encoding != null
141                             ? new InputStreamReader( inputStream, encoding )
142                             : new InputStreamReader( inputStream ); 
143                         Reader filtered =
144                             createReaderFilter( source, configSource.getEscapeString(), configSource.getDelimiters(),
145                                                 configSource, isPropertyFile );
146                         result = encoding != null
147                             ? new ReaderInputStream( filtered, encoding )
148                             : new ReaderInputStream( filtered );
149                     }
150                     if ( transformLineEndings )
151                     {
152                         checkifFileTypeIsAppropriateForLineEndingTransformation( plexusIoResource );
153                         result = LineEndingsUtils.lineEndingConverter( result, lineEndingToUse );
154                     }
155                     return result;
156                 }
157             };
158         }
159         return null;
160     }
161 }