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 }