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<String>();
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() );
89              ioe.initCause( e ); // plain old Java 5...
90              throw ioe;
91          }
92      }
93  
94  
95      private static boolean isForbiddenFiletypes( PlexusIoResource plexusIoResource )
96          throws IOException
97      {
98          String fileName = plexusIoResource.getName().toLowerCase();
99          return ( fileName.endsWith( ".zip" ) || fileName.endsWith( ".jar" ) );
100     }
101 
102     private static void checkifFileTypeIsAppropriateForLineEndingTransformation( PlexusIoResource plexusIoResource )
103         throws IOException
104     {
105         if ( isForbiddenFiletypes( plexusIoResource ) )
106         {
107             throw new IOException( "Cannot transform line endings on this kind of file: " + plexusIoResource.getName()
108                                        + "\nDoing so is more or less guaranteed to destroy the file, and it indicates"
109                                        + " a problem with your assembly descriptor."
110                                        + "\nThis error message is new as of 2.5.3. "
111                                        + "\nEarlier versions of assembly-plugin will silently destroy your file. "
112                                        + "Fix your descriptor" );
113         }
114 
115     }
116 
117     @Nullable
118     public static InputStreamTransformer getFileSetTransformers( final AssemblerConfigurationSource configSource,
119                                                                  final boolean isFiltered, 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                 @Nonnull
132                 public InputStream transform( @Nonnull PlexusIoResource plexusIoResource,
133                                               @Nonnull InputStream inputStream )
134                     throws IOException
135                 {
136                     InputStream result = inputStream;
137                     if ( isFiltered )
138                     {
139                         boolean isPropertyFile = AssemblyFileUtils.isPropertyFile( plexusIoResource.getName() );
140                         final String encoding = isPropertyFile ? "ISO-8859-1" : configSource.getEncoding();
141 
142                         Reader source = encoding != null
143                             ? new InputStreamReader( inputStream, encoding )
144                             : new InputStreamReader( inputStream ); // wtf platform encoding ? TODO: Fix this
145                         Reader filtered =
146                             createReaderFilter( source, configSource.getEscapeString(), configSource.getDelimiters(),
147                                                 configSource, isPropertyFile );
148                         result = encoding != null
149                             ? new ReaderInputStream( filtered, encoding )
150                             : new ReaderInputStream( filtered );
151                     }
152                     if ( transformLineEndings )
153                     {
154                         checkifFileTypeIsAppropriateForLineEndingTransformation( plexusIoResource );
155                         result = LineEndingsUtils.lineEndingConverter( result, lineEndingToUse );
156                     }
157                     return result;
158                 }
159             };
160         }
161         return null;
162     }
163 }