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 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, configSource.getMavenSession(), null );
56              
57              filterRequest.setEscapeString( escapeString );
58  
59              // if these are NOT set, just use the defaults, which are '${*}' and '@'.
60              if ( delimiters != null && !delimiters.isEmpty() )
61              {
62                  LinkedHashSet<String> delims = new LinkedHashSet<>();
63                  for ( String delim : delimiters )
64                  {
65                      if ( delim == null )
66                      {
67                          // FIXME: ${filter:*} could also trigger this condition. Need a better long-term solution.
68                          delims.add( "${*}" );
69                      }
70                      else
71                      {
72                          delims.add( delim );
73                      }
74                  }
75  
76                  filterRequest.setDelimiters( delims );
77              }
78              else
79              {
80                  filterRequest.setDelimiters( filterRequest.getDelimiters() );
81              }
82  
83              filterRequest.setInjectProjectBuildFilters( configSource.isIncludeProjectBuildFilters() );
84              return configSource.getMavenReaderFilter().filter( filterRequest );
85          }
86          catch ( MavenFilteringException e )
87          {
88              IOException ioe = new IOException( "Error filtering file '" + source + "': " + e.getMessage(), e );
89              throw ioe;
90          }
91      }
92  
93  
94      private static boolean isForbiddenFiletypes( PlexusIoResource plexusIoResource )
95      {
96          String fileName = plexusIoResource.getName().toLowerCase();
97          return ( fileName.endsWith( ".zip" ) || fileName.endsWith( ".jar" ) );
98      }
99  
100     private static void checkifFileTypeIsAppropriateForLineEndingTransformation( PlexusIoResource plexusIoResource )
101         throws IOException
102     {
103         if ( isForbiddenFiletypes( plexusIoResource ) )
104         {
105             throw new IOException( "Cannot transform line endings on this kind of file: " + plexusIoResource.getName()
106                                        + "\nDoing so is more or less guaranteed to destroy the file, and it indicates"
107                                        + " a problem with your assembly descriptor."
108                                        + "\nThis error message is new as of 2.5.3. "
109                                        + "\nEarlier versions of assembly-plugin will silently destroy your file. "
110                                        + "Fix your descriptor" );
111         }
112 
113     }
114 
115     @Nullable
116     public static InputStreamTransformer getFileSetTransformers( final AssemblerConfigurationSource configSource,
117                                                                  final boolean isFiltered, String fileSetLineEnding )
118         throws AssemblyFormattingException
119     {
120         final LineEndings lineEndingToUse = LineEndingsUtils.getLineEnding( fileSetLineEnding );
121 
122         final boolean transformLineEndings = !LineEndings.keep.equals( lineEndingToUse );
123 
124         if ( transformLineEndings || isFiltered )
125         {
126             return new InputStreamTransformer()
127             {
128                 @Override
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 ); // wtf platform encoding ? TODO: Fix this
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 }