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 org.apache.commons.lang3.StringUtils;
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugins.annotations.Component;
30  import org.apache.maven.plugins.annotations.LifecyclePhase;
31  import org.apache.maven.plugins.annotations.Mojo;
32  import org.apache.maven.plugins.annotations.Parameter;
33  import org.apache.maven.plugins.annotations.ResolutionScope;
34  import org.eclipse.aether.RepositorySystem;
35  import org.eclipse.aether.RepositorySystemSession;
36  import org.eclipse.aether.repository.RemoteRepository;
37  
38  import io.wcm.tooling.commons.packmgr.install.PackageInstaller;
39  
40  /**
41   * Install a Content Package on a remote CRX or AEM system.
42   */
43  @Mojo(name = "install", defaultPhase = LifecyclePhase.INSTALL, requiresProject = false, requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true)
44  public final class InstallMojo extends AbstractContentPackageMojo {
45  
46    /**
47     * Whether to install (unpack) the uploaded package automatically or not.
48     */
49    @Parameter(property = "vault.install", defaultValue = "true")
50    private boolean install;
51  
52    /**
53     * Force upload and install of content package. If set to:
54     * <ul>
55     * <li><code>true</code>: Package is always installed, even if it was already uploaded before.</li>
56     * <li><code>false</code>: Package is only installed if it was not already uploade before.</li>
57     * <li>nothing (default): Force is applied to packages with the string "-SNAPSHOT" in it's filename.</li>
58     * </ul>
59     */
60    @Parameter(property = "vault.force")
61    private Boolean force;
62  
63    /**
64     * If set to true nested packages get installed as well.
65     */
66    @Parameter(property = "vault.recursive", defaultValue = "true")
67    private boolean recursive;
68  
69    /**
70     * The groupId of the artifact to install.
71     * Works only if used together with <code>artifactId</code> and <code>version</code>.
72     */
73    @Parameter(property = "vault.groupId")
74    private String groupId;
75  
76    /**
77     * The artifactId of the artifact to install.
78     * Works only if used together with <code>groupId</code> and <code>version</code>.
79     */
80    @Parameter(property = "vault.artifactId")
81    private String artifactId;
82  
83    /**
84     * The packaging of the artifact to install.
85     */
86    @Parameter(alias = "packaging", property = "vault.packaging", defaultValue = "zip")
87    private String type;
88  
89    /**
90     * The version of the artifact to install.
91     * Works only if used together with <code>artifactId</code> and <code>groupId</code>.
92     */
93    @Parameter(property = "vault.version")
94    private String version;
95  
96    /**
97     * The classifier of the artifact to install.
98     */
99    @Parameter(property = "vault.classifier")
100   private String classifier;
101 
102   /**
103    * A string of the form <code>groupId:artifactId[:packaging][:classifier]:version</code>.
104    */
105   @Parameter(property = "vault.artifact")
106   private String artifact;
107 
108   /**
109    * <p>
110    * The names of the content package files to install on the target system, separated by ",".
111    * </p>
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    * <p>
140    * Allows to specify multiple package files at once, either referencing local file systems or maven artifacts.
141    * This has higher precedence than all other options to specify files.
142    * </p>
143    * <p>
144    * You can set the following properties for each package item:
145    * </p>
146    * <ul>
147    * <li><code>packageFile</code>: Content package file.</li>
148    * <li><code>groupId</code>: The groupId of the artifact to install.</li>
149    * <li><code>artifactId</code>: The artifactId of the artifact to install.</li>
150    * <li><code>type</code>: The packaging of the artifact to install. (default: zip)</li>
151    * <li><code>version</code>: The version of the artifact to install.</li>
152    * <li><code>classifier</code>: The classifier of the artifact to install.</li>
153    * <li><code>artifact</code>: A string of the form
154    * <code>groupId:artifactId[:packaging][:classifier]:version</code>.</li>
155    * <li><code>install</code>: Whether to install (unpack) the uploaded package automatically or not.</li>
156    * <li><code>force</code>: Force upload and install of content package. If set to false a package is not uploaded or
157    * installed if it was already uploaded before.</li>
158    * <li><code>recursive</code>: If set to true nested packages get installed as well.</li>
159    * <li><code>delayAfterInstallSec</code>: Delay further steps after package installation by this amount of
160    * seconds.</li>
161    * <li><code>httpSocketTimeoutSec</code>: HTTP socket timeout (in seconds) for this package.</li>
162    * </ul>
163    */
164   @Parameter
165   private PackageFile[] packageFiles;
166 
167   @Component
168   private RepositorySystem repoSystem;
169   @Parameter(defaultValue = "${repositorySystemSession}", readonly = true, required = true)
170   private RepositorySystemSession repoSession;
171   @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true, required = true)
172   private List<RemoteRepository> repositories;
173 
174   @Override
175   public void execute() throws MojoExecutionException, MojoFailureException {
176     if (isSkip()) {
177       return;
178     }
179 
180     // collect files to install
181     List<io.wcm.tooling.commons.packmgr.install.PackageFile> items = new ArrayList<>();
182     ArtifactHelper helper = new ArtifactHelper(repoSystem, repoSession, repositories);
183     if (packageFiles != null && packageFiles.length > 0) {
184       for (PackageFile ref : packageFiles) {
185         io.wcm.tooling.commons.packmgr.install.PackageFile item = toPackageFile(ref, helper);
186         if (item.getFile() != null) {
187           items.add(item);
188         }
189       }
190     }
191     else if (StringUtils.isNotBlank(packageFileList)) {
192       String[] fileNames = StringUtils.split(packageFileList, ",");
193       for (String fileName : fileNames) {
194         File file = new File(StringUtils.trimToEmpty(fileName));
195         items.add(toPackageFile(file));
196       }
197     }
198     else {
199       File file = helper.getArtifactFile(artifactId, groupId, version, type, classifier, artifact);
200       if (file == null) {
201         file = getPackageFile();
202         if (file != null && !file.exists() && !failOnNoFile) {
203           file = null;
204         }
205       }
206       if (file != null) {
207         items.add(toPackageFile(file));
208       }
209     }
210 
211     // ensure any file exist
212     if (items.isEmpty()) {
213       if (failOnNoFile) {
214         throw new MojoExecutionException("No file found for installing.");
215       }
216       else {
217         getLog().warn("No file found for installing.");
218       }
219       return;
220     }
221 
222     // install files
223     PackageInstaller installer = new PackageInstaller(getPackageManagerProperties());
224     installer.setReplicate(this.replicate);
225     installer.installFiles(items);
226   }
227 
228   private io.wcm.tooling.commons.packmgr.install.PackageFile toPackageFile(PackageFile ref, ArtifactHelper helper)
229       throws MojoFailureException, MojoExecutionException {
230     io.wcm.tooling.commons.packmgr.install.PackageFile output = new io.wcm.tooling.commons.packmgr.install.PackageFile();
231 
232     File file = helper.getArtifactFile(ref.getArtifactId(), ref.getGroupId(), ref.getVersion(), ref.getType(), ref.getClassifier(), ref.getArtifact());
233     if (file == null) {
234       file = ref.getPackageFile();
235     }
236     output.setFile(file);
237 
238     if (ref.getInstall() != null) {
239       output.setInstall(ref.getInstall());
240     }
241     else {
242       output.setInstall(this.install);
243     }
244     if (ref.getForce() != null) {
245       output.setForce(ref.getForce());
246     }
247     else {
248       output.setForce(this.force);
249     }
250     if (ref.getRecursive() != null) {
251       output.setRecursive(ref.getRecursive());
252     }
253     else {
254       output.setRecursive(this.recursive);
255     }
256     if (ref.getDelayAfterInstallSec() != null) {
257       output.setDelayAfterInstallSec(ref.getDelayAfterInstallSec());
258     }
259     else if (this.delayAfterInstallSec != null) {
260       output.setDelayAfterInstallSec(this.delayAfterInstallSec);
261     }
262     else {
263       output.setDelayAfterInstallSecAutoDetect();
264     }
265     output.setHttpSocketTimeoutSec(ref.getHttpSocketTimeoutSec());
266 
267     return output;
268   }
269 
270   private io.wcm.tooling.commons.packmgr.install.PackageFile toPackageFile(File file) {
271     io.wcm.tooling.commons.packmgr.install.PackageFile output = new io.wcm.tooling.commons.packmgr.install.PackageFile();
272 
273     output.setFile(file);
274     output.setInstall(this.install);
275     output.setForce(this.force);
276     output.setRecursive(this.recursive);
277     if (this.delayAfterInstallSec != null) {
278       output.setDelayAfterInstallSec(this.delayAfterInstallSec);
279     }
280 
281     return output;
282   }
283 
284 }