View Javadoc
1   /*
2    * #%L
3    * wcm.io
4    * %%
5    * Copyright (C) 2014 wcm.io
6    * %%
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   * #L%
19   */
20  package io.wcm.maven.plugins.contentpackage;
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import javax.inject.Inject;
27  
28  import org.apache.commons.lang3.StringUtils;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.MojoFailureException;
31  import org.apache.maven.plugins.annotations.LifecyclePhase;
32  import org.apache.maven.plugins.annotations.Mojo;
33  import org.apache.maven.plugins.annotations.Parameter;
34  import org.apache.maven.plugins.annotations.ResolutionScope;
35  import org.eclipse.aether.RepositorySystem;
36  import org.eclipse.aether.RepositorySystemSession;
37  import org.eclipse.aether.repository.RemoteRepository;
38  
39  import io.wcm.tooling.commons.packmgr.install.PackageInstaller;
40  
41  /**
42   * Install a Content Package on a remote CRX or AEM system.
43   */
44  @Mojo(name = "install", defaultPhase = LifecyclePhase.INSTALL, requiresProject = false, requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true)
45  public final class InstallMojo extends AbstractContentPackageMojo {
46  
47    /**
48     * Whether to install (unpack) the uploaded package automatically or not.
49     */
50    @Parameter(property = "vault.install", defaultValue = "true")
51    private boolean install;
52  
53    /**
54     * Force upload and install of content package. If set to:
55     * <ul>
56     * <li><code>true</code>: Package is always installed, even if it was already uploaded before.</li>
57     * <li><code>false</code>: Package is only installed if it was not already uploade before.</li>
58     * <li>nothing (default): Force is applied to packages with the string "-SNAPSHOT" in it's filename.</li>
59     * </ul>
60     */
61    @Parameter(property = "vault.force")
62    private Boolean force;
63  
64    /**
65     * If set to true nested packages get installed as well.
66     */
67    @Parameter(property = "vault.recursive", defaultValue = "true")
68    private boolean recursive;
69  
70    /**
71     * The groupId of the artifact to install.
72     * Works only if used together with <code>artifactId</code> and <code>version</code>.
73     */
74    @Parameter(property = "vault.groupId")
75    private String groupId;
76  
77    /**
78     * The artifactId of the artifact to install.
79     * Works only if used together with <code>groupId</code> and <code>version</code>.
80     */
81    @Parameter(property = "vault.artifactId")
82    private String artifactId;
83  
84    /**
85     * The packaging of the artifact to install.
86     */
87    @Parameter(alias = "packaging", property = "vault.packaging", defaultValue = "zip")
88    private String type;
89  
90    /**
91     * The version of the artifact to install.
92     * Works only if used together with <code>artifactId</code> and <code>groupId</code>.
93     */
94    @Parameter(property = "vault.version")
95    private String version;
96  
97    /**
98     * The classifier of the artifact to install.
99     */
100   @Parameter(property = "vault.classifier")
101   private String classifier;
102 
103   /**
104    * A string of the form <code>groupId:artifactId[:packaging][:classifier]:version</code>.
105    */
106   @Parameter(property = "vault.artifact")
107   private String artifact;
108 
109   /**
110    * The names of the content package files to install on the target system, separated by ",".
111    *
112    * <p>
113    * This has lower precedence than the 'packageFiles' parameter, but higher precedence than other options to specify
114    * files.
115    * </p>
116    */
117   @Parameter(property = "vault.fileList")
118   private String packageFileList;
119 
120   /**
121    * Delay further steps after package installation by this amount of seconds
122    */
123   @Parameter(property = "vault.delayAfterInstallSec")
124   private Integer delayAfterInstallSec;
125 
126   /**
127    * Fail build when no file was found for installing.
128    */
129   @Parameter(property = "vault.failOnNoFile", defaultValue = "true")
130   private boolean failOnNoFile;
131 
132   /**
133    * Replicate package(s) to publish instance after upload.
134    */
135   @Parameter(property = "vault.replicate")
136   private boolean replicate;
137 
138   /**
139    * Allows to specify multiple package files at once, either referencing local file systems or maven artifacts.
140    * This has higher precedence than all other options to specify files.
141    *
142    * <p>
143    * You can set the following properties for each package item:
144    * </p>
145    * <ul>
146    * <li><code>packageFile</code>: Content package file.</li>
147    * <li><code>groupId</code>: The groupId of the artifact to install.</li>
148    * <li><code>artifactId</code>: The artifactId of the artifact to install.</li>
149    * <li><code>type</code>: The packaging of the artifact to install. (default: zip)</li>
150    * <li><code>version</code>: The version of the artifact to install.</li>
151    * <li><code>classifier</code>: The classifier of the artifact to install.</li>
152    * <li><code>artifact</code>: A string of the form
153    * <code>groupId:artifactId[:packaging][:classifier]:version</code>.</li>
154    * <li><code>install</code>: Whether to install (unpack) the uploaded package automatically or not.</li>
155    * <li><code>force</code>: Force upload and install of content package. If set to false a package is not uploaded or
156    * installed if it was already uploaded before.</li>
157    * <li><code>recursive</code>: If set to true nested packages get installed as well.</li>
158    * <li><code>delayAfterInstallSec</code>: Delay further steps after package installation by this amount of
159    * seconds.</li>
160    * <li><code>httpSocketTimeoutSec</code>: HTTP socket timeout (in seconds) for this package.</li>
161    * </ul>
162    */
163   @Parameter
164   private PackageFile[] packageFiles;
165 
166   @Inject
167   private RepositorySystem repoSystem;
168   @Parameter(defaultValue = "${repositorySystemSession}", readonly = true, required = true)
169   private RepositorySystemSession repoSession;
170   @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true, required = true)
171   private List<RemoteRepository> repositories;
172 
173   @Override
174   public void execute() throws MojoExecutionException, MojoFailureException {
175     if (isSkip()) {
176       return;
177     }
178 
179     // collect files to install
180     List<io.wcm.tooling.commons.packmgr.install.PackageFile> items = new ArrayList<>();
181     ArtifactHelper helper = new ArtifactHelper(repoSystem, repoSession, repositories);
182     if (packageFiles != null && packageFiles.length > 0) {
183       for (PackageFile ref : packageFiles) {
184         io.wcm.tooling.commons.packmgr.install.PackageFile item = toPackageFile(ref, helper);
185         if (item.getFile() != null) {
186           items.add(item);
187         }
188       }
189     }
190     else if (StringUtils.isNotBlank(packageFileList)) {
191       String[] fileNames = StringUtils.split(packageFileList, ",");
192       for (String fileName : fileNames) {
193         File file = new File(StringUtils.trimToEmpty(fileName));
194         items.add(toPackageFile(file));
195       }
196     }
197     else {
198       File file = helper.getArtifactFile(artifactId, groupId, version, type, classifier, artifact);
199       if (file == null) {
200         file = getPackageFile();
201         if (file != null && !file.exists() && !failOnNoFile) {
202           file = null;
203         }
204       }
205       if (file != null) {
206         items.add(toPackageFile(file));
207       }
208     }
209 
210     // ensure any file exist
211     if (items.isEmpty()) {
212       if (failOnNoFile) {
213         throw new MojoExecutionException("No file found for installing.");
214       }
215       else {
216         getLog().warn("No file found for installing.");
217       }
218       return;
219     }
220 
221     // install files
222     PackageInstaller installer = new PackageInstaller(getPackageManagerProperties());
223     installer.setReplicate(this.replicate);
224     installer.installFiles(items);
225   }
226 
227   private io.wcm.tooling.commons.packmgr.install.PackageFile toPackageFile(PackageFile ref, ArtifactHelper helper)
228       throws MojoFailureException, MojoExecutionException {
229     io.wcm.tooling.commons.packmgr.install.PackageFile output = new io.wcm.tooling.commons.packmgr.install.PackageFile();
230 
231     File file = helper.getArtifactFile(ref.getArtifactId(), ref.getGroupId(), ref.getVersion(), ref.getType(), ref.getClassifier(), ref.getArtifact());
232     if (file == null) {
233       file = ref.getPackageFile();
234     }
235     output.setFile(file);
236 
237     if (ref.getInstall() != null) {
238       output.setInstall(ref.getInstall());
239     }
240     else {
241       output.setInstall(this.install);
242     }
243     if (ref.getForce() != null) {
244       output.setForce(ref.getForce());
245     }
246     else {
247       output.setForce(this.force);
248     }
249     if (ref.getRecursive() != null) {
250       output.setRecursive(ref.getRecursive());
251     }
252     else {
253       output.setRecursive(this.recursive);
254     }
255     if (ref.getDelayAfterInstallSec() != null) {
256       output.setDelayAfterInstallSec(ref.getDelayAfterInstallSec());
257     }
258     else if (this.delayAfterInstallSec != null) {
259       output.setDelayAfterInstallSec(this.delayAfterInstallSec);
260     }
261     else {
262       output.setDelayAfterInstallSecAutoDetect();
263     }
264     output.setHttpSocketTimeoutSec(ref.getHttpSocketTimeoutSec());
265 
266     return output;
267   }
268 
269   private io.wcm.tooling.commons.packmgr.install.PackageFile toPackageFile(File file) {
270     io.wcm.tooling.commons.packmgr.install.PackageFile output = new io.wcm.tooling.commons.packmgr.install.PackageFile();
271 
272     output.setFile(file);
273     output.setInstall(this.install);
274     output.setForce(this.force);
275     output.setRecursive(this.recursive);
276     if (this.delayAfterInstallSec != null) {
277       output.setDelayAfterInstallSec(this.delayAfterInstallSec);
278     }
279 
280     return output;
281   }
282 
283 }