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