📄 subant.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.IOException;import java.util.Vector;import java.util.Enumeration;import org.apache.tools.ant.Task;import org.apache.tools.ant.Project;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.types.Path;import org.apache.tools.ant.types.DirSet;import org.apache.tools.ant.types.FileSet;import org.apache.tools.ant.types.FileList;import org.apache.tools.ant.types.PropertySet;import org.apache.tools.ant.types.Reference;import org.apache.tools.ant.types.ResourceCollection;import org.apache.tools.ant.taskdefs.Ant.TargetElement;/** * Calls a given target for all defined sub-builds. This is an extension * of ant for bulk project execution. * <p> * <h2> Use with directories </h2> * <p> * subant can be used with directory sets to execute a build from different directories. * 2 different options are offered * </p> * <ul> * <li> * run the same build file /somepath/otherpath/mybuild.xml * with different base directories use the genericantfile attribute * </li> * <li>if you want to run directory1/build.xml, directory2/build.xml, .... * use the antfile attribute. The base directory does not get set by the subant task in this case, * because you can specify it in each build file. * </li> * </ul> * @since Ant1.6 * @ant.task name="subant" category="control" */public class SubAnt extends Task { private Path buildpath; private Ant ant = null; private String subTarget = null; private String antfile = "build.xml"; private File genericantfile = null; private boolean verbose = false; private boolean inheritAll = false; private boolean inheritRefs = false; private boolean failOnError = true; private String output = null; private Vector properties = new Vector(); private Vector references = new Vector(); private Vector propertySets = new Vector(); /** the targets to call on the new project */ private Vector/*<TargetElement>*/ targets = new Vector(); /** * Pass output sent to System.out to the new project. * * @param output a line of output * @since Ant 1.6.2 */ public void handleOutput(String output) { if (ant != null) { ant.handleOutput(output); } else { super.handleOutput(output); } } /** * Process input into the ant task * * @param buffer the buffer into which data is to be read. * @param offset the offset into the buffer at which data is stored. * @param length the amount of data to read * * @return the number of bytes read * * @exception IOException if the data cannot be read * * @see Task#handleInput(byte[], int, int) * * @since Ant 1.6.2 */ public int handleInput(byte[] buffer, int offset, int length) throws IOException { if (ant != null) { return ant.handleInput(buffer, offset, length); } else { return super.handleInput(buffer, offset, length); } } /** * Pass output sent to System.out to the new project. * * @param output The output to log. Should not be <code>null</code>. * * @since Ant 1.6.2 */ public void handleFlush(String output) { if (ant != null) { ant.handleFlush(output); } else { super.handleFlush(output); } } /** * Pass output sent to System.err to the new project. * * @param output The error output to log. Should not be <code>null</code>. * * @since Ant 1.6.2 */ public void handleErrorOutput(String output) { if (ant != null) { ant.handleErrorOutput(output); } else { super.handleErrorOutput(output); } } /** * Pass output sent to System.err to the new project. * * @param output The error output to log. Should not be <code>null</code>. * * @since Ant 1.6.2 */ public void handleErrorFlush(String output) { if (ant != null) { ant.handleErrorFlush(output); } else { super.handleErrorFlush(output); } } /** * Runs the various sub-builds. */ public void execute() { if (buildpath == null) { throw new BuildException("No buildpath specified"); } final String[] filenames = buildpath.list(); final int count = filenames.length; if (count < 1) { log("No sub-builds to iterate on", Project.MSG_WARN); return; }/* //REVISIT: there must be cleaner way of doing this, if it is merited at all if (subTarget == null) { subTarget = getOwningTarget().getName(); }*/ BuildException buildException = null; for (int i = 0; i < count; ++i) { File file = null; String subdirPath = null; Throwable thrownException = null; try { File directory = null; file = new File(filenames[i]); if (file.isDirectory()) { if (verbose) { subdirPath = file.getPath(); log("Entering directory: " + subdirPath + "\n", Project.MSG_INFO); } if (genericantfile != null) { directory = file; file = genericantfile; } else { file = new File(file, antfile); } } execute(file, directory); if (verbose && subdirPath != null) { log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO); } } catch (RuntimeException ex) { if (!(getProject().isKeepGoingMode())) { if (verbose && subdirPath != null) { log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO); } throw ex; // throw further } thrownException = ex; } catch (Throwable ex) { if (!(getProject().isKeepGoingMode())) { if (verbose && subdirPath != null) { log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO); } throw new BuildException(ex); } thrownException = ex; } if (thrownException != null) { if (thrownException instanceof BuildException) { log("File '" + file + "' failed with message '" + thrownException.getMessage() + "'.", Project.MSG_ERR); // only the first build exception is reported if (buildException == null) { buildException = (BuildException) thrownException; } } else { log("Target '" + file + "' failed with message '" + thrownException.getMessage() + "'.", Project.MSG_ERR); thrownException.printStackTrace(System.err); if (buildException == null) { buildException = new BuildException(thrownException); } } if (verbose && subdirPath != null) { log("Leaving directory: " + subdirPath + "\n", Project.MSG_INFO); } } } // check if one of the builds failed in keep going mode if (buildException != null) { throw buildException; } } /** * Runs the given target on the provided build file. * * @param file the build file to execute * @param directory the directory of the current iteration * @throws BuildException is the file cannot be found, read, is * a directory, or the target called failed, but only if * <code>failOnError</code> is <code>true</code>. Otherwise, * a warning log message is simply output. */ private void execute(File file, File directory) throws BuildException { if (!file.exists() || file.isDirectory() || !file.canRead()) { String msg = "Invalid file: " + file; if (failOnError) { throw new BuildException(msg); } log(msg, Project.MSG_WARN); return; } ant = createAntTask(directory); String antfilename = file.getAbsolutePath(); ant.setAntfile(antfilename); for (int i = 0; i < targets.size(); i++) { TargetElement targetElement = (TargetElement) targets.get(i); ant.addConfiguredTarget(targetElement); } try { ant.execute(); } catch (BuildException e) { if (failOnError) { throw e; } log("Failure for target '" + subTarget + "' of: " + antfilename + "\n" + e.getMessage(), Project.MSG_WARN); } catch (Throwable e) { if (failOnError) { throw new BuildException(e); } log("Failure for target '" + subTarget + "' of: " + antfilename + "\n" + e.toString(), Project.MSG_WARN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -