1 18 package org.apache.tools.ant.types; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.util.Enumeration ; 23 import java.util.Hashtable ; 24 import java.util.Properties ; 25 import java.util.Vector ; 26 27 import org.apache.tools.ant.Project; 28 import org.apache.tools.ant.BuildException; 29 import org.apache.tools.ant.util.FileUtils; 30 31 37 public class FilterSet extends DataType implements Cloneable { 38 39 43 public static class Filter { 44 46 String token; 47 48 49 String value; 50 52 58 public Filter(String token, String value) { 59 setToken(token); 60 setValue(value); 61 } 62 63 66 public Filter() { 67 } 68 69 74 public void setToken(String token) { 75 this.token = token; 76 } 77 78 83 public void setValue(String value) { 84 this.value = value; 85 } 86 87 92 public String getToken() { 93 return token; 94 } 95 96 101 public String getValue() { 102 return value; 103 } 104 } 105 106 110 public class FiltersFile { 111 112 115 public FiltersFile() { 116 } 117 118 123 public void setFile(File file) { 124 filtersFiles.add(file); 125 } 126 } 127 128 133 public static class OnMissing extends EnumeratedAttribute { 134 private static final String [] VALUES 135 = new String [] {"fail", "warn", "ignore"}; 136 137 138 public static final OnMissing FAIL = new OnMissing("fail"); 139 140 public static final OnMissing WARN = new OnMissing("warn"); 141 142 public static final OnMissing IGNORE = new OnMissing("ignore"); 143 144 private static final int FAIL_INDEX = 0; 145 private static final int WARN_INDEX = 1; 146 private static final int IGNORE_INDEX = 2; 147 148 151 public OnMissing() { 152 } 153 154 158 public OnMissing(String value) { 159 setValue(value); 160 } 161 162 164 public String [] getValues() { 165 return VALUES; 166 } 167 } 168 169 170 public static final String DEFAULT_TOKEN_START = "@"; 171 172 173 public static final String DEFAULT_TOKEN_END = "@"; 174 175 private String startOfToken = DEFAULT_TOKEN_START; 176 private String endOfToken = DEFAULT_TOKEN_END; 177 178 179 private Vector passedTokens; 180 181 private boolean duplicateToken = false; 182 183 private boolean recurse = true; 184 private Hashtable filterHash = null; 185 private Vector filtersFiles = new Vector (); 186 private OnMissing onMissingFiltersFile = OnMissing.FAIL; 187 private boolean readingFiles = false; 188 189 private int recurseDepth = 0; 190 191 194 private Vector filters = new Vector (); 195 196 199 public FilterSet() { 200 } 201 202 207 protected FilterSet(FilterSet filterset) { 208 super(); 209 this.filters = (Vector ) filterset.getFilters().clone(); 210 } 211 212 217 protected synchronized Vector getFilters() { 218 if (isReference()) { 219 return getRef().getFilters(); 220 } 221 if (!readingFiles) { 223 readingFiles = true; 224 for (int i = 0, sz = filtersFiles.size(); i < sz; i++) { 225 readFiltersFromFile((File ) filtersFiles.get(i)); 226 } 227 filtersFiles.clear(); 228 readingFiles = false; 229 } 230 return filters; 231 } 232 233 238 protected FilterSet getRef() { 239 return (FilterSet) getCheckedRef(FilterSet.class, "filterset"); 240 } 241 242 247 public synchronized Hashtable getFilterHash() { 248 if (filterHash == null) { 249 filterHash = new Hashtable (getFilters().size()); 250 for (Enumeration e = getFilters().elements(); e.hasMoreElements();) { 251 Filter filter = (Filter) e.nextElement(); 252 filterHash.put(filter.getToken(), filter.getValue()); 253 } 254 } 255 return filterHash; 256 } 257 258 265 public void setFiltersfile(File filtersFile) throws BuildException { 266 if (isReference()) { 267 throw tooManyAttributes(); 268 } 269 filtersFiles.add(filtersFile); 270 } 271 272 277 public void setBeginToken(String startOfToken) { 278 if (isReference()) { 279 throw tooManyAttributes(); 280 } 281 if (startOfToken == null || "".equals(startOfToken)) { 282 throw new BuildException("beginToken must not be empty"); 283 } 284 this.startOfToken = startOfToken; 285 } 286 287 292 public String getBeginToken() { 293 if (isReference()) { 294 return getRef().getBeginToken(); 295 } 296 return startOfToken; 297 } 298 299 304 public void setEndToken(String endOfToken) { 305 if (isReference()) { 306 throw tooManyAttributes(); 307 } 308 if (endOfToken == null || "".equals(endOfToken)) { 309 throw new BuildException("endToken must not be empty"); 310 } 311 this.endOfToken = endOfToken; 312 } 313 314 319 public String getEndToken() { 320 if (isReference()) { 321 return getRef().getEndToken(); 322 } 323 return endOfToken; 324 } 325 326 330 public void setRecurse(boolean recurse) { 331 this.recurse = recurse; 332 } 333 334 338 public boolean isRecurse() { 339 return recurse; 340 } 341 342 348 public synchronized void readFiltersFromFile(File filtersFile) throws BuildException { 349 if (isReference()) { 350 throw tooManyAttributes(); 351 } 352 if (!filtersFile.exists()) { 353 handleMissingFile("Could not read filters from file " 354 + filtersFile + " as it doesn't exist."); 355 } 356 if (filtersFile.isFile()) { 357 log("Reading filters from " + filtersFile, Project.MSG_VERBOSE); 358 FileInputStream in = null; 359 try { 360 Properties props = new Properties (); 361 in = new FileInputStream (filtersFile); 362 props.load(in); 363 364 Enumeration e = props.propertyNames(); 365 Vector filts = getFilters(); 366 while (e.hasMoreElements()) { 367 String strPropName = (String ) e.nextElement(); 368 String strValue = props.getProperty(strPropName); 369 filts.addElement(new Filter(strPropName, strValue)); 370 } 371 } catch (Exception ex) { 372 throw new BuildException("Could not read filters from file: " 373 + filtersFile); 374 } finally { 375 FileUtils.close(in); 376 } 377 } else { 378 handleMissingFile( 379 "Must specify a file rather than a directory in " 380 + "the filtersfile attribute:" + filtersFile); 381 } 382 filterHash = null; 383 } 384 385 395 public synchronized String replaceTokens(String line) { 396 return iReplaceTokens(line); 397 } 398 399 404 public synchronized void addFilter(Filter filter) { 405 if (isReference()) { 406 throw noChildrenAllowed(); 407 } 408 filters.addElement(filter); 409 filterHash = null; 410 } 411 412 417 public FiltersFile createFiltersfile() { 418 if (isReference()) { 419 throw noChildrenAllowed(); 420 } 421 return new FiltersFile(); 422 } 423 424 430 public synchronized void addFilter(String token, String value) { 431 if (isReference()) { 432 throw noChildrenAllowed(); 433 } 434 addFilter(new Filter(token, value)); 435 } 436 437 442 public synchronized void addConfiguredFilterSet(FilterSet filterSet) { 443 if (isReference()) { 444 throw noChildrenAllowed(); 445 } 446 for (Enumeration e = filterSet.getFilters().elements(); e.hasMoreElements();) { 447 addFilter((Filter) e.nextElement()); 448 } 449 } 450 451 456 public synchronized boolean hasFilters() { 457 return getFilters().size() > 0; 458 } 459 460 467 public synchronized Object clone() throws BuildException { 468 if (isReference()) { 469 return ((FilterSet) getRef()).clone(); 470 } 471 try { 472 FilterSet fs = (FilterSet) super.clone(); 473 fs.filters = (Vector ) getFilters().clone(); 474 fs.setProject(getProject()); 475 return fs; 476 } catch (CloneNotSupportedException e) { 477 throw new BuildException(e); 478 } 479 } 480 481 485 public void setOnMissingFiltersFile(OnMissing onMissingFiltersFile) { 486 this.onMissingFiltersFile = onMissingFiltersFile; 487 } 488 489 493 public OnMissing getOnMissingFiltersFile() { 494 return onMissingFiltersFile; 495 } 496 497 505 private synchronized String iReplaceTokens(String line) { 506 String beginToken = getBeginToken(); 507 String endToken = getEndToken(); 508 int index = line.indexOf(beginToken); 509 510 if (index > -1) { 511 Hashtable tokens = getFilterHash(); 512 try { 513 StringBuffer b = new StringBuffer (); 514 int i = 0; 515 String token = null; 516 String value = null; 517 518 while (index > -1) { 519 int endIndex = line.indexOf(endToken, 521 index + beginToken.length() + 1); 522 if (endIndex == -1) { 523 break; 524 } 525 token 526 = line.substring(index + beginToken.length(), endIndex); 527 b.append(line.substring(i, index)); 528 if (tokens.containsKey(token)) { 529 value = (String ) tokens.get(token); 530 if (recurse && !value.equals(token)) { 531 value = replaceTokens(value, token); 533 } 534 log("Replacing: " + beginToken + token + endToken 535 + " -> " + value, Project.MSG_VERBOSE); 536 b.append(value); 537 i = index + beginToken.length() + token.length() 538 + endToken.length(); 539 } else { 540 b.append(beginToken); 542 i = index + beginToken.length(); 543 } 544 index = line.indexOf(beginToken, i); 545 } 546 547 b.append(line.substring(i)); 548 return b.toString(); 549 } catch (StringIndexOutOfBoundsException e) { 550 return line; 551 } 552 } else { 553 return line; 554 } 555 } 556 557 564 private synchronized String replaceTokens(String line, String parent) 565 throws BuildException { 566 String beginToken = getBeginToken(); 567 String endToken = getEndToken(); 568 if (recurseDepth == 0) { 569 passedTokens = new Vector (); 570 } 571 recurseDepth++; 572 if (passedTokens.contains(parent) && !duplicateToken) { 573 duplicateToken = true; 574 System.out.println( 575 "Infinite loop in tokens. Currently known tokens : " 576 + passedTokens.toString() + "\nProblem token : " + beginToken 577 + parent + endToken + " called from " + beginToken 578 + passedTokens.lastElement().toString() + endToken); 579 recurseDepth--; 580 return parent; 581 } 582 passedTokens.addElement(parent); 583 String value = iReplaceTokens(line); 584 if (value.indexOf(beginToken) == -1 && !duplicateToken 585 && recurseDepth == 1) { 586 passedTokens = null; 587 } else if (duplicateToken) { 588 if (passedTokens.size() > 0) { 590 value = (String ) passedTokens.remove(passedTokens.size() - 1); 591 if (passedTokens.size() == 0) { 592 value = beginToken + value + endToken; 593 duplicateToken = false; 594 } 595 } 596 } 597 recurseDepth--; 598 return value; 599 } 600 601 private void handleMissingFile(String message) { 602 switch (onMissingFiltersFile.getIndex()) { 603 case OnMissing.IGNORE_INDEX: 604 return; 605 case OnMissing.FAIL_INDEX: 606 throw new BuildException(message); 607 case OnMissing.WARN_INDEX: 608 log(message, Project.MSG_WARN); 609 return; 610 default: 611 throw new BuildException("Invalid value for onMissingFiltersFile"); 612 } 613 } 614 615 } 616 | Popular Tags |