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.dependency.utils;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  import javax.inject.Singleton;
24  
25  import java.io.File;
26  
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.logging.Log;
29  import org.codehaus.plexus.archiver.ArchiverException;
30  import org.codehaus.plexus.archiver.UnArchiver;
31  import org.codehaus.plexus.archiver.manager.ArchiverManager;
32  import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
33  import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
34  import org.codehaus.plexus.components.io.filemappers.FileMapper;
35  import org.codehaus.plexus.components.io.fileselectors.IncludeExcludeFileSelector;
36  import org.sonatype.plexus.build.incremental.BuildContext;
37  
38  /**
39   * Provide unpack method in one place for {@link org.apache.maven.plugins.dependency.fromConfiguration.UnpackMojo}
40   * and {@link org.apache.maven.plugins.dependency.fromDependencies.UnpackDependenciesMojo}
41   */
42  @Named
43  @Singleton
44  public class UnpackUtil {
45  
46      /**
47       * To look up Archiver/UnArchiver implementations
48       */
49      private final ArchiverManager archiverManager;
50  
51      /**
52       * For IDE build support
53       */
54      private final BuildContext buildContext;
55  
56      /**
57       * Default constructor.
58       *
59       * @param archiverManager an archiver {@link ArchiverManager} to use
60       * @param buildContext    a build context
61       */
62      @Inject
63      public UnpackUtil(ArchiverManager archiverManager, BuildContext buildContext) {
64          this.archiverManager = archiverManager;
65          this.buildContext = buildContext;
66      }
67  
68      /**
69       * @param file              file to unpack
70       * @param type              file / artifact type
71       * @param location          The location.
72       * @param includes          includes list.
73       * @param excludes          excludes list.
74       * @param encoding          the encoding.
75       * @param ignorePermissions ignore permissions
76       * @param fileMappers       {@link FileMapper}s to be used for rewriting each target path, or {@code null} if no
77       *                          rewriting
78       *                          shall happen.
79       * @param logger            a Mojo logger
80       * @throws MojoExecutionException in case of an error.
81       */
82      public void unpack(
83              File file,
84              String type,
85              File location,
86              String includes,
87              String excludes,
88              String encoding,
89              boolean ignorePermissions,
90              FileMapper[] fileMappers,
91              Log logger)
92              throws MojoExecutionException {
93          try {
94              logUnpack(logger, file, location, includes, excludes);
95  
96              location.mkdirs();
97              if (!location.exists()) {
98                  throw new MojoExecutionException(
99                          "Location to write unpacked files to could not be created: " + location);
100             }
101 
102             if (file.isDirectory()) {
103                 // usual case is a future jar packaging, but there are special cases: classifier and other packaging
104                 throw new MojoExecutionException("Artifact has not been packaged yet. When used on reactor artifact, "
105                         + "unpack should be executed after packaging: see MDEP-98.");
106             }
107 
108             UnArchiver unArchiver;
109 
110             try {
111                 unArchiver = archiverManager.getUnArchiver(type);
112                 logger.debug("Found unArchiver: " + unArchiver.getClass().getName() + " by type: " + type);
113             } catch (NoSuchArchiverException e) {
114                 unArchiver = archiverManager.getUnArchiver(file);
115                 logger.debug("Found unArchiver: " + unArchiver.getClass().getName() + " by file extension: " + file);
116             }
117 
118             if (encoding != null && unArchiver instanceof ZipUnArchiver) {
119                 ((ZipUnArchiver) unArchiver).setEncoding(encoding);
120                 logger.info("Unpacks '" + type + "' with encoding '" + encoding + "'.");
121             }
122 
123             unArchiver.setIgnorePermissions(ignorePermissions);
124 
125             unArchiver.setSourceFile(file);
126 
127             unArchiver.setDestDirectory(location);
128 
129             if ((excludes != null && !excludes.isEmpty()) || (includes != null && !includes.isEmpty())) {
130                 // Create the selectors that will filter
131                 // based on include/exclude parameters
132                 // MDEP-47
133                 IncludeExcludeFileSelector[] selectors =
134                         new IncludeExcludeFileSelector[] {new IncludeExcludeFileSelector()};
135 
136                 if (excludes != null && !excludes.isEmpty()) {
137                     selectors[0].setExcludes(excludes.split(","));
138                 }
139 
140                 if (includes != null && !includes.isEmpty()) {
141                     selectors[0].setIncludes(includes.split(","));
142                 }
143 
144                 unArchiver.setFileSelectors(selectors);
145             }
146 
147             unArchiver.setFileMappers(fileMappers);
148 
149             unArchiver.extract();
150         } catch (NoSuchArchiverException e) {
151             throw new MojoExecutionException("Unknown archiver type", e);
152         } catch (ArchiverException e) {
153             throw new MojoExecutionException("Error unpacking file: " + file + " to: " + location, e);
154         }
155         buildContext.refresh(location);
156     }
157 
158     private void logUnpack(Log logger, File file, File location, String includes, String excludes) {
159         if (logger.isInfoEnabled()) {
160             return;
161         }
162 
163         StringBuilder msg = new StringBuilder();
164         msg.append("Unpacking ");
165         msg.append(file);
166         msg.append(" to ");
167         msg.append(location);
168 
169         if (includes != null && excludes != null) {
170             msg.append(" with includes \"");
171             msg.append(includes);
172             msg.append("\" and excludes \"");
173             msg.append(excludes);
174             msg.append("\"");
175         } else if (includes != null) {
176             msg.append(" with includes \"");
177             msg.append(includes);
178             msg.append("\"");
179         } else if (excludes != null) {
180             msg.append(" with excludes \"");
181             msg.append(excludes);
182             msg.append("\"");
183         }
184 
185         logger.info(msg.toString());
186     }
187 }