diff options
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java')
-rw-r--r-- | framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java | 527 |
1 files changed, 527 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java new file mode 100644 index 00000000..cb0c958d --- /dev/null +++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/taskdefs/Expand.java @@ -0,0 +1,527 @@ +/* + * 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.taskdefs; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.FileSet; +import org.apache.tools.ant.types.Mapper; +import org.apache.tools.ant.types.PatternSet; +import org.apache.tools.ant.types.Resource; +import org.apache.tools.ant.types.ResourceCollection; +import org.apache.tools.ant.types.resources.FileProvider; +import org.apache.tools.ant.types.resources.Union; +import org.apache.tools.ant.types.selectors.SelectorUtils; +import org.apache.tools.ant.util.FileNameMapper; +import org.apache.tools.ant.util.FileUtils; +import org.apache.tools.ant.util.IdentityMapper; +import org.apache.tools.zip.ZipEntry; +import org.apache.tools.zip.ZipFile; + +/** + * Unzip a file. + * + * @since Ant 1.1 + * + * @ant.task category="packaging" + * name="unzip" + * name="unjar" + * name="unwar" + */ +public class Expand extends Task { + private static final int BUFFER_SIZE = 1024; + private File dest; //req + private File source; // req + private boolean overwrite = true; + private Mapper mapperElement = null; + private Vector<PatternSet> patternsets = new Vector<PatternSet>(); + private Union resources = new Union(); + private boolean resourcesSpecified = false; + private boolean failOnEmptyArchive = false; + private boolean stripAbsolutePathSpec = false; + private boolean scanForUnicodeExtraFields = true; + + public static final String NATIVE_ENCODING = "native-encoding"; + + private String encoding; + /** Error message when more that one mapper is defined */ + public static final String ERROR_MULTIPLE_MAPPERS = "Cannot define more than one mapper"; + + private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); + + /** + * Creates an Expand instance and sets encoding to UTF-8. + */ + public Expand() { + this("UTF8"); + } + + /** + * Creates an Expand instance and sets the given encoding. + * + * @since Ant 1.9.5 + */ + protected Expand(String encoding) { + this.encoding = encoding; + } + + /** + * Whether try ing to expand an empty archive would be an error. + * + * @since Ant 1.8.0 + */ + public void setFailOnEmptyArchive(boolean b) { + failOnEmptyArchive = b; + } + + /** + * Whether try ing to expand an empty archive would be an error. + * + * @since Ant 1.8.0 + */ + public boolean getFailOnEmptyArchive() { + return failOnEmptyArchive; + } + + /** + * Do the work. + * + * @exception BuildException Thrown in unrecoverable error. + */ + public void execute() throws BuildException { + if ("expand".equals(getTaskType())) { + log("!! expand is deprecated. Use unzip instead. !!"); + } + + if (source == null && !resourcesSpecified) { + throw new BuildException("src attribute and/or resources must be " + + "specified"); + } + + if (dest == null) { + throw new BuildException( + "Dest attribute must be specified"); + } + + if (dest.exists() && !dest.isDirectory()) { + throw new BuildException("Dest must be a directory.", getLocation()); + } + + if (source != null) { + if (source.isDirectory()) { + throw new BuildException("Src must not be a directory." + + " Use nested filesets instead.", getLocation()); + } else if (!source.exists()) { + throw new BuildException("src '" + source + "' doesn't exist."); + } else if (!source.canRead()) { + throw new BuildException("src '" + source + "' cannot be read."); + } else { + expandFile(FILE_UTILS, source, dest); + } + } + for (Resource r : resources) { + if (!r.isExists()) { + log("Skipping '" + r.getName() + "' because it doesn't exist."); + continue; + } + + FileProvider fp = r.as(FileProvider.class); + if (fp != null) { + expandFile(FILE_UTILS, fp.getFile(), dest); + } else { + expandResource(r, dest); + } + } + } + + /** + * This method is to be overridden by extending unarchival tasks. + * + * @param fileUtils the fileUtils + * @param srcF the source file + * @param dir the destination directory + */ + protected void expandFile(FileUtils fileUtils, File srcF, File dir) { + log("Expanding: " + srcF + " into " + dir, Project.MSG_INFO); + ZipFile zf = null; + FileNameMapper mapper = getMapper(); + if (!srcF.exists()) { + throw new BuildException("Unable to expand " + + srcF + + " as the file does not exist", + getLocation()); + } + try { + zf = new ZipFile(srcF, encoding, scanForUnicodeExtraFields); + boolean empty = true; + Enumeration<ZipEntry> e = zf.getEntries(); + while (e.hasMoreElements()) { + empty = false; + ZipEntry ze = e.nextElement(); + InputStream is = null; + log("extracting " + ze.getName(), Project.MSG_DEBUG); + try { + extractFile(fileUtils, srcF, dir, + is = zf.getInputStream(ze), + ze.getName(), new Date(ze.getTime()), + ze.isDirectory(), mapper); + } finally { + FileUtils.close(is); + } + } + if (empty && getFailOnEmptyArchive()) { + throw new BuildException("archive '" + srcF + "' is empty"); + } + log("expand complete", Project.MSG_VERBOSE); + } catch (IOException ioe) { + throw new BuildException( + "Error while expanding " + srcF.getPath() + + "\n" + ioe.toString(), + ioe); + } finally { + ZipFile.closeQuietly(zf); + } + } + + /** + * This method is to be overridden by extending unarchival tasks. + * + * @param srcR the source resource + * @param dir the destination directory + */ + protected void expandResource(Resource srcR, File dir) { + throw new BuildException("only filesystem based resources are" + + " supported by this task."); + } + + /** + * get a mapper for a file + * @return a filenamemapper for a file + */ + protected FileNameMapper getMapper() { + FileNameMapper mapper = null; + if (mapperElement != null) { + mapper = mapperElement.getImplementation(); + } else { + mapper = new IdentityMapper(); + } + return mapper; + } + + // CheckStyle:ParameterNumberCheck OFF - bc + /** + * extract a file to a directory + * @param fileUtils a fileUtils object + * @param srcF the source file + * @param dir the destination directory + * @param compressedInputStream the input stream + * @param entryName the name of the entry + * @param entryDate the date of the entry + * @param isDirectory if this is true the entry is a directory + * @param mapper the filename mapper to use + * @throws IOException on error + */ + protected void extractFile(FileUtils fileUtils, File srcF, File dir, + InputStream compressedInputStream, + String entryName, Date entryDate, + boolean isDirectory, FileNameMapper mapper) + throws IOException { + + if (stripAbsolutePathSpec && entryName.length() > 0 + && (entryName.charAt(0) == File.separatorChar + || entryName.charAt(0) == '/' + || entryName.charAt(0) == '\\')) { + log("stripped absolute path spec from " + entryName, + Project.MSG_VERBOSE); + entryName = entryName.substring(1); + } + + if (patternsets != null && patternsets.size() > 0) { + String name = entryName.replace('/', File.separatorChar) + .replace('\\', File.separatorChar); + + boolean included = false; + Set<String> includePatterns = new HashSet<String>(); + Set<String> excludePatterns = new HashSet<String>(); + final int size = patternsets.size(); + for (int v = 0; v < size; v++) { + PatternSet p = patternsets.elementAt(v); + String[] incls = p.getIncludePatterns(getProject()); + if (incls == null || incls.length == 0) { + // no include pattern implicitly means includes="**" + incls = new String[] {"**"}; + } + + for (int w = 0; w < incls.length; w++) { + String pattern = incls[w].replace('/', File.separatorChar) + .replace('\\', File.separatorChar); + if (pattern.endsWith(File.separator)) { + pattern += "**"; + } + includePatterns.add(pattern); + } + + String[] excls = p.getExcludePatterns(getProject()); + if (excls != null) { + for (int w = 0; w < excls.length; w++) { + String pattern = excls[w] + .replace('/', File.separatorChar) + .replace('\\', File.separatorChar); + if (pattern.endsWith(File.separator)) { + pattern += "**"; + } + excludePatterns.add(pattern); + } + } + } + + for (Iterator<String> iter = includePatterns.iterator(); + !included && iter.hasNext();) { + String pattern = iter.next(); + included = SelectorUtils.matchPath(pattern, name); + } + + for (Iterator<String> iter = excludePatterns.iterator(); + included && iter.hasNext();) { + String pattern = iter.next(); + included = !SelectorUtils.matchPath(pattern, name); + } + + if (!included) { + //Do not process this file + log("skipping " + entryName + + " as it is excluded or not included.", + Project.MSG_VERBOSE); + return; + } + } + String[] mappedNames = mapper.mapFileName(entryName); + if (mappedNames == null || mappedNames.length == 0) { + mappedNames = new String[] {entryName}; + } + File f = fileUtils.resolveFile(dir, mappedNames[0]); + try { + if (!overwrite && f.exists() + && f.lastModified() >= entryDate.getTime()) { + log("Skipping " + f + " as it is up-to-date", + Project.MSG_DEBUG); + return; + } + + log("expanding " + entryName + " to " + f, + Project.MSG_VERBOSE); + // create intermediary directories - sometimes zip don't add them + File dirF = f.getParentFile(); + if (dirF != null) { + dirF.mkdirs(); + } + + if (isDirectory) { + f.mkdirs(); + } else { + byte[] buffer = new byte[BUFFER_SIZE]; + int length = 0; + FileOutputStream fos = null; + try { + fos = new FileOutputStream(f); + + while ((length = + compressedInputStream.read(buffer)) >= 0) { + fos.write(buffer, 0, length); + } + + fos.close(); + fos = null; + } finally { + FileUtils.close(fos); + } + } + + fileUtils.setFileLastModified(f, entryDate.getTime()); + } catch (FileNotFoundException ex) { + log("Unable to expand to file " + f.getPath(), + ex, + Project.MSG_WARN); + } + + } + // CheckStyle:ParameterNumberCheck ON + + /** + * Set the destination directory. File will be unzipped into the + * destination directory. + * + * @param d Path to the directory. + */ + public void setDest(File d) { + this.dest = d; + } + + /** + * Set the path to zip-file. + * + * @param s Path to zip-file. + */ + public void setSrc(File s) { + this.source = s; + } + + /** + * Should we overwrite files in dest, even if they are newer than + * the corresponding entries in the archive? + * @param b a <code>boolean</code> value + */ + public void setOverwrite(boolean b) { + overwrite = b; + } + + /** + * Add a patternset. + * @param set a pattern set + */ + public void addPatternset(PatternSet set) { + patternsets.addElement(set); + } + + /** + * Add a fileset + * @param set a file set + */ + public void addFileset(FileSet set) { + add(set); + } + + /** + * Add a resource collection. + * @param rc a resource collection. + * @since Ant 1.7 + */ + public void add(ResourceCollection rc) { + resourcesSpecified = true; + resources.add(rc); + } + + /** + * Defines the mapper to map source entries to destination files. + * @return a mapper to be configured + * @exception BuildException if more than one mapper is defined + * @since Ant1.7 + */ + public Mapper createMapper() throws BuildException { + if (mapperElement != null) { + throw new BuildException(ERROR_MULTIPLE_MAPPERS, + getLocation()); + } + mapperElement = new Mapper(getProject()); + return mapperElement; + } + + /** + * A nested filenamemapper + * @param fileNameMapper the mapper to add + * @since Ant 1.6.3 + */ + public void add(FileNameMapper fileNameMapper) { + createMapper().add(fileNameMapper); + } + + + /** + * Sets the encoding to assume for file names and comments. + * + * <p>Set to <code>native-encoding</code> if you want your + * platform's native encoding, defaults to UTF8.</p> + * @param encoding the name of the character encoding + * @since Ant 1.6 + */ + public void setEncoding(String encoding) { + internalSetEncoding(encoding); + } + + /** + * Supports grand-children that want to support the attribute + * where the child-class doesn't (i.e. Unzip in the compress + * Antlib). + * + * @since Ant 1.8.0 + */ + protected void internalSetEncoding(String encoding) { + if (NATIVE_ENCODING.equals(encoding)) { + encoding = null; + } + this.encoding = encoding; + } + + /** + * @since Ant 1.8.0 + */ + public String getEncoding() { + return encoding; + } + + /** + * Whether leading path separators should be stripped. + * + * @since Ant 1.8.0 + */ + public void setStripAbsolutePathSpec(boolean b) { + stripAbsolutePathSpec = b; + } + + /** + * Whether unicode extra fields will be used if present. + * + * @since Ant 1.8.0 + */ + public void setScanForUnicodeExtraFields(boolean b) { + internalSetScanForUnicodeExtraFields(b); + } + + /** + * Supports grand-children that want to support the attribute + * where the child-class doesn't (i.e. Unzip in the compress + * Antlib). + * + * @since Ant 1.8.0 + */ + protected void internalSetScanForUnicodeExtraFields(boolean b) { + scanForUnicodeExtraFields = b; + } + + /** + * @since Ant 1.8.0 + */ + public boolean getScanForUnicodeExtraFields() { + return scanForUnicodeExtraFields; + } + +} |