1. /*
  2. * Copyright 2001-2002,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;
  18. import java.io.File;
  19. import java.util.Stack;
  20. import java.util.StringTokenizer;
  21. import java.util.Vector;
  22. import org.apache.tools.ant.BuildException;
  23. import org.apache.tools.ant.Project;
  24. /**
  25. * FileList represents an explicitly named list of files. FileLists
  26. * are useful when you want to capture a list of files regardless of
  27. * whether they currently exist. By contrast, FileSet operates as a
  28. * filter, only returning the name of a matched file if it currently
  29. * exists in the file system.
  30. */
  31. public class FileList extends DataType {
  32. private Vector filenames = new Vector();
  33. private File dir;
  34. /**
  35. * The default constructor.
  36. *
  37. */
  38. public FileList() {
  39. super();
  40. }
  41. /**
  42. * A copy constructor.
  43. *
  44. * @param filelist a <code>FileList</code> value
  45. */
  46. protected FileList(FileList filelist) {
  47. this.dir = filelist.dir;
  48. this.filenames = filelist.filenames;
  49. setProject(filelist.getProject());
  50. }
  51. /**
  52. * Makes this instance in effect a reference to another FileList
  53. * instance.
  54. *
  55. * <p>You must not set another attribute or nest elements inside
  56. * this element if you make it a reference.</p>
  57. * @param r the reference to another filelist.
  58. * @exception BuildException if an error occurs.
  59. */
  60. public void setRefid(Reference r) throws BuildException {
  61. if ((dir != null) || (filenames.size() != 0)) {
  62. throw tooManyAttributes();
  63. }
  64. super.setRefid(r);
  65. }
  66. /**
  67. * Set the dir attribute.
  68. *
  69. * @param dir the directory this filelist is relative to.
  70. * @exception BuildException if an error occurs
  71. */
  72. public void setDir(File dir) throws BuildException {
  73. if (isReference()) {
  74. throw tooManyAttributes();
  75. }
  76. this.dir = dir;
  77. }
  78. /**
  79. * @param p the current project
  80. * @return the directory attribute
  81. */
  82. public File getDir(Project p) {
  83. if (isReference()) {
  84. return getRef(p).getDir(p);
  85. }
  86. return dir;
  87. }
  88. /**
  89. * Set the filenames attribute.
  90. *
  91. * @param filenames a string contains filenames, separated by , or
  92. * by whitespace.
  93. */
  94. public void setFiles(String filenames) {
  95. if (isReference()) {
  96. throw tooManyAttributes();
  97. }
  98. if (filenames != null && filenames.length() > 0) {
  99. StringTokenizer tok = new StringTokenizer(
  100. filenames, ", \t\n\r\f", false);
  101. while (tok.hasMoreTokens()) {
  102. this.filenames.addElement(tok.nextToken());
  103. }
  104. }
  105. }
  106. /**
  107. * Returns the list of files represented by this FileList.
  108. * @param p the current project
  109. * @return the list of files represented by this FileList.
  110. */
  111. public String[] getFiles(Project p) {
  112. if (isReference()) {
  113. return getRef(p).getFiles(p);
  114. }
  115. if (dir == null) {
  116. throw new BuildException("No directory specified for filelist.");
  117. }
  118. if (filenames.size() == 0) {
  119. throw new BuildException("No files specified for filelist.");
  120. }
  121. String[] result = new String[filenames.size()];
  122. filenames.copyInto(result);
  123. return result;
  124. }
  125. /**
  126. * Performs the check for circular references and returns the
  127. * referenced FileList.
  128. * @param p the current project
  129. * @return the FileList represented by a referenced filelist.
  130. */
  131. protected FileList getRef(Project p) {
  132. if (!isChecked()) {
  133. Stack stk = new Stack();
  134. stk.push(this);
  135. dieOnCircularReference(stk, p);
  136. }
  137. Object o = getRefid().getReferencedObject(p);
  138. if (!(o instanceof FileList)) {
  139. String msg = getRefid().getRefId() + " doesn\'t denote a filelist";
  140. throw new BuildException(msg);
  141. } else {
  142. return (FileList) o;
  143. }
  144. }
  145. /**
  146. * Inner class corresponding to the <file> nested element.
  147. */
  148. public static class FileName {
  149. private String name;
  150. /**
  151. * The name attribute of the file element.
  152. *
  153. * @param name the name of a file to add to the file list.
  154. */
  155. public void setName(String name) {
  156. this.name = name;
  157. }
  158. /**
  159. * @return the name of the file for this element.
  160. */
  161. public String getName() {
  162. return name;
  163. }
  164. }
  165. /**
  166. * Add a nested <file> nested element.
  167. *
  168. * @param name a configured file element with a name.
  169. */
  170. public void addConfiguredFile(FileName name) {
  171. if (name.getName() == null) {
  172. throw new BuildException(
  173. "No name specified in nested file element");
  174. }
  175. filenames.addElement(name.getName());
  176. }
  177. }