View Javadoc
1   package org.apache.maven.plugin.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.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              // if these are NOT set, just use the defaults, which are '${*}' and '@'.
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                          // FIXME: ${filter:*} could also trigger this condition. Need a better long-term solution.
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 ); // plain old Java 5...
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 ); // 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 }