1. /*
  2. * Copyright 2001-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 org.apache.tools.ant.BuildException;
  21. import org.apache.tools.ant.DirectoryScanner;
  22. import org.apache.tools.ant.Project;
  23. import org.apache.tools.zip.UnixStat;
  24. /**
  25. * A ZipFileSet is a FileSet with extra attributes useful in the context of
  26. * Zip/Jar tasks.
  27. *
  28. * A ZipFileSet extends FileSets with the ability to extract a subset of the
  29. * entries of a Zip file for inclusion in another Zip file. It also includes
  30. * a prefix attribute which is prepended to each entry in the output Zip file.
  31. *
  32. * Since ant 1.6 ZipFileSet can be defined with an id and referenced in packaging tasks
  33. *
  34. */
  35. public class ZipFileSet extends FileSet {
  36. /**
  37. * Default value for the dirmode attribute.
  38. *
  39. * @since Ant 1.5.2
  40. */
  41. public static final int DEFAULT_DIR_MODE =
  42. UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;
  43. /**
  44. * Default value for the filemode attribute.
  45. *
  46. * @since Ant 1.5.2
  47. */
  48. public static final int DEFAULT_FILE_MODE =
  49. UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM;
  50. private File srcFile = null;
  51. private String prefix = "";
  52. private String fullpath = "";
  53. private boolean hasDir = false;
  54. private int fileMode = DEFAULT_FILE_MODE;
  55. private int dirMode = DEFAULT_DIR_MODE;
  56. private boolean fileModeHasBeenSet = false;
  57. private boolean dirModeHasBeenSet = false;
  58. public ZipFileSet() {
  59. super();
  60. }
  61. protected ZipFileSet(FileSet fileset) {
  62. super(fileset);
  63. }
  64. protected ZipFileSet(ZipFileSet fileset) {
  65. super(fileset);
  66. srcFile = fileset.srcFile;
  67. prefix = fileset.prefix;
  68. fullpath = fileset.fullpath;
  69. hasDir = fileset.hasDir;
  70. fileMode = fileset.fileMode;
  71. dirMode = fileset.dirMode;
  72. fileModeHasBeenSet = fileset.fileModeHasBeenSet;
  73. dirModeHasBeenSet = fileset.dirModeHasBeenSet;
  74. }
  75. /**
  76. * Set the directory for the fileset. Prevents both "dir" and "src"
  77. * from being specified.
  78. */
  79. public void setDir(File dir) throws BuildException {
  80. if (isReference()) {
  81. throw tooManyAttributes();
  82. }
  83. if (srcFile != null) {
  84. throw new BuildException("Cannot set both dir and src attributes");
  85. } else {
  86. super.setDir(dir);
  87. hasDir = true;
  88. }
  89. }
  90. /**
  91. * Set the source Zip file for the zipfileset. Prevents both
  92. * "dir" and "src" from being specified.
  93. *
  94. * @param srcFile The zip file from which to extract entries.
  95. */
  96. public void setSrc(File srcFile) {
  97. if (isReference()) {
  98. throw tooManyAttributes();
  99. }
  100. if (hasDir) {
  101. throw new BuildException("Cannot set both dir and src attributes");
  102. }
  103. this.srcFile = srcFile;
  104. }
  105. /**
  106. * Get the zip file from which entries will be extracted.
  107. * References are not followed, since it is not possible
  108. * to have a reference to a ZipFileSet, only to a FileSet.
  109. */
  110. public File getSrc(Project p) {
  111. if (isReference()) {
  112. return ((ZipFileSet) getRef(p)).getSrc(p);
  113. }
  114. return srcFile;
  115. }
  116. /**
  117. * Prepend this prefix to the path for each zip entry.
  118. * Prevents both prefix and fullpath from being specified
  119. *
  120. * @param prefix The prefix to prepend to entries in the zip file.
  121. */
  122. public void setPrefix(String prefix) {
  123. if (!prefix.equals("") && !fullpath.equals("")) {
  124. throw new BuildException("Cannot set both fullpath and prefix attributes");
  125. }
  126. this.prefix = prefix;
  127. }
  128. /**
  129. * Return the prefix prepended to entries in the zip file.
  130. */
  131. public String getPrefix(Project p) {
  132. if (isReference()) {
  133. return ((ZipFileSet) getRef(p)).getPrefix(p);
  134. }
  135. return prefix;
  136. }
  137. /**
  138. * Set the full pathname of the single entry in this fileset.
  139. * Prevents both prefix and fullpath from being specified
  140. *
  141. * @param fullpath the full pathname of the single entry in this fileset.
  142. */
  143. public void setFullpath(String fullpath) {
  144. if (!prefix.equals("") && !fullpath.equals("")) {
  145. throw new BuildException("Cannot set both fullpath and prefix attributes");
  146. }
  147. this.fullpath = fullpath;
  148. }
  149. /**
  150. * Return the full pathname of the single entry in this fileset.
  151. */
  152. public String getFullpath(Project p) {
  153. if (isReference()) {
  154. return ((ZipFileSet) getRef(p)).getFullpath(p);
  155. }
  156. return fullpath;
  157. }
  158. /**
  159. * Return the DirectoryScanner associated with this FileSet.
  160. * If the ZipFileSet defines a source Zip file, then a ZipScanner
  161. * is returned instead.
  162. */
  163. public DirectoryScanner getDirectoryScanner(Project p) {
  164. if (isReference()) {
  165. return getRef(p).getDirectoryScanner(p);
  166. }
  167. if (srcFile != null) {
  168. ZipScanner zs = new ZipScanner();
  169. zs.setSrc(srcFile);
  170. super.setDir(p.getBaseDir());
  171. setupDirectoryScanner(zs, p);
  172. zs.init();
  173. return zs;
  174. } else {
  175. return super.getDirectoryScanner(p);
  176. }
  177. }
  178. /**
  179. * A 3 digit octal string, specify the user, group and
  180. * other modes in the standard Unix fashion;
  181. * optional, default=0644
  182. *
  183. * @since Ant 1.5.2
  184. */
  185. public void setFileMode(String octalString) {
  186. fileModeHasBeenSet = true;
  187. this.fileMode =
  188. UnixStat.FILE_FLAG | Integer.parseInt(octalString, 8);
  189. }
  190. /**
  191. * @since Ant 1.5.2
  192. */
  193. public int getFileMode(Project p) {
  194. if (isReference()) {
  195. return ((ZipFileSet) getRef(p)).getFileMode(p);
  196. }
  197. return fileMode;
  198. }
  199. /**
  200. * Whether the user has specified the mode explicitly.
  201. *
  202. * @since Ant 1.6
  203. */
  204. public boolean hasFileModeBeenSet() {
  205. if (isReference()) {
  206. return ((ZipFileSet) getRef(getProject())).hasFileModeBeenSet();
  207. }
  208. return fileModeHasBeenSet;
  209. }
  210. /**
  211. * A 3 digit octal string, specify the user, group and
  212. * other modes in the standard Unix fashion;
  213. * optional, default=0755
  214. *
  215. * @since Ant 1.5.2
  216. */
  217. public void setDirMode(String octalString) {
  218. dirModeHasBeenSet = true;
  219. this.dirMode =
  220. UnixStat.DIR_FLAG | Integer.parseInt(octalString, 8);
  221. }
  222. /**
  223. * @since Ant 1.5.2
  224. */
  225. public int getDirMode(Project p) {
  226. if (isReference()) {
  227. return ((ZipFileSet) getRef(p)).getDirMode(p);
  228. }
  229. return dirMode;
  230. }
  231. /**
  232. * Whether the user has specified the mode explicitly.
  233. *
  234. * @since Ant 1.6
  235. */
  236. public boolean hasDirModeBeenSet() {
  237. if (isReference()) {
  238. return ((ZipFileSet) getRef(getProject())).hasDirModeBeenSet();
  239. }
  240. return dirModeHasBeenSet;
  241. }
  242. /**
  243. * A ZipFileset accepts another ZipFileSet or a FileSet as reference
  244. * FileSets are often used by the war task for the lib attribute
  245. */
  246. protected AbstractFileSet getRef(Project p) {
  247. if (!isChecked()) {
  248. Stack stk = new Stack();
  249. stk.push(this);
  250. dieOnCircularReference(stk, p);
  251. }
  252. Object o = getRefid().getReferencedObject(p);
  253. if (o instanceof ZipFileSet) {
  254. return (AbstractFileSet) o;
  255. } else if (o instanceof FileSet) {
  256. ZipFileSet zfs = new ZipFileSet((FileSet) o);
  257. zfs.setPrefix(prefix);
  258. zfs.setFullpath(fullpath);
  259. zfs.fileModeHasBeenSet = fileModeHasBeenSet;
  260. zfs.fileMode = fileMode;
  261. zfs.dirModeHasBeenSet = dirModeHasBeenSet;
  262. zfs.dirMode = dirMode;
  263. return zfs;
  264. } else {
  265. String msg = getRefid().getRefId() + " doesn\'t denote a zipfileset or a fileset";
  266. throw new BuildException(msg);
  267. }
  268. }
  269. /**
  270. * Return a ZipFileSet that has the same properties
  271. * as this one.
  272. * @since Ant 1.6
  273. */
  274. public Object clone() {
  275. if (isReference()) {
  276. return ((ZipFileSet) getRef(getProject())).clone();
  277. } else {
  278. return super.clone();
  279. }
  280. }
  281. }