source: release-kits/lirk3/resources/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/cvslib/CvsTagDiff.java@ 14982

Last change on this file since 14982 was 14982, checked in by oranfry, 16 years ago

initial import of LiRK3

File size: 15.2 KB
Line 
1/*
2 * Copyright 2002-2005 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.cvslib;
18
19import java.io.BufferedReader;
20import java.io.File;
21import java.io.FileOutputStream;
22import java.io.FileReader;
23import java.io.IOException;
24import java.io.OutputStreamWriter;
25import java.io.PrintWriter;
26import java.io.UnsupportedEncodingException;
27import java.util.Vector;
28import java.util.StringTokenizer;
29
30import org.apache.tools.ant.BuildException;
31import org.apache.tools.ant.Project;
32import org.apache.tools.ant.taskdefs.AbstractCvsTask;
33import org.apache.tools.ant.util.DOMElementWriter;
34import org.apache.tools.ant.util.DOMUtils;
35import org.apache.tools.ant.util.FileUtils;
36
37import org.w3c.dom.Document;
38import org.w3c.dom.Element;
39
40/**
41 * Examines the output of cvs rdiff between two tags.
42 *
43 * It produces an XML output representing the list of changes.
44 * <PRE>
45 * &lt;!-- Root element --&gt;
46 * &lt;!ELEMENT tagdiff ( entry+ ) &gt;
47 * &lt;!-- Start tag of the report --&gt;
48 * &lt;!ATTLIST tagdiff startTag NMTOKEN #IMPLIED &gt;
49 * &lt;!-- End tag of the report --&gt;
50 * &lt;!ATTLIST tagdiff endTag NMTOKEN #IMPLIED &gt;
51 * &lt;!-- Start date of the report --&gt;
52 * &lt;!ATTLIST tagdiff startDate NMTOKEN #IMPLIED &gt;
53 * &lt;!-- End date of the report --&gt;
54 * &lt;!ATTLIST tagdiff endDate NMTOKEN #IMPLIED &gt;
55 *
56 * &lt;!-- CVS tag entry --&gt;
57 * &lt;!ELEMENT entry ( file ) &gt;
58 * &lt;!-- File added, changed or removed --&gt;
59 * &lt;!ELEMENT file ( name, revision?, prevrevision? ) &gt;
60 * &lt;!-- Name of the file --&gt;
61 * &lt;!ELEMENT name ( #PCDATA ) &gt;
62 * &lt;!-- Revision number --&gt;
63 * &lt;!ELEMENT revision ( #PCDATA ) &gt;
64 * &lt;!-- Previous revision number --&gt;
65 * &lt;!ELEMENT prevrevision ( #PCDATA ) &gt;
66 * </PRE>
67 *
68 * @since Ant 1.5
69 * @ant.task name="cvstagdiff"
70 */
71public class CvsTagDiff extends AbstractCvsTask {
72
73 /** stateless helper for writing the XML document */
74 private static final DOMElementWriter DOM_WRITER = new DOMElementWriter();
75
76 /**
77 * Token to identify the word file in the rdiff log
78 */
79 static final String FILE_STRING = "File ";
80 /**
81 * Token to identify the word file in the rdiff log
82 */
83 static final String TO_STRING = " to ";
84 /**
85 * Token to identify a new file in the rdiff log
86 */
87 static final String FILE_IS_NEW = " is new;";
88 /**
89 * Token to identify the revision
90 */
91 static final String REVISION = "revision ";
92
93 /**
94 * Token to identify a modified file in the rdiff log
95 */
96 static final String FILE_HAS_CHANGED = " changed from revision ";
97
98 /**
99 * Token to identify a removed file in the rdiff log
100 */
101 static final String FILE_WAS_REMOVED = " is removed";
102
103 /**
104 * The cvs package/module to analyse
105 */
106 private String mypackage;
107
108 /**
109 * The earliest tag from which diffs are to be included in the report.
110 */
111 private String mystartTag;
112
113 /**
114 * The latest tag from which diffs are to be included in the report.
115 */
116 private String myendTag;
117
118 /**
119 * The earliest date from which diffs are to be included in the report.
120 */
121 private String mystartDate;
122
123 /**
124 * The latest date from which diffs are to be included in the report.
125 */
126 private String myendDate;
127
128 /**
129 * The file in which to write the diff report.
130 */
131 private File mydestfile;
132
133 /**
134 * Used to create the temp file for cvs log
135 */
136 private FileUtils myfileUtils = FileUtils.newFileUtils();
137
138 /**
139 * The package/module to analyze.
140 * @param p the name of the package to analyse
141 */
142 public void setPackage(String p) {
143 mypackage = p;
144 }
145
146 /**
147 * Set the start tag.
148 *
149 * @param s the start tag.
150 */
151 public void setStartTag(String s) {
152 mystartTag = s;
153 }
154
155 /**
156 * Set the start date.
157 *
158 * @param s the start date.
159 */
160 public void setStartDate(String s) {
161 mystartDate = s;
162 }
163
164 /**
165 * Set the end tag.
166 *
167 * @param s the end tag.
168 */
169 public void setEndTag(String s) {
170 myendTag = s;
171 }
172
173 /**
174 * Set the end date.
175 *
176 * @param s the end date.
177 */
178 public void setEndDate(String s) {
179 myendDate = s;
180 }
181
182 /**
183 * Set the output file for the diff.
184 *
185 * @param f the output file for the diff.
186 */
187 public void setDestFile(File f) {
188 mydestfile = f;
189 }
190
191 /**
192 * Execute task.
193 *
194 * @exception BuildException if an error occurs
195 */
196 public void execute() throws BuildException {
197 // validate the input parameters
198 validate();
199
200 // build the rdiff command
201 addCommandArgument("rdiff");
202 addCommandArgument("-s");
203 if (mystartTag != null) {
204 addCommandArgument("-r");
205 addCommandArgument(mystartTag);
206 } else {
207 addCommandArgument("-D");
208 addCommandArgument(mystartDate);
209 }
210 if (myendTag != null) {
211 addCommandArgument("-r");
212 addCommandArgument(myendTag);
213 } else {
214 addCommandArgument("-D");
215 addCommandArgument(myendDate);
216 }
217 // support multiple packages
218 StringTokenizer myTokenizer = new StringTokenizer(mypackage);
219 while (myTokenizer.hasMoreTokens()) {
220 addCommandArgument(myTokenizer.nextToken());
221 }
222 // force command not to be null
223 setCommand("");
224 File tmpFile = null;
225 try {
226 tmpFile = myfileUtils.createTempFile("cvstagdiff", ".log", null);
227 tmpFile.deleteOnExit();
228 setOutput(tmpFile);
229
230 // run the cvs command
231 super.execute();
232
233 // parse the rdiff
234 CvsTagEntry[] entries = parseRDiff(tmpFile);
235
236 // write the tag diff
237 writeTagDiff(entries);
238
239 } finally {
240 if (tmpFile != null) {
241 tmpFile.delete();
242 }
243 }
244 }
245
246 /**
247 * Parse the tmpFile and return and array of CvsTagEntry to be
248 * written in the output.
249 *
250 * @param tmpFile the File containing the output of the cvs rdiff command
251 * @return the entries in the output
252 * @exception BuildException if an error occurs
253 */
254 private CvsTagEntry[] parseRDiff(File tmpFile) throws BuildException {
255 // parse the output of the command
256 BufferedReader reader = null;
257
258 try {
259 reader = new BufferedReader(new FileReader(tmpFile));
260
261 // entries are of the form:
262 //CVS 1.11
263 // File module/filename is new; current revision 1.1
264 //CVS 1.11.9
265 // File module/filename is new; cvstag_2003_11_03_2 revision 1.1
266 // or
267 // File module/filename changed from revision 1.4 to 1.6
268 // or
269 // File module/filename is removed; not included in
270 // release tag SKINLF_12
271 //CVS 1.11.9
272 // File testantoine/antoine.bat is removed; TESTANTOINE_1 revision 1.1.1.1
273 //
274 // get rid of 'File module/"
275 String toBeRemoved = FILE_STRING + mypackage + "/";
276 int headerLength = toBeRemoved.length();
277 Vector entries = new Vector();
278
279 String line = reader.readLine();
280 int index;
281 CvsTagEntry entry = null;
282
283 while (null != line) {
284 if (line.length() > headerLength) {
285 if (line.startsWith(toBeRemoved)) {
286 line = line.substring(headerLength);
287 } else {
288 line = line.substring(FILE_STRING.length());
289 }
290
291 if ((index = line.indexOf(FILE_IS_NEW)) != -1) {
292 // it is a new file
293 // set the revision but not the prevrevision
294 String filename = line.substring(0, index);
295 String rev = null;
296 int indexrev = -1;
297 if ((indexrev = line.indexOf(REVISION, index)) != -1) {
298 rev = line.substring(indexrev + REVISION.length());
299 }
300 entry = new CvsTagEntry(filename, rev);
301 entries.addElement(entry);
302 log(entry.toString(), Project.MSG_VERBOSE);
303 } else if ((index = line.indexOf(FILE_HAS_CHANGED)) != -1) {
304 // it is a modified file
305 // set the revision and the prevrevision
306 String filename = line.substring(0, index);
307 int revSeparator = line.indexOf(" to ", index);
308 String prevRevision =
309 line.substring(index + FILE_HAS_CHANGED.length(),
310 revSeparator);
311 String revision = line.substring(revSeparator + TO_STRING.length());
312 entry = new CvsTagEntry(filename,
313 revision,
314 prevRevision);
315 entries.addElement(entry);
316 log(entry.toString(), Project.MSG_VERBOSE);
317 } else if ((index = line.indexOf(FILE_WAS_REMOVED)) != -1) {
318 // it is a removed file
319 String filename = line.substring(0, index);
320 String rev = null;
321 int indexrev = -1;
322 if ((indexrev = line.indexOf(REVISION, index)) != -1) {
323 rev = line.substring(indexrev + REVISION.length());
324 }
325 entry = new CvsTagEntry(filename, null, rev);
326 entries.addElement(entry);
327 log(entry.toString(), Project.MSG_VERBOSE);
328 }
329 }
330 line = reader.readLine();
331 }
332
333 CvsTagEntry[] array = new CvsTagEntry[entries.size()];
334 entries.copyInto(array);
335
336 return array;
337 } catch (IOException e) {
338 throw new BuildException("Error in parsing", e);
339 } finally {
340 if (reader != null) {
341 try {
342 reader.close();
343 } catch (IOException e) {
344 log(e.toString(), Project.MSG_ERR);
345 }
346 }
347 }
348 }
349
350 /**
351 * Write the rdiff log.
352 *
353 * @param entries a <code>CvsTagEntry[]</code> value
354 * @exception BuildException if an error occurs
355 */
356 private void writeTagDiff(CvsTagEntry[] entries) throws BuildException {
357 FileOutputStream output = null;
358 try {
359 output = new FileOutputStream(mydestfile);
360 PrintWriter writer = new PrintWriter(
361 new OutputStreamWriter(output, "UTF-8"));
362 writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
363 Document doc = DOMUtils.newDocument();
364 Element root = doc.createElement("tagdiff");
365 if (mystartTag != null) {
366 root.setAttribute("startTag", mystartTag);
367 } else {
368 root.setAttribute("startDate", mystartDate);
369 }
370 if (myendTag != null) {
371 root.setAttribute("endTag", myendTag);
372 } else {
373 root.setAttribute("endDate", myendDate);
374 }
375
376 root.setAttribute("cvsroot", getCvsRoot());
377 root.setAttribute("package", mypackage);
378 DOM_WRITER.openElement(root, writer, 0, "\t");
379 writer.println();
380 for (int i = 0, c = entries.length; i < c; i++) {
381 writeTagEntry(doc, writer, entries[i]);
382 }
383 DOM_WRITER.closeElement(root, writer, 0, "\t", true);
384 writer.flush();
385 writer.close();
386 } catch (UnsupportedEncodingException uee) {
387 log(uee.toString(), Project.MSG_ERR);
388 } catch (IOException ioe) {
389 throw new BuildException(ioe.toString(), ioe);
390 } finally {
391 if (null != output) {
392 try {
393 output.close();
394 } catch (IOException ioe) {
395 log(ioe.toString(), Project.MSG_ERR);
396 }
397 }
398 }
399 }
400
401 /**
402 * Write a single entry to the given writer.
403 *
404 * @param doc Document used to create elements.
405 * @param writer a <code>PrintWriter</code> value
406 * @param entry a <code>CvsTagEntry</code> value
407 */
408 private void writeTagEntry(Document doc, PrintWriter writer,
409 CvsTagEntry entry)
410 throws IOException {
411 Element ent = doc.createElement("entry");
412 Element f = DOMUtils.createChildElement(ent, "file");
413 DOMUtils.appendCDATAElement(f, "name", entry.getFile());
414 if (entry.getRevision() != null) {
415 DOMUtils.appendTextElement(f, "revision", entry.getRevision());
416 }
417 if (entry.getPreviousRevision() != null) {
418 DOMUtils.appendTextElement(f, "prevrevision",
419 entry.getPreviousRevision());
420 }
421 DOM_WRITER.write(ent, writer, 1, "\t");
422 }
423
424 /**
425 * Validate the parameters specified for task.
426 *
427 * @exception BuildException if a parameter is not correctly set
428 */
429 private void validate() throws BuildException {
430 if (null == mypackage) {
431 throw new BuildException("Package/module must be set.");
432 }
433
434 if (null == mydestfile) {
435 throw new BuildException("Destfile must be set.");
436 }
437
438 if (null == mystartTag && null == mystartDate) {
439 throw new BuildException("Start tag or start date must be set.");
440 }
441
442 if (null != mystartTag && null != mystartDate) {
443 throw new BuildException("Only one of start tag and start date "
444 + "must be set.");
445 }
446
447 if (null == myendTag && null == myendDate) {
448 throw new BuildException("End tag or end date must be set.");
449 }
450
451 if (null != myendTag && null != myendDate) {
452 throw new BuildException("Only one of end tag and end date must "
453 + "be set.");
454 }
455 }
456}
Note: See TracBrowser for help on using the repository browser.