📄 expand.java
字号:
/* * 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.FileResource;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 patternsets = new Vector(); private Union resources = new Union(); private boolean resourcesSpecified = false; private static final String NATIVE_ENCODING = "native-encoding"; private String encoding = "UTF8"; /** 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(); /** * 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 { expandFile(FILE_UTILS, source, dest); } } Iterator iter = resources.iterator(); while (iter.hasNext()) { Resource r = (Resource) iter.next(); if (!r.isExists()) { continue; } if (r instanceof FileResource) { expandFile(FILE_UTILS, ((FileResource) r).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(); try { zf = new ZipFile(srcF, encoding); Enumeration e = zf.getEntries(); while (e.hasMoreElements()) { ZipEntry ze = (ZipEntry) e.nextElement(); extractFile(fileUtils, srcF, dir, zf.getInputStream(ze), ze.getName(), new Date(ze.getTime()), ze.isDirectory(), mapper); } 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 (patternsets != null && patternsets.size() > 0) { String name = entryName.replace('/', File.separatorChar) .replace('\\', File.separatorChar); boolean included = false; Set includePatterns = new HashSet(); Set excludePatterns = new HashSet(); for (int v = 0, size = patternsets.size(); v < size; v++) { PatternSet p = (PatternSet) 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 iter = includePatterns.iterator(); !included && iter.hasNext();) { String pattern = (String) iter.next(); included = SelectorUtils.matchPath(pattern, name); } for (Iterator iter = excludePatterns.iterator(); included && iter.hasNext();) { String pattern = (String) iter.next(); included = !SelectorUtils.matchPath(pattern, name); } if (!included) { //Do not process this file 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(), 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) { if (NATIVE_ENCODING.equals(encoding)) { encoding = null; } this.encoding = encoding; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -