1 18 package org.apache.tools.ant.util; 19 20 import java.io.File ; 21 import java.io.Reader ; 22 import java.io.InputStream ; 23 import java.io.IOException ; 24 import java.io.OutputStream ; 25 import java.io.BufferedReader ; 26 import java.io.BufferedWriter ; 27 import java.io.InputStreamReader ; 28 import java.io.OutputStreamWriter ; 29 import java.io.BufferedInputStream ; 30 import java.util.Arrays ; 31 import java.util.Vector ; 32 import java.util.Iterator ; 33 34 import org.apache.tools.ant.Project; 35 import org.apache.tools.ant.ProjectComponent; 36 import org.apache.tools.ant.filters.util.ChainReaderHelper; 37 import org.apache.tools.ant.types.Resource; 38 import org.apache.tools.ant.types.TimeComparison; 39 import org.apache.tools.ant.types.ResourceFactory; 40 import org.apache.tools.ant.types.ResourceCollection; 41 import org.apache.tools.ant.types.FilterSetCollection; 42 import org.apache.tools.ant.types.resources.Union; 43 import org.apache.tools.ant.types.resources.Restrict; 44 import org.apache.tools.ant.types.resources.Resources; 45 import org.apache.tools.ant.types.resources.Touchable; 46 import org.apache.tools.ant.types.resources.selectors.Or; 47 import org.apache.tools.ant.types.resources.selectors.And; 48 import org.apache.tools.ant.types.resources.selectors.Not; 49 import org.apache.tools.ant.types.resources.selectors.Date; 50 import org.apache.tools.ant.types.resources.selectors.Type; 51 import org.apache.tools.ant.types.resources.selectors.Exists; 52 import org.apache.tools.ant.types.resources.selectors.ResourceSelector; 53 import org.apache.tools.ant.types.selectors.SelectorUtils; 54 55 57 62 public class ResourceUtils { 63 64 private static final class Outdated implements ResourceSelector { 65 private Resource control; 66 private long granularity; 67 private Outdated(Resource control, long granularity) { 68 this.control = control; 69 this.granularity = granularity; 70 } 71 public boolean isSelected(Resource r) { 72 return SelectorUtils.isOutOfDate(control, r, granularity); 73 } 74 } 75 76 private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); 77 78 private static final ResourceSelector NOT_EXISTS = new Not(new Exists()); 79 80 94 public static Resource[] selectOutOfDateSources(ProjectComponent logTo, 95 Resource[] source, 96 FileNameMapper mapper, 97 ResourceFactory targets) { 98 return selectOutOfDateSources(logTo, source, mapper, targets, 99 FILE_UTILS.getFileTimestampGranularity()); 100 } 101 102 119 public static Resource[] selectOutOfDateSources(ProjectComponent logTo, 120 Resource[] source, 121 FileNameMapper mapper, 122 ResourceFactory targets, 123 long granularity) { 124 Union u = new Union(); 125 u.addAll(Arrays.asList(source)); 126 ResourceCollection rc 127 = selectOutOfDateSources(logTo, u, mapper, targets, granularity); 128 return rc.size() == 0 ? new Resource[0] : ((Union) rc).listResources(); 129 } 130 131 143 public static ResourceCollection selectOutOfDateSources(ProjectComponent logTo, 144 ResourceCollection source, 145 FileNameMapper mapper, 146 ResourceFactory targets, 147 long granularity) { 148 if (source.size() == 0) { 149 logTo.log("No sources found.", Project.MSG_VERBOSE); 150 return Resources.NONE; 151 } 152 source = Union.getInstance(source); 153 logFuture(logTo, source, granularity); 154 155 Union result = new Union(); 156 for (Iterator iter = source.iterator(); iter.hasNext();) { 157 Resource sr = (Resource) iter.next(); 158 String srName = sr.getName(); 159 srName = srName == null 160 ? srName : srName.replace('/', File.separatorChar); 161 162 String [] targetnames = null; 163 try { 164 targetnames = mapper.mapFileName(srName); 165 } catch (Exception e) { 166 logTo.log("Caught " + e + " mapping resource " + sr, 167 Project.MSG_VERBOSE); 168 } 169 if (targetnames == null || targetnames.length == 0) { 170 logTo.log(sr + " skipped - don\'t know how to handle it", 171 Project.MSG_VERBOSE); 172 continue; 173 } 174 Union targetColl = new Union(); 175 for (int i = 0; i < targetnames.length; i++) { 176 targetColl.add(targets.getResource( 177 targetnames[i].replace(File.separatorChar, '/'))); 178 } 179 Restrict r = new Restrict(); 181 r.add(new And(new ResourceSelector[] {Type.FILE, new Or( 182 new ResourceSelector[] {NOT_EXISTS, new Outdated(sr, granularity)})})); 183 r.add(targetColl); 184 if (r.size() > 0) { 185 result.add(sr); 186 Resource t = (Resource) (r.iterator().next()); 187 logTo.log(sr.getName() + " added as " + t.getName() 188 + (t.isExists() ? " is outdated." : " doesn\'t exist."), 189 Project.MSG_VERBOSE); 190 continue; 191 } 192 logTo.log(sr.getName() 194 + " omitted as " + targetColl.toString() 195 + (targetColl.size() == 1 ? " is" : " are ") 196 + " up to date.", Project.MSG_VERBOSE); 197 } 198 return result; 199 } 200 201 214 public static void copyResource(Resource source, Resource dest) throws IOException { 215 copyResource(source, dest, null); 216 } 217 218 232 public static void copyResource(Resource source, Resource dest, Project project) 233 throws IOException { 234 copyResource(source, dest, null, null, false, 235 false, null, null, project); 236 } 237 238 265 public static void copyResource(Resource source, Resource dest, 266 FilterSetCollection filters, Vector filterChains, 267 boolean overwrite, boolean preserveLastModified, 268 String inputEncoding, String outputEncoding, 269 Project project) 270 throws IOException { 271 if (!overwrite) { 272 long slm = source.getLastModified(); 273 if (dest.isExists() && slm != 0 274 && dest.getLastModified() > slm) { 275 return; 276 } 277 } 278 final boolean filterSetsAvailable = (filters != null 279 && filters.hasFilters()); 280 final boolean filterChainsAvailable = (filterChains != null 281 && filterChains.size() > 0); 282 if (filterSetsAvailable) { 283 BufferedReader in = null; 284 BufferedWriter out = null; 285 try { 286 InputStreamReader isr = null; 287 if (inputEncoding == null) { 288 isr = new InputStreamReader (source.getInputStream()); 289 } else { 290 isr = new InputStreamReader (source.getInputStream(), 291 inputEncoding); 292 } 293 in = new BufferedReader (isr); 294 OutputStreamWriter osw = null; 295 if (outputEncoding == null) { 296 osw = new OutputStreamWriter (dest.getOutputStream()); 297 } else { 298 osw = new OutputStreamWriter (dest.getOutputStream(), 299 outputEncoding); 300 } 301 out = new BufferedWriter (osw); 302 if (filterChainsAvailable) { 303 ChainReaderHelper crh = new ChainReaderHelper(); 304 crh.setBufferSize(FileUtils.BUF_SIZE); 305 crh.setPrimaryReader(in); 306 crh.setFilterChains(filterChains); 307 crh.setProject(project); 308 Reader rdr = crh.getAssembledReader(); 309 in = new BufferedReader (rdr); 310 } 311 LineTokenizer lineTokenizer = new LineTokenizer(); 312 lineTokenizer.setIncludeDelims(true); 313 String newline = null; 314 String line = lineTokenizer.getToken(in); 315 while (line != null) { 316 if (line.length() == 0) { 317 out.newLine(); 320 } else { 321 newline = filters.replaceTokens(line); 322 out.write(newline); 323 } 324 line = lineTokenizer.getToken(in); 325 } 326 } finally { 327 FileUtils.close(out); 328 FileUtils.close(in); 329 } 330 } else if (filterChainsAvailable 331 || (inputEncoding != null 332 && !inputEncoding.equals(outputEncoding)) 333 || (inputEncoding == null && outputEncoding != null)) { 334 BufferedReader in = null; 335 BufferedWriter out = null; 336 try { 337 InputStreamReader isr = null; 338 if (inputEncoding == null) { 339 isr = new InputStreamReader (source.getInputStream()); 340 } else { 341 isr = new InputStreamReader (source.getInputStream(), 342 inputEncoding); 343 } 344 in = new BufferedReader (isr); 345 OutputStreamWriter osw = null; 346 if (outputEncoding == null) { 347 osw = new OutputStreamWriter (dest.getOutputStream()); 348 } else { 349 osw = new OutputStreamWriter (dest.getOutputStream(), 350 outputEncoding); 351 } 352 out = new BufferedWriter (osw); 353 if (filterChainsAvailable) { 354 ChainReaderHelper crh = new ChainReaderHelper(); 355 crh.setBufferSize(FileUtils.BUF_SIZE); 356 crh.setPrimaryReader(in); 357 crh.setFilterChains(filterChains); 358 crh.setProject(project); 359 Reader rdr = crh.getAssembledReader(); 360 in = new BufferedReader (rdr); 361 } 362 char[] buffer = new char[FileUtils.BUF_SIZE]; 363 while (true) { 364 int nRead = in.read(buffer, 0, buffer.length); 365 if (nRead == -1) { 366 break; 367 } 368 out.write(buffer, 0, nRead); 369 } 370 } finally { 371 FileUtils.close(out); 372 FileUtils.close(in); 373 } 374 } else { 375 InputStream in = null; 376 OutputStream out = null; 377 try { 378 in = source.getInputStream(); 379 out = dest.getOutputStream(); 380 381 byte[] buffer = new byte[FileUtils.BUF_SIZE]; 382 int count = 0; 383 do { 384 out.write(buffer, 0, count); 385 count = in.read(buffer, 0, buffer.length); 386 } while (count != -1); 387 } finally { 388 FileUtils.close(out); 389 FileUtils.close(in); 390 } 391 } 392 if (preserveLastModified && dest instanceof Touchable) { 393 setLastModified((Touchable) dest, source.getLastModified()); 394 } 395 } 396 398 407 public static void setLastModified(Touchable t, long time) { 408 t.touch((time < 0) ? System.currentTimeMillis() : time); 409 } 410 411 424 public static boolean contentEquals(Resource r1, Resource r2, boolean text) throws IOException { 425 if (r1.isExists() != r2.isExists()) { 426 return false; 427 } 428 if (!r1.isExists()) { 429 return true; 431 } 432 if (r1.isDirectory() || r2.isDirectory()) { 435 return false; 437 } 438 if (r1.equals(r2)) { 439 return true; 440 } 441 if (!text && r1.getSize() != r2.getSize()) { 442 return false; 443 } 444 return compareContent(r1, r2, text) == 0; 445 } 446 447 460 public static int compareContent(Resource r1, Resource r2, boolean text) throws IOException { 461 if (r1.equals(r2)) { 462 return 0; 463 } 464 boolean e1 = r1.isExists(); 465 boolean e2 = r2.isExists(); 466 if (!(e1 || e2)) { 467 return 0; 468 } 469 if (e1 != e2) { 470 return e1 ? 1 : -1; 471 } 472 boolean d1 = r1.isDirectory(); 473 boolean d2 = r2.isDirectory(); 474 if (d1 && d2) { 475 return 0; 476 } 477 if (d1 || d2) { 478 return d1 ? -1 : 1; 479 } 480 return text ? textCompare(r1, r2) : binaryCompare(r1, r2); 481 } 482 483 498 private static int binaryCompare(Resource r1, Resource r2) throws IOException { 499 InputStream in1 = null; 500 InputStream in2 = null; 501 try { 502 in1 = new BufferedInputStream (r1.getInputStream()); 503 in2 = new BufferedInputStream (r2.getInputStream()); 504 505 for (int b1 = in1.read(); b1 != -1; b1 = in1.read()) { 506 int b2 = in2.read(); 507 if (b1 != b2) { 508 return b1 > b2 ? 1 : -1; 509 } 510 } 511 return in2.read() == -1 ? 0 : -1; 512 } finally { 513 FileUtils.close(in1); 514 FileUtils.close(in2); 515 } 516 } 517 518 528 private static int textCompare(Resource r1, Resource r2) throws IOException { 529 BufferedReader in1 = null; 530 BufferedReader in2 = null; 531 try { 532 in1 = new BufferedReader (new InputStreamReader (r1.getInputStream())); 533 in2 = new BufferedReader (new InputStreamReader (r2.getInputStream())); 534 535 String expected = in1.readLine(); 536 while (expected != null) { 537 String actual = in2.readLine(); 538 if (!expected.equals(actual)) { 539 return expected.compareTo(actual); 540 } 541 expected = in1.readLine(); 542 } 543 return in2.readLine() == null ? 0 : -1; 544 } finally { 545 FileUtils.close(in1); 546 FileUtils.close(in2); 547 } 548 } 549 550 557 private static void logFuture(ProjectComponent logTo, 558 ResourceCollection rc, long granularity) { 559 long now = System.currentTimeMillis() + granularity; 560 Date sel = new Date(); 561 sel.setMillis(now); 562 sel.setWhen(TimeComparison.AFTER); 563 Restrict future = new Restrict(); 564 future.add(sel); 565 future.add(rc); 566 for (Iterator iter = future.iterator(); iter.hasNext();) { 567 logTo.log("Warning: " + ((Resource) iter.next()).getName() 568 + " modified in the future.", Project.MSG_WARN); 569 } 570 } 571 572 } 573 | Popular Tags |