/*
* ALMA - Atacama Large Millimiter Array
* (c) European Southern Observatory, 2002
* Copyright by ESO (in the framework of the ALMA collaboration),
* All rights reserved
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
package alma.acs.makesupport;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
import java.util.logging.Logger;
/**
* Creates a jar file with java sources copied from inside jar files that are found
* in a number of given directories.
* <p>
* The java source files are allowed to be stored with a prefix path "src" or "test"
* inside the jar files. The constructed jar file will not use any prefix path though.
*
* @author hsommer
* created Sep 23, 2003 10:50:00 AM
*/
public class JarSourceExtractorRunner
{
public static final String PROPERTY_EXTRACT_ONLY_GENERATED_JARS = "jarExtract.onlyGeneratedJars";
public final static String Manifest_Attr_ACSGeneratedFromFile = "ACS-Generated-FromFile";
/**
* First argument must be the jar file name to which all Java sources
* @param args
*/
public static void main(String[] args)
{
if (args.length < 2)
{
System.err.println("usage: " + JarSourceExtractorRunner.class.getName() +
" outputJarFile jarDirectory1 jarDirectory2 ...");
return;
}
try
{
Logger logger = Logger.getLogger("ACS.JarSourceExtractorRunner");
// set up output jar file
File targetJarFile = new File(args[0]);
if (targetJarFile.exists())
{
targetJarFile.delete();
}
else
{
File parent = targetJarFile.getParentFile();
if (parent != null)
{
parent.mkdirs();
}
}
targetJarFile.createNewFile();
if (!targetJarFile.isFile() || !targetJarFile.canWrite())
{
throw new IOException(targetJarFile + " is not a writable file.");
}
// get all input jar files
File[] dirs = getDirectories(args);
AcsJarFileFinder jarFinder = new AcsJarFileFinder(dirs, logger);
File[] jarFiles = jarFinder.getAllFiles();
// extract java sources
if (jarFiles.length > 0)
{
JarSourceExtractor extractor = new JarSourceExtractor();
FileOutputStream out = new FileOutputStream(targetJarFile);
JarOutputStream jarOut = new JarOutputStream(out);
try {
for (int i = 0; i < jarFiles.length; i++) {
JarFile jarFile = new JarFile(jarFiles[i]);
if (needsProcessing(jarFile)) {
extractor.extractJavaSourcesToJar(jarFile, jarOut);
}
}
}
finally {
jarOut.finish();
jarOut.close();
}
}
else
{
System.out.println("no jar files found.");
}
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
/**
* Encapsulates evaluation of possible flags (properties) that may restrict the set of jar files to be processed
* for source extraction, for example based on the manifest information.
* <p>
* Currently only looks at the boolean property <code>jarExtract.onlyGeneratedJars</code>.
*
* @param jarFile
* @return
* @throws IOException
*/
static boolean needsProcessing(JarFile jarFile) throws IOException {
// flag to
boolean onlyGeneratedJars = Boolean.getBoolean(PROPERTY_EXTRACT_ONLY_GENERATED_JARS);
boolean needed = !onlyGeneratedJars;
// only look inside if we are not already sure that this jar file is needed
if (!needed) {
Manifest mani = jarFile.getManifest();
if (mani != null) {
Map<String, Attributes> entries = mani.getEntries();
// System.out.println("\n\nManifest for file " + jarFile.getName());
Attributes mainAttrs = mani.getMainAttributes();
for (Iterator mainAttrIter = mainAttrs.keySet().iterator(); mainAttrIter.hasNext();) {
String attr = ((Attributes.Name) mainAttrIter.next()).toString();
String value = mainAttrs.getValue(attr);
if (attr.equals(Manifest_Attr_ACSGeneratedFromFile)) {
needed = true;
break;
}
// System.out.println(attr + "=" + value);
}
}
}
return needed;
}
/**
* Identifies valid directories from the argument list.
*
* @param mainArgs arguments supplied to main method;
* directories are given at indices 1...n
* @return the valid directories as File objects
* @throws Exception
*/
static File[] getDirectories(String[] mainArgs)
{
List<File> dirList = new ArrayList<File>();
for (int i = 1; i < mainArgs.length; i++)
{
File jarDir = new File(mainArgs[i]);
if (jarDir.exists() && jarDir.isDirectory())
{
dirList.add(jarDir);
}
else
{
System.err.println("ignoring invalid directory " + jarDir.getAbsolutePath());
}
}
return (File[]) dirList.toArray(new File[dirList.size()]);
}
}