001 /**
002 * Copyright (C) 2009 Progress Software, Inc.
003 * http://fusesource.com
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.fusesource.hawtjni.maven;
018
019 import java.io.File;
020 import java.util.List;
021
022 import org.apache.maven.plugin.AbstractMojo;
023 import org.apache.maven.plugin.MojoExecutionException;
024 import org.apache.maven.project.MavenProject;
025 import org.apache.maven.project.MavenProjectHelper;
026 import org.codehaus.plexus.archiver.jar.JarArchiver;
027 import org.codehaus.plexus.archiver.jar.Manifest;
028 import org.codehaus.plexus.archiver.jar.Manifest.Attribute;
029 import org.codehaus.plexus.archiver.manager.ArchiverManager;
030 import org.fusesource.hawtjni.runtime.Library;
031
032 /**
033 * This goal allows allows you to package the JNI library created by build goal
034 * in a JAR which the HawtJNI runtime can unpack when the library needs to be
035 * loaded.
036 *
037 * This platform specific jar is attached with a classifier which matches the
038 * current platform.
039 *
040 * @goal package-jar
041 * @phase package
042 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
043 */
044 public class PackageJarMojo extends AbstractMojo {
045
046 /**
047 * The maven project.
048 *
049 * @parameter expression="${project}"
050 * @required
051 * @readonly
052 */
053 protected MavenProject project;
054
055 /**
056 * The base name of the library, used to determine generated file names.
057 *
058 * @parameter default-value="${project.artifactId}"
059 */
060 private String name;
061
062 /**
063 * @component
064 * @required
065 * @readonly
066 */
067 private ArchiverManager archiverManager;
068
069 /**
070 * @component
071 * @required
072 * @readonly
073 */
074 private MavenProjectHelper projectHelper;
075
076 /**
077 * The output directory where the built JNI library will placed. This
078 * directory will be added to as a test resource path so that unit tests can
079 * verify the built JNI library.
080 *
081 * The library will placed under the META-INF/native/${platform} directory
082 * that the HawtJNI Library uses to find JNI libraries as classpath
083 * resources.
084 *
085 * @parameter
086 * default-value="${project.build.directory}/generated-sources/hawtjni/lib"
087 */
088 private File libDirectory;
089
090 /**
091 * The platform identifier of this build. If not specified,
092 * it will be automatically detected. This will be used as the
093 * artifact classifier for the platform specific jar.
094 *
095 * @parameter default-value="${hawtjni-platform}"
096 */
097 private String platform;
098
099 /**
100 * The osgi platforms that the library match for. Example value:
101 * osname=MacOS;processor=x86-64
102 *
103 * @parameter
104 */
105 private List<String> osgiPlatforms;
106
107 public void execute() throws MojoExecutionException {
108 try {
109
110 Library library = new Library(name);
111 if (platform == null || platform.trim().length()==0 ) {
112 platform = library.getPlatform();
113 }
114
115 String packageName = project.getArtifactId() + "-" + project.getVersion() + "-" + platform;
116 JarArchiver archiver = (JarArchiver) archiverManager.getArchiver("jar");
117
118 File packageFile = new File(new File(project.getBuild().getDirectory()), packageName + ".jar");
119 archiver.setDestFile(packageFile);
120 archiver.setIncludeEmptyDirs(true);
121 archiver.addDirectory(libDirectory);
122
123 Manifest manifest = new Manifest();
124 manifest.addConfiguredAttribute(new Attribute("Bundle-SymbolicName", project.getArtifactId() + "-" + platform));
125 manifest.addConfiguredAttribute(new Attribute("Bundle-Name", name + " for " + platform));
126 manifest.addConfiguredAttribute(new Attribute("Bundle-NativeCode", getNativeCodeValue(library)));
127 manifest.addConfiguredAttribute(new Attribute("Bundle-Version", project.getVersion()));
128 manifest.addConfiguredAttribute(new Attribute("Bundle-ManifestVersion", "2"));
129 manifest.addConfiguredAttribute(new Attribute("Bundle-Description", project.getDescription()));
130 archiver.addConfiguredManifest(manifest);
131
132 archiver.createArchive();
133
134 projectHelper.attachArtifact(project, "jar", platform, packageFile);
135
136 } catch (Exception e) {
137 throw new MojoExecutionException("packageing failed: " + e, e);
138 }
139 }
140
141 public String getNativeCodeValue(Library library) {
142 if (osgiPlatforms == null || osgiPlatforms.isEmpty() ) {
143 return library.getPlatformSpecifcResourcePath(platform) + ";" +"osname=" + getOsgiOSName() + ";processor=" + getOsgiProcessor()+ ",*";
144 }
145 boolean first=true;
146 String rc = "";
147 for (String s : osgiPlatforms) {
148 if( !first ) {
149 rc += ",";
150 }
151 first = false;
152 if( "*".equals(s) ) {
153 rc += s;
154 } else {
155 rc += library.getPlatformSpecifcResourcePath(platform) + ";"+s;
156 }
157 }
158 return rc;
159 }
160
161 public String getOsgiOSName() {
162 String name = System.getProperty("os.name");
163
164 String trimmed = name.toLowerCase().trim();
165 if (trimmed.startsWith("win")) {
166 return "Win32";
167 } else if (trimmed.startsWith("linux")) {
168 return "Linux";
169 } else if (trimmed.startsWith("macos") || trimmed.startsWith("mac os")) {
170 return "MacOS";
171 } else if (trimmed.startsWith("aix")) {
172 return "AIX";
173 } else if (trimmed.startsWith("hpux")) {
174 return "HPUX";
175 } else if (trimmed.startsWith("irix")) {
176 return "IRIX";
177 } else if (trimmed.startsWith("netware")) {
178 return "Netware";
179 } else if (trimmed.startsWith("openbsd")) {
180 return "OpenBSD";
181 } else if (trimmed.startsWith("netbsd")) {
182 return "NetBSD";
183 } else if (trimmed.startsWith("os2") || trimmed.startsWith("os/2")) {
184 return "OS2";
185 } else if (trimmed.startsWith("qnx") || trimmed.startsWith("procnto")) {
186 return "QNX";
187 } else if (trimmed.startsWith("solaris")) {
188 return "Solaris";
189 } else if (trimmed.startsWith("sunos")) {
190 return "SunOS";
191 } else if (trimmed.startsWith("vxworks")) {
192 return "VxWorks";
193 }
194 return name;
195 }
196
197 public String getOsgiProcessor() {
198 String name = System.getProperty("os.arch");
199 String trimmed = name.toLowerCase().trim();
200 if (trimmed.startsWith("x86-64") || trimmed.startsWith("amd64") || trimmed.startsWith("em64") || trimmed.startsWith("x86_64")) {
201 return "x86-64";
202 } else if (trimmed.startsWith("x86") || trimmed.startsWith("pentium") || trimmed.startsWith("i386")
203 || trimmed.startsWith("i486") || trimmed.startsWith("i586") || trimmed.startsWith("i686")) {
204 return "x86";
205 } else if (trimmed.startsWith("68k")) {
206 return "68k";
207 } else if (trimmed.startsWith("arm")) {
208 return "ARM";
209 } else if (trimmed.startsWith("alpha")) {
210 return "Alpha";
211 } else if (trimmed.startsWith("ignite") || trimmed.startsWith("psc1k")) {
212 return "Ignite";
213 } else if (trimmed.startsWith("mips")) {
214 return "Mips";
215 } else if (trimmed.startsWith("parisc")) {
216 return "PArisc";
217 } else if (trimmed.startsWith("powerpc") || trimmed.startsWith("power") || trimmed.startsWith("ppc")) {
218 return "PowerPC";
219 } else if (trimmed.startsWith("sparc")) {
220 return "Sparc";
221 }
222 return name;
223 }
224
225 }