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

Last change on this file since 21843 was 21843, checked in by oranfry, 14 years ago

api change

File size: 9.2 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 fromLine = -1;
40 private int toLine = -1;
41 private boolean winPath = false;
42
43 public static void main( String[] args ) {
44
45 RegexSearchReplace rsr = new RegexSearchReplace();
46 rsr.setFile(new File (args[0]));
47 rsr.setPattern(args[1]);
48 rsr.setReplacement(args[2]);
49 rsr.setLines(args[3]);
50
51 rsr.execute();
52
53 }
54
55 public void execute() {
56
57 if ( file == null && fileset == null ) {
58 throw new BuildException( "Error - No file or fileset specified !!" );
59 }
60
61 if ( file != null && !file.exists() ) {
62 throw new BuildException( "Error - File not found !!" );
63 }
64
65 DirectoryScanner dirScanner = null;
66 if ( fileset != null ) {
67 dirScanner = fileset.getDirectoryScanner(project);
68 dirScanner.scan();
69 }
70
71 if ( jobs == null && pattern == null ) {
72 throw new BuildException( "Error - No pattern attribute and no nested jobs !!" );
73 }
74
75 if ( jobs != null && pattern != null ) {
76 throw new BuildException( "Error - Both pattern attribute and nested jobs given !!" );
77 }
78
79 if ( pattern != null && replacement == null ) {
80 throw new BuildException( "Error - pattern attribute given but no replacement attribute given !!" );
81 }
82
83 if ( jobs != null ) {
84 for ( int i=0; i<jobs.size(); i++ ) {
85 if ( ((RegexSearchReplaceJob)(jobs.get(i))).getPattern() == null ) {
86 throw new BuildException( "Error - One of the jobs lacks a pattern!!" );
87 }
88 if ( ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement() == null ) {
89 throw new BuildException( "Error - One of the jobs lacks a replacement!!" );
90 }
91 }
92 }
93
94
95 //sus out filename(s)
96 File[] files = null;
97 if ( file != null ) {
98 files = new File[1];
99 files[0] = file;
100 } else {
101 String[] fileStrings = dirScanner.getIncludedFiles();
102 files = new File[fileStrings.length];
103 for ( int i=0; i<fileStrings.length; i++ ) {
104 files[i] = new File( dirScanner.getBasedir() + File.separator + fileStrings[i] );
105 }
106 }
107
108 //output greeting
109 System.out.println( "--------------------" );
110 System.out.println( " RegexSearchReplace " );
111 System.out.println( "--------------------" );
112
113 //output replacement(s)
114 System.out.println( "Replacements:" );
115 if ( pattern != null ) {
116 System.out.println( " " + pattern + " -> " + replacement );
117 } else {
118 for ( int i=0; i<jobs.size(); i++ ) {
119 System.out.println( " " + ((RegexSearchReplaceJob)(jobs.get(i))).getPattern() + " -> " + ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement() );
120 }
121 }
122 System.out.println();
123
124 //output lines if necessary
125 if ( this.fromLine != -1 || this.toLine != -1 ) {
126 System.out.println( "Lines: " + (this.fromLine==-1?"Start":Integer.toString(this.fromLine)) + " ~ " + (this.toLine==-1?"End":Integer.toString(this.toLine)) );
127 System.out.println();
128 }
129
130 System.out.println( "Files: " );
131 for ( int fileIndex=0; fileIndex<files.length; fileIndex++ ) {
132
133 int noReplaces = 0;
134
135 File inputFile = files[fileIndex];
136 System.out.println( " " + inputFile );
137
138 //create the output stream
139 BufferedWriter out = null;
140 File temp = null;
141 try {
142 //create temp file.
143 temp = File.createTempFile("rsr", ".tmp");
144
145 //delete temp file when program exits.
146 temp.deleteOnExit();
147
148 //writer to temp file
149 out = new BufferedWriter( new OutputStreamWriter(new FileOutputStream(temp), "UTF8") );
150
151 } catch (IOException e) {
152 throw new BuildException( "Error - Couldn't create or open the temp file" );
153 }
154
155
156 //create the input stream
157 BufferedReader in = null;
158 try {
159 in = new BufferedReader( new InputStreamReader(new FileInputStream(inputFile), "UTF8") );
160 } catch ( Exception e ) {
161 throw new BuildException( "Error - Couldn't open the specified file" );
162 }
163
164 //pass the file through, searching and replacing
165 String line = null;
166 int lineNumber = 1;
167 boolean hasMoreLines = true;
168 while ( hasMoreLines ) {
169
170 try {
171 line = in.readLine();
172 } catch ( Exception e ) {
173 System.err.println( e.getMessage() );
174 throw new BuildException( "Error - Couldn't read from the specified file" );
175 }
176
177 if ( line == null ) {
178 hasMoreLines = false;
179 } else {
180
181 //only if within the given line range
182 if ( ( fromLine == -1 || lineNumber >= fromLine ) && ( toLine == -1 || lineNumber < toLine ) ) {
183 String oldLine = line;
184 if ( pattern != null ) {
185 String rp = replacement;
186 if ( winPath ) {
187 rp = rp.replaceAll("\\\\","\\\\\\\\");
188 }
189 line = line.replaceAll((String)pattern, (String)rp);
190 } else {
191 for ( int i=0; i<jobs.size(); i++ ) {
192 String rp = ((RegexSearchReplaceJob)(jobs.get(i))).getReplacement();
193 if ( ((RegexSearchReplaceJob)(jobs.get(i))).getWinPath() ) {
194 rp = rp.replaceAll("\\\\","\\\\\\\\");
195 }
196 line = line.replaceAll( ((RegexSearchReplaceJob)(jobs.get(i))).getPattern(), rp );
197 }
198 }
199
200 if ( !oldLine.equals( line ) ) {
201 noReplaces++;
202 }
203 }
204
205 try {
206 out.write( line );
207 out.newLine();
208 } catch ( Exception e ) {
209 throw new BuildException( "Error - Couldn't write to the temp file" );
210 }
211 }
212 lineNumber++;
213 }
214
215 try {
216 //close them both up
217 in.close();
218 out.close();
219 } catch ( Exception e ) {
220 throw new BuildException( "Error - Couldn't close a file" );
221 }
222
223
224 //copy the new file (temp) over the original
225 InputStream i;
226 OutputStream o;
227 try {
228 i = new FileInputStream(temp);
229 o = new FileOutputStream(inputFile);
230
231 } catch ( Exception e ) {
232 throw new BuildException( "Error - Couldn't open the temp file" );
233 }
234
235 try {
236
237 // Transfer bytes from in to out
238 byte[] buf = new byte[1024];
239 int len;
240 while ((len = i.read(buf)) > 0) {
241 o.write(buf, 0, len);
242 }
243
244 //close them up
245 i.close();
246 o.close();
247 } catch ( Exception e ) {
248 throw new BuildException( "Error - Couldn't write to the specified file" );
249 }
250
251
252 if ( noReplaces == 0 ) {
253 System.out.println( " No Changes Made" );
254 } else if ( noReplaces == 1 ) {
255 System.out.println( " Successfully changed 1 line" );
256 } else {
257 System.out.println( " Successfully changed " + noReplaces + " lines" );
258 }
259 System.out.println();
260
261 }
262
263 }
264
265 public void setFile(File file) {
266 if ( this.fileset != null || this.file != null ) {
267 throw new BuildException( "Error - Only one file or one fileset may be given!!" );
268 }
269 this.file = file;
270 }
271
272 public void setLines(String lines) {
273 //lines should be in the form "2" or "2-5"
274
275 //trim
276 lines.replaceAll("\\s","");
277
278 if ( lines == "" ) {
279 throw new BuildException( "Error - no line number(s) given in lines attribute!! " );
280 }
281
282 //split into parts
283 String[] parts = lines.split("-",2);
284
285 try {
286 if ( parts.length == 1 ) {
287 this.fromLine = Integer.parseInt( parts[0] );
288 this.toLine = this.fromLine + 1;
289 } else {
290 if ( !parts[0].equals("") ) this.fromLine = Integer.parseInt( parts[0] );
291 if ( !parts[1].equals("") ) this.toLine = Integer.parseInt( parts[1] );
292 }
293 } catch( NumberFormatException nfe ) {
294 throw new BuildException( "Error - invalid line numbers given in lines attribute!! '" + parts[0] + "' - '" + parts[1] + "'" );
295 }
296
297 }
298
299
300 public void setPattern(String pattern) {
301 this.pattern = pattern;
302 }
303
304 public void setReplacement(String replacement) {
305 replacement = replacement.replaceAll( "\\\\", "\\\\\\\\" );
306 this.replacement = replacement;
307 }
308
309 public void setWinPath( boolean isWinPath ) {
310 this.winPath = isWinPath;
311 }
312
313 public RegexSearchReplaceJob createJob() {
314 RegexSearchReplaceJob job = new RegexSearchReplaceJob();
315 if ( jobs == null ) {
316 jobs = new ArrayList();
317 }
318 jobs.add( job );
319 return job;
320
321 }
322
323 public FileSet createFileset() {
324 if ( this.fileset != null || this.file != null ) {
325 throw new BuildException( "Error - Only one file or one fileset may be given!!" );
326 }
327 fileset = new FileSet();
328 return fileset;
329 }
330
331}
Note: See TracBrowser for help on using the repository browser.