View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.assembly.archive.task;
20  
21  import java.io.File;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.HashSet;
25  import java.util.List;
26  
27  import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
28  import org.apache.maven.plugins.assembly.archive.ArchiveCreationException;
29  import org.apache.maven.plugins.assembly.format.AssemblyFormattingException;
30  import org.apache.maven.plugins.assembly.format.ReaderFormatter;
31  import org.apache.maven.plugins.assembly.model.FileSet;
32  import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
33  import org.apache.maven.plugins.assembly.utils.AssemblyFormatUtils;
34  import org.apache.maven.plugins.assembly.utils.TypeConversionUtils;
35  import org.apache.maven.project.MavenProject;
36  import org.codehaus.plexus.archiver.Archiver;
37  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  /**
42   *
43   */
44  public class AddFileSetsTask {
45      private static final Logger LOGGER = LoggerFactory.getLogger(AddFileSetsTask.class);
46  
47      private final List<FileSet> fileSets;
48  
49      private MavenProject project;
50  
51      private MavenProject moduleProject;
52  
53      public AddFileSetsTask(final List<FileSet> fileSets) {
54          this.fileSets = fileSets;
55      }
56  
57      public AddFileSetsTask(final FileSet... fileSets) {
58          this.fileSets = new ArrayList<>(Arrays.asList(fileSets));
59      }
60  
61      public void execute(final Archiver archiver, final AssemblerConfigurationSource configSource)
62              throws ArchiveCreationException, AssemblyFormattingException {
63          // don't need this check here. it's more efficient here, but the logger is not actually
64          // used until addFileSet(..)...and the check should be there in case someone extends the
65          // class.
66          // checkLogger();
67  
68          final File archiveBaseDir = configSource.getArchiveBaseDirectory();
69  
70          if (archiveBaseDir != null) {
71              if (!archiveBaseDir.exists()) {
72                  throw new ArchiveCreationException(
73                          "The archive base directory '" + archiveBaseDir.getAbsolutePath() + "' does not exist");
74              } else if (!archiveBaseDir.isDirectory()) {
75                  throw new ArchiveCreationException("The archive base directory '" + archiveBaseDir.getAbsolutePath()
76                          + "' exists, but it is not a directory");
77              }
78          }
79  
80          for (final FileSet fileSet : fileSets) {
81              addFileSet(fileSet, archiver, configSource, archiveBaseDir);
82          }
83      }
84  
85      void addFileSet(
86              final FileSet fileSet,
87              final Archiver archiver,
88              final AssemblerConfigurationSource configSource,
89              final File archiveBaseDir)
90              throws AssemblyFormattingException, ArchiveCreationException {
91          if (project == null) {
92              project = configSource.getProject();
93          }
94  
95          final File basedir = project.getBasedir();
96  
97          String destDirectory = fileSet.getOutputDirectory();
98  
99          if (destDirectory == null) {
100             destDirectory = fileSet.getDirectory();
101 
102             AssemblyFormatUtils.warnForPlatformSpecifics(LOGGER, destDirectory);
103         }
104 
105         destDirectory = AssemblyFormatUtils.getOutputDirectory(
106                 destDirectory,
107                 configSource.getFinalName(),
108                 configSource,
109                 AssemblyFormatUtils.moduleProjectInterpolator(moduleProject),
110                 AssemblyFormatUtils.artifactProjectInterpolator(project));
111 
112         if (LOGGER.isDebugEnabled()) {
113             LOGGER.debug("FileSet[" + destDirectory + "]" + " dir perms: "
114                     + Integer.toString(archiver.getOverrideDirectoryMode(), 8) + " file perms: "
115                     + Integer.toString(archiver.getOverrideFileMode(), 8)
116                     + (fileSet.getLineEnding() == null ? "" : " lineEndings: " + fileSet.getLineEnding()));
117         }
118 
119         LOGGER.debug("The archive base directory is '" + archiveBaseDir + "'");
120 
121         File fileSetDir = getFileSetDirectory(fileSet, basedir, archiveBaseDir);
122 
123         if (fileSetDir.exists()) {
124             InputStreamTransformer fileSetTransformers = ReaderFormatter.getFileSetTransformers(
125                     configSource,
126                     fileSet.isFiltered(),
127                     new HashSet<>(fileSet.getNonFilteredFileExtensions()),
128                     fileSet.getLineEnding());
129             if (fileSetTransformers == null) {
130                 LOGGER.debug("NOT reformatting any files in " + fileSetDir);
131             }
132 
133             if (fileSetDir.getPath().equals(File.separator)) {
134                 throw new AssemblyFormattingException(
135                         "Your assembly descriptor specifies a directory of " + File.separator
136                                 + ", which is your *entire* file system.\nThese are not the files you are looking for");
137             }
138             final AddDirectoryTask task = new AddDirectoryTask(fileSetDir, fileSetTransformers);
139 
140             final int dirMode = TypeConversionUtils.modeToInt(fileSet.getDirectoryMode(), LOGGER);
141             if (dirMode != -1) {
142                 task.setDirectoryMode(dirMode);
143             }
144 
145             final int fileMode = TypeConversionUtils.modeToInt(fileSet.getFileMode(), LOGGER);
146             if (fileMode != -1) {
147                 task.setFileMode(fileMode);
148             }
149 
150             task.setUseDefaultExcludes(fileSet.isUseDefaultExcludes());
151             task.setExcludes(fileSet.getExcludes());
152             task.setIncludes(fileSet.getIncludes());
153             task.setOutputDirectory(destDirectory);
154 
155             task.execute(archiver);
156         }
157     }
158 
159     File getFileSetDirectory(final FileSet fileSet, final File basedir, final File archiveBaseDir)
160             throws ArchiveCreationException, AssemblyFormattingException {
161         String sourceDirectory = fileSet.getDirectory();
162 
163         if (sourceDirectory == null || sourceDirectory.trim().length() < 1) {
164             sourceDirectory = basedir.getAbsolutePath();
165         }
166 
167         File fileSetDir;
168 
169         if (archiveBaseDir == null) {
170             fileSetDir = new File(sourceDirectory);
171 
172             // If the file is not absolute then it's a subpath of the current project basedir
173             // For OS compatibility we also must treat any path starting with "/" as absolute
174             // as File#isAbsolute() returns false for /absolutePath under Windows :(
175             // Note that in Windows an absolute path with / will be on the 'current drive'.
176             // But I think we can live with this.
177             if (!AssemblyFileUtils.isAbsolutePath(fileSetDir)) {
178                 fileSetDir = new File(basedir, sourceDirectory);
179             }
180         } else {
181             fileSetDir = new File(archiveBaseDir, sourceDirectory);
182         }
183 
184         return fileSetDir;
185     }
186 
187     public void setProject(final MavenProject project) {
188         this.project = project;
189     }
190 
191     public void setModuleProject(final MavenProject moduleProject) {
192         this.moduleProject = moduleProject;
193     }
194 }