View Javadoc

1   /*
2    * #%L
3    * Native ARchive plugin for Maven
4    * %%
5    * Copyright (C) 2002 - 2014 NAR Maven Plugin developers.
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 com.github.maven_nar;
21  
22  import java.io.File;
23  import java.util.Collections;
24  import java.util.List;
25  import java.util.Properties;
26  
27  import org.apache.maven.model.Model;
28  import org.apache.maven.plugin.AbstractMojo;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.MojoFailureException;
31  import org.apache.maven.plugins.annotations.Component;
32  import org.apache.maven.plugins.annotations.Parameter;
33  import org.apache.maven.project.MavenProject;
34  
35  /**
36   * @author Mark Donszelmann
37   */
38  public abstract class AbstractNarMojo extends AbstractMojo implements NarConstants {
39  
40    /**
41     * Skip running of NAR plugins (any) altogether.
42     */
43    @Parameter(property = "nar.skip", defaultValue = "false")
44    protected boolean skip;
45  
46    /**
47     * Skip the tests. Listens to Maven's general 'maven.skip.test'.
48     */
49    @Parameter(property = "maven.test.skip")
50    boolean skipTests;
51  
52    /**
53     * Ignore errors and failures.
54     */
55    @Parameter(property = "nar.ignore", defaultValue = "false")
56    private boolean ignore;
57  
58    /**
59     * The Architecture for the nar, Some choices are: "x86", "i386", "amd64",
60     * "ppc", "sparc", ... Defaults to a derived
61     * value from ${os.arch}
62     */
63    @Parameter(property = "nar.arch")
64    private String architecture;
65  
66    /**
67     * The Operating System for the nar. Some choices are: "Windows", "Linux",
68     * "MacOSX", "SunOS", ... Defaults to a
69     * derived value from ${os.name} FIXME table missing
70     */
71    @Parameter(property = "nar.os")
72    private String os;
73  
74    /**
75     * Architecture-OS-Linker name. Defaults to: arch-os-linker.
76     */
77    @Parameter(defaultValue = "")
78    private String aol;
79  
80    /**
81     * Linker
82     */
83    @Parameter
84    private Linker linker;
85  
86    // these could be obtained from an injected project model.
87  
88    @Parameter(property = "project.build.directory", readonly = true)
89    private File outputDirectory;
90  
91    @Parameter(property = "project.build.outputDirectory", readonly = true)
92    protected File classesDirectory;
93  
94    /**
95     * Name of the output
96     * - for jni default-value="${project.artifactId}-${project.version}"
97     * - for libs default-value="${project.artifactId}-${project.version}"
98     * - for exe default-value="${project.artifactId}"
99     * -- for tests default-value="${test.name}"
100    * 
101    */
102   @Parameter
103   private String output;
104 
105   @Parameter(property = "project.basedir", readonly = true)
106   private File baseDir;
107 
108   /**
109    * Target directory for Nar file construction. Defaults to
110    * "${project.build.directory}/nar" for "nar-compile" goal
111    */
112   @Parameter
113   private File targetDirectory;
114 
115   /**
116    * Target directory for Nar test construction. Defaults to
117    * "${project.build.directory}/test-nar" for "nar-testCompile" goal
118    */
119   @Parameter
120   private File testTargetDirectory;
121 
122   /**
123    * Target directory for Nar file unpacking. Defaults to "${targetDirectory}"
124    */
125   @Parameter
126   private File unpackDirectory;
127 
128   /**
129    * Target directory for Nar test unpacking. Defaults to
130    * "${testTargetDirectory}"
131    */
132   @Parameter
133   private File testUnpackDirectory;
134 
135   /**
136    * List of classifiers which you want download/unpack/assemble
137    * Example ppc-MacOSX-g++, x86-Windows-msvc, i386-Linux-g++.
138    * Not setting means all.
139    */
140   @Parameter
141   protected List<String> classifiers;
142 
143   /**
144    * List of libraries to create
145    */
146   @Parameter
147   protected List<Library> libraries;
148 
149   /**
150    * Name of the libraries included
151    */
152   @Parameter
153   private String libsName;
154 
155   /**
156    * Layout to be used for building and unpacking artifacts
157    */
158   @Parameter(property = "nar.layout", defaultValue = "com.github.maven_nar.NarLayout21", required = true)
159   private String layout;
160 
161   private NarLayout narLayout;
162 
163   @Component
164   private MavenProject mavenProject;
165 
166   private AOL aolId;
167 
168   private NarInfo narInfo;
169 
170   /**
171    * Javah info
172    */
173   @Parameter
174   private Javah javah;
175 
176   /**
177    * The home of the Java system. Defaults to a derived value from ${java.home}
178    * which is OS specific.
179    */
180   @Parameter(readonly = true)
181   private File javaHome;
182 
183   @Parameter
184   private Msvc msvc = new Msvc();
185 
186   @Override
187   public final void execute() throws MojoExecutionException, MojoFailureException {
188     if (this.skip) {
189       getLog().info(getClass().getName() + " skipped");
190       return;
191     }
192 
193     try {
194       validate();
195       narExecute();
196     } catch (final MojoFailureException | MojoExecutionException mfe) {
197       if (this.ignore) {
198         getLog().warn("IGNORED: " + mfe.getMessage());
199       } else {
200         throw mfe;
201       }
202     }
203   }
204 
205   protected final AOL getAOL() throws MojoFailureException, MojoExecutionException {
206     return this.aolId;
207   }
208 
209   protected final String getArchitecture() {
210     return this.architecture;
211   }
212 
213   protected final File getBasedir() {
214     return this.baseDir;
215   }
216 
217   protected final Javah getJavah() {
218     if (this.javah == null) {
219       this.javah = new Javah();
220     }
221     this.javah.setAbstractCompileMojo(this);
222     return this.javah;
223   }
224 
225   protected final File getJavaHome(final AOL aol) throws MojoExecutionException {
226     // FIXME should be easier by specifying default...
227     return getNarInfo().getProperty(aol, "javaHome", NarUtil.getJavaHome(this.javaHome, getOS()));
228   }
229 
230   protected final NarLayout getLayout() throws MojoExecutionException {
231     if (this.narLayout == null) {
232       this.narLayout = AbstractNarLayout.getLayout(this.layout, getLog());
233     }
234     return this.narLayout;
235   }
236 
237   protected final List<Library> getLibraries() {
238     if (this.libraries == null) {
239       this.libraries = Collections.emptyList();
240     }
241     return this.libraries;
242   }
243 
244   protected final Linker getLinker() {
245     return this.linker;
246   }
247 
248   protected final MavenProject getMavenProject() {
249     return this.mavenProject;
250   }
251 
252   public Msvc getMsvc() throws MojoFailureException, MojoExecutionException {
253     this.msvc.setMojo(this);
254     return this.msvc;
255   }
256 
257   protected NarInfo getNarInfo() throws MojoExecutionException {
258     if (this.narInfo == null) {
259       final String groupId = getMavenProject().getGroupId();
260       final String artifactId = getMavenProject().getArtifactId();
261       final String path = "META-INF/nar/" + groupId + "/" + artifactId + "/" + NarInfo.NAR_PROPERTIES;
262       File propertiesFile = new File(this.classesDirectory, path);
263       // should not need to try and read from source.
264       if (!propertiesFile.exists()) {
265         propertiesFile = new File(getMavenProject().getBasedir(), "src/main/resources/" + path);
266       }
267 
268       this.narInfo = new NarInfo(groupId, artifactId, getMavenProject().getVersion(), getLog(), propertiesFile);
269     }
270     return this.narInfo;
271   }
272 
273   protected final String getOS() {
274     return this.os;
275   }
276 
277   protected final String getOutput(final boolean versioned) throws MojoExecutionException {
278     if (this.output != null && !this.output.trim().isEmpty()) {
279       return this.output;
280     } else {
281       if (versioned) {
282         return getMavenProject().getArtifactId() + "-" + getMavenProject().getVersion();
283       } else {
284         return getMavenProject().getArtifactId();
285       }
286     }
287   }
288 
289   protected final String getLibsName() throws MojoExecutionException {
290     if (this.libsName != null && !this.libsName.trim().isEmpty()) {
291       return this.libsName;
292     } else {
293       return null;
294     }
295   }
296 
297   protected final File getOutputDirectory() {
298     return this.outputDirectory;
299   }
300 
301   protected final File getTargetDirectory() {
302     return this.targetDirectory;
303   }
304 
305   protected final File getTestTargetDirectory() {
306     return this.testTargetDirectory;
307   }
308 
309   protected final File getTestUnpackDirectory() {
310     return this.testUnpackDirectory;
311   }
312 
313   protected File getUnpackDirectory() {
314     return this.unpackDirectory;
315   }
316 
317   public abstract void narExecute() throws MojoFailureException, MojoExecutionException;
318 
319   protected final void validate() throws MojoFailureException, MojoExecutionException {
320 
321     this.architecture = NarUtil.getArchitecture(this.architecture);
322     this.os = NarUtil.getOS(this.os);
323     this.msvc.setMojo(this);
324     this.linker = NarUtil.getLinker(this.linker, getLog()); // linker name set in NarUtil.getAOL if not configured
325     this.aolId = NarUtil.getAOL(this.mavenProject, this.architecture, this.os, this.linker, this.aol, getLog());
326 
327     final Model model = this.mavenProject.getModel();
328     final Properties properties = model.getProperties();
329     properties.setProperty("nar.arch", getArchitecture());
330     properties.setProperty("nar.os", getOS());
331     properties.setProperty("nar.linker", getLinker().getName());
332     properties.setProperty("nar.aol", this.aolId.toString());
333     properties.setProperty("nar.aol.key", this.aolId.getKey());
334     model.setProperties(properties);
335 
336     if (this.targetDirectory == null) {
337       this.targetDirectory = new File(this.mavenProject.getBuild().getDirectory(), "nar");
338     }
339     if (this.testTargetDirectory == null) {
340       this.testTargetDirectory = new File(this.mavenProject.getBuild().getDirectory(), "test-nar");
341     }
342 
343     if (this.unpackDirectory == null) {
344       this.unpackDirectory = this.targetDirectory;
345     }
346     if (this.testUnpackDirectory == null) {
347       this.testUnpackDirectory = this.testTargetDirectory;
348     }
349   }
350 }