1. /*
  2. * Copyright 2003-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. *
  16. */
  17. package org.apache.tools.ant.util;
  18. import org.apache.tools.ant.Project;
  19. import org.apache.tools.ant.ProjectComponent;
  20. import org.apache.tools.ant.taskdefs.condition.Os;
  21. import org.apache.tools.ant.types.Resource;
  22. import org.apache.tools.ant.types.ResourceFactory;
  23. import org.apache.tools.ant.types.selectors.SelectorUtils;
  24. import java.io.File;
  25. import java.util.Vector;
  26. /**
  27. * this class provides utility methods to process resources
  28. *
  29. * @since Ant 1.5.2
  30. */
  31. public class ResourceUtils {
  32. /**
  33. * tells which source files should be reprocessed based on the
  34. * last modification date of target files
  35. * @param logTo where to send (more or less) interesting output
  36. * @param source array of resources bearing relative path and last
  37. * modification date
  38. * @param mapper filename mapper indicating how to find the target
  39. * files
  40. * @param targets object able to map as a resource a relative path
  41. * at <b>destination</b>
  42. * @return array containing the source files which need to be
  43. * copied or processed, because the targets are out of date or do
  44. * not exist
  45. */
  46. public static Resource[] selectOutOfDateSources(ProjectComponent logTo,
  47. Resource[] source,
  48. FileNameMapper mapper,
  49. ResourceFactory targets) {
  50. return selectOutOfDateSources(logTo, source, mapper, targets,
  51. FileUtils.newFileUtils()
  52. .getFileTimestampGranularity());
  53. }
  54. /**
  55. * tells which source files should be reprocessed based on the
  56. * last modification date of target files
  57. * @param logTo where to send (more or less) interesting output
  58. * @param source array of resources bearing relative path and last
  59. * modification date
  60. * @param mapper filename mapper indicating how to find the target
  61. * files
  62. * @param targets object able to map as a resource a relative path
  63. * at <b>destination</b>
  64. * @param granularity The number of milliseconds leeway to give
  65. * before deciding a target is out of date.
  66. * @return array containing the source files which need to be
  67. * copied or processed, because the targets are out of date or do
  68. * not exist
  69. * @since Ant 1.6.2
  70. */
  71. public static Resource[] selectOutOfDateSources(ProjectComponent logTo,
  72. Resource[] source,
  73. FileNameMapper mapper,
  74. ResourceFactory targets,
  75. long granularity) {
  76. long now = (new java.util.Date()).getTime() + granularity;
  77. Vector vresult = new Vector();
  78. for (int counter = 0; counter < source.length; counter++) {
  79. if (source[counter].getLastModified() > now) {
  80. logTo.log("Warning: " + source[counter].getName()
  81. + " modified in the future.",
  82. Project.MSG_WARN);
  83. }
  84. String[] targetnames =
  85. mapper.mapFileName(source[counter].getName()
  86. .replace('/', File.separatorChar));
  87. if (targetnames != null) {
  88. boolean added = false;
  89. StringBuffer targetList = new StringBuffer();
  90. for (int ctarget = 0; !added && ctarget < targetnames.length;
  91. ctarget++) {
  92. Resource atarget =
  93. targets.getResource(targetnames[ctarget]
  94. .replace(File.separatorChar, '/'));
  95. // if the target does not exist, or exists and
  96. // is older than the source, then we want to
  97. // add the resource to what needs to be copied
  98. if (!atarget.isExists()) {
  99. logTo.log(source[counter].getName() + " added as "
  100. + atarget.getName()
  101. + " doesn\'t exist.", Project.MSG_VERBOSE);
  102. vresult.addElement(source[counter]);
  103. added = true;
  104. } else if (!atarget.isDirectory() &&
  105. SelectorUtils.isOutOfDate(source[counter],
  106. atarget,
  107. (int) granularity)) {
  108. logTo.log(source[counter].getName() + " added as "
  109. + atarget.getName()
  110. + " is outdated.", Project.MSG_VERBOSE);
  111. vresult.addElement(source[counter]);
  112. added = true;
  113. } else {
  114. if (targetList.length() > 0) {
  115. targetList.append(", ");
  116. }
  117. targetList.append(atarget.getName());
  118. }
  119. }
  120. if (!added) {
  121. logTo.log(source[counter].getName()
  122. + " omitted as " + targetList.toString()
  123. + (targetnames.length == 1 ? " is" : " are ")
  124. + " up to date.", Project.MSG_VERBOSE);
  125. }
  126. } else {
  127. logTo.log(source[counter].getName()
  128. + " skipped - don\'t know how to handle it",
  129. Project.MSG_VERBOSE);
  130. }
  131. }
  132. Resource[] result = new Resource[vresult.size()];
  133. vresult.copyInto(result);
  134. return result;
  135. }
  136. }