Java/Ant/Custom Task

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Ant Write Our Own Task

/*
 *  Uses org.apache.tools.ant.Main,
 *  which is Copyright 2000-2005 The Apache Software Foundation.
 *
 *  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 org.mwrm.ant.tasks;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.Main;
/**
 * <p>The <code>ProjectHelpTask</code> class displays usage information
 * for the current project. This is the same information as is displayed
 * by <code>-projecthelp</code>.</p>
 *
 */
public class ProjectHelpTask extends Task {
    /** The location of the build file to use
     * when obtaining usage information. */
    private String buildfile;
    /**
     * <p>Runs the task.
     * It calls {@link org.apache.tools.ant.Main#main(String[] args)
     * org.apache.tools.ant.Main.main()} with the <code>-projecthelp</code>
     * parameter. It will also send the current build file"s file name
     * via the <code>-f</code> parameter.</p>
     *
     * <p>The <code>buildfile</code> attribute is optional.
     * The default is the task"s build file.</p>
     * @see org.apache.tools.ant.Main org.apache.tools.ant.Main
     */
    public final void execute() {
        // If the buildfile attribute is null, we"ll use the task"s build file
        if (buildfile == null) {
            buildfile = getLocation().getFileName();
        }
        // The arguments that we will pass to the Main class.
        // The buildfile attribute must follow the -f parameter.
        String[] args = {"-projecthelp", "-f", buildfile};
        // Call the Main Ant class with the arguments.
        Main.main(args);
    }
    /**
     * Setter method for the <code>buildfile</code> attribute.
     * @param file The file name of the build file to use.
     *
     */
    public final void setBuildfile(final String file) {
        this.buildfile = file;
    }
}





Create your own Ant task

/*
Code revised from 

Cooking with Java XP
by Eric M. Burke and Brian M. Coyner
ISBN: 0-596-00387-0
Pages: 288
*/
<?xml version="1.0"?>
<project name="Ant Task" default="compile" basedir=".">
  <property name="dir.build" value="build"/>
  <property name="dir.dist" value="dist"/>
  <property name="dir.src" value="src"/>
  <path id="classpath.project">
    <pathelement path="${dir.build}"/>
  </path>
  <target name="compile" description="Compile all source code.">
    <javac srcdir="${dir.src}" destdir="${dir.build}">
      <classpath refid="classpath.project"/>
    </javac>
  </target>
  <target name="demoDialogBox" depends="compile">
      <taskdef name="dialogbox"
              classname="DialogBoxTask"
              classpath="${dir.build}"/>
      <dialogbox message="Are you ready?"
                 title="Important Question"
                 property="response"
                 optiontype="yes_no"/>
      <dialogbox message="You entered ${response}!"/>
      <dialogbox title="First response: ${response}">This is a dialog with a multi-line message.</dialogbox>
  </target>
</project>

-------------------------------------------------------------------
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.ProjectHelper;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.types.EnumeratedAttribute;
import javax.swing.*;
public class DialogBoxTask extends Task {
    private String message;
    private String title = "Question";
    private int optionType = -1;
    private String propertyName;
    public void setTitle(String title) {
        this.title = title;
    }
    public void setProperty(String propertyName) {
        this.propertyName = propertyName;
    }
    public void setOptiontype(OptionType ot) {
        log("Calling setOptionType: " + ot.getValue(),
                Project.MSG_DEBUG);
        String value = ot.getValue();
        if ("ok".equals(value)) {
            optionType = -1;
        } else if ("ok_cancel".equals(value)) {
            optionType = JOptionPane.OK_CANCEL_OPTION;
        } else if ("yes_no".equals(value)) {
            optionType = JOptionPane.YES_NO_OPTION;
        } else {
            // only remaining possibility
            optionType = JOptionPane.YES_NO_CANCEL_OPTION;
        }
    }
    public void setMessage(String msg) {
        // ant always replaces properties for attributes
        message = msg;
    }
    public void addText(String msg) {
        if (message == null) {
            message = "";
        }
        // we must manually replace properties for nested text
        message += ProjectHelper.replaceProperties(
                getProject(), msg, getProject().getProperties());
    }
    public void execute() throws BuildException {
        validateAttributes();
        log("optionType = " + optionType, Project.MSG_DEBUG);
        if (optionType == -1) {
            JOptionPane.showMessageDialog(
                    null, // parent
                    message,
                    title,
                    JOptionPane.INFORMATION_MESSAGE);
        } else {
            int response = JOptionPane.showConfirmDialog(
                    null, // parent
                    message,
                    title,
                    optionType,
                    JOptionPane.QUESTION_MESSAGE);
            if (propertyName != null) {
                String responseText = formatResponseCode(response);
                log("Setting " + propertyName + " to " + responseText,
                        Project.MSG_VERBOSE);
                getProject().setProperty(propertyName, responseText);
            }
        }
    }
    protected void validateAttributes() {
        if (message == null) {
            throw new BuildException("Message must be specified using the "
                    + "message attribute or nested text.");
        }
        if (optionType == -1 && propertyName != null) {
            throw new BuildException(
                    "Cannot specify property unless optionType is "
                    + ""ok_cancel", "yes_no", or "yes_no_cancel"");
        }
    }
    public static class OptionType extends EnumeratedAttribute {
        public String[] getValues() {
            return new String[]{
                "ok",
                "ok_cancel",
                "yes_no",
                "yes_no_cancel",
            };
        }
    }
    private String formatResponseCode(int optionPaneResponse) {
        switch (optionPaneResponse) {
            // note: JOptionPane.OK_OPTION is the same as YES_OPTION
            case JOptionPane.YES_OPTION:
                return "yes";
            case JOptionPane.NO_OPTION:
                return "no";
            case JOptionPane.CANCEL_OPTION:
            case JOptionPane.CLOSED_OPTION:
                return "cancel";
            default:
                throw new BuildException("Internal error: Unknown option " +
                        "pane response: " + optionPaneResponse);
        }
    }
}





Extend Javadoc Task

/*
 *  Extends org.apache.tools.ant.taskdefs.Javadoc
 *  and uses org.apache.tools.ant.taskdefs.UpToDate,
 *  which are Copyright 2000-2005 The Apache Software Foundation.
 *
 *  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 org.mwrm.ant.tasks;
import java.io.File;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.Vector;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.taskdefs.Javadoc;
import org.apache.tools.ant.taskdefs.UpToDate;
import org.apache.tools.ant.types.FileSet;
/**
 * <p>The <code>ExtendJavadocTask</code> class
 * extends the {@link org.apache.tools.ant.taskdefs.Javadoc Javadoc} task.
 * It checks whether a set of source files are newer than a set of target files
 * and if so, it generates Javadocs.</p>
 *
 */
public class ExtendJavadocTask extends Javadoc {
    /** The attribute of the task element. */
    private File target;
    /** A set of file sets,
     * each of which is provided by a nested file set. */
    private Vector targetFileSets  = new Vector();
    /** The internal uptodate task. */
    private UpToDate utd;
    /**
     * <p>Creates a new instance of an internal
     * <code>&lt;uptodate&gt;</code> task
     * and adds it to the current project.</p>
     * @see UpToDate org.apache.tools.ant.taskdefs.UpToDate
     */
    public final void init() {
        // We need an instance of the <uptodate> task
        utd = new UpToDate();
        // We need to add the task to this project
        utd.setProject(this.getProject());
    }
    /**
     * <p>Checks if Javadocs should be created
     * and then calls <code>super.execute()</code> if so.</p>
     * <p>This method does usage checks on the task"s attributes
     * and its nested elements.
     * It will throw a <code>BuildException</code> if there is a violation.</p>
     */
    public final void execute() {
        // This is the usage information
        // We can"t have a target attribute
        // and nested targetfiles elements
        if (target != null && targetFileSets.size() > 0) {
            String msg = "You can"t specify a targetfile attribute "
                + "and <targetfiles> elements.";
            throw new BuildException(msg);
        }
        // We have to specify either a target attribute
        // or at least one nested targetfiles elements
        if (target == null && targetFileSets.size() == 0) {
            String msg = "You must specify either a targetfile attribute "
                + "or at least one <targetfiles> element.";
            throw new BuildException(msg);
        }
        // If this is false, the files aren"t up to date
        // and we have to run the javadocs
        boolean eval = false;
        // If we"ve got to this point, we know the usage must be correct.
        // Let"s check whether a single target attribute has been used.
        if (target != null) {
            // Get the results of the check
            eval = getResult(target);
        } else {
            // If a target attribute wasn"t specified,
            // at least one nested targetfiles element was.
            // We first get all the file sets represented by the nested elements
            Enumeration e = targetFileSets.elements();
            // And then iterate over them
            while (e.hasMoreElements()) {
                // The next element is a file set, so we get its files
                // in a semi-colon-separated list
                String files = e.nextElement().toString();
                // Next, we split the list into its file names
                StringTokenizer st = new StringTokenizer(files, ";");
                // And iterate over them to test each one
                while (st.hasMoreTokens()) {
                    // We create a file
                    //from the current file name in the iteration
                    File tempTarget = new File(st.nextToken());
                    // Get the results of the check
                    eval = getResult(tempTarget);
                    // One false result is enough to fail the whole file set
                    if (!eval) {
                        break;
                    }
                }
                // One false result is enough to fail the whole file set
                if (!eval) {
                    break;
                }
            }
        }
        // If the test failed, we want to generate Javadocs
        if (!eval) {
            super.execute();
        } else {
            log("Skipping Javadoc creation. The files are up to date.",
                Project.MSG_INFO);
        }
    }
    /** <p>Checks whether the files are up to date.</p>
     * @param file The file to evaluate
     * @return boolean The result
     */
    private boolean getResult(final File file) {
        // Set the target property in the <uptodate> task
        utd.setTargetFile(file);
        // Evaluate the files
        return utd.eval();
    }
    /**
     * <p>The setter method for the <code>target</code> attribute.</p>
     * @param targetFile A file to check against
     */
    public final void setTarget(final File targetFile) {
        this.target = targetFile;
    }
    /**
     * <p>The setter method for the file set
     * contained in the nested <code>&lt;srcfiles&gt;</code> element.</p>
     * @param fileset A file set of source files
     */
    public final void addSrcfiles(final FileSet fileset) {
        utd.addSrcfiles(fileset);
    }
    /**
     * <p>The setter method for the file sets
     * contained in nested <code>&lt;targetfiles&gt;</code> elements.</p>
     * @param fileset A file set of target files
     */
    public final void addTargetfiles(final FileSet fileset) {
        targetFileSets.add(fileset);
    }
}





How to use a Class argument in a custom class attribute

/*
 *
 *  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 org.mwrm.ant.tasks;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
/**
 * <p>The <code>ClassSetTask</code> class
 * demonstrates how to use a <code>Class</code> argument
 * in a custom class attribute.</p>
 *
 */
public class ClassSetTask extends Task {
    /** The qualified class name. */
    private Class qualifiedName;
    /**
     * <p>Runs the task and displays the qualified name of the class
     * that is set as the <code>setQualifiedName</code> attribute.</p>
     *
     */
    public final void execute() {
        log("qualifiedName: " + qualifiedName, Project.MSG_INFO);
    }
    /**
     * <p>Sets the fully qualified name of the class.</p>
     ** @param qName The fully qualified name of a class
     */
    public final void setQualifiedName(final Class qName) {
        if (qName.getName().equals("java.lang.Integer")
            ||
            qName.getName().equals("java.lang.String")) {
            log(qName.getName() + " found.", Project.MSG_INFO);
        } else {
            String msg = "You can only specify java.lang.Integer "
                + "or java.lang.String in qualifiedName.";
            throw new BuildException(msg);
        }
        this.qualifiedName = qName;
    }
}





Life Cycle Task

/*
 *
 *  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 org.mwrm.ant.tasks;
import java.util.Hashtable;
import java.util.Enumeration;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
/**
 * <p>At each stage in a task"s life cycle, this class displays information
 * to show the internal state of the task and its position with in the project.
 * It takes a <code>name</code> attribute.</p>
 */
public class LifeCycleTask extends Task {
    /** The <code>name</code> attribute of this task. */
    private String name;
    /** The body text of this task. */
    private String text;
    /**
     * <p>The constructor displays the state of the task
     * as it is instantiated.</p>
     */
    public LifeCycleTask() {
        System.out.println("---------------");
        System.out.println("Constructor called");
        System.out.println("Value of name attribute: " + name);
        System.out.println("Value of the body text: " + text);
        System.out.println("Project: " + getProject());
        System.out.println("Location: " + getLocation());
        System.out.println("Target: " + getOwningTarget());
        System.out.println("---------------");
    }
    /**
     * <p>Displays the state of the task at initialization.</p>
     * @see #logAll(String method)
     */
    public final void init() {
        logAll("init()");
    }
    /**
     * <p>Displays the state of the task when Ant runs it.
     * This method also runs some usage checks
     * to ensure the task is being used properly.</p>
     */
    public final void execute() {
        if (name == null) {
            throw new BuildException("You must specify a name attribute in "
                                     + getTaskName() + ".");
        }
        logAll("execute()");
        // Write the name to output
        log(name, Project.MSG_INFO);
    }
    /**
     * <p>Sets the name to display
     * and shows the state of the task afterwards.</p>
     * @param aName The name to display
     */
    public final void setName(final String aName) {
        // The value of the name attribute
        this.name = aName;
        logAll("setName()");
    }
    /**
     * <p>Sets the body text of the task
     * and shows the state of the task afterwards.</p>
     * @param bodyText The body text
     */
    public final void addText(final String bodyText) {
        // If the body text is just whitespace, it might as well be null
        if (bodyText.trim().equals("")) {
            this.text = null;
        } else {
            this.text = bodyText.trim();
        }
        logAll("addText()");
    }
    /** <p>Checks for task references.</p>
     * @return String
     * A string that tells us details of the reference check
     */
    private String referenceCheck() {
        // The default setting
        String setString = "Reference not found.";
        // We need the references that have been set in this project
        Hashtable refs = getProject().getReferences();
        Enumeration e = refs.elements();
        // Let"s iterate over them
        while (e.hasMoreElements()) {
            // We want to work with each object, so we"ll instantiate an object
            Object obj = e.nextElement();
            // Check to see whether this object is a task
            // If it is, we"ll build a string that contains its name and type
            if (obj.getClass().getName().
                equals("org.apache.tools.ant.UnknownElement")
                ||
                obj.getClass().getName().
                equals(this.getClass().getName())) {
                Task aTask = (Task) obj;
                setString =
                    "Reference to " + aTask.getTaskName() + " found, of type "
                    + aTask.getClass().getName() + ". ";
                setString = setString + "Its id is "
                    + aTask.getRuntimeConfigurableWrapper().
            getAttributeMap().get("id") + ".";
            }
        }
        return setString;
    }
    /**
     * <p>A central logging method that all the life-cycle methods call
     * to display the state of the task.
     * It displays the value of the <code>name</code> attribute
     * and other information about the task,
     * including the name of its project and its location in the build file.</p>
     * @param method The name of the method that issued the logging call
     */
    public final void logAll(final String method) {
        log("---------------", Project.MSG_VERBOSE);
        log(method + " called", Project.MSG_VERBOSE);
        log("Value of name attribute: " + name, Project.MSG_VERBOSE);
        log("Value of the body text: " + text, Project.MSG_VERBOSE);
        log("Project: " + getProject().getName(), Project.MSG_VERBOSE);
        // Here we build some information on the location
        // within the build file
        String locationString = getLocation().getFileName();
        locationString = locationString + " at line "
            + getLocation().getLineNumber();
        // Location.getColumnNumber() is for Ant 1.7+
        // Comment it out if you are using Ant 1.6.x
        //locationString = locationString + " and column "
        // + getLocation().getColumnNumber();
        log("Location: " + locationString, Project.MSG_VERBOSE);
        // We could use the Location.toString() method
        //log("Location: " + getLocation(), Project.MSG_VERBOSE);
        log("Target: " + getOwningTarget(), Project.MSG_VERBOSE);
        // referenceCheck() returns a string with information
        // on any references to custom tasks
        log(referenceCheck(), Project.MSG_VERBOSE);
        // If the configuration wrapper is null, we use its
        // run-time equivalent
        if (getWrapper() == null) {
            log("Reference id: "
                + getRuntimeConfigurableWrapper().getAttributeMap().get("id"),
                Project.MSG_VERBOSE);
        } else {
            // This time we use the protected getWrapper() method
            log("Reference id: " + getWrapper().getAttributeMap().get("id"),
                Project.MSG_VERBOSE);
        }
        log("---------------", Project.MSG_VERBOSE);
    }
}





The third-party tasks