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.io.IOException;
24  import java.lang.reflect.Constructor;
25  import java.lang.reflect.InvocationTargetException;
26  
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugin.logging.Log;
30  import org.apache.maven.project.MavenProject;
31  import org.apache.maven.project.MavenProjectHelper;
32  import org.codehaus.plexus.archiver.Archiver;
33  import org.codehaus.plexus.archiver.ArchiverException;
34  import org.codehaus.plexus.archiver.UnArchiver;
35  import org.codehaus.plexus.archiver.manager.ArchiverManager;
36  import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
37  
38  /**
39   * @author Mark Donszelmann (Mark.Donszelmann@gmail.com)
40   * @version $Id$
41   */
42  public abstract class AbstractNarLayout implements NarLayout, NarConstants {
43    /**
44     * @return
45     * @throws MojoExecutionException
46     */
47    public static NarLayout getLayout(final String layoutName, final Log log) throws MojoExecutionException {
48      final String className = layoutName.indexOf('.') < 0 ? NarLayout21.class.getPackage().getName() + "." + layoutName
49          : layoutName;
50      log.debug("Using " + className);
51      Class cls;
52      try {
53        cls = Class.forName(className);
54        final Constructor ctor = cls.getConstructor(Log.class);
55        return (NarLayout) ctor.newInstance(log);
56      } catch (final ClassNotFoundException e) {
57        throw new MojoExecutionException("Cannot find class for layout " + className, e);
58      } catch (final InstantiationException e) {
59        throw new MojoExecutionException("Cannot instantiate class for layout " + className, e);
60      } catch (final IllegalAccessException | SecurityException e) {
61        throw new MojoExecutionException("Cannot access class for layout " + className, e);
62      } catch (final NoSuchMethodException e) {
63        throw new MojoExecutionException("Cannot find ctor(Log) for layout " + className, e);
64      } catch (final IllegalArgumentException e) {
65        throw new MojoExecutionException("Wrong arguments ctor(Log) for layout " + className, e);
66      } catch (final InvocationTargetException e) {
67        throw new MojoExecutionException("Cannot invokector(Log) for layout " + className, e);
68      }
69    }
70  
71    private final Log log;
72  
73    protected AbstractNarLayout(final Log log) {
74      this.log = log;
75    }
76  
77    protected final void attachNar(final ArchiverManager archiverManager, final MavenProjectHelper projectHelper,
78        final MavenProject project, final String classifier, final File dir, final String include)
79        throws MojoExecutionException {
80      final File narFile = new File(project.getBuild().getDirectory(), project.getBuild().getFinalName() + "-"
81          + classifier + "." + NarConstants.NAR_EXTENSION);
82      if (narFile.exists()) {
83        narFile.delete();
84      }
85      try {
86        final Archiver archiver = archiverManager.getArchiver(NarConstants.NAR_ROLE_HINT);
87        archiver.addDirectory(dir, new String[] {
88          include
89        }, null);
90        archiver.setDestFile(narFile);
91        archiver.createArchive();
92      } catch (final NoSuchArchiverException e) {
93        throw new MojoExecutionException("NAR: cannot find archiver", e);
94      } catch (final ArchiverException | IOException e) {
95        throw new MojoExecutionException("NAR: cannot create NAR archive '" + narFile + "'", e);
96      }
97      projectHelper.attachArtifact(project, NarConstants.NAR_TYPE, classifier, narFile);
98    }
99  
100   protected Log getLog() {
101     return this.log;
102   }
103 
104   protected void unpackNarAndProcess(final ArchiverManager archiverManager, final File file, final File narLocation,
105       final String os, final String linkerName, final AOL defaultAOL)
106       throws MojoExecutionException, MojoFailureException {
107 
108     final String gpp = "g++";
109     final String gcc = "gcc";
110 
111     narLocation.mkdirs();
112 
113     // unpack
114     try {
115       UnArchiver unArchiver;
116       unArchiver = archiverManager.getUnArchiver(NarConstants.NAR_ROLE_HINT);
117       unArchiver.setSourceFile(file);
118       unArchiver.setDestDirectory(narLocation);
119       unArchiver.extract();
120     } catch (final NoSuchArchiverException | ArchiverException e) {
121       throw new MojoExecutionException("Error unpacking file: " + file + " to: " + narLocation, e);
122     }
123 
124     // process
125     if (!NarUtil.getOS(os).equals(OS.WINDOWS)) {
126       NarUtil.makeExecutable(new File(narLocation, "bin/" + defaultAOL), this.log);
127       // FIXME clumsy
128       if (defaultAOL.hasLinker(gpp)) {
129         NarUtil.makeExecutable(new File(narLocation, "bin/" + NarUtil.replace(gpp, gcc, defaultAOL.toString())),
130             this.log);
131       }
132       // add link to versioned so files
133       NarUtil.makeLink(new File(narLocation, "lib/" + defaultAOL), this.log);
134     }
135     if (linkerName.equals(gcc) || linkerName.equals(gpp)) {
136       NarUtil.runRanlib(new File(narLocation, "lib/" + defaultAOL), this.log);
137       // FIXME clumsy
138       if (defaultAOL.hasLinker(gpp)) {
139         NarUtil.runRanlib(new File(narLocation, "lib/" + NarUtil.replace(gpp, gcc, defaultAOL.toString())), this.log);
140       }
141     }
142     // TODO: Find replacement action to install name tool
143     // install name tool adjusts the internal lookup directory for the
144     // libraries,
145     // this isn't really appropriate, removing signatures for one.
146     // however don't have a replacement action currently... having commented
147     // this,
148     // may break some usage, perhaps if don't find solution make configurable.
149     // if ( NarUtil.getOS( os ).equals( OS.MACOSX ) )
150     // {
151     // File[] dylibDirs = new File[2];
152     // dylibDirs[0] = new File( narLocation, "lib/" + defaultAOL + "/" +
153     // Library.SHARED );
154     // dylibDirs[1] = new File( narLocation, "lib/" + defaultAOL + "/" +
155     // Library.JNI );
156     //
157     // NarUtil.runInstallNameTool( dylibDirs, log );
158     // }
159   }
160 
161 }