1 18 package org.apache.tools.ant.taskdefs.optional; 19 20 import java.io.BufferedReader ; 21 import java.io.BufferedWriter ; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileReader ; 25 import java.io.FileOutputStream ; 26 import java.io.FileWriter ; 27 import java.io.InputStreamReader ; 28 import java.io.IOException ; 29 import java.io.OutputStreamWriter ; 30 import java.io.PrintWriter ; 31 import java.io.Reader ; 32 import java.io.Writer ; 33 import java.util.Vector ; 34 import org.apache.tools.ant.BuildException; 35 import org.apache.tools.ant.DirectoryScanner; 36 import org.apache.tools.ant.Project; 37 import org.apache.tools.ant.Task; 38 import org.apache.tools.ant.types.FileSet; 39 import org.apache.tools.ant.types.RegularExpression; 40 import org.apache.tools.ant.types.Substitution; 41 import org.apache.tools.ant.util.FileUtils; 42 import org.apache.tools.ant.util.regexp.Regexp; 43 44 115 public class ReplaceRegExp extends Task { 116 117 private File file; 118 private String flags; 119 private boolean byline; 120 private Vector filesets; private RegularExpression regex; 122 private Substitution subs; 123 124 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 125 126 129 private String encoding = null; 130 131 132 public ReplaceRegExp() { 133 super(); 134 this.file = null; 135 this.filesets = new Vector (); 136 this.flags = ""; 137 this.byline = false; 138 139 this.regex = null; 140 this.subs = null; 141 } 142 143 144 149 public void setFile(File file) { 150 this.file = file; 151 } 152 153 154 159 public void setMatch(String match) { 160 if (regex != null) { 161 throw new BuildException("Only one regular expression is allowed"); 162 } 163 164 regex = new RegularExpression(); 165 regex.setPattern(match); 166 } 167 168 169 175 176 public void setReplace(String replace) { 177 if (subs != null) { 178 throw new BuildException("Only one substitution expression is " 179 + "allowed"); 180 } 181 182 subs = new Substitution(); 183 subs.setExpression(replace); 184 } 185 186 201 public void setFlags(String flags) { 202 this.flags = flags; 203 } 204 205 206 216 public void setByLine(String byline) { 217 Boolean res = Boolean.valueOf(byline); 218 219 if (res == null) { 220 res = Boolean.FALSE; 221 } 222 this.byline = res.booleanValue(); 223 } 224 225 233 public void setByLine(boolean byline) { 234 this.byline = byline; 235 } 236 237 238 245 public void setEncoding(String encoding) { 246 this.encoding = encoding; 247 } 248 249 253 public void addFileset(FileSet set) { 254 filesets.addElement(set); 255 } 256 257 258 264 public RegularExpression createRegexp() { 265 if (regex != null) { 266 throw new BuildException("Only one regular expression is allowed."); 267 } 268 269 regex = new RegularExpression(); 270 return regex; 271 } 272 273 274 279 public Substitution createSubstitution() { 280 if (subs != null) { 281 throw new BuildException("Only one substitution expression is " 282 + "allowed"); 283 } 284 285 subs = new Substitution(); 286 return subs; 287 } 288 289 290 300 protected String doReplace(RegularExpression r, 301 Substitution s, 302 String input, 303 int options) { 304 String res = input; 305 Regexp regexp = r.getRegexp(getProject()); 306 307 if (regexp.matches(input, options)) { 308 log("Found match; substituting", Project.MSG_DEBUG); 309 res = regexp.substitute(input, s.getExpression(getProject()), 310 options); 311 } 312 313 return res; 314 } 315 316 317 324 protected void doReplace(File f, int options) 325 throws IOException { 326 File temp = FILE_UTILS.createTempFile("replace", ".txt", null); 327 temp.deleteOnExit(); 328 329 Reader r = null; 330 Writer w = null; 331 332 try { 333 if (encoding == null) { 334 r = new FileReader (f); 335 w = new FileWriter (temp); 336 } else { 337 r = new InputStreamReader (new FileInputStream (f), encoding); 338 w = new OutputStreamWriter (new FileOutputStream (temp), 339 encoding); 340 } 341 342 BufferedReader br = new BufferedReader (r); 343 BufferedWriter bw = new BufferedWriter (w); 344 PrintWriter pw = new PrintWriter (bw); 345 346 boolean changes = false; 347 348 log("Replacing pattern '" + regex.getPattern(getProject()) 349 + "' with '" + subs.getExpression(getProject()) 350 + "' in '" + f.getPath() + "'" + (byline ? " by line" : "") 351 + (flags.length() > 0 ? " with flags: '" + flags + "'" : "") 352 + ".", Project.MSG_VERBOSE); 353 354 if (byline) { 355 StringBuffer linebuf = new StringBuffer (); 356 String line = null; 357 String res = null; 358 int c; 359 boolean hasCR = false; 360 361 do { 362 c = br.read(); 363 364 if (c == '\r') { 365 if (hasCR) { 366 line = linebuf.toString(); 368 res = doReplace(regex, subs, line, options); 369 370 if (!res.equals(line)) { 371 changes = true; 372 } 373 374 pw.print(res); 375 pw.print('\r'); 376 377 linebuf = new StringBuffer (); 378 } else { 380 hasCR = true; 382 } 383 } else if (c == '\n') { 384 line = linebuf.toString(); 386 res = doReplace(regex, subs, line, options); 387 388 if (!res.equals(line)) { 389 changes = true; 390 } 391 392 pw.print(res); 393 if (hasCR) { 394 pw.print('\r'); 395 hasCR = false; 396 } 397 pw.print('\n'); 398 399 linebuf = new StringBuffer (); 400 } else { if ((hasCR) || (c < 0)) { 402 line = linebuf.toString(); 404 res = doReplace(regex, subs, line, options); 405 406 if (!res.equals(line)) { 407 changes = true; 408 } 409 410 pw.print(res); 411 if (hasCR) { 412 pw.print('\r'); 413 hasCR = false; 414 } 415 416 linebuf = new StringBuffer (); 417 } 418 419 if (c >= 0) { 420 linebuf.append((char) c); 421 } 422 } 423 } while (c >= 0); 424 425 pw.flush(); 426 } else { 427 String buf = FileUtils.readFully(br); 428 if (buf == null) { 429 buf = ""; 430 } 431 432 String res = doReplace(regex, subs, buf, options); 433 434 if (!res.equals(buf)) { 435 changes = true; 436 } 437 438 pw.print(res); 439 pw.flush(); 440 } 441 442 r.close(); 443 r = null; 444 w.close(); 445 w = null; 446 447 if (changes) { 448 log("File has changed; saving the updated file", Project.MSG_VERBOSE); 449 try { 450 FILE_UTILS.rename(temp, f); 451 temp = null; 452 } catch (IOException e) { 453 throw new BuildException("Couldn't rename temporary file " 454 + temp, getLocation()); 455 } 456 } else { 457 log("No change made", Project.MSG_DEBUG); 458 } 459 } finally { 460 FileUtils.close(r); 461 FileUtils.close(w); 462 if (temp != null) { 463 temp.delete(); 464 } 465 } 466 } 467 468 469 474 public void execute() throws BuildException { 475 if (regex == null) { 476 throw new BuildException("No expression to match."); 477 } 478 if (subs == null) { 479 throw new BuildException("Nothing to replace expression with."); 480 } 481 482 if (file != null && filesets.size() > 0) { 483 throw new BuildException("You cannot supply the 'file' attribute " 484 + "and filesets at the same time."); 485 } 486 487 int options = 0; 488 489 if (flags.indexOf('g') != -1) { 490 options |= Regexp.REPLACE_ALL; 491 } 492 493 if (flags.indexOf('i') != -1) { 494 options |= Regexp.MATCH_CASE_INSENSITIVE; 495 } 496 497 if (flags.indexOf('m') != -1) { 498 options |= Regexp.MATCH_MULTILINE; 499 } 500 501 if (flags.indexOf('s') != -1) { 502 options |= Regexp.MATCH_SINGLELINE; 503 } 504 505 if (file != null && file.exists()) { 506 try { 507 doReplace(file, options); 508 } catch (IOException e) { 509 log("An error occurred processing file: '" 510 + file.getAbsolutePath() + "': " + e.toString(), 511 Project.MSG_ERR); 512 } 513 } else if (file != null) { 514 log("The following file is missing: '" 515 + file.getAbsolutePath() + "'", Project.MSG_ERR); 516 } 517 518 int sz = filesets.size(); 519 520 for (int i = 0; i < sz; i++) { 521 FileSet fs = (FileSet) (filesets.elementAt(i)); 522 DirectoryScanner ds = fs.getDirectoryScanner(getProject()); 523 524 String [] files = ds.getIncludedFiles(); 525 526 for (int j = 0; j < files.length; j++) { 527 File f = new File (fs.getDir(getProject()), files[j]); 528 529 if (f.exists()) { 530 try { 531 doReplace(f, options); 532 } catch (Exception e) { 533 log("An error occurred processing file: '" 534 + f.getAbsolutePath() + "': " + e.toString(), 535 Project.MSG_ERR); 536 } 537 } else { 538 log("The following file is missing: '" 539 + f.getAbsolutePath() + "'", Project.MSG_ERR); 540 } 541 } 542 } 543 } 544 545 } 546 547 548 | Popular Tags |