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