source: main/trunk/ant-tasks/src/org/greenstone/anttasks/RegexSearchReplace.java@ 28156

Last change on this file since 28156 was 28156, checked in by davidb, 11 years ago

Minor tweak to output message

File size: 10.0 KB
Line 
1/*
2 * RegexSearchReplace.java
3 * A task to replace occurences of a given pattern with a given replacement in a given file
4 *
5 * Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21package org.greenstone.anttasks;
22
23import java.util.ArrayList;
24import org.apache.tools.ant.*;
25import org.apache.tools.ant.taskdefs.*;
26import java.util.*;
27import java.io.*;
28import java.util.regex.*;
29import org.apache.tools.ant.types.FileSet;
30import org.apache.tools.ant.DirectoryScanner;
31
32public class RegexSearchReplace extends Task {
33
34 private File file = null;
35 private ArrayList jobs = null;
36 private FileSet fileset = null;
37 private String pattern = null;
38 private String replacement = null;
39 private int verbosity = 1;
40 private int fromLine = -1;
41 private int toLine = -1;
42 private boolean winPath = false;
43
44 public static void main( String[] args ) {
45
46 RegexSearchReplace rsr = new RegexSearchReplace();
47 rsr.setFile(new File (args[0]));
48 rsr.setPattern(args[1]);
49 rsr.setReplacement(args[2]);
50 rsr.setLines(args[3]);
51
52 rsr.execute();
53
54 }
55
56 public void execute() {
57
58 if ( file == null && fileset == null ) {
59 throw new BuildException( "Error - No file or fileset specified !!" );
60 }
61
62 if ( file != null && !file.exists() ) {
63 throw new BuildException( "Error - File not found !!" );
64 }
65
66 DirectoryScanner dirScanner = null;
67 if ( fileset != null ) {
68 dirScanner = fileset.getDirectoryScanner(project);
69 dirScanner.scan();
70 }
71
72 if ( jobs == null && pattern == null ) {
73 throw new BuildException( "Error - No pattern attribute and no nested jobs !!" );
74 }
75
76 if ( jobs != null && pattern != null ) {
77 throw new BuildException( "Error - Both pattern attribute and nested jobs given !!" );
78 }
79
80 if ( pattern != null && replacement == null ) {
81 throw new BuildException( "Error - pattern attribute given but no replacement attribute given !!" );
82 }
83
84 if ( jobs != null ) {
85 for ( int i=0; i<jobs.size(); i++ ) {
86 if ( ((RegexSearchReplaceJob)(jobs.get(i))).getPattern() == null ) {
87 throw new BuildException( "Error - One of the jobs lacks a pattern!!" );
88 }
89 if ( ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement() == null ) {
90 throw new BuildException( "Error - One of the jobs lacks a replacement!!" );
91 }
92 }
93 }
94
95
96 //sus out filename(s)
97 File[] files = null;
98 if ( file != null ) {
99 files = new File[1];
100 files[0] = file;
101 } else {
102 String[] fileStrings = dirScanner.getIncludedFiles();
103 files = new File[fileStrings.length];
104 for ( int i=0; i<fileStrings.length; i++ ) {
105 files[i] = new File( dirScanner.getBasedir() + File.separator + fileStrings[i] );
106 }
107 }
108
109 //output greeting
110 if (verbosity >= 3) {
111 System.out.println( "--------------------" );
112 System.out.println( " RegexSearchReplace " );
113 System.out.println( "--------------------" );
114
115
116 //output replacement(s)
117 System.out.println( "Replacements:" );
118
119 if ( pattern != null ) {
120 System.out.println( " " + pattern + " -> " + replacement );
121 } else {
122 for ( int i=0; i<jobs.size(); i++ ) {
123 System.out.println( " " + ((RegexSearchReplaceJob)(jobs.get(i))).getPattern() + " -> " + ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement() );
124 }
125 }
126 System.out.println();
127
128
129 //output lines if necessary
130 if ( this.fromLine != -1 || this.toLine != -1 ) {
131 System.out.println( "Lines: " + (this.fromLine==-1?"Start":Integer.toString(this.fromLine)) + " ~ " + (this.toLine==-1?"End":Integer.toString(this.toLine)) );
132 System.out.println();
133 }
134 }
135
136 if (verbosity == 1) {
137 if (files.length == 1) {
138 System.out.println("Regex Search and Replace on file: ");
139 }
140 else {
141 System.out.println("Regex Search and Replace on files: ");
142 }
143 }
144 else if (verbosity > 1) {
145 System.out.println( "File(s): " );
146 }
147
148
149 for ( int fileIndex=0; fileIndex<files.length; fileIndex++ ) {
150
151 int noReplaces = 0;
152
153 File inputFile = files[fileIndex];
154 if (verbosity >= 1) {
155 System.out.println( " " + inputFile );
156 }
157
158 //create the output stream
159 BufferedWriter out = null;
160 File temp = null;
161 try {
162 //create temp file.
163 temp = File.createTempFile("rsr", ".tmp");
164
165 //delete temp file when program exits.
166 temp.deleteOnExit();
167
168 //writer to temp file
169 out = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(temp), "UTF8") );
170
171 } catch (IOException e) {
172 throw new BuildException( "Error - Couldn't create or open the temp file" );
173 }
174
175
176 //create the input stream
177 BufferedReader in = null;
178 try {
179 in = new BufferedReader( new InputStreamReader(new FileInputStream(inputFile), "UTF8") );
180 } catch ( Exception e ) {
181 throw new BuildException( "Error - Couldn't open the specified file" );
182 }
183
184 //pass the file through, searching and replacing
185 String line = null;
186 int lineNumber = 1;
187 boolean hasMoreLines = true;
188 while ( hasMoreLines ) {
189
190 try {
191 line = in.readLine();
192 } catch ( Exception e ) {
193 System.err.println( e.getMessage() );
194 throw new BuildException( "Error - Couldn't read from the specified file" );
195 }
196
197 if ( line == null ) {
198 hasMoreLines = false;
199 } else {
200
201 //only if within the given line range
202 if ( ( fromLine == -1 || lineNumber >= fromLine ) && ( toLine == -1 || lineNumber < toLine ) ) {
203 String oldLine = line;
204 if ( pattern != null ) {
205 String rp = replacement;
206 if ( winPath ) {
207 rp = rp.replaceAll("\\\\","\\\\\\\\");
208 }
209 line = line.replaceAll((String)pattern, (String)rp);
210 } else {
211 for ( int i=0; i<jobs.size(); i++ ) {
212 String rp = ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement();
213 if ( ((RegexSearchReplaceJob)(jobs.get(i))).getWinPath() ) {
214 rp = rp.replaceAll("\\\\","\\\\\\\\");
215 }
216 line = line.replaceAll( ((RegexSearchReplaceJob)(jobs.get(i))).getPattern(), rp );
217 }
218 }
219
220 if ( !oldLine.equals( line ) ) {
221 noReplaces++;
222 }
223 }
224
225 try {
226 out.write( line );
227 out.newLine();
228 } catch ( Exception e ) {
229 throw new BuildException( "Error - Couldn't write to the temp file" );
230 }
231 }
232 lineNumber++;
233 }
234
235 try {
236 //close them both up
237 in.close();
238 out.close();
239 } catch ( Exception e ) {
240 throw new BuildException( "Error - Couldn't close a file" );
241 }
242
243
244 //copy the new file (temp) over the original
245 InputStream i;
246 OutputStream o;
247 try {
248 i = new FileInputStream(temp);
249 o = new FileOutputStream(inputFile);
250
251 } catch ( Exception e ) {
252 throw new BuildException( "Error - Couldn't open the temp file" );
253 }
254
255 try {
256
257 // Transfer bytes from in to out
258 byte[] buf = new byte[1024];
259 int len;
260 while ((len = i.read(buf)) > 0) {
261 o.write(buf, 0, len);
262 }
263
264 //close them up
265 i.close();
266 o.close();
267 } catch ( Exception e ) {
268 throw new BuildException( "Error - Couldn't write to the specified file" );
269 }
270
271
272 if (verbosity >= 2) {
273 if ( noReplaces == 0 ) {
274 System.out.println( " No Changes Made" );
275 } else if ( noReplaces == 1 ) {
276 System.out.println( " Successfully changed 1 line" );
277 } else {
278 System.out.println( " Successfully changed " + noReplaces + " lines" );
279 }
280 System.out.println();
281 }
282
283 }
284
285 }
286
287 public void setFile(File file) {
288 if ( this.fileset != null || this.file != null ) {
289 throw new BuildException( "Error - Only one file or one fileset may be given!!" );
290 }
291 this.file = file;
292 }
293
294 public void setLines(String lines) {
295 //lines should be in the form "2" or "2-5"
296
297 //trim
298 lines.replaceAll("\\s","");
299
300 if ( lines == "" ) {
301 throw new BuildException( "Error - no line number(s) given in lines attribute!! " );
302 }
303
304 //split into parts
305 String[] parts = lines.split("-",2);
306
307 try {
308 if ( parts.length == 1 ) {
309 this.fromLine = Integer.parseInt( parts[0] );
310 this.toLine = this.fromLine + 1;
311 } else {
312 if ( !parts[0].equals("") ) this.fromLine = Integer.parseInt( parts[0] );
313 if ( !parts[1].equals("") ) this.toLine = Integer.parseInt( parts[1] );
314 }
315 } catch( NumberFormatException nfe ) {
316 throw new BuildException( "Error - invalid line numbers given in lines attribute!! '" + parts[0] + "' - '" + parts[1] + "'" );
317 }
318
319 }
320
321 public void setVerbosity(String verbosity_str) {
322
323 //trim
324 verbosity_str.replaceAll("\\s","");
325
326 if (verbosity_str == "" ) {
327 throw new BuildException("Error - no value found in 'verbosity' attribute!");
328 }
329
330 try {
331 this.verbosity = Integer.parseInt(verbosity_str);
332 } catch( NumberFormatException nfe ) {
333 throw new BuildException("Error - invalid line numbers given in 'verbosity' attribute! '"
334 + verbosity_str + "'" );
335 }
336
337 }
338
339 public void setPattern(String pattern) {
340 this.pattern = pattern;
341 }
342
343 public void setReplacement(String replacement) {
344 replacement = replacement.replaceAll( "\\\\", "\\\\\\\\" );
345 this.replacement = replacement;
346 }
347
348 public void setWinPath( boolean isWinPath ) {
349 this.winPath = isWinPath;
350 }
351
352 public RegexSearchReplaceJob createJob() {
353 RegexSearchReplaceJob job = new RegexSearchReplaceJob();
354 if ( jobs == null ) {
355 jobs = new ArrayList();
356 }
357 jobs.add( job );
358 return job;
359
360 }
361
362 public FileSet createFileset() {
363 if ( this.fileset != null || this.file != null ) {
364 throw new BuildException( "Error - Only one file or one fileset may be given!!" );
365 }
366 fileset = new FileSet();
367 return fileset;
368 }
369
370}
Note: See TracBrowser for help on using the repository browser.