diff options
author | mattinger <[email protected]> | 2006-07-06 21:53:00 +0000 |
---|---|---|
committer | mattinger <[email protected]> | 2006-07-06 21:53:00 +0000 |
commit | 1159111b7a71b72eb04326df33211e1733f7e742 (patch) | |
tree | f0a80c384f633e521649654ab78e6239cf5e0d6f /src/java/net/sf/antcontrib/logic/TryCatchTask.java |
Initial addition into subversion with build script changes
git-svn-id: file:///home/sven/projects/JOGL/temp/ant-contrib/svn/ant-contrib-code/trunk/ant-contrib@5 32d7a393-a5a9-423c-abd3-5d954feb1f2f
Diffstat (limited to 'src/java/net/sf/antcontrib/logic/TryCatchTask.java')
-rw-r--r-- | src/java/net/sf/antcontrib/logic/TryCatchTask.java | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/java/net/sf/antcontrib/logic/TryCatchTask.java b/src/java/net/sf/antcontrib/logic/TryCatchTask.java new file mode 100644 index 0000000..4933e7d --- /dev/null +++ b/src/java/net/sf/antcontrib/logic/TryCatchTask.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2001-2004 Ant-Contrib project. All rights reserved. + * + * Licensed 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 net.sf.antcontrib.logic; + +import java.util.Enumeration; +import java.util.Vector; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.taskdefs.Sequential; + +/** + * A wrapper that lets you run a set of tasks and optionally run a + * different set of tasks if the first set fails and yet another set + * after the first one has finished. + * + * <p>This mirrors Java's try/catch/finally.</p> + * + * <p>The tasks inside of the required <code><try></code> + * element will be run. If one of them should throw a {@link + * org.apache.tools.ant.BuildException BuildException} several things + * can happen:</p> + * + * <ul> + * <li>If there is no <code><catch></code> block, the + * exception will be passed through to Ant.</li> + * + * <li>If the property attribute has been set, a property of the + * given name will be set to the message of the exception.</li> + * + * <li>If the reference attribute has been set, a reference of the + * given id will be created and point to the exception object.</li> + * + * <li>If there is a <code><catch></code> block, the tasks + * nested into it will be run.</li> + * </ul> + * + * <p>If a <code><finally></code> block is present, the task + * nested into it will be run, no matter whether the first tasks have + * thrown an exception or not.</p> + * + * <p><strong>Attributes:</strong></p> + * + * <table> + * <tr> + * <td>Name</td> + * <td>Description</td> + * <td>Required</td> + * </tr> + * <tr> + * <td>property</td> + * <td>Name of a property that will receive the message of the + * exception that has been caught (if any)</td> + * <td>No</td> + * </tr> + * <tr> + * <td>reference</td> + * <td>Id of a reference that will point to the exception object + * that has been caught (if any)</td> + * <td>No</td> + * </tr> + * </table> + * + * <p>Use the following task to define the <code><trycatch></code> + * task before you use it the first time:</p> + * + * <pre><code> + * <taskdef name="trycatch" + * classname="net.sf.antcontrib.logic.TryCatchTask" /> + * </code></pre> + * + * <h3>Crude Example</h3> + * + * <pre><code> + * <trycatch property="foo" reference="bar"> + * <try> + * <fail>Tada!</fail> + * </try> + * + * <catch> + * <echo>In &lt;catch&gt;.</echo> + * </catch> + * + * <finally> + * <echo>In &lt;finally&gt;.</echo> + * </finally> + * </trycatch> + * + * <echo>As property: ${foo}</echo> + * <property name="baz" refid="bar" /> + * <echo>From reference: ${baz}</echo> + * </code></pre> + * + * <p>results in</p> + * + * <pre><code> + * [trycatch] Caught exception: Tada! + * [echo] In <catch>. + * [echo] In <finally>. + * [echo] As property: Tada! + * [echo] From reference: Tada! + * </code></pre> + * + * @author <a href="mailto:[email protected]">Stefan Bodewig</a> + * @author <a href="mailto:[email protected]">Dan Ritchey</a> + */ +public class TryCatchTask extends Task { + + public static final class CatchBlock extends Sequential { + private String throwable = BuildException.class.getName(); + + public CatchBlock() { + super(); + } + + public void setThrowable(String throwable) { + this.throwable = throwable; + } + + public boolean execute(Throwable t) throws BuildException { + try { + Class c = Thread.currentThread().getContextClassLoader().loadClass(throwable); + if (c.isAssignableFrom(t.getClass())) { + execute(); + return true; + } + return false; + } + catch (ClassNotFoundException e) { + throw new BuildException(e); + } + } + } + + + private Sequential tryTasks = null; + private Vector catchBlocks = new Vector(); + private Sequential finallyTasks = null; + private String property = null; + private String reference = null; + + /** + * Adds a nested <try> block - one is required, more is + * forbidden. + */ + public void addTry(Sequential seq) throws BuildException { + if (tryTasks != null) { + throw new BuildException("You must not specify more than one <try>"); + } + + tryTasks = seq; + } + + public void addCatch(CatchBlock cb) { + catchBlocks.add(cb); + } + + /** + * Adds a nested <finally> block - at most one is allowed. + */ + public void addFinally(Sequential seq) throws BuildException { + if (finallyTasks != null) { + throw new BuildException("You must not specify more than one <finally>"); + } + + finallyTasks = seq; + } + + /** + * Sets the property attribute. + */ + public void setProperty(String p) { + property = p; + } + + /** + * Sets the reference attribute. + */ + public void setReference(String r) { + reference = r; + } + + /** + * The heart of the task. + */ + public void execute() throws BuildException { + if (tryTasks == null) { + throw new BuildException("A nested <try> element is required"); + } + + try { + tryTasks.perform(); + } catch (Throwable e) { + if (property != null) { + /* + * Using setProperty instead of setNewProperty to + * be able to compile with Ant < 1.5. + */ + getProject().setProperty(property, e.getMessage()); + } + + if (reference != null) { + getProject().addReference(reference, e); + } + + boolean executed = false; + Enumeration blocks = catchBlocks.elements(); + while (blocks.hasMoreElements() && ! executed) { + CatchBlock cb = (CatchBlock)blocks.nextElement(); + executed = cb.execute(e); + } + } finally { + if (finallyTasks != null) { + finallyTasks.perform(); + } + } + } + +} |