Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Apache Jakarta and Beyond: A Java Programmeramp;#039;s Introduction [Electronic resources] - نسخه متنی

Larne Pekowsky

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







2.9. Creating New Tasks


Many examples in this chapter used the custom ls task. A build file can use a custom task by importing it with the taskdef element that associates a name for the task with a class, as can be seen in Listing 2.2 . Creating a new task is simply a matter of writing this implementation class, which will extend Task from the org.apache.tools.ant package.

All the potentially difficult aspects of writing a task are managed by either the Task base class or Ant itself with the help of some introspection. Task developers can concentrate on making their tasks perform the necessary actions.

The entry point for a task is a method called execute(), which takes no arguments, and this is the only method that a task must provide. This method is called by Ant when the task is reached within a target. Listing 2.4 shows the simplest possible task.


Listing 2.4. A simple custom task


package com.awl.toolbook.chapter02;
import org.apache.tools.ant.*;
public class DemoTask extends Task {
public void execute() {
System.out.println("Hello, ant!");
}
}

This task could be used by a build file in the obvious way


<project default="demo">
<taskdef name="demoTask"
classname="com.awl.toolbook.chapter02.DemoTask"/>
<target name="demo">
<demoTask/>
</target>
</project>

which will produce the expected output when run


demo:
[demoTask] Hello, ant!

Options to tasks that may be provided by build files are treated as JavaBean properties. The implementing class needs to provide a set method for each option. Ant will take care of invoking this method with provided values, as well as converting from strings to the appropriate types as needed. These features are demonstrated in Listing 2.5 , which takes two options, a message to display and a repeatCount giving the number of times to repeat the message.


Listing 2.5. A custom task with properties


package com.awl.toolbook.chapter02;
import org.apache.tools.ant.*;
public class SimpleEchoTask extends Task {
private int repeatCount = 1;
public void setRepeatCount(int count) {
repeatCount = count;
}
private String message = null;
public void setMessage(String message) {
this.message = message;
}
public void execute() throws BuildException {
if(message == null) {
throw new BuildException(
"Please specify a message");
}
for(int i=0;i<repeatCount;i++) {
System.out.println(i + "." + message);
}
}
}

This could be used from a build file as


<simpleEcho message="Hello" repeatCount="8"/>

Note that Ant automatically converts the repeatCount to an integer. To quote the Ant manual: "It's really this simple!"

Listing 2.5 introduces another new feature, the BuildException. Tasks may throw this exception when they have not been given necessary configuration information as is done here or because they were unable to complete for any external reason. In either case, the build will immediately terminate with a "build failed" message that will include the text used to construct the BuildException.

Handling filesets is only slightly more difficult than handling primitive values. Instead of providing a set method, the task class provides an addFileset() method, which takes as an argument a FileSet from the org.apache.tools.ant.types package. This addFilset() method will be called once for each fileset constructed from the set in the build file. The task should hold on to each FileSet until the execute() method is called.

Within the execute() method sets of files are obtained from each FileSet through use of a DirectoryScanner. The DirectoryScanner will look through a directory or set of directories and select files based on the given include, exclude, contains, and other selection elements, and can return an array of matching file names. Task developers do not need to worry about the details of how this filtering happens. Ant takes care of all that within the DirectoryScanner.

This is sufficient information to write the ls task that has been used in this chapter, and it is shown in Listing 2.6.


Listing 2.6. The directory listing task


package com.awl.toolbook.chapter02;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.util.FileUtils;
import java.util.Vector;
import java.io.File;
public class LsTask extends Task {
private boolean showSize = false;
public boolean getShowSize() {return showSize;}
public void setShowSize(boolean showSize) {
this.showSize = showSize;
}
private Vector fileSets = new Vector();
private FileUtils fileUtils;
public void addFileset(FileSet set) {
fileSets.addElement(set);
}
public void execute() throws BuildException {
if(fileSets.size() == 0) {
throw
new BuildException(
"Please specify at least one fileset.");
}
for(int i=0;i<fileSets.size();i++) {
FileSet fileset =
(FileSet) fileSets.elementAt(i);
DirectoryScanner scanner =
fileset.getDirectoryScanner(project);
File baseDir = fileset.getDir(project);
// Handle the files in this fileset
String files[] = scanner.getIncludedFiles();
for(int j=0;j<files.length;j++) {
handleFile(baseDir,files[j]);
}
}
}
private void handleFile(File baseDir,String f) {
File file = new File(baseDir,f);
if(showSize) {
System.out.println(f +
"(" + f.length() +
" bytes)");
} else {
System.out.println(f);
}
}
}

As explained, the addFileset() method simply stores the provided FileSet in a Vector for later use by execute(). execute() traverses this vector and for each element obtains a set of files through a DirectoryScanner. Each DirectoryScanner needs to know what project it is a part of to obtain certain global information. This is accomplished by passing the project variable, which is defined in the base Task class.


/ 207