add eclipse signing plugin
diff --git a/eclipse-signing-maven-plugin/README.txt b/eclipse-signing-maven-plugin/README.txt
new file mode 100644
index 0000000..77fc063
--- /dev/null
+++ b/eclipse-signing-maven-plugin/README.txt
@@ -0,0 +1,95 @@
+Example usage:
+
+ <profiles>
+ <profile>
+ <id>build-server</id>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.eclipse.dash.m4e</groupId>
+ <artifactId>eclipse-signing-maven-plugin</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ <executions>
+ <!--
+ Pack the p2 repository.
+ -->
+ <execution>
+ <id>pack</id>
+ <phase>package</phase>
+ <goals>
+ <goal>pack</goal>
+ </goals>
+ </execution>
+ <!--
+ Sign the p2 repository
+ -->
+ <execution>
+ <id>sign</id>
+ <configuration>
+ <signerInputDirectory>/home/data/httpd/download-staging.priv/rt/PROJECT</signerInputDirectory>
+ </configuration>
+ <phase>package</phase>
+ <goals>
+ <goal>sign</goal>
+ </goals>
+ </execution>
+ <!--
+ Repack the p2 repository
+ -->
+ <execution>
+ <id>repack</id>
+ <configuration>
+ <inputFile>${project.build.directory}/signed/site_assembly.zip</inputFile> <!-- this is output from signer mojo -->
+ </configuration>
+ <phase>package</phase>
+ <goals>
+ <goal>pack</goal>
+ </goals>
+ </execution>
+ <!--
+ Signing and packing alters checksums so fix them
+ -->
+ <execution>
+ <id>fixCheckSums</id>
+ <phase>package</phase>
+ <goals>
+ <goal>fixCheckSums</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <!--
+ This is what I use to deploy a p2 repository someplace to test from before manually making active.
+ -->
+ <plugin>
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>deploy</id>
+ <phase>install</phase>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ <configuration>
+ <tasks>
+ <delete includeemptydirs="false">
+ <fileset
+ dir="/home/data/httpd/download.eclipse.org/jetty/updates/jetty-wtp/development">
+ <include name="**" />
+ </fileset>
+ </delete>
+ <copy includeemptydirs="false"
+ todir="/home/data/httpd/download.eclipse.org/jetty/updates/jetty-wtp/development">
+ <fileset dir="target/checksumFix">
+ <include name="**" />
+ </fileset>
+ </copy>
+ </tasks>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
diff --git a/eclipse-signing-maven-plugin/pom.xml b/eclipse-signing-maven-plugin/pom.xml
new file mode 100644
index 0000000..b71411e
--- /dev/null
+++ b/eclipse-signing-maven-plugin/pom.xml
@@ -0,0 +1,105 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <artifactId>jetty-toolchain</artifactId>
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <version>1.4</version>
+ <relativePath>../jetty-toolchain/pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.eclipse.jetty.toolchain</groupId>
+ <artifactId>eclipse-signing-maven-plugin</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <name>Jetty :: Toolchain :: Eclipse Signing Maven Plugin</name>
+ <description>Plugin for signing code on the eclipse build servers.</description>
+ <packaging>maven-plugin</packaging>
+ <scm>
+ <connection>scm:git:http://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.toolchain.git</connection>
+ <developerConnection>scm:git:ssh://git.eclipse.org/gitroot/jetty/org.eclipse.jetty.toolchain.git</developerConnection>
+ <url>http://git.eclipse.org/c/jetty/org.eclipse.jetty.toolchain.git/tree/eclipse-signing-maven-plugin</url>
+ </scm>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-project</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-artifact</artifactId>
+ <version>2.0.8</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-tools-api</artifactId>
+ <version>2.1</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-archiver</artifactId>
+ <version>2.0</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-utils</artifactId>
+ <version>3.0</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.8.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>wagon-maven-plugin</artifactId>
+ <version>1.0-beta-3</version>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <version>2.9</version>
+ <!--configuration>
+ <skip>true</skip>
+ </configuration-->
+ </plugin>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>2.3.2</version>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </plugin>
+ <plugin>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.8</version>
+ <executions>
+ <execution>
+ <id>exec-plugin-doc</id>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>helpmojo</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <reporting>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-plugin-plugin</artifactId>
+ <version>2.8</version>
+ </plugin>
+ </plugins>
+ </reporting>
+</project>
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/AbstractEclipseSigningMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/AbstractEclipseSigningMojo.java
new file mode 100644
index 0000000..0c0082f
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/AbstractEclipseSigningMojo.java
@@ -0,0 +1,143 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses.
+//========================================================================
+
+import java.io.File;
+import java.net.InetAddress;
+
+import org.apache.maven.artifact.manager.WagonManager;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.settings.Settings;
+import org.apache.maven.wagon.CommandExecutor;
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.mojo.wagon.shared.WagonUtils;
+
+public abstract class AbstractEclipseSigningMojo extends AbstractMojo
+{
+ /**
+ * @component
+ */
+ protected WagonManager wagonManager;
+
+ /**
+ * The current user system settings for use in Maven.
+ *
+ * @parameter expression="${settings}"
+ * @readonly
+ */
+ protected Settings settings;
+
+ /**
+ * protocol for the wagon connection
+ *
+ * Example: scp://
+ *
+ * @parameter
+ */
+ protected String wagonProtocol;
+
+ /**
+ * host portion of the wagon connection
+ *
+ * Example: build.eclipse.org
+ *
+ * @parameter
+ */
+ protected String wagonHost;
+
+ /**
+ * path portion of the wagon connection
+ *
+ * Example: /home/data/users/jmcconnell
+ *
+ * @parameter
+ */
+ protected String wagonPath;
+
+ /**
+ * @parameter
+ */
+ protected String serverId;
+
+ /**
+ * @parameter default-value="900000";
+ * @required
+ */
+ protected int wagonTimeout;
+
+ /**
+ *
+ * @return
+ * @throws Exception
+ */
+ protected boolean runningOnBuildMachine() throws Exception
+ {
+ if (InetAddress.getLocalHost().getHostName().equals("build.eclipse.org"))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ protected String adjustToWagonPath(String location)
+ {
+ return wagonPath + File.separator + location;
+ }
+
+ protected String getWagonUrl() throws Exception
+ {
+ if (wagonProtocol == null || wagonHost == null || wagonPath == null)
+ {
+ throw new IllegalArgumentException("missing wagon configuration bits, unable to operate remotely");
+ }
+
+ if (runningOnBuildMachine())
+ {
+ return wagonProtocol + wagonPath;
+ }
+
+ return wagonProtocol + wagonHost + wagonPath;
+ }
+
+ protected Wagon createWagon(String id, String url) throws MojoExecutionException
+ {
+ try
+ {
+ return WagonUtils.createWagon(id,url,wagonManager,settings,this.getLog());
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException("Unable to create a Wagon instance for " + url,e);
+ }
+
+ }
+
+ protected CommandExecutor getCommandExecutor(Wagon wagon) throws Exception
+ {
+ if (!(wagon instanceof CommandExecutor))
+ {
+ throw new MojoExecutionException("unable to operate remotely, requires wagon capable of invoking commands");
+ }
+
+ CommandExecutor exec = (CommandExecutor)wagon;
+
+ exec.setTimeout(wagonTimeout);
+
+ return exec;
+ }
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/ChecksumMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/ChecksumMojo.java
new file mode 100644
index 0000000..26ab4b8
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/ChecksumMojo.java
@@ -0,0 +1,482 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses.
+//========================================================================
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.Iterator;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
+import org.codehaus.plexus.util.FileUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * This plugin walks through a p2 repository and repairs the artifacts.xml.
+ * <br/>
+ * It also insert the property <code><property name='publishPackFilesAsSiblings' value='true'/></code>
+ * and the mapping rules if they were not present already:
+ * <br/>
+ * <code><rule filter='(& (classifier=osgi.bundle) (format=packed))'
+ * output='${repoUrl}/plugins/${id}_${version}.jar.pack.gz'/></code>
+ * <br/><code><rule filter='(& (classifier=org.eclipse.update.feature) (format=packed))'
+ * output='${repoUrl}/features/${id}_${version}.jar.pack.gz'/></code>
+ * @goal fixCheckSums
+ * @phase package
+ * @description updates the md5 checksum and file size
+ */
+public class ChecksumMojo extends AbstractEclipseSigningMojo
+{
+ /**
+ * zip file to get checksum'ed
+ *
+ * @parameter default-value="${project.build.directory}/packed/site_assembly.zip"
+ * @required
+ */
+ protected String inputFile;
+
+ /**
+ * zip file to get checksum'ed
+ *
+ * @parameter default-value="${project.build.directory}/fixed/site_assembly.zip"
+ * @required
+ */
+ protected String outputFile;
+
+ /**
+ * zip file to get checksum'ed
+ *
+ * @parameter default-value="${project.build.directory}/checksumFix"
+ * @required
+ */
+ protected String unzipDir;
+
+ /**
+ * unpack path for artifact
+ *
+ * @parameter default-value="/"
+ * @required
+ */
+ protected String unpackPath;
+
+ /**
+ * checksum file
+ *
+ * @parameter default-value="${project.build.directory}/checksumFix/artifacts.xml
+ * @required
+ */
+ protected String artifactsXml;
+
+ public void execute() throws MojoExecutionException, MojoFailureException
+ {
+ try
+ {
+
+ if (!FileUtils.fileExists(unzipDir))
+ {
+ info("creating directory to hold unzipped artifact");
+ FileUtils.mkdir(unzipDir);
+ }
+
+ if (!FileUtils.fileExists(FileUtils.dirname(outputFile)))
+ {
+ info("creating directory to hold output");
+ FileUtils.mkdir(FileUtils.dirname(outputFile));
+ }
+
+ ZipUnArchiver unzipper = new ZipUnArchiver(new File(inputFile));
+ unzipper.extract("",new File(unzipDir));
+
+ ZipUnArchiver unzipper2 = new ZipUnArchiver(new File(unzipDir + "/artifacts.jar"));
+ unzipper2.extract("",new File(unzipDir));
+
+ FileUtils.fileDelete(unzipDir + "/artifacts.jar.pack.gz");
+ FileUtils.fileDelete(unzipDir + "/content.jar.pack.gz");
+
+ insertPropertyAndMappingRules();
+
+ @SuppressWarnings("unchecked")
+ List<String> files = FileUtils.getFileNames(new File(unzipDir),"**/*.jar","",true);
+
+ for (Iterator<String> i = files.iterator(); i.hasNext();)
+ {
+ String filename = i.next();
+ info("Processing: " + filename);
+ if (filename.endsWith("artifacts.jar"))
+ {
+ continue;
+ }
+ else if (filename.endsWith("content.jar"))
+ {
+ continue;
+ }
+ else
+ {
+ update(filename);
+ }
+ }
+
+ FileUtils.fileDelete(unzipDir + "/artifacts.jar");
+
+ ZipArchiver zipper = new ZipArchiver();
+ zipper.addFile(new File(unzipDir + "/artifacts.xml"),"artifacts.xml");
+ // zipper.addDirectory(new File(unzipDir));
+ zipper.setDestFile(new File(unzipDir + "/artifacts.jar"));
+ zipper.createArchive();
+
+ FileUtils.fileDelete(unzipDir + "/artifacts.xml");
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void update(String plugin)
+ {
+ try
+ {
+ /*
+ * some people have features the same as plugins features so we need to tweak the xpath
+ */
+ boolean isPlugin = plugin.contains("/plugins/");
+
+ String pluginFile = FileUtils.basename(plugin,".jar");
+
+ Pattern p = Pattern.compile("_\\d*\\.");
+
+ String[] bits = p.split(pluginFile);
+
+ //System.out.println(file.substring(0, bits[0].length()) + " / " + file.substring(bits[0].length() + 1 , file.length()));
+
+ int versionSplitUnderscore = bits[0].length();
+
+ String[] artifactBits = new String[2];
+
+ artifactBits[0] = pluginFile.substring(0,versionSplitUnderscore);
+ artifactBits[1] = pluginFile.substring(versionSplitUnderscore + 1, pluginFile.length());
+
+ getLog().info(" Artifact: " + artifactBits[0] + " / Version: " + artifactBits[1] + " / isPlugin: " + isPlugin );
+
+ File inFile = new File(plugin);
+ String inFileSize = Long.toString(inFile.length());
+
+ int count = 0;
+ byte[] buffer = new byte[1024 * 16];
+ InputStream in = new FileInputStream(inFile);
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ while ((count = in.read(buffer)) > 0)
+ {
+ md.update(buffer,0,count);
+ }
+ in.close();
+
+ String inFileMD5 = convert(md.digest());// (new BigInteger(1, md.digest())).toString(16);
+
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document document = builder.parse(new File(artifactsXml));
+
+ String expr;
+ XPath xpath = XPathFactory.newInstance().newXPath();
+
+ if ( isPlugin )
+ {
+ expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='osgi.bundle']/properties//property[@name='artifact.size']/@value";
+ }
+ else
+ {
+ expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='org.eclipse.update.feature']/properties//property[@name='artifact.size']/@value";
+ }
+ Node artifactSize = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+ if (artifactSize != null)
+ {
+ artifactSize.setNodeValue(inFileSize);
+ }
+
+ if (isPlugin)
+ {
+ expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='osgi.bundle']/properties//property[@name='download.size']/@value";
+ }
+ else
+ {
+ expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='org.eclipse.update.feature']/properties//property[@name='download.size']/@value";
+ }
+
+ Node downloadSize = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+ if (downloadSize != null)
+ {
+ downloadSize.setNodeValue(inFileSize);
+ }
+
+ if ( isPlugin )
+ {
+ expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='osgi.bundle']/properties//property[@name='download.md5']/@value";
+ }
+ else
+ {
+ expr = "/repository/artifacts//artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "' and @classifier='org.eclipse.update.feature']/properties//property[@name='download.md5']/@value";
+ }
+ Node downloadMD5 = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+ if (downloadMD5 != null)
+ {
+ downloadMD5.setNodeValue(inFileMD5);
+ }
+
+ if (FileUtils.fileExists(plugin + ".pack.gz"))
+ {
+ File packFile = new File(plugin + ".pack.gz");
+ String packFileSize = Long.toString(packFile.length());
+
+ expr = "/repository/artifacts";// //artifact[@id='" + artifactBits[0] + "' and @version='" + artifactBits[1] + "']";
+ Node normal = (Node)xpath.evaluate(expr,document,XPathConstants.NODE);
+ Element packed = document.createElement("artifact");
+
+ packed.setAttribute("classifier", isPlugin ? "osgi.bundle" : "org.eclipse.update.feature");
+ packed.setAttribute("id",artifactBits[0]);
+ packed.setAttribute("version",artifactBits[1]);
+
+ Element processing = document.createElement("processing");
+ processing.setAttribute("size","1");
+ packed.appendChild(processing);
+
+ Element step = document.createElement("step");
+ step.setAttribute("id","org.eclipse.equinox.p2.processing.Pack200Unpacker");
+ step.setAttribute("required","true");
+ processing.appendChild(step);
+
+ Element properties = document.createElement("properties");
+ properties.setAttribute("size","3");
+ packed.appendChild(properties);
+
+ Element prop1 = document.createElement("property");
+ prop1.setAttribute("name","artifact.size");
+ prop1.setAttribute("value",inFileSize);
+ properties.appendChild(prop1);
+
+ Element prop2 = document.createElement("property");
+ prop2.setAttribute("name","download.size");
+ prop2.setAttribute("value",packFileSize);
+ properties.appendChild(prop2);
+
+ Element prop3 = document.createElement("property");
+ prop3.setAttribute("name","format");
+ prop3.setAttribute("value","packed");
+ properties.appendChild(prop3);
+
+ normal.appendChild(packed);
+
+ }
+
+ Transformer txformer = TransformerFactory.newInstance().newTransformer();
+ DOMSource src = new DOMSource(document);
+ StreamResult res = new StreamResult(artifactsXml);
+ txformer.transform(src,res);
+ }
+ catch (Exception e)
+ {
+ getLog().error(e);
+ }
+ }
+
+ /**
+ * Creates the extra property and mapping rules for the pack.gz
+ */
+ protected void insertPropertyAndMappingRules()
+ {
+ try
+ {
+ DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document document = builder.parse(new File(artifactsXml));
+
+ boolean documentWasModified = false;
+
+ {
+ //<property name='publishPackFilesAsSiblings' value='true'/>
+ String selectPublishPackfilesAsSiblings = "/repository/properties/property[@name='publishPackFilesAsSiblings']";
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ Element propertyEl = (Element)xpath.evaluate(selectPublishPackfilesAsSiblings,document,XPathConstants.NODE);
+
+ String selectProperties = "/repository/properties";
+ xpath = XPathFactory.newInstance().newXPath();
+ Element propertiesEl = (Element)xpath.evaluate(selectProperties,document,XPathConstants.NODE);
+ if (propertiesEl == null)
+ {
+ throw new IllegalArgumentException("The artifacts.xml document must have a /repository/properties element.");
+ }
+
+ if (propertyEl == null)
+ {
+ Element publishPackElem = document.createElement("property");
+ publishPackElem.setAttribute("name", "publishPackFilesAsSiblings");
+ publishPackElem.setAttribute("value", "true");
+ propertiesEl.appendChild(publishPackElem);
+ documentWasModified = true;
+ }
+ else
+ {
+ if (!"true".equals(propertyEl.getAttribute("value")))
+ {
+ propertyEl.setAttribute("value", "true");
+ documentWasModified = true;
+ }
+ }
+
+ //update the number of properties attribute
+ if (documentWasModified)
+ {
+ int size = propertiesEl.getElementsByTagName("property").getLength();
+ propertiesEl.setAttribute("size", String.valueOf(size));
+ }
+ }//end of properties processor
+
+ {
+ //<rule filter='(& (classifier=osgi.bundle) (format=packed))'
+ // output='${repoUrl}/plugins/${id}_${version}.jar.pack.gz'/>
+ //<rule filter='(& (classifier=org.eclipse.update.feature) (format=packed))'
+ // output='${repoUrl}/features/${id}_${version}.jar.pack.gz'/>
+ String selectMappings = "/repository/mappings";
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ Element mappingsEl = (Element)xpath.evaluate(selectMappings,document,XPathConstants.NODE);
+ if (mappingsEl == null)
+ {
+ throw new IllegalArgumentException("The artifacts.xml document must have a /repository/mappings element.");
+ }
+
+ //Just iterate over the rules elements and look at the value of the attributes.
+ boolean foundPackedBundleFilter = false;
+ boolean foundPackedFeatureFilter = false;
+ NodeList nl = mappingsEl.getChildNodes();
+ for (int i = 0; i < nl.getLength(); i++)
+ {
+ Node c = nl.item(i);
+ if (c.getNodeType() == Node.ELEMENT_NODE)
+ {
+ Element rule = (Element)c;
+ String filter = rule.getAttribute("filter");
+ if (filter.indexOf("format=packed") != -1)
+ {
+ if (filter.indexOf("classifier=osgi.bundle") != -1)
+ {
+ foundPackedBundleFilter = true;
+ }
+ else if (filter.indexOf("classifier=org.eclipse.update.feature") != -1)
+ {
+ foundPackedFeatureFilter = true;
+ }
+ if (foundPackedBundleFilter && foundPackedFeatureFilter)
+ {
+ break;
+ }
+ }
+ }
+ }
+ if (!foundPackedBundleFilter)
+ {
+ Element ruleElem = document.createElement("rule");
+ ruleElem.setAttribute("filter", "(& (classifier=osgi.bundle) (format=packed))");
+ ruleElem.setAttribute("output", "${repoUrl}/plugins/${id}_${version}.jar.pack.gz");
+ // Bug 356931 format=packed must be first rule in mappings
+ Node firstRule = mappingsEl.getFirstChild();
+ mappingsEl.insertBefore(ruleElem, firstRule);
+ documentWasModified = true;
+ }
+ if (!foundPackedFeatureFilter)
+ {
+ Element ruleElem = document.createElement("rule");
+ ruleElem.setAttribute("filter", "(& (classifier=org.eclipse.update.feature) (format=packed))");
+ ruleElem.setAttribute("output", "${repoUrl}/features/${id}_${version}.jar.pack.gz");
+ // Bug 356931 format=packed must be first rule in mappings
+ Node firstRule = mappingsEl.getFirstChild();
+ mappingsEl.insertBefore(ruleElem, firstRule);
+
+ documentWasModified = true;
+ }
+ //update the number of properties attribute
+ if (!foundPackedFeatureFilter || !foundPackedBundleFilter)
+ {
+ int size = mappingsEl.getElementsByTagName("rule").getLength();
+ mappingsEl.setAttribute("size", String.valueOf(size));
+ }
+
+ }//end of rules processor
+
+ if (documentWasModified)
+ {
+ Transformer txformer = TransformerFactory.newInstance().newTransformer();
+ DOMSource src = new DOMSource(document);
+ StreamResult res = new StreamResult(artifactsXml);
+ txformer.transform(src,res);
+ }
+ }
+ catch (Exception e)
+ {
+ getLog().error(e);
+ }
+
+ }
+
+ private String convert(byte[] bytes)
+ {
+ StringBuffer sb = new StringBuffer();
+
+ for (int i = 0; i < bytes.length; ++i)
+ {
+ sb.append(Character.forDigit((bytes[i] >> 4) & 0xf,16));
+ sb.append(Character.forDigit(bytes[i] & 0xf,16));
+ }
+ return sb.toString();
+ }
+
+ private void info(String log)
+ {
+ getLog().info("[FIX] " + log);
+ }
+
+ public static void main(String[] args ) throws Exception
+ {
+ String file = "org.eclipse.equinox.server.core_1.1.1.R37x_v20110907-7K7TFBYDzbeA3ypK_98cDL15A4A";
+ Pattern p = Pattern.compile("_\\d");
+
+ String[] bits = p.split(file);
+
+ System.out.println(file.substring(0, bits[0].length()) + " / " + file.substring(bits[0].length() + 1 , file.length()));
+
+
+
+
+ }
+
+
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/PackMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/PackMojo.java
new file mode 100644
index 0000000..bddae4c
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/PackMojo.java
@@ -0,0 +1,348 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses.
+//========================================================================
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/**
+ *
+ * @goal pack
+ * @phase package
+ * @description runs the eclipse packing process
+ */
+public class PackMojo extends AbstractEclipseSigningMojo
+{
+ private static final String __PACK_JAR = "org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar";
+
+ private static final String __PACK_PROPERTIES = "pack.properties";
+
+ /**
+ * zip file to be packed
+ *
+ * @parameter default-value= "${project.build.directory}/site_assembly.zip"
+ * @required
+ */
+ protected String inputFile;
+
+ /**
+ * directory monitor for artifact
+ *
+ * @parameter default-value="${project.build.directory}/packed"
+ * @required
+ */
+ protected String packedOutputDirectory;
+
+ /**
+ * directory for required bits
+ *
+ * @parameter default-value="${project.build.directory}/pack-stage"
+ * @required
+ */
+ protected String stagingDirectory;
+
+ /**
+ * location of pack200
+ *
+ * @parameter default-value="/shared/common/jdk-1.5.0-22.x86_64/bin"
+ * @required
+ */
+ protected String pack200;
+
+ /**
+ * @parameter default-value="/usr/local/bin/java"
+ * @required
+ */
+ protected String javaExecutable;
+
+ /** @parameter expression="${project}" */
+ protected MavenProject project;
+
+ /**
+ * List of patterns for a directory scanner to select the jars that must not be packed.
+ *
+ * @parameter
+ */
+ protected String packExclude;
+
+ /**
+ * when true, remove the pack.gz files to make sure no confusion will happen later.
+ *
+ * @parameter default-value="false"
+ * @required
+ */
+ protected boolean conditionOnly;
+
+ public void execute() throws MojoExecutionException, MojoFailureException
+ {
+ if (!FileUtils.fileExists(inputFile))
+ {
+ throw new MojoFailureException("file to pack does not exist! -> " + inputFile);
+ }
+
+ if (!FileUtils.fileExists(packedOutputDirectory))
+ {
+ info("creating directory to hold packed output");
+ FileUtils.mkdir(packedOutputDirectory);
+ }
+
+ if (!FileUtils.fileExists(stagingDirectory))
+ {
+ info("creating directory to hold pack staging bits");
+ FileUtils.mkdir(stagingDirectory);
+ }
+
+ if (new File(inputFile).isDirectory())
+ {
+
+ setupPackProperties(new File(inputFile),null);
+
+ ZipArchiver zipper = new ZipArchiver();
+ File destFile = new File(project.getBuild().getDirectory(),"repository-zipped/" + project.getArtifactId() + "-" + project.getVersion() + ".zip");
+
+ try
+ {
+ destFile.getParentFile().mkdirs();
+ zipper.addDirectory(new File(inputFile));
+ zipper.setDestFile(destFile);
+ zipper.createArchive();
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException("Error packing product",e);
+ }
+ inputFile = destFile.getAbsolutePath();
+ }
+
+ try
+ {
+ packLocally();
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException(e.getMessage(),e);
+ }
+
+ }
+
+ /**
+ * Some jars must not go through the packer. This is controlled via the pack.properties file at the root of the directory where jars are packed.
+ * <p>
+ * When the pack.properties file is copied, update the property pack.excludes for example:<br/>
+ * pack.excludes=plugins/com.ibm.icu.base_3.6.1.v20070417.jar,plugins/com. ibm.icu_3.6.1.v20070417.jar,plugins/com.jcraft.jsch_0.1.31.jar
+ * </p>
+ * <p>
+ * More doc here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=178723
+ * </p>
+ */
+ @SuppressWarnings("deprecation")
+ private void setupPackProperties(File targetRepo, File packPropertiesSource) throws MojoExecutionException
+ {
+ // pack.excludes=com.ibm.icu.base_3.6.1.v20070417.jar,com.ibm.icu_3.6.1.v20070417.jar,com.jcraft.jsch_0.1.31.jar
+ Properties props = new Properties();
+ InputStream inStream = null;
+ OutputStream outStream = null;
+ try
+ {
+ if (packPropertiesSource != null && packPropertiesSource.canRead())
+ {
+ props.load(inStream);
+ }
+ else
+ {
+ // put the default property:
+ props.put("pack200.default.args","-E4");
+ }
+ props.put("pack.excludes",getPackExcluded(targetRepo).toString());
+
+ File out = new File(targetRepo,__PACK_PROPERTIES);
+ if (!out.exists())
+ out.createNewFile();
+ outStream = new FileOutputStream(out);
+ props.save(outStream,"Pack.properties generated by the packmojo");
+ }
+ catch (IOException ioe)
+ {
+ throw new MojoExecutionException("Unable to setup the pack.properties file",ioe);
+ }
+ finally
+ {
+ if (inStream != null)
+ {
+ try
+ {
+ inStream.close();
+ }
+ catch (IOException ioe)
+ {
+ }
+ }
+ if (outStream != null)
+ {
+ try
+ {
+ outStream.close();
+ }
+ catch (IOException ioe)
+ {
+ }
+ }
+ }
+ }
+
+ private String getPackExcluded(File targetRepoDirectory)
+ {
+ StringBuilder patterns = new StringBuilder("artifacts.jar,content.jar");
+ if (packExclude != null)
+ {
+ patterns.append("," + packExclude);
+ }
+ DirectoryScanner scanner = new DirectoryScanner();
+ scanner.setBasedir(targetRepoDirectory);
+ StringTokenizer tokenizer = new StringTokenizer(patterns.toString(),", \r\n\t",false);
+ String[] incls = new String[tokenizer.countTokens()];
+ int i = 0;
+ while (tokenizer.hasMoreTokens())
+ {
+ String tok = tokenizer.nextToken();
+ incls[i] = tok;
+ i++;
+ }
+ scanner.setIncludes(incls);
+ scanner.scan();
+ String[] includedFiles = scanner.getIncludedFiles();
+ StringBuilder excluded = null;
+ for (String incl : includedFiles)
+ {
+ incl = incl.replace('\\','/');
+ if (excluded == null)
+ {
+ excluded = new StringBuilder(incl);
+ }
+ else
+ {
+ excluded.append("," + incl);
+ }
+ }
+ return excluded.toString();
+ }
+
+
+ private String[] generatePackExecuteString(String jarPackerLoc, String toPack, String outputDirectory)
+ {
+
+ // http://wiki.eclipse.org/index.php/Pack200
+ /*
+ * 3.5 style: java -cp org.eclipse.equinox.p2.jarprocessor_1.0.100.v20090520-1905.jar org.eclipse.equinox.internal.p2.jarprocessor.Main -processAll
+ * -repack -sign signing-script.sh -outputDir ./out eclipse-SDK.zip 3.6 syle: java -jar org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100123-1019.jar
+ * -processAll -repack -sign signing-script.sh -pack -outputDir ./out eclipse-SDK.zip
+ */
+ return new String[]
+ { "-Dorg.eclipse.update.jarprocessor.pack200=" + pack200, "-jar", jarPackerLoc, "-processAll", "-pack", "-repack",
+ // this does not work with the new version of the jar processor
+ /*
+ * "-f", FileUtils.dirname(jarPackerLoc) + File.separator + "pack.properties",
+ */
+ "-verbose", "-outputDir", outputDirectory, toPack };
+
+ }
+
+ private void positionPackJarForExecution() throws MojoExecutionException
+ {
+ info("getting jar packer into position");
+
+ URL jarPacker = this.getClass().getClassLoader().getResource(__PACK_JAR);
+ URL jarProperties = this.getClass().getClassLoader().getResource(__PACK_PROPERTIES);
+ try
+ {
+ FileUtils.copyURLToFile(jarPacker,new File(stagingDirectory + File.separator + __PACK_JAR));
+ FileUtils.copyURLToFile(jarProperties,new File(stagingDirectory + File.separator + __PACK_PROPERTIES));
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ throw new MojoExecutionException("unable to position jar packer",e);
+ }
+ }
+
+ private void packLocally() throws Exception
+ {
+
+ if (!FileUtils.fileExists(packedOutputDirectory))
+ {
+ info("creating directory to hold packed output");
+ FileUtils.mkdir(packedOutputDirectory);
+ }
+
+ try
+ {
+ String packTempDirectory = stagingDirectory + File.separator + UUID.randomUUID().toString();
+
+ FileUtils.mkdir(packTempDirectory);
+
+ FileUtils.copyFileToDirectory(inputFile,packTempDirectory);
+
+ CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
+ CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
+
+ positionPackJarForExecution();
+
+ Commandline pack = new Commandline();
+ pack.setWorkingDirectory(FileUtils.dirname(packTempDirectory));
+ pack.setExecutable(javaExecutable);
+ pack.addArguments(generatePackExecuteString(stagingDirectory + "/" + __PACK_JAR,inputFile,packedOutputDirectory));
+
+ info("executing pack200, output at end of execution : " + pack);
+ CommandLineUtils.executeCommandLine(pack,out,err);
+
+ String packErrput = IOUtil.toString(new StringReader(err.getOutput()));
+ String packOutput = IOUtil.toString(new StringReader(out.getOutput()));
+
+ info("pack200 output:\n" + packOutput);
+ if (packErrput != null || !"".equals(packErrput))
+ {
+ getLog().error(packErrput);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ getLog().error(e);
+ }
+ }
+
+ private void info(String log)
+ {
+ getLog().info("[PACK] " + log);
+ }
+
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/RepackMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/RepackMojo.java
new file mode 100644
index 0000000..fbd06e3
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/RepackMojo.java
@@ -0,0 +1,350 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.StringReader;
+import java.net.URL;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses.
+//========================================================================
+
+
+/**
+ *
+ * @goal repack
+ * @phase package
+ * @description runs the eclipse packing process
+ */
+public class RepackMojo extends AbstractEclipseSigningMojo
+{
+
+ private static final String __PACK_JAR = "org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar";
+
+ private static final String __PACK_PROPERTIES = "pack.properties";
+
+ /**
+ * zip file to be packed
+ *
+ * @parameter default-value= "${project.build.directory}/signed/site_assembly.zip"
+ * @required
+ */
+ protected String inputFile;
+
+ /**
+ * directory monitor for artifact
+ *
+ * @parameter default-value="${project.build.directory}/packed"
+ * @required
+ */
+ protected String packedOutputDirectory;
+
+ /**
+ * directory for required bits
+ *
+ * @parameter default-value="${project.build.directory}/pack-stage"
+ * @required
+ */
+ protected String stagingDirectory;
+
+ /**
+ * location of pack200
+ *
+ * @parameter default-value="/shared/common/jdk-1.5.0-22.x86_64/bin"
+ * @required
+ */
+ protected String pack200;
+
+ /**
+ * @parameter default-value="/usr/local/bin/java"
+ * @required
+ */
+ protected String javaExecutable;
+
+ /** @parameter expression="${project}" */
+ protected MavenProject project;
+
+ /**
+ * List of patterns for a directory scanner to select the jars that must not be packed.
+ *
+ * @parameter
+ */
+ protected String packExclude;
+
+ /**
+ * when true, remove the pack.gz files to make sure no confusion will happen later.
+ *
+ * @parameter default-value="false"
+ * @required
+ */
+ protected boolean conditionOnly;
+
+ public void execute() throws MojoExecutionException, MojoFailureException
+ {
+ if (!FileUtils.fileExists(inputFile))
+ {
+ throw new MojoFailureException("file to pack does not exist! -> " + inputFile);
+ }
+
+ if (!FileUtils.fileExists(packedOutputDirectory))
+ {
+ info("creating directory to hold packed output");
+ FileUtils.mkdir(packedOutputDirectory);
+ }
+
+ if (!FileUtils.fileExists(stagingDirectory))
+ {
+ info("creating directory to hold pack staging bits");
+ FileUtils.mkdir(stagingDirectory);
+ }
+
+ if (new File(inputFile).isDirectory())
+ {
+
+ setupPackProperties(new File(inputFile),null);
+
+ ZipArchiver zipper = new ZipArchiver();
+ File destFile = new File(project.getBuild().getDirectory(),"repository-zipped/" + project.getArtifactId() + "-" + project.getVersion() + ".zip");
+
+ try
+ {
+ destFile.getParentFile().mkdirs();
+ zipper.addDirectory(new File(inputFile));
+ zipper.setDestFile(destFile);
+ zipper.createArchive();
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException("Error packing product",e);
+ }
+ inputFile = destFile.getAbsolutePath();
+ }
+
+ try
+ {
+ packLocally();
+ }
+ catch (Exception e)
+ {
+ throw new MojoExecutionException(e.getMessage(),e);
+ }
+
+ }
+
+ /**
+ * Some jars must not go through the packer. This is controlled via the pack.properties file at the root of the directory where jars are packed.
+ * <p>
+ * When the pack.properties file is copied, update the property pack.excludes for example:<br/>
+ * pack.excludes=plugins/com.ibm.icu.base_3.6.1.v20070417.jar,plugins/com. ibm.icu_3.6.1.v20070417.jar,plugins/com.jcraft.jsch_0.1.31.jar
+ * </p>
+ * <p>
+ * More doc here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=178723
+ * </p>
+ */
+ @SuppressWarnings("deprecation")
+ private void setupPackProperties(File targetRepo, File packPropertiesSource) throws MojoExecutionException
+ {
+ // pack.excludes=com.ibm.icu.base_3.6.1.v20070417.jar,com.ibm.icu_3.6.1.v20070417.jar,com.jcraft.jsch_0.1.31.jar
+ Properties props = new Properties();
+ InputStream inStream = null;
+ OutputStream outStream = null;
+ try
+ {
+ if (packPropertiesSource != null && packPropertiesSource.canRead())
+ {
+ props.load(inStream);
+ }
+ else
+ {
+ // put the default property:
+ props.put("pack200.default.args","-E4");
+ }
+ props.put("pack.excludes",getPackExcluded(targetRepo).toString());
+
+ File out = new File(targetRepo,__PACK_PROPERTIES);
+ if (!out.exists())
+ out.createNewFile();
+ outStream = new FileOutputStream(out);
+ props.save(outStream,"Pack.properties generated by the packmojo");
+ }
+ catch (IOException ioe)
+ {
+ throw new MojoExecutionException("Unable to setup the pack.properties file",ioe);
+ }
+ finally
+ {
+ if (inStream != null)
+ {
+ try
+ {
+ inStream.close();
+ }
+ catch (IOException ioe)
+ {
+ }
+ }
+ if (outStream != null)
+ {
+ try
+ {
+ outStream.close();
+ }
+ catch (IOException ioe)
+ {
+ }
+ }
+ }
+ }
+
+ private String getPackExcluded(File targetRepoDirectory)
+ {
+ StringBuilder patterns = new StringBuilder("artifacts.jar,content.jar");
+ if (packExclude != null)
+ {
+ patterns.append("," + packExclude);
+ }
+ DirectoryScanner scanner = new DirectoryScanner();
+ scanner.setBasedir(targetRepoDirectory);
+ StringTokenizer tokenizer = new StringTokenizer(patterns.toString(),", \r\n\t",false);
+ String[] incls = new String[tokenizer.countTokens()];
+ int i = 0;
+ while (tokenizer.hasMoreTokens())
+ {
+ String tok = tokenizer.nextToken();
+ incls[i] = tok;
+ i++;
+ }
+ scanner.setIncludes(incls);
+ scanner.scan();
+ String[] includedFiles = scanner.getIncludedFiles();
+ StringBuilder excluded = null;
+ for (String incl : includedFiles)
+ {
+ incl = incl.replace('\\','/');
+ if (excluded == null)
+ {
+ excluded = new StringBuilder(incl);
+ }
+ else
+ {
+ excluded.append("," + incl);
+ }
+ }
+ return excluded.toString();
+ }
+
+
+ private String[] generatePackExecuteString(String jarPackerLoc, String toPack, String outputDirectory)
+ {
+
+ // http://wiki.eclipse.org/index.php/Pack200
+ /*
+ * 3.5 style: java -cp org.eclipse.equinox.p2.jarprocessor_1.0.100.v20090520-1905.jar org.eclipse.equinox.internal.p2.jarprocessor.Main -processAll
+ * -repack -sign signing-script.sh -outputDir ./out eclipse-SDK.zip 3.6 syle: java -jar org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100123-1019.jar
+ * -processAll -repack -sign signing-script.sh -pack -outputDir ./out eclipse-SDK.zip
+ */
+ return new String[]
+ { "-Dorg.eclipse.update.jarprocessor.pack200=" + pack200, "-jar", jarPackerLoc, "-processAll", "-pack", "-repack",
+ // this does not work with the new version of the jar processor
+ /*
+ * "-f", FileUtils.dirname(jarPackerLoc) + File.separator + "pack.properties",
+ */
+ "-verbose", "-outputDir", outputDirectory, toPack };
+
+ }
+
+ private void positionPackJarForExecution() throws MojoExecutionException
+ {
+ info("getting jar packer into position");
+
+ URL jarPacker = this.getClass().getClassLoader().getResource(__PACK_JAR);
+ URL jarProperties = this.getClass().getClassLoader().getResource(__PACK_PROPERTIES);
+ try
+ {
+ FileUtils.copyURLToFile(jarPacker,new File(stagingDirectory + File.separator + __PACK_JAR));
+ FileUtils.copyURLToFile(jarProperties,new File(stagingDirectory + File.separator + __PACK_PROPERTIES));
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ throw new MojoExecutionException("unable to position jar packer",e);
+ }
+ }
+
+ private void packLocally() throws Exception
+ {
+
+ if (!FileUtils.fileExists(packedOutputDirectory))
+ {
+ info("creating directory to hold packed output");
+ FileUtils.mkdir(packedOutputDirectory);
+ }
+
+ try
+ {
+ String packTempDirectory = stagingDirectory + File.separator + UUID.randomUUID().toString();
+
+ FileUtils.mkdir(packTempDirectory);
+
+ FileUtils.copyFileToDirectory(inputFile,packTempDirectory);
+
+ CommandLineUtils.StringStreamConsumer out = new CommandLineUtils.StringStreamConsumer();
+ CommandLineUtils.StringStreamConsumer err = new CommandLineUtils.StringStreamConsumer();
+
+ positionPackJarForExecution();
+
+ Commandline pack = new Commandline();
+ pack.setWorkingDirectory(FileUtils.dirname(packTempDirectory));
+ pack.setExecutable(javaExecutable);
+ pack.addArguments(generatePackExecuteString(stagingDirectory + "/" + __PACK_JAR,inputFile,packedOutputDirectory));
+
+ info("executing pack200, output at end of execution : " + pack);
+ CommandLineUtils.executeCommandLine(pack,out,err);
+
+ String packErrput = IOUtil.toString(new StringReader(err.getOutput()));
+ String packOutput = IOUtil.toString(new StringReader(out.getOutput()));
+
+ info("pack200 output:\n" + packOutput);
+ if (packErrput != null || !"".equals(packErrput))
+ {
+ getLog().error(packErrput);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ getLog().error(e);
+ }
+ }
+
+ private void info(String log)
+ {
+ getLog().info("[PACK] " + log);
+ }
+
+}
diff --git a/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/SignMojo.java b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/SignMojo.java
new file mode 100644
index 0000000..12f0f9b
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/java/org/eclipse/dash/m4e/eclipse/signing/SignMojo.java
@@ -0,0 +1,374 @@
+package org.eclipse.dash.m4e.eclipse.signing;
+
+//========================================================================
+//Copyright (c) 2010 Intalio, Inc.
+//------------------------------------------------------------------------
+//All rights reserved. This program and the accompanying materials
+//are made available under the terms of the Eclipse Public License v1.0
+//and Apache License v2.0 which accompanies this distribution.
+//The Eclipse Public License is available at
+//http://www.eclipse.org/legal/epl-v10.html
+//The Apache License v2.0 is available at
+//http://www.opensource.org/licenses/apache2.0.php
+//You may elect to redistribute this code under either of these licenses.
+//========================================================================
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.wagon.CommandExecutor;
+import org.apache.maven.wagon.Streams;
+import org.apache.maven.wagon.Wagon;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.archiver.util.DefaultFileSet;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
+import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
+import org.codehaus.plexus.components.io.fileselectors.FileInfo;
+import org.codehaus.plexus.components.io.fileselectors.FileSelector;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ *
+ * @goal sign
+ * @phase package
+ * @description runs the eclipse signing process
+ */
+public class SignMojo extends AbstractEclipseSigningMojo
+{
+
+ /**
+ * Accepted values are 'local' and 'remote'
+ *
+ * @parameter default-value="local"
+ * @required
+ */
+ protected String execute;
+
+ /**
+ * zip file to get signed
+ *
+ * @parameter default-value= "${project.build.directory}/packed/site_assembly.zip"
+ * @required
+ */
+ protected String inputFile;
+
+ /**
+ * zip file to get signed
+ *
+ * @parameter default-value= "${project.build.directory}/signed/site_assembly.zip"
+ * @required
+ */
+ protected String outputFile;
+
+ /**
+ * directory to send artifact to be signed
+ *
+ * should be akin to: /home/data/httpd/download-staging.priv/rt/<project>
+ *
+ * @parameter
+ * @required
+ */
+ protected String signerInputDirectory;
+
+ /**
+ * directory monitor for signed artifact
+ *
+ * @parameter
+ */
+ protected String signerOutputDirectory;
+
+ /**
+ * directory monitor interval for signed artifact
+ *
+ * @parameter default-value="60000"
+ * @required
+ */
+ protected int zipCheckInterval;
+
+ /**
+ * directory monitor for signed artifact
+ *
+ * @parameter default-value="30"
+ * @required
+ */
+ protected int maxZipChecks;
+
+ /** @component */
+ protected PlexusContainer plexus;
+
+ public void execute() throws MojoExecutionException, MojoFailureException
+ {
+
+ if (!FileUtils.fileExists(inputFile))
+ throw new MojoExecutionException("zip file does not exist - " + inputFile);
+
+ try
+ {
+
+ if (!FileUtils.fileExists(FileUtils.dirname(outputFile)))
+ {
+ info("creating directory to hold signed artifact");
+ FileUtils.mkdir(FileUtils.dirname(outputFile));
+ }
+
+ System.err.println("input file " + inputFile);
+
+ // remove the *.pack.gz if any:
+ File in = new File(inputFile);
+ ZipUnArchiver unarchive = (ZipUnArchiver)plexus.lookup(ZipUnArchiver.ROLE,"zip");
+ File dest = new File(in.getParentFile(),"repository");
+ dest.mkdir();
+ unarchive.setDestDirectory(dest);
+ unarchive.setSourceFile(in);
+ unarchive.setFileSelectors(new FileSelector[]
+ { new FileSelector()
+ {
+ public boolean isSelected(FileInfo arg0) throws IOException
+ {
+ return !arg0.getName().endsWith(".pack.gz");
+ }
+
+ } });
+ System.err.println(unarchive.getSourceFile() + " - unarchived into - " + unarchive.getDestDirectory());
+ System.err.println(unarchive.getSourceFile().getAbsolutePath() + " unarchived into " + unarchive.getDestDirectory().getAbsolutePath());
+ unarchive.extract();// path, new File(in.getParentFile(), "repository"));
+
+ FileUtils.rename(in,new File(in.getParentFile(),in.getName() + "-before-removing-pack-gz.zip"));
+
+ ZipArchiver archiver = (ZipArchiver)plexus.lookup(ZipArchiver.ROLE,"zip");// new ZipArchiver();
+ // archiver.addDirectory(unarchive.getDestDirectory(), "repository");//, new String[] {"**/*.jar"}, new String[] {"**/*.pack.gz"});
+ DefaultFileSet fileset = new DefaultFileSet();
+ fileset.setDirectory(unarchive.getDestDirectory());
+ fileset.setFileSelectors(new FileSelector[]
+ { new FileSelector()
+ {
+ public boolean isSelected(FileInfo arg0) throws IOException
+ {
+ System.err.println("looking at " + arg0.getName());
+ return !arg0.getName().endsWith(".pack.gz");
+ }
+
+ } });
+ archiver.addFileSet(fileset);
+ File tmpDest = new File(in.getParentFile(),in.getName() + "-after-removing.zip");
+ archiver.setDestFile(tmpDest);
+ System.err.println("....archive " + unarchive.getDestDirectory() + " into " + new File(inputFile).getAbsolutePath());
+ archiver.createArchive();
+ FileUtils.copyFile(tmpDest,in);
+
+ if ("local".equals(execute))
+ {
+ signLocally();
+ }
+ else if ("remote".equals(execute))
+ {
+ signRemotely();
+ }
+
+ }
+ catch (Exception e)
+ {
+ getLog().error(e);
+ if (e instanceof MojoExecutionException)
+ {
+ throw (MojoExecutionException)e;
+ }
+ if (e instanceof MojoFailureException)
+ {
+ throw (MojoFailureException)e;
+ }
+ }
+ }
+
+ private void signLocally() throws Exception
+ {
+ signerInputDirectory = signerInputDirectory + File.separator + UUID.randomUUID().toString();
+
+ signerOutputDirectory = signerInputDirectory + File.separator + "signed";
+
+ FileUtils.mkdir(signerInputDirectory);
+
+ if (!FileUtils.fileExists(signerInputDirectory))
+ {
+ throw new MojoFailureException("Unable to create the directory " + signerInputDirectory);
+ }
+
+ FileUtils.mkdir(signerOutputDirectory);
+ FileUtils.copyFile(new File(inputFile),new File(signerInputDirectory + File.separator + FileUtils.filename(inputFile)));
+
+ Process pc = Runtime.getRuntime().exec(new String[]
+ { "/bin/chmod", "-R", "ugo+rw", signerInputDirectory });
+ pc.waitFor();
+
+ Process ps = Runtime.getRuntime().exec(new String[]
+ { "/usr/bin/sign", signerInputDirectory + File.separator + FileUtils.filename(inputFile), "nomail", signerOutputDirectory });
+
+ BufferedReader is = new BufferedReader(new InputStreamReader(ps.getInputStream()));
+
+ String liner;
+ while ((liner = is.readLine()) != null)
+ System.out.println(liner);
+
+ System.out.println("In Main after EOF");
+ System.out.flush();
+ try
+ {
+ ps.waitFor(); // wait for process to complete
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println(e); // "Can'tHappen"
+ return;
+ }
+
+ boolean keepChecking = true;
+ int count = 0;
+ while (keepChecking && count < maxZipChecks)
+ {
+ try
+ {
+ info("monitoring for signed file in " + signerOutputDirectory);
+ ++count;
+ Thread.sleep(zipCheckInterval);
+
+
+ @SuppressWarnings("unchecked")
+ List<String> signedDirList = FileUtils.getFileNames(new File(signerOutputDirectory),"**",null,true);
+
+ info("signed dir output: " + signedDirList.size());
+
+ for (String line : signedDirList)
+ {
+ getLog().info("-> " + line);
+ }
+
+ if (signedDirList.size() == 1) // . .. signed file
+ {
+ // if ( FileUtils.filename(toSignZipFile).equals(signedDirList.get(0)))
+ // {
+ info("found the signed file");
+ keepChecking = false;
+ // }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ if (count == maxZipChecks)
+ {
+ getLog().error("signer process never signaled completion");
+ FileUtils.deleteDirectory(signerInputDirectory);
+ return;
+ }
+ else
+ {
+ getLog().info("copying signed artifact to :" + outputFile);
+ FileUtils.copyFile(new File(signerOutputDirectory + File.separator + FileUtils.filename(inputFile)),new File(outputFile));
+ FileUtils.deleteDirectory(signerInputDirectory);
+ return;
+ }
+
+ }
+
+ private void signRemotely() throws Exception
+ {
+ Wagon wagon = createWagon(serverId,getWagonUrl());
+
+ CommandExecutor exec = getCommandExecutor(wagon);
+
+ signerInputDirectory = UUID.randomUUID().toString();
+
+ signerOutputDirectory = signerInputDirectory + File.separator + "signed";
+
+ info("creating remote input directory");
+ exec.executeCommand("/bin/mkdir -p " + signerInputDirectory);
+
+ info("setting permissions");
+ exec.executeCommand("/bin/mkdir -p " + signerOutputDirectory);
+
+ info("copying file to sign to remote directory");
+ wagon.put(new File(inputFile),signerInputDirectory + File.separator + FileUtils.filename(inputFile));
+
+ info("setting permissions on file");
+ exec.executeCommand("/bin/chmod -R ugo+rw " + signerInputDirectory);
+
+ info("calling sign script");
+ info("/usr/bin/sign " + adjustToWagonPath(signerInputDirectory) + File.separator + FileUtils.filename(inputFile) + " nomail signed");
+
+ Streams s = exec.executeCommand("/usr/bin/sign " + adjustToWagonPath(signerInputDirectory) + File.separator + FileUtils.filename(inputFile)
+ + " nomail signed",false);
+
+ info("sign script output\n" + s.getOut());
+
+ boolean keepChecking = true;
+ int count = 0;
+ while (keepChecking && count < maxZipChecks)
+ {
+ try
+ {
+ info("monitoring for signed file");
+ ++count;
+ Thread.sleep(zipCheckInterval);
+
+ @SuppressWarnings("unchecked")
+ List<String> signedDirList = exec.getFileList(signerOutputDirectory);
+
+ info("signed dir output:");
+
+ for (String line : signedDirList)
+ {
+ getLog().info("-> " + line);
+ }
+
+ if (signedDirList.size() == 1) // . .. signed file
+ {
+ // if ( FileUtils.filename(toSignZipFile).equals(signedDirList.get(0)))
+ // {
+ info("found the signed file");
+ keepChecking = false;
+ // }
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ if (count == maxZipChecks)
+ {
+ getLog().error("signer process never signaled completion");
+ cleanup(exec,signerInputDirectory);
+ return;
+ }
+ else
+ {
+ getLog().info("copying signed artifact to :" + outputFile);
+ wagon.get(signerOutputDirectory + File.separator + FileUtils.filename(inputFile),new File(outputFile));
+ cleanup(exec,signerInputDirectory);
+ return;
+ }
+
+ }
+
+ private void cleanup(CommandExecutor exec, String signerInputDirectory) throws Exception
+ {
+ exec.executeCommand("/bin/rm -Rf " + adjustToWagonPath(signerInputDirectory));
+ // FileUtils.removePath(signerInputDirectory);
+ // FileUtils.removePath(signerOutputDirectory);
+ }
+
+ private void info(String log)
+ {
+ getLog().info("[SIGN] " + log);
+ }
+}
diff --git a/eclipse-signing-maven-plugin/src/main/resources/org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar b/eclipse-signing-maven-plugin/src/main/resources/org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar
new file mode 100644
index 0000000..5149366
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/resources/org.eclipse.equinox.p2.jarprocessor_1.0.200.v20100503a.jar
Binary files differ
diff --git a/eclipse-signing-maven-plugin/src/main/resources/pack.properties b/eclipse-signing-maven-plugin/src/main/resources/pack.properties
new file mode 100644
index 0000000..b212c86
--- /dev/null
+++ b/eclipse-signing-maven-plugin/src/main/resources/pack.properties
@@ -0,0 +1,2 @@
+pack200.default.args=-E4
+pack.excludes=eclipse/plugins/@excludejars@
\ No newline at end of file