diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java | 596 |
1 files changed, 596 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java new file mode 100644 index 00000000..e9a07303 --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/ArchiveFileSet.java @@ -0,0 +1,596 @@ +/* + * 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 + * + * http://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 + */ +public abstract class ArchiveFileSet extends FileSet { + + private static final int BASE_OCTAL = 8; + + /** + * 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 + */ + 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 */ + public ArchiveFileSet() { + super(); + } + + /** + * Constructor using a fileset argument. + * @param fileset the fileset to use + */ + protected ArchiveFileSet(FileSet fileset) { + super(fileset); + } + + /** + * 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. + * @param dir the directory for the fileset + * @throws BuildException on error + */ + 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. + * @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. + * + * @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. + * + * @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. + * @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. + * + * @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. + * @return the archive in case the archive is a file, null otherwise. + */ + public File getSrc() { + if (isReference()) { + return ((ArchiveFileSet) getCheckedRef()).getSrc(); + } + dieOnCircularReference(); + if (src != null) { + FileProvider fp = src.as(FileProvider.class); + if (fp != null) { + return fp.getFile(); + } + } + return null; + } + + /** + * Performs the check for circular references and returns the + * referenced object. + * This is an override which does not delegate to the superclass; instead it invokes + * {@link #getRef(Project)}, because that contains the special support for fileset + * references, which can be handled by all ArchiveFileSets. + * @param p the Ant Project instance against which to resolve references. + * @return the dereferenced object. + * @throws BuildException if the reference is invalid (circular ref, wrong class, etc). + * @since Ant 1.8 + */ + // TODO is the above true? AFAICT the calls look circular :/ + protected Object getCheckedRef(Project p) { + return getRef(p); + } + + /** + * 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 (!"".equals(prefix) && !"".equals(fullpath)) { + throw new BuildException(ERROR_PATH_AND_PREFIX); + } + this.prefix = 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 + * + * @param fullpath the full pathname of the single entry in this fileset. + */ + public void setFullpath(String fullpath) { + checkArchiveAttributesAllowed(); + if (!"".equals(prefix) && !"".equals(fullpath)) { + throw new BuildException(ERROR_PATH_AND_PREFIX); + } + this.fullpath = fullpath; + } + + /** + * 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. + * @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. + * @return String encoding. + * @since Ant 1.9.5 + */ + public String getEncoding() { + if (isReference()) { + AbstractFileSet ref = getRef(getProject()); + if (ref instanceof ArchiveFileSet) { + return ((ArchiveFileSet) ref).getEncoding(); + } else { + return null; + } + } + return encoding; + } + + /** + * 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. + * @param p the project to use + * @return a directory scanner + */ + 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. + * @return Iterator of Resources. + * @since Ant 1.7 + */ + public Iterator<Resource> iterator() { + if (isReference()) { + return ((ResourceCollection) (getRef(getProject()))).iterator(); + } + if (src == null) { + return super.iterator(); + } + ArchiveScanner as = (ArchiveScanner) getDirectoryScanner(getProject()); + return as.getResourceFiles(getProject()); + } + + /** + * Fulfill the ResourceCollection contract. + * @return size of the collection as int. + * @since Ant 1.7 + */ + public int size() { + if (isReference()) { + return ((ResourceCollection) (getRef(getProject()))).size(); + } + if (src == null) { + return super.size(); + } + ArchiveScanner as = (ArchiveScanner) getDirectoryScanner(getProject()); + return as.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. + * @return whether this is a filesystem-only resource collection. + * @since Ant 1.7 + */ + public boolean isFilesystemOnly() { + if (isReference()) { + return ((ArchiveFileSet) getCheckedRef()).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 + * @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 + * + * <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 + * @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. + * @return true if it has been set + */ + public boolean hasFileModeBeenSet() { + if (isReference()) { + return ((ArchiveFileSet) getRef(getProject())).hasFileModeBeenSet(); + } + dieOnCircularReference(); + return fileModeHasBeenSet; + } + + /** + * 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 + * <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 + * @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. + * + * @return true if it has been set + */ + public boolean hasDirModeBeenSet() { + if (isReference()) { + return ((ArchiveFileSet) getRef(getProject())).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 + * @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. + * @return the cloned archiveFileSet + * @since Ant 1.6 + */ + public Object clone() { + if (isReference()) { + return getCheckedRef(ArchiveFileSet.class, getDataTypeName(), getProject()).clone(); + } + return super.clone(); + } + + /** + * 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. + */ + 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. + * @return the prefix. + * @deprecated since 1.7. + */ + public String getPrefix() { + return prefix; + } + + /** + * Return the full pathname of the single entryZ in this fileset. + * @return the full pathname. + * @deprecated since 1.7. + */ + public String getFullpath() { + return fullpath; + } + + /** + * @return the file mode. + * @deprecated since 1.7. + */ + public int getFileMode() { + return fileMode; + } + + /** + * @return the dir mode. + * @deprecated since 1.7. + */ + 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). + */ + private void checkArchiveAttributesAllowed() { + if (getProject() == null + || (isReference() + && (getRefid().getReferencedObject( + getProject()) + instanceof ArchiveFileSet))) { + checkAttributesAllowed(); + } + } + + 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); + } + } +} |