Blame | Last modification | View Log | RSS feed
package com.erggroup.mass.ant.taskdefs;import java.io.*;import java.util.*;import java.util.zip.*;import org.apache.tools.ant.*;import org.apache.tools.ant.taskdefs.*;import org.apache.tools.ant.types.*;/*** Custom ANT task - given a code JAR and a source base, build a JAR* containing the corresponding source code.** @ant.examples Here are examples**/public class JarSrc extends Task{/*** The binary source file; the src jar will be constructed with a* corresponding name (-src) and will contain the code counterparts.*/private String binary;/*** The location that the source file will be created in.*/private String toDir;/*** The FileSet indicating which corresponding source files should be* obtained (if they exist) from the source path.*/private FileSet correspondingFileSet = null;/*** The set of directories under which the source code is located in* its' expected location.*/private ArrayList dirsets = new ArrayList();/*** Set the filename of the source file. This file is used as a basis* for emulation, by constructing a src package to match.** @param value the filename.*/public void setBinary( String value ){binary = value;}/*** Set the 'todir', being the directory location in which the source* file will be constructed.** @param value the directory.*/public void setToDir( String value ){toDir = value;}/*** Nested element - this tag supports nested 'DirSet' elements.*/public DirSet createDirSet(){DirSet dirset = new DirSet();dirsets.add( dirset );return dirset;}/****/public void execute() throws BuildException{if ( dirsets.size() == 0 ){throw new BuildException("At least one DirSet must be provided");}for ( Iterator i=dirsets.iterator(); i.hasNext(); ){DirSet dirset = (DirSet)i.next();FileScanner scanner = dirset.getDirectoryScanner( getProject() );String[] directories = scanner.getIncludedDirectories();File basedir = scanner.getBasedir();for ( int j=0; j<directories.length; j++ ){File srcDirectory = new File( basedir, directories[j] );packageSource( srcDirectory );}}}/****/private void packageSource( File srcDir ) throws BuildException{log("Packaging source from '" + srcDir + "'", Project.MSG_VERBOSE );FileSet corresponding = null;try{corresponding = getCorrespondingNames();corresponding.setDir( srcDir );}catch (IOException x){throw new BuildException( "Could not read binary '" + binary + "'", x);}File binarySource = new File( srcDir, binary );String binaryName = binarySource.getName();String destName = binaryName.substring(0, binaryName.lastIndexOf("."));destName += "-src.jar";File destDir = new File( toDir );File destFile = new File( toDir, destName );// Check that the corresponding src JAR exists; if not, create one.Jar jarTask = new Jar();jarTask.setTaskName(this.getTaskName());jarTask.setProject( getProject() );jarTask.setDestFile( destFile );jarTask.setUpdate(true);jarTask.addFileset( corresponding );jarTask.execute();}/*** Get the corresponding java source names (as a FileSet), by* using the configured 'binary'.** @return a FileSet containing a list of the expected source* files.** @throws IOException if the binary could not be read.*/private FileSet getCorrespondingNames() throws IOException{if ( correspondingFileSet == null ){FileSet corresponding = new FileSet();corresponding.setProject( getProject() );ZipFile zf = null;try{log("Loading from source binary '" + binary + "'", Project.MSG_VERBOSE );zf = new ZipFile(binary);Enumeration l_enum = zf.entries();while (l_enum.hasMoreElements()){ZipEntry ze = (ZipEntry)l_enum.nextElement();String entryName = ze.getName();if ( entryName.endsWith( ".class" ) ){String correspondingName = entryName.substring(0, entryName.indexOf(".class") );correspondingName += ".java";log("Adding '" + correspondingName + "' to FileSet", Project.MSG_VERBOSE );corresponding.setIncludes( correspondingName );}}}finally{if (zf != null){try{zf.close();}catch (IOException e){}}}correspondingFileSet = corresponding;}return correspondingFileSet;}}