Subversion Repositories DevTools

Rev

Rev 1615 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1615 mhunt 1
package com.erggroup.mass.ant.taskdefs;
2
 
3
import java.io.*;
4
import java.util.*;
5
import java.util.zip.*;
6
import org.apache.tools.ant.*;
7
import org.apache.tools.ant.taskdefs.*;
8
import org.apache.tools.ant.types.*;
9
 
10
 
11
/**
1619 skinsman 12
 * Custom ANT task - given a code JAR and a source base, build a JAR
1615 mhunt 13
 * containing the corresponding source code.
1619 skinsman 14
 *
1615 mhunt 15
 * @ant.examples Here are examples
1619 skinsman 16
 *
1615 mhunt 17
 */
18
public class JarSrc extends Task
19
{
20
	/**
21
	 * The binary source file; the src jar will be constructed with a
22
	 * corresponding name (-src) and will contain the code counterparts.
23
	 */
24
	private String binary;
25
 
26
	/**
27
	 * The location that the source file will be created in.
1619 skinsman 28
	 */
1615 mhunt 29
	private String toDir;
1619 skinsman 30
 
1615 mhunt 31
	/**
32
	 * The FileSet indicating which corresponding source files should be
33
	 * obtained (if they exist) from the source path.
34
	 */
35
	private FileSet correspondingFileSet = null;
1619 skinsman 36
 
1615 mhunt 37
	/**
38
	 * The set of directories under which the source code is located in
39
	 * its' expected location.
40
	 */
1619 skinsman 41
	private ArrayList dirsets = new ArrayList();
42
 
1615 mhunt 43
	/**
44
	 * Set the filename of the source file. This file is used as a basis
45
	 * for emulation, by constructing a src package to match.
1619 skinsman 46
	 *
1615 mhunt 47
	 * @param value the filename.
48
	 */
49
	public void setBinary( String value )
50
	{
51
		binary = value;
52
	}
53
 
54
	/**
55
	 * Set the 'todir', being the directory location in which the source
56
	 * file will be constructed.
1619 skinsman 57
	 *
1615 mhunt 58
	 * @param value the directory.
59
	 */
60
	public void setToDir( String value )
61
	{
62
		toDir = value;
63
	}
1619 skinsman 64
 
1615 mhunt 65
	/**
66
	 * Nested element - this tag supports nested 'DirSet' elements.
67
	 */
68
	public DirSet createDirSet()
69
	{
70
		DirSet dirset = new DirSet();
71
		dirsets.add( dirset );
72
		return dirset;
73
	}
1619 skinsman 74
 
1615 mhunt 75
	/**
1619 skinsman 76
	 *
1615 mhunt 77
	 */
78
	public void execute() throws BuildException
79
	{
1619 skinsman 80
		if ( dirsets.size() == 0 )
1615 mhunt 81
		{
1619 skinsman 82
			throw new BuildException("At least one DirSet must be provided");
1615 mhunt 83
		}
84
 
85
		for ( Iterator i=dirsets.iterator(); i.hasNext(); )
86
		{
87
			DirSet dirset = (DirSet)i.next();
88
			FileScanner scanner = dirset.getDirectoryScanner( getProject() );
89
			String[] directories = scanner.getIncludedDirectories();
90
			File basedir = scanner.getBasedir();
91
			for ( int j=0; j<directories.length; j++ )
92
			{
93
				File srcDirectory = new File( basedir, directories[j] );
94
				packageSource( srcDirectory );
95
			}
96
		}
97
	}
1619 skinsman 98
 
1615 mhunt 99
	/**
1619 skinsman 100
	 *
1615 mhunt 101
	 */
102
	private void packageSource( File srcDir ) throws BuildException
103
	{
1619 skinsman 104
		log("Packaging source from '" + srcDir + "'", Project.MSG_VERBOSE );
1615 mhunt 105
		FileSet corresponding = null;
1619 skinsman 106
 
1615 mhunt 107
		try
108
		{
109
			corresponding = getCorrespondingNames();
110
			corresponding.setDir( srcDir );
111
		}
112
		catch (IOException x)
113
		{
114
			throw new BuildException( "Could not read binary '" + binary + "'", x);
115
		}
1619 skinsman 116
 
1615 mhunt 117
		File binarySource = new File( srcDir, binary );
118
		String binaryName = binarySource.getName();
119
		String destName = binaryName.substring(0, binaryName.lastIndexOf("."));
120
		destName += "-src.jar";
121
		File destDir = new File( toDir );
122
		File destFile = new File( toDir, destName );
1619 skinsman 123
 
1615 mhunt 124
		// Check that the corresponding src JAR exists; if not, create one.
125
		Jar jarTask = new Jar();
126
		jarTask.setTaskName(this.getTaskName());
127
		jarTask.setProject( getProject() );
128
		jarTask.setDestFile( destFile );
129
		jarTask.setUpdate(true);
1619 skinsman 130
 
1615 mhunt 131
		jarTask.addFileset( corresponding );
132
		jarTask.execute();
133
	}
1619 skinsman 134
 
1615 mhunt 135
	/**
136
	 * Get the corresponding java source names (as a FileSet), by
137
	 * using the configured 'binary'.
1619 skinsman 138
	 *
1615 mhunt 139
	 * @return a FileSet containing a list of the expected source
140
	 *         files.
1619 skinsman 141
	 *
1615 mhunt 142
	 * @throws IOException if the binary could not be read.
143
	 */
144
	private FileSet getCorrespondingNames() throws IOException
145
	{
146
		if ( correspondingFileSet == null )
147
		{
148
			FileSet corresponding = new FileSet();
149
			corresponding.setProject( getProject() );
1619 skinsman 150
 
1615 mhunt 151
			ZipFile zf = null;
1619 skinsman 152
			try
1615 mhunt 153
			{
154
				log("Loading from source binary '" + binary + "'", Project.MSG_VERBOSE );
155
				zf = new ZipFile(binary);
1619 skinsman 156
				Enumeration l_enum = zf.entries();
157
				while (l_enum.hasMoreElements())
1615 mhunt 158
				{
1619 skinsman 159
					ZipEntry ze = (ZipEntry)l_enum.nextElement();
1615 mhunt 160
					String entryName = ze.getName();
161
					if ( entryName.endsWith( ".class" ) )
162
					{
163
						String correspondingName = entryName.substring(0, entryName.indexOf(".class") );
164
						correspondingName += ".java";
1619 skinsman 165
						log("Adding '" + correspondingName + "' to FileSet", Project.MSG_VERBOSE );
1615 mhunt 166
						corresponding.setIncludes( correspondingName );
167
					}
168
				}
1619 skinsman 169
			}
170
			finally
1615 mhunt 171
			{
1619 skinsman 172
				if (zf != null)
1615 mhunt 173
				{
1619 skinsman 174
					try
1615 mhunt 175
					{
176
						zf.close();
1619 skinsman 177
					}
178
					catch (IOException e)
1615 mhunt 179
					{
180
					}
181
				}
182
			}
183
			correspondingFileSet = corresponding;
1619 skinsman 184
		}
1615 mhunt 185
		return correspondingFileSet;
186
	}
187
}