View Javadoc
1   package org.apache.maven.plugins.assembly.archive.phase;
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 javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import static org.codehaus.plexus.components.io.resources.ResourceFactory.createResource;
26  
27  import java.io.File;
28  import java.io.FileInputStream;
29  import java.io.IOException;
30  import java.io.InputStream;
31  import java.io.SequenceInputStream;
32  import java.util.ArrayList;
33  import java.util.Collection;
34  import java.util.Collections;
35  import java.util.List;
36  
37  import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
38  import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
39  import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
40  import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
41  import org.apache.maven.plugins.assembly.format.ReaderFormatter;
42  import org.apache.maven.plugins.assembly.model.Assembly;
43  import org.apache.maven.plugins.assembly.model.FileItem;
44  import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
45  import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
46  import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
47  import org.codehaus.plexus.archiver.Archiver;
48  import org.codehaus.plexus.archiver.ArchiverException;
49  import org.codehaus.plexus.components.io.functions.ContentSupplier;
50  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
51  import org.codehaus.plexus.components.io.resources.PlexusIoFileResource;
52  import org.codehaus.plexus.components.io.resources.PlexusIoResource;
53  import org.slf4j.Logger;
54  import org.slf4j.LoggerFactory;
55  
56  /**
57   * Handles the top-level <files/> section of the assembly descriptor.
58   *
59   *
60   */
61  @Singleton
62  @Named( "file-items" )
63  public class FileItemAssemblyPhase implements AssemblyArchiverPhase, PhaseOrder
64  {
65      private static final Logger LOGGER = LoggerFactory.getLogger( FileItemAssemblyPhase.class );
66  
67      /**
68       * {@inheritDoc}
69       */
70      @Override
71      public void execute( final Assembly assembly, final Archiver archiver,
72                           final AssemblerConfigurationSource configSource )
73          throws ArchiveCreationException, AssemblyFormattingException, InvalidAssemblerConfigurationException
74      {
75          final List<FileItem> fileList = assembly.getFiles();
76          final File basedir = configSource.getBasedir();
77  
78          for ( final FileItem fileItem : fileList )
79          {
80              if ( fileItem.getSource() != null ^ fileItem.getSources().isEmpty() )
81              {
82                  throw new InvalidAssemblerConfigurationException( 
83                                                        "Misconfigured file: one of source or sources must be set" );
84              }
85              
86              String destName = fileItem.getDestName();
87              
88              final String sourcePath;
89              if ( fileItem.getSource() != null )
90              {
91                  sourcePath = fileItem.getSource();
92              }
93              else if ( destName != null )
94              {
95                  // because createResource() requires a file
96                  sourcePath = fileItem.getSources().get( 0 );
97              }
98              else
99              {
100                 throw new InvalidAssemblerConfigurationException( 
101                                 "Misconfigured file: specify destName when using sources" );
102             }            
103 
104             // ensure source file is in absolute path for reactor build to work
105             File source = new File( sourcePath );
106 
107             // save the original sourcefile's name, because filtration may
108             // create a temp file with a different name.
109             final String sourceName = source.getName();
110 
111             if ( !AssemblyFileUtils.isAbsolutePath( source ) )
112             {
113                 source = new File( basedir, sourcePath );
114             }
115             if ( destName == null )
116             {
117                 destName = sourceName;
118             }
119 
120             final String outputDirectory1 = fileItem.getOutputDirectory();
121 
122             final String outputDirectory =
123                 AssemblyFormatUtils.getOutputDirectory( outputDirectory1, configSource.getFinalName(), configSource,
124                                                         AssemblyFormatUtils.moduleProjectInterpolator(
125                                                             configSource.getProject() ),
126                                                         AssemblyFormatUtils.artifactProjectInterpolator( null ) );
127 
128             String target;
129 
130             // omit the last char if ends with / or \\
131             if ( outputDirectory.endsWith( "/" ) || outputDirectory.endsWith( "\\" ) )
132             {
133                 target = outputDirectory + destName;
134             }
135             else if ( outputDirectory.length() < 1 )
136             {
137                 target = destName;
138             }
139             else
140             {
141                 target = outputDirectory + "/" + destName;
142             }
143 
144             try
145             {
146                 final InputStreamTransformer fileSetTransformers =
147                     ReaderFormatter.getFileSetTransformers( configSource, fileItem.isFiltered(),
148                                                             Collections.<String>emptySet(),
149                                                             fileItem.getLineEnding() );
150                 
151                 final PlexusIoResource restoUse;
152                 if ( !fileItem.getSources().isEmpty() )
153                 {
154                     List<InputStream> content = new ArrayList<>( fileItem.getSources().size() );
155                     for ( String contentSourcePath : fileItem.getSources() )
156                     {
157                         File contentSource = new File( contentSourcePath );
158                         if ( !AssemblyFileUtils.isAbsolutePath( contentSource ) )
159                         {
160                             contentSource = new File( basedir, contentSourcePath );
161                         }
162                         content.add( new FileInputStream( contentSource ) );
163                     }
164                     
165                     String name = PlexusIoFileResource.getName( source );
166                     restoUse = createResource( source, name, getContentSupplier( content ), fileSetTransformers );
167                 }
168                 else
169                 {
170                     restoUse = createResource( source, fileSetTransformers );
171                 }
172 
173                 int mode = TypeConversionUtils.modeToInt( fileItem.getFileMode(), LOGGER );
174                 archiver.addResource( restoUse, target, mode );
175             }
176             catch ( final ArchiverException | IOException e )
177             {
178                 throw new ArchiveCreationException( "Error adding file to archive: " + e.getMessage(), e );
179             }
180         }
181     }
182 
183     @Override
184     public int order()
185     {
186         return 10;
187     }
188     
189     private ContentSupplier getContentSupplier( final Collection<InputStream> contentStreams ) 
190     {
191         return new ContentSupplier()
192         {
193             @Override
194             public InputStream getContents()
195                 throws IOException
196             {
197                 return new SequenceInputStream( Collections.enumeration( contentStreams ) );
198             }
199         };
200     }
201 }