blob: 878292bbd78c1876c54a79fc388ebaadae79f269 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.geronimo.eclipse.devtools;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.installer.ArtifactInstallationException;
import org.apache.maven.artifact.installer.ArtifactInstaller;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.ProjectArtifactMetadata;
import org.codehaus.plexus.util.IOUtil;
import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.Constants;
import sun.util.BuddhistCalendar;
/**
* This maven plugin installs to the local maven repository eclipse plugin
* dependencies for a pom from an eclipse distribution.
*
* Plugins dependencies are defined with the "org.eclipse.plugins" groupId.
*
* The artifactId is the bundle id. If the bundle is a directory, then all jars
* inside the bundle will be installed. The bundle id can be appendend with "." +
* the name of the jar inside the bundle, excluding the ".jar" extension in
* order to explicitly define a jar dependency.
*
* @goal install
*
* @version $Rev$ $Date$
*/
public class InstallPluginDependenciesMojo extends AbstractMojo {
public static final String GROUP_ID = "org.eclipse.plugins";
/**
* @parameter expression="${project}"
*/
private MavenProject project;
/**
* @parameter expression="${component.org.apache.maven.artifact.factory.ArtifactFactory}"
* @required
* @readonly
*/
private ArtifactFactory artifactFactory;
/**
* @parameter expression="${component.org.apache.maven.artifact.installer.ArtifactInstaller}"
* @required
* @readonly
*/
protected ArtifactInstaller installer;
/**
* @parameter expression="${localRepository}"
* @required
* @readonly
*/
protected ArtifactRepository localRepository;
/**
* @parameter expression="${eclipseHome}"
*/
private File eclipseHome;
/**
* @parameter expression="${useDistributionVersions}"
*/
protected boolean useDistributionVersion = true;
private List removeList = new ArrayList();
private List addList = new ArrayList();
private int depth = 0;
public InstallPluginDependenciesMojo() {
super();
}
/*
* (non-Javadoc)
*
* @see org.apache.maven.plugin.Mojo#execute()
*/
public void execute() throws MojoExecutionException, MojoFailureException {
if (!isValid())
throw new MojoFailureException("Eclipse home directory is not valid. " + eclipseHome);
processDependencies();
project.getDependencies().removeAll(removeList);
project.getDependencies().addAll(addList);
}
protected void processDependencies() {
List dependencies = project.getDependencies();
Iterator i = dependencies.iterator();
while (i.hasNext()) {
Dependency dependency = (Dependency) i.next();
if (GROUP_ID.equals(dependency.getGroupId())) {
getLog().debug("\n");
getLog().debug("========== Processing Plug-in Dependency: " + dependency.getArtifactId() + "==========");
if ("org.eclipse.swt".equals(dependency.getArtifactId())) {
Dependency fragment = getSWTFragmentDependency(dependency);
processDependency(fragment);
addList.add(fragment);
}
processDependency(dependency);
}
}
}
private void processDependency(Dependency dependency) {
File bundle = findBundleForDependency(dependency);
getLog().debug("Matching bundle: " + bundle);
if (bundle != null) {
process(bundle, dependency);
if (bundle.isDirectory() && getBundleName(bundle).equals(dependency.getArtifactId())) {
getLog().info("Removing bundle directory dependency: " + dependency.getArtifactId());
removeList.add(dependency);
}
} else {
getLog().error("Bundle for dependency not found: " + dependency.getArtifactId());
}
}
private Dependency getSWTFragmentDependency(Dependency swtDependency) {
Dependency fragment = new Dependency();
fragment.setGroupId(swtDependency.getGroupId());
fragment.setType(swtDependency.getType());
fragment.setVersion(swtDependency.getVersion());
String id = swtDependency.getArtifactId();
String platform = System.getProperty("os.name");
String arch = System.getProperty("os.arch");
if (platform.startsWith("Windows")) {
fragment.setArtifactId(id.concat(".win32.win32.x86"));
} else if (platform.startsWith("Linux")) {
if (arch.equalsIgnoreCase("x86_64")
|| arch.equalsIgnoreCase("amd64"))
fragment.setArtifactId(id.concat(".gtk.linux.x86_64"));
else if (arch.startsWith("ppc"))
fragment.setArtifactId(id.concat(".gtk.linux.ppc"));
else
fragment.setArtifactId(id.concat(".gtk.linux.x86"));
} else if (platform.startsWith("Mac")) {
fragment.setArtifactId(id.concat(".carbon.macosx"));
} else if (platform.startsWith("SunOS")) {
if (arch.startsWith("x86") || arch.startsWith("amd"))
fragment.setArtifactId(id.concat(".gtk.solaris.x86"));
else
fragment.setArtifactId(id.concat(".gtk.solaris.sparc"));
} else if (platform.startsWith("AIX")) {
fragment.setArtifactId(id.concat(".motif.aix.ppc"));
}
getLog().info("SWTFragment: " + fragment.toString());
return fragment;
}
protected boolean isValid() {
return eclipseHome != null && eclipseHome.isDirectory();
}
private File findBundleForDependency(Dependency dependency) {
File pluginsDir = new File(eclipseHome + File.separator + "plugins");
File[] members = pluginsDir.listFiles();
for (int i = 0; i < members.length; i++) {
if (isBundleForDependency(dependency, members[i]))
return members[i];
}
return null;
}
private boolean isBundleForDependency(Dependency dependency, File bundle) {
String bundleName = getBundleName(bundle);
boolean match = dependency.getArtifactId().equals(bundleName);
if(match) {
getLog().debug("Found match using bundle name: " + bundleName);
}
return match;
}
protected void process(File file, Dependency dependency) {
if (file.isDirectory()) {
depth++;
File[] members = file.listFiles();
for (int i = 0; i < members.length; i++) {
process(members[i], dependency);
}
depth--;
} else {
if (file.getName().endsWith(".jar")) {
File bundle = getBundle(file);
install(file, bundle);
if (useDistributionVersion)
dependency.setVersion(getBundleVersion(bundle));
}
}
}
protected void install(File artifact, File bundle) {
String artifactId = getArtifactID(artifact, bundle);
String version = getBundleVersion(bundle);
if (!useDistributionVersion)
version = fixVersion(version);
if (bundle.isDirectory())
addList.add(createDependency(artifactId, version));
try {
doIt(artifact, GROUP_ID, artifactId, version, "jar");
} catch (MojoExecutionException e) {
e.printStackTrace();
} catch (MojoFailureException e) {
e.printStackTrace();
}
}
/**
* Converts eclipse qualifier convention to maven convention.
*
* major.minor.revision.qualifier is converted to major.minor.revision-build
* where build is the eclipse qualifier with all non-numeric characters
* removed.
*
* @param version
* @return
*/
public static String fixVersion(String version) {
int qualifierIndex = version.indexOf(".", 5);
if (qualifierIndex == -1)
return version; // has no qualifier
String eclipseQualifier = version.substring(qualifierIndex + 1);
String newQualifier = eclipseQualifier.replaceAll("[^\\d]", "");
return version.substring(0, qualifierIndex) + "-" + newQualifier;
}
protected File getBundle(File file) {
File bundle = file;
if (depth > 0) {
bundle = file.getParentFile();
for (int i = depth - 1; i > 0; i--) {
bundle = bundle.getParentFile();
}
}
return bundle;
}
public static String getBundleNameFromFileName(File bundle) {
String id = removeJarExtension(bundle);
if (id.lastIndexOf("_") != -1)
id = id.substring(0, id.lastIndexOf("_"));
return id;
}
public static String getBundleName(File bundle) {
try {
Manifest manifest = null;
if(bundle.isFile()) {
JarFile jar = new JarFile(bundle);
manifest = jar.getManifest();
} else {
FileInputStream fis = new FileInputStream(new File(bundle, "META-INF/MANIFEST.MF"));
manifest = new Manifest(fis);
fis.close();
}
if(manifest != null) {
String id = manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME);
if(id != null) {
ManifestElement[] elements = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, id);
if (elements != null) {
return elements[0].getValue();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String getBundleVersion(File bundle) {
String id = removeJarExtension(bundle);
return id.substring(id.indexOf("_") + 1, id.length());
}
public static String getArtifactID(File artifact, File bundle) {
String artifactId = getBundleName(bundle);
if (bundle.isDirectory())
artifactId = artifactId + "." + removeJarExtension(artifact);
return artifactId;
}
private void doIt(File file, String groupId, String artifactId, String version, String packaging) throws MojoExecutionException, MojoFailureException {
getLog().debug("Installing " + file + ": " + groupId + " " + artifactId + " " + version + " ");
Artifact artifact = artifactFactory.createArtifact(groupId, artifactId, version, null, packaging);
generatePOM(artifact, groupId, artifactId, version);
try {
String localPath = localRepository.pathOf(artifact);
File destination = new File(localRepository.getBasedir(), localPath);
if (destination.exists()) {
getLog().info(artifactId + " : " + version + " already exists in local repository.");
return;
}
if (!file.getPath().equals(destination.getPath())) {
installer.install(file, artifact, localRepository);
} else {
throw new MojoFailureException("Cannot install artifact. Artifact is already in the local repository.\n\nFile in question is: " + file + "\n");
}
} catch (ArtifactInstallationException e) {
throw new MojoExecutionException("Error installing artifact '" + artifact.getDependencyConflictId() + "': " + e.getMessage(), e);
}
}
private void generatePOM(Artifact artifact, String groupId, String artifactId, String version) throws MojoExecutionException {
FileWriter fw = null;
try {
File tempFile = File.createTempFile("mvninstall", ".pom");
tempFile.deleteOnExit();
Model model = new Model();
model.setModelVersion("4.0.0");
model.setGroupId(groupId);
model.setArtifactId(artifactId);
model.setVersion(version);
model.setPackaging(".jar");
model.setDescription("POM was created from install:install-file");
fw = new FileWriter(tempFile);
tempFile.deleteOnExit();
new MavenXpp3Writer().write(fw, model);
ArtifactMetadata metadata = new ProjectArtifactMetadata(artifact, tempFile);
artifact.addMetadata(metadata);
} catch (IOException e) {
throw new MojoExecutionException("Error writing temporary pom file: " + e.getMessage(), e);
} finally {
IOUtil.close(fw);
}
}
public static String removeJarExtension(File file) {
String fileName = file.getName();
if (fileName.endsWith(".jar"))
return fileName.substring(0, fileName.lastIndexOf(".jar"));
return fileName;
}
private Dependency createDependency(String artifactId, String version) {
Dependency dependency = new Dependency();
dependency.setGroupId("org.eclipse.plugins");
dependency.setArtifactId(artifactId);
dependency.setVersion(version);
return dependency;
}
}