Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1974 jgill 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
/**
12
 * Custom ANT task - given a code JAR and a source base, build a JAR
13
 * containing the corresponding source code.
14
 *
15
 * @ant.examples Here are examples
16
 *
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.
28
	 */
29
	private String toDir;
30
 
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;
36
 
37
	/**
38
	 * The set of directories under which the source code is located in
39
	 * its' expected location.
40
	 */
41
	private ArrayList dirsets = new ArrayList();
42
 
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.
46
	 *
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.
57
	 *
58
	 * @param value the directory.
59
	 */
60
	public void setToDir( String value )
61
	{
62
		toDir = value;
63
	}
64
 
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
	}
74
 
75
	/**
76
	 *
77
	 */
78
	public void execute() throws BuildException
79
	{
80
		if ( dirsets.size() == 0 )
81
		{
82
			throw new BuildException("At least one DirSet must be provided");
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
	}
98
 
99
	/**
100
	 *
101
	 */
102
	private void packageSource( File srcDir ) throws BuildException
103
	{
104
		log("Packaging source from '" + srcDir + "'", Project.MSG_VERBOSE );
105
		FileSet corresponding = null;
106
 
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
		}
116
 
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 );
123
 
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);
130
 
131
		jarTask.addFileset( corresponding );
132
		jarTask.execute();
133
	}
134
 
135
	/**
136
	 * Get the corresponding java source names (as a FileSet), by
137
	 * using the configured 'binary'.
138
	 *
139
	 * @return a FileSet containing a list of the expected source
140
	 *         files.
141
	 *
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() );
150
 
151
			ZipFile zf = null;
152
			try
153
			{
154
				log("Loading from source binary '" + binary + "'", Project.MSG_VERBOSE );
155
				zf = new ZipFile(binary);
156
				Enumeration l_enum = zf.entries();
157
				while (l_enum.hasMoreElements())
158
				{
159
					ZipEntry ze = (ZipEntry)l_enum.nextElement();
160
					String entryName = ze.getName();
161
					if ( entryName.endsWith( ".class" ) )
162
					{
163
						String correspondingName = entryName.substring(0, entryName.indexOf(".class") );
164
						correspondingName += ".java";
165
						log("Adding '" + correspondingName + "' to FileSet", Project.MSG_VERBOSE );
166
						corresponding.setIncludes( correspondingName );
167
					}
168
				}
169
			}
170
			finally
171
			{
172
				if (zf != null)
173
				{
174
					try
175
					{
176
						zf.close();
177
					}
178
					catch (IOException e)
179
					{
180
					}
181
				}
182
			}
183
			correspondingFileSet = corresponding;
184
		}
185
		return correspondingFileSet;
186
	}
187
}