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.jlink;
20  
21  /*
22   * Licensed to the Apache Software Foundation (ASF) under one
23   * or more contributor license agreements.  See the NOTICE file
24   * distributed with this work for additional information
25   * regarding copyright ownership.  The ASF licenses this file
26   * to you under the Apache License, Version 2.0 (the
27   * "License"); you may not use this file except in compliance
28   * with the License.  You may obtain a copy of the License at
29   *
30   *   http://www.apache.org/licenses/LICENSE-2.0
31   *
32   * Unless required by applicable law or agreed to in writing,
33   * software distributed under the License is distributed on an
34   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
35   * KIND, either express or implied.  See the License for the
36   * specific language governing permissions and limitations
37   * under the License.
38   */
39  
40  import java.io.File;
41  import java.lang.reflect.Method;
42  import java.util.Collection;
43  import java.util.List;
44  import java.util.Map;
45  import java.util.Optional;
46  
47  import org.apache.maven.execution.MavenSession;
48  import org.apache.maven.plugin.AbstractMojo;
49  import org.apache.maven.plugins.annotations.Component;
50  import org.apache.maven.plugins.annotations.Parameter;
51  import org.apache.maven.project.MavenProject;
52  import org.apache.maven.toolchain.Toolchain;
53  import org.apache.maven.toolchain.ToolchainManager;
54  
55  /**
56   * @author Karl Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a>
57   */
58  public abstract class AbstractJLinkMojo extends AbstractMojo {
59      /**
60       * <p>
61       * Specify the requirements for this jdk toolchain. This overrules the toolchain selected by the
62       * maven-toolchain-plugin.
63       * </p>
64       * <strong>note:</strong> requires at least Maven 3.3.1
65       */
66      @Parameter
67      private Map<String, String> jdkToolchain;
68  
69      @Parameter(defaultValue = "${project}", readonly = true, required = true)
70      private MavenProject project;
71  
72      @Parameter(defaultValue = "${session}", readonly = true, required = true)
73      private MavenSession session;
74  
75      @Component
76      private ToolchainManager toolchainManager;
77  
78      /**
79       * Overload this to produce a zip with another classifier, for example a jlink-zip.
80       * @return get the classifier.
81       */
82      protected abstract String getClassifier();
83  
84      protected JLinkExecutor getJlinkExecutor() {
85          return new JLinkExecutor(getToolchain().orElse(null), getLog());
86      }
87  
88      protected Optional<Toolchain> getToolchain() {
89          Toolchain tc = null;
90  
91          if (jdkToolchain != null) {
92              // Maven 3.3.1 has plugin execution scoped Toolchain Support
93              try {
94                  Method getToolchainsMethod = toolchainManager
95                          .getClass()
96                          .getMethod("getToolchains", MavenSession.class, String.class, Map.class);
97  
98                  @SuppressWarnings("unchecked")
99                  List<Toolchain> tcs = (List<Toolchain>)
100                         getToolchainsMethod.invoke(toolchainManager, getSession(), "jdk", jdkToolchain);
101 
102                 if (tcs != null && tcs.size() > 0) {
103                     tc = tcs.get(0);
104                 }
105             } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException e) {
106                 // ignore
107             }
108         }
109 
110         if (tc == null) {
111             // TODO: Check if we should make the type configurable?
112             tc = toolchainManager.getToolchainFromBuildContext("jdk", getSession());
113         }
114 
115         return Optional.ofNullable(tc);
116     }
117 
118     protected MavenProject getProject() {
119         return project;
120     }
121 
122     protected MavenSession getSession() {
123         return session;
124     }
125 
126     /**
127      * Returns the archive file to generate, based on an optional classifier.
128      *
129      * @param basedir the output directory
130      * @param finalName the name of the ear file
131      * @param classifier an optional classifier
132      * @param archiveExt The extension of the file.
133      * @return the file to generate
134      */
135     protected File getArchiveFile(File basedir, String finalName, String classifier, String archiveExt) {
136         if (basedir == null) {
137             throw new IllegalArgumentException("basedir is not allowed to be null");
138         }
139         if (finalName == null) {
140             throw new IllegalArgumentException("finalName is not allowed to be null");
141         }
142         if (archiveExt == null) {
143             throw new IllegalArgumentException("archiveExt is not allowed to be null");
144         }
145 
146         if (finalName.isEmpty()) {
147             throw new IllegalArgumentException("finalName is not allowed to be empty.");
148         }
149         if (archiveExt.isEmpty()) {
150             throw new IllegalArgumentException("archiveExt is not allowed to be empty.");
151         }
152 
153         StringBuilder fileName = new StringBuilder(finalName);
154 
155         if (hasClassifier(classifier)) {
156             fileName.append("-").append(classifier);
157         }
158 
159         fileName.append('.');
160         fileName.append(archiveExt);
161 
162         return new File(basedir, fileName.toString());
163     }
164 
165     protected boolean hasClassifier(String classifier) {
166         boolean result = false;
167         if (classifier != null && !classifier.isEmpty()) {
168             result = true;
169         }
170 
171         return result;
172     }
173 
174     /**
175      * This will convert a module path separated by either {@code :} or {@code ;} into a string which uses the platform
176      * depend path separator uniformly.
177      *
178      * @param pluginModulePath The module path.
179      * @return The platform separated module path.
180      */
181     protected StringBuilder convertSeparatedModulePathToPlatformSeparatedModulePath(String pluginModulePath) {
182         StringBuilder sb = new StringBuilder();
183         // Split the module path by either ":" or ";" linux/windows path separator and
184         // convert uniformly to the platform used separator.
185         String[] splitModule = pluginModulePath.split("[;:]");
186         for (String module : splitModule) {
187             if (sb.length() > 0) {
188                 sb.append(File.pathSeparatorChar);
189             }
190             sb.append(module);
191         }
192         return sb;
193     }
194 
195     /**
196      * Convert a list into a string which is separated by platform depend path separator.
197      *
198      * @param modulePaths The list of elements.
199      * @return The string which contains the elements separated by {@link File#pathSeparatorChar}.
200      */
201     protected String getPlatformDependSeparateList(Collection<String> modulePaths) {
202         return String.join(Character.toString(File.pathSeparatorChar), modulePaths);
203     }
204 
205     /**
206      * Convert a list into a
207      * @param modules The list of modules.
208      * @return The string with the module list which is separated by {@code ,}.
209      */
210     protected String getCommaSeparatedList(Collection<String> modules) {
211         return String.join(",", modules);
212     }
213 }