1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 package org.osjava.jardiff.ant;
40
41 import org.apache.tools.ant.BuildException;
42 import org.apache.tools.ant.Task;
43 import java.io.File;
44 import java.io.FileOutputStream;
45 import java.io.IOException;
46 import java.net.URL;
47 import java.util.Set;
48 import java.util.HashSet;
49 import javax.xml.transform.ErrorListener;
50 import javax.xml.transform.Transformer;
51 import javax.xml.transform.TransformerConfigurationException;
52 import javax.xml.transform.TransformerException;
53 import javax.xml.transform.TransformerFactory;
54 import javax.xml.transform.sax.SAXTransformerFactory;
55 import javax.xml.transform.sax.TransformerHandler;
56 import javax.xml.transform.stream.StreamResult;
57 import javax.xml.transform.stream.StreamSource;
58
59 import org.osjava.jardiff.JarDiff;
60 import org.osjava.jardiff.DiffException;
61 import org.osjava.jardiff.StreamDiffHandler;
62 import org.osjava.jardiff.SimpleDiffCriteria;
63
64 /***
65 * Process two jarfiles generating a public API difference report.
66 * This is useful for keeping track of API changes between versions of a
67 * project.
68 *
69 * @author <a href="mailto:antony@cyberiantiger.org">Antony Riley</a>
70 */
71 public class JarDiffTask extends Task {
72
73 /***
74 * The jarfile this diff is from.
75 */
76 private File fromJar = null;
77
78 /***
79 * The jarfile this diff is to.
80 */
81 private File toJar = null;
82
83 /***
84 * The file to write the report to.
85 */
86 private File out = null;
87
88 /***
89 * The name to use for the from version.
90 */
91 private String fromName = null;
92
93 /***
94 * The name to use for the to verison.
95 */
96 private String toName = null;
97
98 /***
99 * Force output, even if the existing output is newer than
100 * the jar files.
101 */
102 private boolean force = false;
103
104 /***
105 * Run the task, generating the jardiff report.
106 *
107 * @throws BuildException When there is an error creating the diff,
108 * When there is a problem with the xml parser,
109 * When there is a problem with the xslt transformer
110 * When the attributes specified are invalid.
111 */
112 public void execute() throws BuildException {
113 try {
114 if(fromJar == null) {
115 throw new BuildException("no fromjar file specified",
116 getLocation());
117 }
118 if(toJar == null) {
119 throw new BuildException("no tojar file specified",
120 getLocation());
121 }
122 if(out == null) {
123 throw new BuildException("no out file specified",
124 getLocation());
125 }
126 if(fromName == null) {
127 fromName = fromJar.getName();
128 }
129 if(toName == null) {
130 toName = toJar.getName();
131 }
132 if(!fromJar.exists() || !fromJar.isFile() || !fromJar.canRead()) {
133 String msg = "fromjar is not a file, or cannot be read";
134 throw new BuildException(msg, getLocation());
135 }
136 if(!toJar.exists() || !toJar.isFile() || !toJar.canRead()) {
137 String msg = "tojar is not a file, or cannot be read";
138 throw new BuildException(msg, getLocation());
139 }
140 long outModified = out.lastModified();
141 long oldModified = fromJar.lastModified();
142 long newModified = toJar.lastModified();
143 if(force || oldModified > outModified || newModified > outModified)
144 {
145 log("Writing xml api diff to "+out);
146 JarDiff jd = new JarDiff();
147 jd.setOldVersion(fromName);
148 jd.setNewVersion(toName);
149 jd.loadOldClasses(fromJar);
150 jd.loadNewClasses(toJar);
151 jd.diff(
152 new StreamDiffHandler(new FileOutputStream(out)),
153 new SimpleDiffCriteria()
154 );
155 }
156 } catch (DiffException de) {
157 throw new BuildException(de);
158 } catch (IOException ioe) {
159 throw new BuildException(ioe);
160 }
161 }
162
163 /***
164 * Set the from jar file.
165 * Required attribute.
166 *
167 * @param fromJar a jar file.
168 */
169 public void setFromjar(File fromJar) {
170 this.fromJar = fromJar;
171 }
172
173 /***
174 * Set the to jar file.
175 * Required attribute.
176 * @param toJar a jar file.
177 */
178 public void setTojar(File toJar) {
179 this.toJar = toJar;
180 }
181
182 /***
183 * Set the out file.
184 * Required attribute.
185 *
186 * @param out an output file.
187 */
188 public void setOut(File out) {
189 this.out = out;
190 }
191
192 /***
193 * Set the from jar visible name.
194 * Optional attribute.
195 * Defaults to the filename of fromjar.
196 *
197 * @param fromName a visible name.
198 */
199 public void setFromname(String fromName) {
200 this.fromName = fromName;
201 }
202
203 /***
204 * Set the to jar visible name.
205 * Optional attribute.
206 * Defaults to the filename of tojar.
207 *
208 * @param toName a visible name.
209 */
210 public void setToname(String toName) {
211 this.toName = toName;
212 }
213
214 /***
215 * Force output even if there is an existing diff file which is
216 * newer than the source jar files.
217 * Optional attribute.
218 * Defaults to false.
219 *
220 * @param force true to force output, false otherwise
221 */
222 public void setForce(boolean force) {
223 this.force = force;
224 }
225 }