KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jester > makealljesterchanges > MakeAllJesterChanges


1 package jester.makealljesterchanges;
2
3 import java.io.BufferedReader JavaDoc;
4 import java.io.BufferedWriter JavaDoc;
5 import java.io.File JavaDoc;
6 import java.io.FileInputStream JavaDoc;
7 import java.io.FileNotFoundException JavaDoc;
8 import java.io.FileReader JavaDoc;
9 import java.io.FileWriter JavaDoc;
10 import java.io.IOException JavaDoc;
11 import java.io.InputStream JavaDoc;
12
13 import javax.xml.parsers.DocumentBuilder JavaDoc;
14 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
15
16 import org.w3c.dom.Attr JavaDoc;
17 import org.w3c.dom.Document JavaDoc;
18 import org.w3c.dom.NamedNodeMap JavaDoc;
19 import org.w3c.dom.Node JavaDoc;
20 import org.w3c.dom.NodeList JavaDoc;
21
22 /**
23  * @author Simon Lever 2005
24  *
25  * Class for applying all the changes in the "jesterReport.xml" file and then
26  * producing a ".jester" modified source file. It uses Java XML processing to
27  * achieve this using the JAXP (Java API for XML Processing) method.
28  *
29  * It uses the absolute file references contained in the jesterReport.xml
30  * produced by Jester in order to be location independent. This could therefore
31  * be easily modified as to pass in the location of the jsterReport.xml as a
32  * command line String argument in "java MakeAllJesterChanges ABSOLUTE_PATH"
33  * then this jesterReport.xml file would be the one used to apply the changes to
34  * the original source and produce the new modified .jester source file
35  *
36  * [NOTE: BECAUSE OF THE NATURE OF THE CHANGES APPLIED TO A SOURCE FILE,
37  * MULTIPLE MODIFICATIONS COULD OCCUR ON ONE LINE AND THUS MAKE THE CODE
38  * NON-COMPILABLE. THE .jester FILE IS MERELY TO BE USED AS A COMPARRISON NOT AS
39  * A NEWLY CREATED FILE THAT HAS BEEN IMPROVED.]
40  */

41 public class MakeAllJesterChanges {
42
43     /**
44      * Main method of this class
45      *
46      * @param args
47      */

48     public static void main(String JavaDoc[] args) {
49         try {
50             /*
51              * create the Builder Factory object for creating the document
52              * builder
53              */

54             DocumentBuilderFactory JavaDoc builderFactory = DocumentBuilderFactory
55                     .newInstance();
56
57             //now create the Document Builder from the above Builder Factory
58
DocumentBuilder JavaDoc builder = builderFactory.newDocumentBuilder();
59
60             /*
61              * now parse the "jesterReport.xml" and produce the modified file
62              * incorporating all the changes
63              */

64             parseXMLAndApplyChanges(builder);
65
66         } catch (Exception JavaDoc e) {
67             //print the exception
68
System.out.println(e);
69         }
70     }
71
72     /**
73      * parseXMLAndApplyChanges method for essentially parsing the
74      * jesterReport.xml and then applying the changes
75      */

76     private static void parseXMLAndApplyChanges(DocumentBuilder JavaDoc builder)
77             throws Exception JavaDoc {
78         //create the input stream for the jesterReport.xml file
79
InputStream JavaDoc in = new FileInputStream JavaDoc("jesterReport.xml");
80
81         //create the Document object for querying the jesterReport.xml file
82
Document JavaDoc doc = builder.parse(in);
83         in.close(); //close the input stream
84

85         //NOW FOR EACH JESTED FILE APPLY THE CHANGES
86

87         //gives all the nodes that are tagged with "JestedFile"
88
NodeList JavaDoc jestedFiles = doc.getElementsByTagName("JestedFile");
89
90         //gives all the ChangeThatDidNotCauseTheTestsToFail tags
91
NodeList JavaDoc changes = doc
92                 .getElementsByTagName("ChangeThatDidNotCauseTestsToFail");
93
94         /*
95          * integer variable for keeping track of how many of the changes have
96          * been made in total in order for the inner change loop to start using
97          * the correct change in the NodeList changes
98          */

99         int noOfChangesSoFarForFiles = 0;
100
101         //loop through all the JestedFile tags
102
for (int i = 0; i < jestedFiles.getLength(); i++) {
103
104             //obtain the current JestedFile tag
105
Node JavaDoc jestedFile = jestedFiles.item(i);
106
107             //obtain the JestedFile tag attributes
108
NamedNodeMap JavaDoc jestedFileAttrs = jestedFile.getAttributes();
109
110             //now obtain the attributes for this JestedFile
111

112             //get the absolute filename path
113
Attr JavaDoc fileNameAttr = (Attr JavaDoc) jestedFileAttrs
114                     .getNamedItem("absolutePathFileName");
115             String JavaDoc fileNameValue = fileNameAttr.getValue();
116
117             //get the number of changes that did not cause the tests to fail
118
Attr JavaDoc noOfChangesNoFail = (Attr JavaDoc) jestedFileAttrs
119                     .getNamedItem("numberOfChangesThatDidNotCauseTestsToFail");
120             int noOfChangesNoFailValue = new Integer JavaDoc(noOfChangesNoFail
121                     .getValue()).intValue();
122
123             //FILE PROCESSING
124

125             //read file contents into a String
126
String JavaDoc originalContents = getContents(new File JavaDoc(fileNameValue));
127
128             /*
129              * parse the filename and make it have the extension ".jester"
130              * instead of ".java" reference the new absolute path filename via a
131              * String
132              */

133             String JavaDoc newAbsolutePathFileName = parseFileName(fileNameValue);
134
135             /*
136              * now create the new file "XXX.jester" and get a handle on the
137              * BufferedWriter which uses a FileWriter to create the file if it
138              * does not exist
139              */

140             BufferedWriter JavaDoc bufWriter = new BufferedWriter JavaDoc(new FileWriter JavaDoc(
141                     newAbsolutePathFileName));
142
143             /*
144              * the integer for recording the index In Original Of Last Change
145              * this represents the last character that was changed and added by
146              * Jester
147              */

148             int indexInOriginalOfLastChange = 0;
149
150             /*
151              * now loop through all the changes for the current JestedFile and
152              * apply the changes to the original source file => making a new
153              * file in the process with the extension ".jester"
154              */

155             for (int j = 0; j < noOfChangesNoFailValue; j++) {
156                 //OBTAIN DATA
157

158                 //get the next change for the current JestedFile
159
Node JavaDoc change = changes.item(j + noOfChangesSoFarForFiles);
160
161                 //get the changes tag attributes
162
NamedNodeMap JavaDoc changesAttrs = change.getAttributes();
163
164                 //now get the index attribute
165
Attr JavaDoc indexOfChange = (Attr JavaDoc) changesAttrs.getNamedItem("index");
166                 int indexOfChangeValue = new Integer JavaDoc(indexOfChange.getValue())
167                         .intValue();
168
169                 //the from attribute
170
Attr JavaDoc fromChange = (Attr JavaDoc) changesAttrs.getNamedItem("from");
171                 String JavaDoc fromChangeValue = fromChange.getValue();
172
173                 //finally the to attribute
174
Attr JavaDoc toChange = (Attr JavaDoc) changesAttrs.getNamedItem("to");
175                 String JavaDoc toChangeValue = toChange.getValue();
176
177                 //PROCESS FILE
178

179                 /*
180                  * if the index for the current change is greater than or equal
181                  * to the index character of the last change then we can get a
182                  * substring from the last change character index to the index
183                  * of the current change and then write this to the output
184                  * buffer
185                  */

186                 if (indexOfChangeValue >= indexInOriginalOfLastChange) {
187                     //obtain the original contents up to the change
188
String JavaDoc originalUpToChange = originalContents.substring(
189                             indexInOriginalOfLastChange, indexOfChangeValue);
190
191                     //write to the new file
192
bufWriter.write(originalUpToChange);
193                 }
194
195                 //write the "to" section of this change
196
bufWriter.write(toChangeValue);
197
198                 /*
199                  * now modify the indexInOriginalOfLastChange variable so the
200                  * start position for the next originalUpToChange substring
201                  * (above) is after the last change
202                  */

203                 indexInOriginalOfLastChange = indexOfChangeValue
204                         + fromChangeValue.length();
205
206             }
207
208             /*
209              * finally after all the changes have been made, write the rest of
210              * the file to the end of the new .jester file. The substring()
211              * method below requires a startIndex only as it will return a
212              * substring from this index to the end of the string.
213              */

214             bufWriter.write(originalContents
215                     .substring(indexInOriginalOfLastChange));
216             //close the stream
217
bufWriter.close();
218
219             /*
220              * the ChangeThatDidNotCauseTestsToFail Nodes are stored in the
221              * changes NodeList previously defined. To make sure that the
222              * algorithm reads the correct changes from the changes NodeList for
223              * the current JestedFile being processed, an incrementation is
224              * needed in order to use the next changes in the sequential list
225              * and not changes that belong to a previous JestedFile.
226              *
227              * This increment is by the integer "noOfChangesNoFailValue" which
228              * represents the total number of ChangeThatDidNotCauseTestsToFail
229              * tags that belong to the current JestedFile, hence making the
230              * noOfChangesSoFarForFiles int being at the correct index for
231              * reading the ChangeThatDidNotCauseTestsToFail for the next
232              * JestedFile.
233              */

234             noOfChangesSoFarForFiles += noOfChangesNoFailValue;
235
236         }
237     }
238
239     /**
240      * Fetch the entire contents of a text file, and return it in a String.
241      *
242      * @param aFile
243      * is a file which already exists and can be read.
244      */

245     public static String JavaDoc getContents(File JavaDoc aFile) {
246         //create a StringBuffer ready for the contents of the file
247
StringBuffer JavaDoc contents = new StringBuffer JavaDoc();
248
249         /*
250          * BufferedReader for reading the file declared here only to make
251          * visible to finally clause
252          */

253         BufferedReader JavaDoc input = null;
254
255         try {
256             //use buffering as this implementation reads one line at a time
257
input = new BufferedReader JavaDoc(new FileReader JavaDoc(aFile));
258
259             //not declared within while loop to be initialised
260
String JavaDoc line = null;
261
262             /*
263              * read in all the lines putting in a system dependent newline
264              * character after every line
265              */

266             while ((line = input.readLine()) != null) {
267                 //append the newly read line String to the StringBuffer
268
contents.append(line);
269                 //followed by a platform independent newline separator
270
contents.append(System.getProperty("line.separator"));
271             }
272
273         } catch (FileNotFoundException JavaDoc ex) {
274             ex.printStackTrace();
275         } catch (IOException JavaDoc ex) {
276             ex.printStackTrace();
277         } /*
278            * make sure that the next statement is always done to close the
279            * stream
280            */

281         finally {
282             try {
283                 if (input != null) {
284                     /*
285                      * flush and close both "input" and its underlying
286                      * FileReader
287                      */

288                     input.close();
289                 }
290             } catch (IOException JavaDoc ex) {
291                 ex.printStackTrace();
292             }
293         }
294
295         //return the file in a string
296
return contents.toString();
297     }
298
299     /**
300      * parseFileName method for essentially removing an old .java filename (5
301      * chars long) and replacing it with .jester in this case
302      */

303     public static String JavaDoc parseFileName(String JavaDoc original) {
304         //gives 0th elem to elem just before ".java"
305
String JavaDoc temp = original.substring(0, original.length() - 5);
306
307         /*
308          * now return the string with ".jester" appended at the end using a
309          * StringBuffer as String's are immutable (not modifiable)
310          */

311         return (new StringBuffer JavaDoc(temp).append(".jester")).toString();
312
313     }
314
315 }
Popular Tags