/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.apache.tools.ant.types;

import java.io.File;
import java.util.Iterator;
import java.util.Stack;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.DirectoryScanner;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.types.resources.FileResource;
import org.apache.tools.zip.UnixStat;

A ArchiveFileSet is a FileSet with extra attributes useful in the context of archiving tasks. It includes a prefix attribute which is prepended to each entry in the output archive file as well as a fullpath attribute. It also supports Unix file permissions for files and directories.
Since:Ant 1.7
/** * A ArchiveFileSet is a FileSet with extra attributes useful in the * context of archiving tasks. * * It includes a prefix attribute which is prepended to each entry in * the output archive file as well as a fullpath attribute. It also * supports Unix file permissions for files and directories. * * @since Ant 1.7 */
public abstract class ArchiveFileSet extends FileSet { private static final int BASE_OCTAL = 8;
Default value for the dirmode attribute.
Since:Ant 1.5.2
/** * Default value for the dirmode attribute. * * @since Ant 1.5.2 */
public static final int DEFAULT_DIR_MODE = UnixStat.DIR_FLAG | UnixStat.DEFAULT_DIR_PERM;
Default value for the filemode attribute.
Since:Ant 1.5.2
/** * Default value for the filemode attribute. * * @since Ant 1.5.2 */
public static final int DEFAULT_FILE_MODE = UnixStat.FILE_FLAG | UnixStat.DEFAULT_FILE_PERM; private Resource src = null; private String prefix = ""; private String fullpath = ""; private boolean hasDir = false; private int fileMode = DEFAULT_FILE_MODE; private int dirMode = DEFAULT_DIR_MODE; private boolean fileModeHasBeenSet = false; private boolean dirModeHasBeenSet = false; private static final String ERROR_DIR_AND_SRC_ATTRIBUTES = "Cannot set both dir and src attributes"; private static final String ERROR_PATH_AND_PREFIX = "Cannot set both fullpath and prefix attributes"; private boolean errorOnMissingArchive = true; private String encoding = null;
Constructor for ArchiveFileSet
/** Constructor for ArchiveFileSet */
public ArchiveFileSet() { super(); }
Constructor using a fileset argument.
Params:
  • fileset – the fileset to use
/** * Constructor using a fileset argument. * @param fileset the fileset to use */
protected ArchiveFileSet(FileSet fileset) { super(fileset); }
Constructor using a archive fileset argument.
Params:
  • fileset – the archivefileset to use
/** * Constructor using a archive fileset argument. * @param fileset the archivefileset to use */
protected ArchiveFileSet(ArchiveFileSet fileset) { super(fileset); src = fileset.src; prefix = fileset.prefix; fullpath = fileset.fullpath; hasDir = fileset.hasDir; fileMode = fileset.fileMode; dirMode = fileset.dirMode; fileModeHasBeenSet = fileset.fileModeHasBeenSet; dirModeHasBeenSet = fileset.dirModeHasBeenSet; errorOnMissingArchive = fileset.errorOnMissingArchive; encoding = fileset.encoding; }
Set the directory for the fileset.
Params:
  • dir – the directory for the fileset
Throws:
/** * Set the directory for the fileset. * @param dir the directory for the fileset * @throws BuildException on error */
@Override public void setDir(File dir) throws BuildException { checkAttributesAllowed(); if (src != null) { throw new BuildException(ERROR_DIR_AND_SRC_ATTRIBUTES); } super.setDir(dir); hasDir = true; }
Set the source Archive file for the archivefileset. Prevents both "dir" and "src" from being specified.
Params:
  • a – the archive as a single element Resource collection.
/** * Set the source Archive file for the archivefileset. Prevents both * "dir" and "src" from being specified. * @param a the archive as a single element Resource collection. */
public void addConfigured(ResourceCollection a) { checkChildrenAllowed(); if (a.size() != 1) { throw new BuildException("only single argument resource collections" + " are supported as archives"); } setSrcResource(a.iterator().next()); }
Set the source Archive file for the archivefileset. Prevents both "dir" and "src" from being specified.
Params:
  • srcFile – The archive from which to extract entries.
/** * Set the source Archive file for the archivefileset. Prevents both * "dir" and "src" from being specified. * * @param srcFile The archive from which to extract entries. */
public void setSrc(File srcFile) { setSrcResource(new FileResource(srcFile)); }
Set the source Archive file for the archivefileset. Prevents both "dir" and "src" from being specified.
Params:
  • src – The archive from which to extract entries.
/** * Set the source Archive file for the archivefileset. Prevents both * "dir" and "src" from being specified. * * @param src The archive from which to extract entries. */
public void setSrcResource(Resource src) { checkArchiveAttributesAllowed(); if (hasDir) { throw new BuildException(ERROR_DIR_AND_SRC_ATTRIBUTES); } this.src = src; setChecked(false); }
Get the archive from which entries will be extracted.
Params:
  • p – the project to use
Returns:the source file
/** * Get the archive from which entries will be extracted. * @param p the project to use * @return the source file */
public File getSrc(Project p) { if (isReference()) { return ((ArchiveFileSet) getRef(p)).getSrc(p); } return getSrc(); }
Sets whether an error is thrown if an archive does not exist.
Params:
  • errorOnMissingArchive – true if missing archives cause errors, false if not.
Since:Ant 1.8.0
/** * Sets whether an error is thrown if an archive does not exist. * * @param errorOnMissingArchive true if missing archives cause errors, * false if not. * @since Ant 1.8.0 */
public void setErrorOnMissingArchive(boolean errorOnMissingArchive) { checkAttributesAllowed(); this.errorOnMissingArchive = errorOnMissingArchive; }
Get the archive file from which entries will be extracted.
Returns:the archive in case the archive is a file, null otherwise.
/** * Get the archive file from which entries will be extracted. * @return the archive in case the archive is a file, null otherwise. */
public File getSrc() { if (isReference()) { return getCheckedRef(ArchiveFileSet.class).getSrc(); } dieOnCircularReference(); if (src == null) { return null; } return src.asOptional(FileProvider.class).map(FileProvider::getFile).orElse(null); }
Performs the check for circular references and returns the referenced object. This method must be overridden together with getRef(Project) providing implementations containing the special support for FileSet references, which can be handled by all ArchiveFileSets. NB! This method cannot be implemented in AbstractFileSet in order to allow FileSet and DirSet to implement it as a private method.
Throws:
  • BuildException – if the reference is invalid (circular ref, wrong class, etc).
Returns:the dereferenced object.
/** * Performs the check for circular references and returns the * referenced object. * This method must be overridden together with * {@link AbstractFileSet#getRef(Project) getRef(Project)} * providing implementations containing the special support * for FileSet references, which can be handled by all ArchiveFileSets. * NB! This method cannot be implemented in AbstractFileSet in order to allow * FileSet and DirSet to implement it as a private method. * @return the dereferenced object. * @throws BuildException if the reference is invalid (circular ref, wrong class, etc). */
protected AbstractFileSet getRef() { return getCheckedRef(AbstractFileSet.class); }
Prepend this prefix to the path for each archive entry. Prevents both prefix and fullpath from being specified
Params:
  • prefix – The prefix to prepend to entries in the archive file.
/** * Prepend this prefix to the path for each archive entry. * Prevents both prefix and fullpath from being specified * * @param prefix The prefix to prepend to entries in the archive file. */
public void setPrefix(String prefix) { checkArchiveAttributesAllowed(); if (!prefix.isEmpty() && !fullpath.isEmpty()) { throw new BuildException(ERROR_PATH_AND_PREFIX); } this.prefix = prefix; }
Return the prefix prepended to entries in the archive file.
Params:
  • p – the project to use
Returns:the prefix
/** * Return the prefix prepended to entries in the archive file. * @param p the project to use * @return the prefix */
public String getPrefix(Project p) { if (isReference()) { return ((ArchiveFileSet) getRef(p)).getPrefix(p); } dieOnCircularReference(p); return prefix; }
Set the full pathname of the single entry in this fileset. Prevents both prefix and fullpath from being specified
Params:
  • fullpath – the full pathname of the single entry in this fileset.
/** * Set the full pathname of the single entry in this fileset. * Prevents both prefix and fullpath from being specified * * @param fullpath the full pathname of the single entry in this fileset. */
public void setFullpath(String fullpath) { checkArchiveAttributesAllowed(); if (!prefix.isEmpty() && !fullpath.isEmpty()) { throw new BuildException(ERROR_PATH_AND_PREFIX); } this.fullpath = fullpath; }
Return the full pathname of the single entry in this fileset.
Params:
  • p – the project to use
Returns:the full path
/** * Return the full pathname of the single entry in this fileset. * @param p the project to use * @return the full path */
public String getFullpath(Project p) { if (isReference()) { return ((ArchiveFileSet) getRef(p)).getFullpath(p); } dieOnCircularReference(p); return fullpath; }
Set the encoding used for this ZipFileSet.
Params:
  • enc – encoding as String.
Since:Ant 1.9.5
/** * Set the encoding used for this ZipFileSet. * @param enc encoding as String. * @since Ant 1.9.5 */
public void setEncoding(String enc) { checkAttributesAllowed(); this.encoding = enc; }
Get the encoding used for this ZipFileSet.
Returns:String encoding.
Since:Ant 1.9.5
/** * Get the encoding used for this ZipFileSet. * @return String encoding. * @since Ant 1.9.5 */
public String getEncoding() { if (isReference()) { AbstractFileSet ref = getRef(); return ref instanceof ArchiveFileSet ? ((ArchiveFileSet) ref).getEncoding() : null; } return encoding; }
Creates a scanner for this type of archive.
Returns:the scanner.
/** * Creates a scanner for this type of archive. * @return the scanner. */
protected abstract ArchiveScanner newArchiveScanner();
Return the DirectoryScanner associated with this FileSet. If the ArchiveFileSet defines a source Archive file, then an ArchiveScanner is returned instead.
Params:
  • p – the project to use
Returns:a directory scanner
/** * Return the DirectoryScanner associated with this FileSet. * If the ArchiveFileSet defines a source Archive file, then an ArchiveScanner * is returned instead. * @param p the project to use * @return a directory scanner */
@Override public DirectoryScanner getDirectoryScanner(Project p) { if (isReference()) { return getRef(p).getDirectoryScanner(p); } dieOnCircularReference(); if (src == null) { return super.getDirectoryScanner(p); } if (!src.isExists() && errorOnMissingArchive) { throw new BuildException( "The archive " + src.getName() + " doesn't exist"); } if (src.isDirectory()) { throw new BuildException("The archive " + src.getName() + " can't be a directory"); } ArchiveScanner as = newArchiveScanner(); as.setErrorOnMissingArchive(errorOnMissingArchive); as.setSrc(src); super.setDir(p.getBaseDir()); setupDirectoryScanner(as, p); as.init(); return as; }
Fulfill the ResourceCollection contract.
Returns:Iterator of Resources.
Since:Ant 1.7
/** * Fulfill the ResourceCollection contract. * @return Iterator of Resources. * @since Ant 1.7 */
@Override public Iterator<Resource> iterator() { if (isReference()) { return ((ResourceCollection) getRef()).iterator(); } if (src == null) { return super.iterator(); } return ((ArchiveScanner) getDirectoryScanner()).getResourceFiles(getProject()); }
Fulfill the ResourceCollection contract.
Returns:size of the collection as int.
Since:Ant 1.7
/** * Fulfill the ResourceCollection contract. * @return size of the collection as int. * @since Ant 1.7 */
@Override public int size() { if (isReference()) { return ((ResourceCollection) getRef()).size(); } if (src == null) { return super.size(); } return getDirectoryScanner().getIncludedFilesCount(); }
Indicate whether this ResourceCollection is composed entirely of Resources accessible via local filesystem conventions. If true, all Resources returned from this ResourceCollection should be instances of FileResource.
Returns:whether this is a filesystem-only resource collection.
Since:Ant 1.7
/** * Indicate whether this ResourceCollection is composed entirely of * Resources accessible via local filesystem conventions. If true, * all Resources returned from this ResourceCollection should be * instances of FileResource. * @return whether this is a filesystem-only resource collection. * @since Ant 1.7 */
@Override public boolean isFilesystemOnly() { if (isReference()) { return ((ArchiveFileSet) getRef()).isFilesystemOnly(); } dieOnCircularReference(); return src == null; }
A 3 digit octal string, specify the user, group and other modes in the standard Unix fashion; optional, default=0644
Params:
  • octalString – a String value
/** * A 3 digit octal string, specify the user, group and * other modes in the standard Unix fashion; * optional, default=0644 * @param octalString a <code>String</code> value */
public void setFileMode(String octalString) { checkArchiveAttributesAllowed(); integerSetFileMode(Integer.parseInt(octalString, BASE_OCTAL)); }
specify the user, group and other modes in the standard Unix fashion; optional, default=0644

We use the strange name so this method doesn't appear in IntrospectionHelpers list of attribute setters.

Params:
  • mode – a int value
Since:Ant 1.7
/** * specify the user, group and * other modes in the standard Unix fashion; * optional, default=0644 * * <p>We use the strange name so this method doesn't appear in * IntrospectionHelpers list of attribute setters.</p> * @param mode a <code>int</code> value * @since Ant 1.7 */
public void integerSetFileMode(int mode) { fileModeHasBeenSet = true; this.fileMode = UnixStat.FILE_FLAG | mode; }
Get the mode of the archive fileset
Params:
  • p – the project to use
Returns:the mode
/** * Get the mode of the archive fileset * @param p the project to use * @return the mode */
public int getFileMode(Project p) { if (isReference()) { return ((ArchiveFileSet) getRef(p)).getFileMode(p); } dieOnCircularReference(); return fileMode; }
Whether the user has specified the mode explicitly.
Returns:true if it has been set
/** * Whether the user has specified the mode explicitly. * @return true if it has been set */
public boolean hasFileModeBeenSet() { if (isReference()) { return ((ArchiveFileSet) getRef()).hasFileModeBeenSet(); } dieOnCircularReference(); return fileModeHasBeenSet; }
A 3 digit octal string, specify the user, group and other modes in the standard Unix fashion; optional, default=0755
Params:
  • octalString – a String value
/** * A 3 digit octal string, specify the user, group and * other modes in the standard Unix fashion; * optional, default=0755 * @param octalString a <code>String</code> value */
public void setDirMode(String octalString) { checkArchiveAttributesAllowed(); integerSetDirMode(Integer.parseInt(octalString, BASE_OCTAL)); }
specify the user, group and other modes in the standard Unix fashion; optional, default=0755

We use the strange name so this method doesn't appear in IntrospectionHelpers list of attribute setters.

Params:
  • mode – a int value
Since:Ant 1.7
/** * specify the user, group and * other modes in the standard Unix fashion; * optional, default=0755 * <p>We use the strange name so this method doesn't appear in * IntrospectionHelpers list of attribute setters.</p> * @param mode a <code>int</code> value * @since Ant 1.7 */
public void integerSetDirMode(int mode) { dirModeHasBeenSet = true; this.dirMode = UnixStat.DIR_FLAG | mode; }
Get the dir mode of the archive fileset
Params:
  • p – the project to use
Returns:the mode
/** * Get the dir mode of the archive fileset * @param p the project to use * @return the mode */
public int getDirMode(Project p) { if (isReference()) { return ((ArchiveFileSet) getRef(p)).getDirMode(p); } dieOnCircularReference(); return dirMode; }
Whether the user has specified the mode explicitly.
Returns:true if it has been set
/** * Whether the user has specified the mode explicitly. * * @return true if it has been set */
public boolean hasDirModeBeenSet() { if (isReference()) { return ((ArchiveFileSet) getRef()).hasDirModeBeenSet(); } dieOnCircularReference(); return dirModeHasBeenSet; }
A ArchiveFileset accepts another ArchiveFileSet or a FileSet as reference FileSets are often used by the war task for the lib attribute
Params:
  • zfs – the project to use
/** * A ArchiveFileset accepts another ArchiveFileSet or a FileSet as reference * FileSets are often used by the war task for the lib attribute * @param zfs the project to use */
protected void configureFileSet(ArchiveFileSet zfs) { zfs.setPrefix(prefix); zfs.setFullpath(fullpath); zfs.fileModeHasBeenSet = fileModeHasBeenSet; zfs.fileMode = fileMode; zfs.dirModeHasBeenSet = dirModeHasBeenSet; zfs.dirMode = dirMode; }
Return a ArchiveFileSet that has the same properties as this one.
Returns:the cloned archiveFileSet
Since:Ant 1.6
/** * Return a ArchiveFileSet that has the same properties * as this one. * @return the cloned archiveFileSet * @since Ant 1.6 */
@Override public Object clone() { if (isReference()) { return getCheckedRef(ArchiveFileSet.class).clone(); } return super.clone(); }
For file-based archivefilesets, return the same as for normal filesets; else just return the path of the zip.
Returns:for file based archivefilesets, included files as a list of semicolon-separated filenames. else just the name of the zip.
/** * For file-based archivefilesets, return the same as for normal filesets; * else just return the path of the zip. * @return for file based archivefilesets, included files as a list * of semicolon-separated filenames. else just the name of the zip. */
@Override public String toString() { if (hasDir && getProject() != null) { return super.toString(); } return src == null ? null : src.getName(); }
Return the prefix prepended to entries in the archive file.
Returns:the prefix.
Deprecated:since 1.7.
/** * Return the prefix prepended to entries in the archive file. * @return the prefix. * @deprecated since 1.7. */
@Deprecated public String getPrefix() { return prefix; }
Return the full pathname of the single entryZ in this fileset.
Returns:the full pathname.
Deprecated:since 1.7.
/** * Return the full pathname of the single entryZ in this fileset. * @return the full pathname. * @deprecated since 1.7. */
@Deprecated public String getFullpath() { return fullpath; }
Returns:the file mode.
Deprecated:since 1.7.
/** * @return the file mode. * @deprecated since 1.7. */
@Deprecated public int getFileMode() { return fileMode; }
Returns:the dir mode.
Deprecated:since 1.7.
/** * @return the dir mode. * @deprecated since 1.7. */
@Deprecated public int getDirMode() { return dirMode; }
A check attributes for archiveFileSet. If there is a reference, and it is a ArchiveFileSet, the archive fileset attributes cannot be used. (Note, we can only see if the reference is an archive fileset if the project has been set).
/** * A check attributes for archiveFileSet. * If there is a reference, and * it is a ArchiveFileSet, the archive fileset attributes * cannot be used. * (Note, we can only see if the reference is an archive * fileset if the project has been set). */
private void checkArchiveAttributesAllowed() { if (getProject() == null || (isReference() && (getRefid().getReferencedObject( getProject()) instanceof ArchiveFileSet))) { checkAttributesAllowed(); } } @Override protected synchronized void dieOnCircularReference(Stack<Object> stk, Project p) throws BuildException { if (isChecked()) { return; } // takes care of nested selectors super.dieOnCircularReference(stk, p); if (!isReference()) { if (src != null) { pushAndInvokeCircularReferenceCheck(src, stk, p); } setChecked(true); } } }