/*******************************************************************************
* Copyright 2013 Geoscience Australia
*
* Licensed 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 au.gov.ga.earthsci.ant;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.FileSet;
/**
* Ant task that generates a script that can sign (and optionally pack) a
* fileset of jars using a keystore.
*
* @author Michael de Hoog (michael.dehoog@ga.gov.au)
*/
public class GenerateSignScript extends Task
{
private String filename;
private boolean pack;
private List<FileSet> filesets = new ArrayList<FileSet>();
private String keystore;
private String alias;
private String storepass;
private String firstline;
public void setFilename(String filename)
{
this.filename = filename;
}
public void setPack(boolean pack)
{
this.pack = pack;
}
public void addFileset(FileSet fileset)
{
filesets.add(fileset);
}
public void setKeystore(String keystore)
{
this.keystore = keystore;
}
public void setAlias(String alias)
{
this.alias = alias;
}
public void setStorepass(String password)
{
this.storepass = password;
}
public void setFirstline(String firstline)
{
this.firstline = firstline;
}
@Override
public void execute() throws BuildException
{
if (filename == null || filename.isEmpty())
{
throw new BuildException("Sign script filename not specified");
}
if (keystore == null || keystore.isEmpty())
{
throw new BuildException("Keystore not specified");
}
if (alias == null || alias.isEmpty())
{
throw new BuildException("Alias not specified");
}
File scriptFile = new File(filename);
File scriptDirectory = scriptFile.getParentFile();
List<File> files = new ArrayList<File>();
for (FileSet fileset : filesets)
{
DirectoryScanner directoryScanner = fileset.getDirectoryScanner(getProject());
String[] includedFiles = directoryScanner.getIncludedFiles();
for (String filename : includedFiles)
{
if (!filename.toLowerCase().endsWith(".jar"))
{
//skip non-jar files
continue;
}
File base = directoryScanner.getBasedir();
File file = new File(base, filename);
File relative;
try
{
relative = Util.getRelativeFile(file, scriptDirectory);
}
catch (IOException e)
{
throw new BuildException("Error generating relative path", e);
}
files.add(relative);
}
}
String newline = System.getProperty("line.separator");
StringBuilder sb = new StringBuilder();
if (firstline != null && !firstline.isEmpty())
{
sb.append(firstline + newline + newline);
}
String keystore = this.keystore;
try
{
File relativeKeystore = Util.getRelativeFile(new File(keystore), scriptDirectory);
keystore = relativeKeystore.getPath();
}
catch (IOException e)
{
throw new BuildException("Error generating relative keystore path", e);
}
String jarsignerPrefix = "jarsigner -keystore \"" + keystore + "\" ";
if (storepass != null && !storepass.isEmpty())
{
jarsignerPrefix += "-storepass \"" + storepass.replaceAll("\"", "\\\"") + "\" ";
}
String jarsignerSuffix = " " + "\"" + alias + "\"";
for (File file : files)
{
sb.append(jarsignerPrefix + "\"" + file.getPath() + "\"" + jarsignerSuffix + newline);
}
if (pack)
{
sb.append(newline);
for (File file : files)
{
String path = file.getPath();
String packPath = path.substring(0, path.length() - 4) + ".pack.gz";
sb.append("pack200 \"" + packPath + "\" \"" + path + "\"" + newline);
}
}
try
{
FileOutputStream fos = new FileOutputStream(scriptFile);
fos.write(sb.toString().getBytes());
fos.close();
}
catch (IOException e)
{
throw new BuildException("Error writing sign script file", e);
}
}
}