1. /*
  2. * Copyright 2000-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.types.selectors;
  18. import org.apache.tools.ant.types.Mapper;
  19. import org.apache.tools.ant.BuildException;
  20. import org.apache.tools.ant.util.IdentityMapper;
  21. import org.apache.tools.ant.util.FileNameMapper;
  22. import org.apache.tools.ant.util.FileUtils;
  23. import java.io.File;
  24. /**
  25. * A mapping selector is an abstract class adding mapping support to the base
  26. * selector
  27. */
  28. public abstract class MappingSelector extends BaseSelector {
  29. protected File targetdir = null;
  30. protected Mapper mapperElement = null;
  31. protected FileNameMapper map = null;
  32. protected int granularity = 0;
  33. /**
  34. * Creates a new <code>MappingSelector</code> instance.
  35. *
  36. */
  37. public MappingSelector() {
  38. granularity = (int) FileUtils.newFileUtils().getFileTimestampGranularity();
  39. }
  40. /**
  41. * The name of the file or directory which is checked for out-of-date
  42. * files.
  43. *
  44. * @param targetdir the directory to scan looking for files.
  45. */
  46. public void setTargetdir(File targetdir) {
  47. this.targetdir = targetdir;
  48. }
  49. /**
  50. * Defines the FileNameMapper to use (nested mapper element).
  51. * @return a mapper to be configured
  52. * @throws BuildException if more that one mapper defined
  53. */
  54. public Mapper createMapper() throws BuildException {
  55. if (mapperElement != null) {
  56. throw new BuildException("Cannot define more than one mapper");
  57. }
  58. mapperElement = new Mapper(getProject());
  59. return mapperElement;
  60. }
  61. /**
  62. * Checks to make sure all settings are kosher. In this case, it
  63. * means that the dest attribute has been set and we have a mapper.
  64. */
  65. public void verifySettings() {
  66. if (targetdir == null) {
  67. setError("The targetdir attribute is required.");
  68. }
  69. if (mapperElement == null) {
  70. map = new IdentityMapper();
  71. } else {
  72. map = mapperElement.getImplementation();
  73. }
  74. if (map == null) {
  75. setError("Could not set <mapper> element.");
  76. }
  77. }
  78. /**
  79. * The heart of the matter. This is where the selector gets to decide
  80. * on the inclusion of a file in a particular fileset.
  81. *
  82. * @param basedir the base directory the scan is being done from
  83. * @param filename is the name of the file to check
  84. * @param file is a java.io.File object the selector can use
  85. * @return whether the file should be selected or not
  86. */
  87. public boolean isSelected(File basedir, String filename, File file) {
  88. // throw BuildException on error
  89. validate();
  90. // Determine file whose out-of-dateness is to be checked
  91. String[] destfiles = map.mapFileName(filename);
  92. // If filename does not match the To attribute of the mapper
  93. // then filter it out of the files we are considering
  94. if (destfiles == null) {
  95. return false;
  96. }
  97. // Sanity check
  98. if (destfiles.length != 1 || destfiles[0] == null) {
  99. throw new BuildException("Invalid destination file results for "
  100. + targetdir.getName() + " with filename " + filename);
  101. }
  102. String destname = destfiles[0];
  103. File destfile = new File(targetdir, destname);
  104. boolean selected = selectionTest(file, destfile);
  105. return selected;
  106. }
  107. /**
  108. * this test is our selection test that compared the file with the destfile
  109. * @param srcfile file to test; may be null
  110. * @param destfile destination file
  111. * @return true if source file compares with destination file
  112. */
  113. protected abstract boolean selectionTest(File srcfile, File destfile);
  114. /**
  115. * Sets the number of milliseconds leeway we will give before we consider
  116. * a file out of date. Defaults to 2000 on MS-DOS derivatives as the FAT
  117. * file system.
  118. * @param granularity the leeway in milliseconds
  119. */
  120. public void setGranularity(int granularity) {
  121. this.granularity = granularity;
  122. }
  123. }