Translate ANT authoritative guidelines.
Chapter 5 User Custom Tasks (Task) The concept of expansion by user customization (Extend) Ant has always become the most important of Ant and its strongly claimed. The builders who have voluntarily claimed to provide us with a sufficient Robust Enough's system comes with the language, tools work together, and has the ability to compatibility with the future language and tools. For example, when Ant appears earlier in 2000, there is no suitable and C # cooperates with the Ant task (Task), but now there is now. A large number of users have developed a large number of Ant tasks (Task) to use various third-party tools, from the component (Groupware) Products such as StarTeam (a control system), to application servers such as BEA's WebLogic or JBoss's JBoss. These changes and improvements have no changes in the core processing engine for Ant. It is very important to extend Ant without changing his core engine, because that means that Ant core engine can be separated and improved by extension development. This way, in two fields can be done in parallel, the result is changed The speed will be more fast than the ANT as a Sneer UnoliTheric system.
All tasks are Java Class, and any programmer can extend the functionality of Ant by writing a new Java task class. These are user-write tasks, and use The same interface of the core task released together (Take Advantage of the Same Interface To Ant Used by the Core Tasks Shipped with an Ant Distribution). The only difference between user self-contained tasks and core tasks is just (Author) and Package Location (sometimes this is the same!). In addition, they play a role in the same level of the system (Function on the Same Level Playing Field). This chapter, we Show you how to expand Ant by writing your own task.
5.1 User Homemade Tasks. Ant has two tasks, Java and Exec, they can perform any Javand-line executable in any Javand-line Executable. This ability may make you doubt whether the custom task is still still? Need. Technically, you can use these two tasks to perform any classes to run any programs. The result is obvious. Some custom tasks do not have any inventive program wrapper (Excution Wrapper) His running Java class or program is exactly the same as Java and Exec task execution. Differences are user custom classes to work more closely with the ANT engine. Customized classes provide more detailed (Detailed) information, handling errors are also more accurate On the other hand, Java and Exec tasks are dealing with unpredictable errors, which gives users a detailed notification. Whether there is an event or wrong nature, it is the same for them, give you The control is very limited. A custom task, in most cases, is a better solution to a problem with Java and Exec to solve a problem in a work process (Build). Errors in the work process (BUILD). ERRORS), events (events) and messages will be initialized by the task and managed by the Ant engine .ant's response to events and perform them under a user-controlled behavior, put them to himself Listeners, or user-defined listeners (more user-defined listeners see Chapter 6). The management of the task is so meticulous (Fine-grained) is better than the end user (end users. " (Software Developers need more information about how their engineering work processes). It is also beneficial to extend new tasks to other users to extend existing tasks, inheriting their work capabilities and consistent with a series of related operations Behavior. These features can make custom tasks a good thing. Not more, these custom tasks have more purposes. Tasks are good at abstract simple operations and make them more powerful. Some Ant The task even has the ability to deal with the difference between the functional line functionality between the universal use of different platforms. For example, on different platforms, copying and deleting files, and deleting files, and directory due to command names and commands The change in the line parameters becomes very painful. By using the task to abstract file operation, Ant eliminates this pain and provides users with a unified interface. In Ant, only one way to copy and delete a file And he can work with which platform of Ant runs in Ant. This is not an abstraction (Abstract CTING) Bring the only benefit. There is no restriction of the feature set, an abstract task provides you with an improved feature set. A DEL command under Windows does not implement delete all. The end of Java is also reserved all the files starting with Abstract. And the Delete task under Ant can do it, which indicates that he has greater flexibility. Better is, he can be in any This matter is completed on the platform. The task design is concerned about work needs, never restricts himself in the characteristics of the tool, because the tool design focuses on the command environment (shell) and system needs. Use the powerful function in the available customization task class You can improve the use of almost any tool. Do not imagine the custom task as a useful supplement to Ant defects .ant and his task model more like "Lego Toy". Increase the ANT task can increase and strengthen Ant Attribute set, but it will not be his bloated. Through beginning, modular and scalability is maintained.
5.2 Ant Task Model (Task Model) Understanding Tasks, first understand the task model .ant, as a Java-based program, use the hierarchy of the Java class and reflecting Capabilities to complete the work. All ANT tasks directly or indirectly inherited from abstract class org.apache.tools.ant.task. Ant engine manages all tasks on this level, because he only operates Task objects. For this engine, every task is Other tasks, inheriting from this same class and having the same core method and attribute. XML parsing and method design of the design of the design makes Ant to use Task all subcategories. In addition, Ant is handled in a fixed manner Task - That is, Ant executes all tasks in the same loop. Of course, you don't need to understand this model and process details, but for complex tasks may exhibit uncharged behavior (Exhibit Undesirable Behaviors). -------------------------------------------------- ---------------------------------------- Write custom data type - except for the task An Ant model also handles data types (a DataType). An example of a data type is a Path task. --Path task has no direct behavior. - On the contrary, he built a data set, data comes from (based on) XML Rules and other information given. - As Ant1.4, users can technical have the ability to customize user data types. - However, the declared data type method (TypeDef task) is a bug and cannot work. The Ant Release1.5 is solved in this problem. --------------------------------------- -------------------------------------------------- -5.2.1 Component part of the task One task includes two sides. One side of the terminal users facing Ant, this time the task is just an XML in a workfile, there is no other thing. Don't have something to do, you need to resolve this. XML and identify the various parts of the task. For the programming staff of the task, the task has become different. Although XML still exists, but just as a guide to the Java's code to write. Can j The AVA code is just a horn of the iceberg. Technically, there are many levels for a task.
5.2.1.1 Common Superstoplasma must inherit from superclars (in a sense, Task) .ant engine strictly operates to Task objects, ignoring any developers attached to anything on the subclass. But, This doesn't mean that you can ignore the Task class hierarchy. Understanding this structure can help you try to get rid of his resistance to your work (IGNORING IT HAMPERS YOUR EFORT). Task subclasses not only demonstrate the tasks in the work file, but also To express the useful features in the classes in other tasks. Sometimes, a subclass is not even a task. For example, if your task needs to use file set (file sets) and mode (Patterns), you should inherit org.apache This class implements most file sets and mode operations to reduce the boring effort you want to pay. This makes you can get a powerful benefit using the giant function. Just like this task and other task classes. (It does you good to standard on Shoulders of Power Ether Giants Such as this and other task classes). You should know some task design similar to you. A good and efficient An example of a reuse is the task of the ZIP family. JARS extends the zip-packaging model (Zip-packaging model), JAR task inherits from ZIP, absorbs most of the ZIP features, only implementing JAR-related features, and further The WAR file is a JAR file with a standard directory structure and an additional must-have file (deployment description file web.xml). Therefore, the WAR task inherits from JAR. In the WAR example, the WAR will retain each point of inheritance. It is only possible to create a function of creating a standard directory structure and testing files in WAR. At the end of this chapter, we will analyze JAR tasks and his hierarchy as an example of custom tasks. 5.2.1.2 Properties (attributes) The attribute is a special XML tag that is described in the form. Programming perspective, ANT parsed and loads the name value pair of attributes from XML, and passes them to each task object .ant will define these string to be defined as the original Data type objects, file objects or classes. A typical application, attribute value represents the Boolean type, play the logo of the task handling process. For example, the property debug in the Javac is a Boolean type. This value is "ON", Javac DEBUG information will be given when compiling classes. For "OFF", the general compilation. 5.2. 1.3 Inline Elements embedded elements or more or less the properties have mutually alternative. They can be tasks or tasks or data types. As the property, the task can clearly handle their embedded Element. Unfortunately, the dealing element is not dealing with the name - the value is so simple. The complexity of the embedder element may become very confused, because there is no certain model to make you designed the inline you use. Element. In theory, your customized task can use any existing task as his embedded element. For example, you can regard Javac as an embedder element. However, such an embedder element is only a clear handling Javac related class Javac can work properly. You must know all the constraints of the Javac implementation, drawbacks. Not that simple feat. Even if you do this, Javac may also perform the operation to make you don't It may take advantage of him as an inline element. This is because there is no standard method to perform these tasks. Even if there is no thing, you can stop you from using Javac as an embedded element, you will also discover the entire work suspension He is not available. The task uses the Introspective call to handle embedded elements, just like processing properties. Differences between embedded elements have corresponding classes containing data and functions in him. And the attribute is only named - Value. One element requires his class to be instantiated, his own properties are resolved, and his main function will be executed. In this process, the error will occur at any time. By comparative and comparison a task to him The use of attributes and the use of the inline elements can prove the differences in attributes and embedded elements. Consider the COPY task: ** / *. java "/> fileset> copy> COPY Task With Property DESTDIR and Embedded Elements 5.2.2 Communication between Ant and Tasks Since you have understood the various parts contained in a task, we now turn attention to the communication mechanism between the ANT work engine and tasks. When writing custom tasks, you need to understand three communication mechanisms. Project class Project is a public instance that can be accessed in each task. This class shows the entire work file and everything that is included. Through him, you can access all tasks (TARGETS), properties (Properties) and other parts of the work file. The work exception is exception, implemented by the BuildException class, providing a way to the Ant work engine for the task trigger error condition. The logging system log system, accessible to the task via the Project class The way the way to display the process of the process gives the user. The following three sections describe each mechanism. 5.2.2.1 Project Class A maximum convenient class for communication between tasks and Ant engines: Project class. Since the parent Task contains an instance of a Project class, this communication is possible. Can be seen in any task Use any variables to use him. The project class provides a lot of powerful features, please pay attention to what he can do, but please pay attention to the place where you have accidentally abuse this power. (You will not intend to abuse, is it? Again, please note that you can use the smart thing you can use in Project in the next release of the ANT that you may not be supported. Please keep an optional design plan or prepare to maintain your own Ant version. The Project class represents the entire work file This class allows you to access every task, target, attribute, and even some core settings for the work files. Developers have very little use of this kind of access, even if he uses his features and capabilities already have already First, the task developer uses Project to provide an Auditing System for the engine through the log method. In addition, Project is a constant and full process for all task definition system. These constants can be called system calls Parameters, such as the parameters of logging. Global method provides a Boolean attribute value of each color function from the conversion path to the localization form to provide the Boolean converter to convert the task. In one task, the field name of the Project class is quite obvious, that is, Project. Here is Some public methods in the task and some can be used: Project.getglobalFilterSet () Returns a global FilterSet object for this work. You can define a global filter collection that excludes or contains a series of files for each task to make files and directory operations on it. If your task needs to be observed This global filter, you can get project.getglobalfilterSet (). More About Fileterset, please see ANT API JAVADOCPROject.getBaseDir () Returns the BASEDIR attribute value in the In addition to obtaining information from the work engine in this section, you can also use him to deliver information to the work engine. But this application is usually destructive, using him more dangerous. Theproject is saved. The setting of the work engine operation, which means you can change some changes in the right place. But just a special example, otherwise it is best nothing. We mention this ability is just let us Knowledge is more comprehensive, not to recommend him when you implement it. The safest way to communicate with your work engine is to use work exception and log information. This is because a task is to be made is those notified. Not anything that may cause destructive things. This means that if the error occurs, the status message should be provided as a running feedback or safe and secure failure. 5.2.2.2 Working exception work exceptions throw through the BuildException class, and provide a mechanism to send an error situation to the ANT work engine. You can throw the buildexception in any place in a task. Engine for him The method call on the task is expected to have buildexception. Look at this example, he shows a buildexception throw process: if (! Manifestfile.exists ()) {throw new buildexception ("Manifest File:" manifestfile "Does not exist GetLocation ());} If the task enters the error status and declares when the task is trying to use the specified specific file, he informs the ANT engine to fail by throwing an error message and a location ( Location) Object (using getLocation () method to extract) The buildexception.location class contains the name of the work file and the line number currently explaining. To some extent, he is also a class similar to Project through his task. From the engine, you get communication. But most developers restrict the use of information from the Location class to build the message in the buildexception. Throw a buildexception immediately to stop this task. Only all the tasks are successful, the goals containing these tasks are successful. With buildexception, Ant knows when a task, his goal, and whole project. For such a rule: only a success of all tasks success. An exception is usually the properties of the Failonerror in the task. The task uses this property to avoid throwing a buildexception, so the work can continue. Of course, there is no ability to be automated, and you as a mission author, it is responsible for implementing this feature. The following is from the CVS class Some of the extracted code performance improve failonerror.xml: } // more code ...} Simply, if the Failonerror property value is false, the CVS class will not throw the buildexception and build an error in the target containing the task. In addition, there is a benefit, not what Not doing, the wrong condition can at least some log information makes the end user know something in addition to the problem. For example, better implementation: // Some Method Code, Blah Blah Blah // throw a build Exception Only if the task is supposed to fail if (! failOnError && retCode = 0) {throw new BuildException ( "cvs exited with error code" retCode);} if {log ( "cvs existed with error code" (failOnError && retCode = 0!!) Retcode); 5.2.2.3 Log System The Project class allows tasks to get information about the work files of the system. He also provides methods to access the work engine audit system. These methods are various variants in the log () form. Whether all information is determined to be called Message level engine range settings. The message is displayed on the five levels below, sorted by Verbosition: Error Level (Warning) Notification Level (Info) Detailed Level (Debug) These levels guides ANT to display messages. For example, if you tell Ant only display a message that only displays the notification level, all error levels, warning levels, and notification levels will be recorded in the log. Message Level values can be taken through the public static domain in the following Project class: Project.msg_err project.msg_warn project.msg_info project.msg_verbose project.msg_debug Verbose and Debug level look very similar, but they don't seem to be similar. When you run Ant, you can specify the Verbose and Debug level messages through a separate parameter. Specify the debug level message resulting will not display the Verbose message The same is true. The log () function sends the message to the registered listener in the work. The listener then processes the message string according to his design. The default log listener prints all the logs to the console. Log () function has three forms available : Log (Message) In the task, the message passes the LOG method of the Project class. By default, the call to log () is the notification level (specified by the MSG_INFO variable). The following example sends the same notification message to the working engine at the default level on MSG_INFO project.log ( "This build step has completed successfully with" numfiles "processed");. log ( "This build step has completed successfully with" numfiles "processed"); examples show, there is a default log ( ) Method (defined in the Task class) available and tasks do not use their Project instance variables. Using the default log () is a good idea, because the future Ant release version of the task hierarchical access will be canceled . Another form of the log (Message, Level) method has a second message level parameter. It is useful when sending the Debug and Verbose message. For example: // use the project variable's log method to log messages Project.log "For loop to process files begins", project.msg_debug; // use the log method from task to log message, project.msg_debug; note that there are two ways to call log (). In addition to the Project class, there are two parameters of the Task class. The implementation of the log () method. You should try to use the two parameters of the TASK log (Message, Level). Log (MSSAGE, LEVEL, TASK) Project class, the third form of log () method has a third A parameter, a task object. There should be a method that should call this method in the self-written task. He is used for work engine; we mentioned here to introduce integrity. 5.3 The life cycle of the task (The Task Life Cycle) Complex tasks, operate multiple files, depending on embedded tasks, use multiple libraries (eg, optional EJBJAR tasks), require in-depth understanding of tasks and ANTs. This is a warning. This section will discuss The full details of the life cycle of the task. If you think that your custom task is not so complicated, please skip this section directly to see our example. When you can go back and see this section, understand the engine and task life The cycle is quite important to be a professional task writer for you, that is not required for writing relatively simple tasks. Ant Processing All tasks are the same .ant set attributes in a fixed phase and process embedded elements. We can predict how a task is operative and further designed. The life cycle of the task can be divided into two major phases. : Analysis When and run. The parsing phase begins to read the task from the XML file in the XML file (the engine imagine the engine to parse the XML file). When the runtime phase begins to successfully completion of the resolution time. 5.3.1 The Parse Phase The Parse Phase The PARSE Phase The Parse Phase The Parse Phase parsing a task when reading an element node in his XML resolution period. Task name, attribute, embedded element is packaged into a single XML element object and stored in Ant storage Space DOM. In parsing, if the task's XML description does not match the specification or task configuration, it will fail. This step will fail. The following is a complete list of thections that Ant generated during parsing: 1. Example Task-class ANT, use the name of the XML element to instantiate a task's corresponding class. Remember, this attribute does not be set and will not be contacted with the working system. 2. Create a reference to Project objects and parent objectives Object. Task Use Engine Communications for their available objects and engines. At this stage, Ant builds references to these objects and allows them to be available. 3. Add Id reference Ant in an internal table storage with Id attribute task list. If the task comes with ID attributes, this phase is only important to other tasks and data types. Especially for those tasks and data types that perform some parallel processing. About parallel processing, Refer to Chapter 7. 4. Call the init () method in the init () task object is called. Remember, the task property is still not available at this time. In addition, the information of the task is not available in the information of its embedded elements. Note, many have been released tasks do not implement this method. 5. Embedded elements are parsed and processed, using addXXX (), addconfiguredxxx (), and createxxx () methods. This perhaps in the process of understanding the whole life cycle (also the hardest step). With the mind, you may think that Ant definition and processing task properties are parsing the time, but the fact is not the case .ant knows the runtime The stage will care about the task properties. This also means that illegal attributes are defined until running. However, Ant is dealing with embedded elements when parsing. So he captures illegal embedded elements to capture illegal properties Before. So, how to deal with embedded elements? He called Createxxxxx (), addConfiguredxxx (), or addxxx () in your task, where xxx is defined as an embedder element name. So what is the difference between these three methods? This mainly depends on how you plan to use the inline element and the properties of the embedded element. If your task needs you to instantiate this object, or this object itself doesn't construct a function, then use create; put it It is seen as "the embedded object created by your task." If your task needs to reference an instantiated object, use add; see him as "ANT adds this object's reference to your task object". " If you need ANT to complete this element node before passing this object, use addConfigured; think it as "Ant to add configured object reference to your task object". If it is not clear, please see Existing tasks are implemented. By the way, Ant first calls createxxx (). If you have multiple functions to a particular element, it will be called. This result will be terrible, so please don't like this Work. 5.3.2 The Runtime Phase The runtime phase is actually ending for a task. He began successfully in the resolution phase. When your task enters the runtime phase, other objectives and tasks may have succeeded. Opened. Maybe you want to make sure your task is expected to be expected to be expected to be completed, but this is a luxury! Your mission should be carried out automatically, and can be used as a work Or the last task is performed. The following is a list of things happening at the task runtime: 1. All attributes of the task are set to imagine these properties into tasks. And passed these values to tasks through the Method to Method SetXXXX (), Where XXX is the name of the property. If a set method, Ant's error will thrown and the task and work declaration failed. 2. Handling the CDATA text XML in the XML file to give you the ability to store the original text, use it! CDATA []]> Construction. You can send the original text to your task. Ant call method addText (String MSG), passing a string object represents character data in XML. Below is an example of a CDATA tag: 5.4 Analysis An example: JAR Task tells so many theories, let us see what will happen (when Rubber Meets the Road). To develop your own Ant task, just write a Java class to implement your design. The task is complicated or simple. To see you, the only important thing is that your Java class must be consistent with the Convention of SET FORTHs in the Ant Object Model. As an example of writing tasks, we analyzed existing tasks: jar.jar task has overwritten all the topics we need. Jar mission class is part of the deep level, while displaying (DEMONSTRANG) has reused by inheritance (RE- This is inherited from zip, and ZIP inherits from matchingTask.jar tasks without its own execute () method implementation, but relying on the implementation in the ZIP class. This indicates that some requirements are so much. Song.jar task also uses a lot of properties and embedded elements, making it a good example of how to handle all of these features. Use existing tasks as an example to strengthen this concept: User write tasks and ANT issuance There is no difference between the tasks contained in the task. Analysis JAR can give us some design tasks. It has the only and easy understanding design goal. We have the task design of this object reuse for future extensions is also open. War and EAR Inherited from JAR and got the same benefit. But we can't involve the features and various aspects of JAR tasks. For more information, take some time to see the source code. Learn more tasks, not only It is a JAR task that can help you become a powerful Ant task developer. ---------------------------------- -------------------------------------------------- ------------ WHERE to LOOK: The Source For Jar, Zip, And MatchingTask is found in the source distribution of ant (http://jakarta.apache.org/builds/jakartaant/ Release / v1.4.1 / src). We analyze the jar task with code snippets from these source files. If you fail to follow some of our decisions or do not understand how a code snippet fits in with the descriptions, feel free to follow along with The Full Source Code at Hand. ------------------------------------ -------------------------------------------------- ---------- This, our analysis is not comprehensive in creating a job task. We simply involve and explain the main point of design and writing JAR tasks, but Details of implementation of input streams such as handling JARs are not involved. He is just a analysis rather than a tutorial. If you try to write and compile the code according to this analysis, you will find that the last thing does not work. In concise (Concise) On the contradiction of Complete, we chose simple, incomplete (Sacrificing), of course, is also a mature user self-contained mission guide. However, our analysis accurate descriptions must write JAR and other tasks Work (EFFORT, if you think we offer, no source code for learning the task is better. Start, we assume that Ant doesn't have JAR tasks. Without it, there is no task in the example of our second chapter. Create these classes of the JAR package. Use Java or Exec to run the command line JAR tool is really too annoying, and it is easy to make mistakes (there is discussion in the introduction of this chapter). 5.4.1 Design JAR Task What is the requirements for a task to create JARS? The better start is starting from the command line tool JAR. In the case of our task, our task should have all the features of this tool in the JAR (and Not all features of this tool). This difference is very important. We don't have to re-implement JAR tools, we just create an available operation for our work, just meet the needs of our work. Command line tools can only achieve this Target. Our work requires us to create Jars, so we should care about JAR creation, not something else. We should define a need, for example, unpacking JARS files, we should need to implement these features. Command line tools Generating a zip-compatible file plus a special folder called Meta-INF. It stores a special file called manifest.mf. No need to get more details, we call Jars as a smart zip file: This document can not only put A set of files are packaged into a file and have a package description type. Minimum case, our task should create JARS and have a list of book files with (allow) user, if any, from the point of view, we The design should allow us to create jars to create a multi-group file with multiple directory and file types. Since a JAR contains a directory result of the class file path, we may need to change how many group files are stored in a JAR file. Experience Ant users use file collection and file mode to identify this matter. (After this chapter, I believe you can do it.) Hurry research on existing tasks also reveals some design of similar related files, such as COPY And zip. Simple, the following is the requirements for our JAR tasks: the JAR creation capability of the Duplicate command line tool gives a naming, a manifest, a set of files or directories, command line tools You can generate JARs. Our tasks should be done. You can operate a series of files, directory, and file modes (Pattern). Many tasks have the ability to process user-defined file collection information, and can handle user-defined file modes. We should prepare to make our tasks with this feature. With XML description, add / modify the list file This is an example of an extensible task to extend its corresponding tool function. Not only is a separate list file, we allow the list to set it into The settings inside the working document are of course the XML node. From our needs analysis, we should have an XML form of task grammar. When you define syntax for your own task, because you continue before Make the design change, please don't be surprised. Our task XML design: We did not find a JAR task. Next, let's take a look at the content of the existing task to achieve almost a reemble. Actual behavior, you may lack enough experience to discover the tasks you want to achieve and have The relationship between some tasks. Read (REVIEW) Chapter 7 and 8, see if you need the task function or some features are implemented in some existing tasks (Exist in Some Other Currently EXISTING TASK. As mentioned earlier, JARS is just a simple zip file plus a manifest file and a different file extension. It is because of this, we pay attention to the ZIP task, in order to discover possible Reuse .zip tasks perform a simple operation to achieve a simple package file from a set of files (Pattern) and rules (Rule). In fact, this operation is only a bit different on the list, and the file name (. Zip and .jar) are different. In this decision! We inherit our object from ZIP. This is the manuscript of our JAR class. Package org.oreilly.rt.tasks; // NEED TO IMPORT IT to Derive from It Import Org.Apache.Tools.nt.taskdefs.zip; / ** * Implementation Class for the When we inherited from Zip, our inherited class automatically becomes part of the Task framework. The most original task framework, org.apache.tools.ant.task, it defines the most important task Rudgetary method. These methods, in addition to those that you are provided in the task implementation, or (allow) a task to get the properties that you get in the XML node in the workfile, and other properties defined in the project. .org.apache.tools.rt.taskdefs.matchingTask inherits org.apache.tools.ant.task, and implements the file and directory operation of the task. For example, COPY and ZIP tasks, inheriting MatchingTask, inheriting These methods. Chapter 4 contains a complete explanation about model and documentation organization. The key here is a re-usability. There is a task object model that it means that the task with the general public (Common) function can inherit the same parent task object. Weighing priority work is not only seeking code execution Reuse, and to seek object reuse. The object model is so powerful, and it is explained why Ant is so rapidly in less than two years. Design efforts work and the initial research reduces the minimum cost. Pays off in the end). The useful changes in the framework make all tasks benefit: there is almost no maintenance. 5.4.3 Implementing the Property Setting Method Ant to give the task setting attribute by the task author-defined set method. Method naming in accordance with a naming rule similar to the JavaBean property setup: Set uppercase The attribute name of the letter begins. These methods must be public visible, and the caller does not return anything (Return Nothing to the caller). The parameter is usually a string, but it is an object listed in any of the following list, any original object (They will switch from String objects), or any user-defined type, but it must have a constructor with a string object as a parameter. Valid attribute setting parameter type is: String This parameter is most common. ANT transmits the original value (RAW value) to the setting method from XML. File Object If there is a file object parameter, it will try to be a baseDir property in Remember, in our JAR mission, we don't implement all attribute setting methods, just that there is no processing in the zip task, or those who have different processing in JAR and ZIP (this is actually the father This method is overloaded). Table 5-1 lists the properties of our JAR task (see XML examples of JAR tasks given earlier). Table 5-1 JAR Related JAR Tasks Unique Property Name Description Do I need to implement JARFILE Package JAR files in the JAR task object, which is unavailable in the zip task object to verify and include The manifest file name is that it is the root directory of the source of the BaseDir JAR file in the ZIP task object. The zip object has implemented the setting method for this property. Next is the implementation of the setjarfile () attribute setting method. It uses a file object as a parameter .ant detected a file object through the internal provumeration function, and attempts to create a file object via the attribute value of XML. Create a file error will throw from Ant itself Out, you don't have to worry about invalid file names. Similarly, since our method comes from zip, we only need to call the setzipfile () method of the ZIP class, and this method sets the File object of the task instance. / ** * set the value of the JAR filename * The instance variable is zipFile * / public void setJarFile (File pValue) {log ( "Using Zip object 'setZipFile' to identify the JAR filename", MSG_DEBUG); super.setZipFile (pValue);} Another example, we will show you the property setting method in the JAR class: Manifest. Icon setjarfile (), setmanifest () method has a File object parameter: / ** * set the manifest file to be packaged with the JAR * the manifest instance variable can be used to add new * manifest attribute entries with nested elements of the * jar task. * / public void setManifest (file manifestFile) {// this is a file attribute // check if file exists // If there is no existence, throw a buildexception, work failed if (! Manifestfile.exists ()) {throw new buildexception ("Manifest File:" ManifestFile "Does not exist.", GetLocation ());} // the list of documents setting instance variables this.manifestFile = manifestFile; InputStream is = null; // load the manifest file An object to handle manifest files // was written by Conor MacNeil and is available with Ant This // object guarantees that.. the manifest file is properly formatted // and has the right default values try {is = new FileInputStream (manifestFile);. Manifest newManifest = new Manifest (is); if (manifest == null) {manifest = getDefaultManifest ();} manifest .merge (newmanifest); // let's log twi s operation for task developers log ( "Loaded" manifestFile.toString (), Project.MSG_DEBUG);} catch (ManifestException e) {// ManifestException is thrown from the Manifest object // Just like the Manifest object, a custom object exists // TO WARN About Manifest File Errors. log ("Manifest Is Invalid:" E.GetMessage (), Project.msg_err); Throw New BuildException ("Invalid Manifest:" ManifestFile, E, getLocation ());} catch (IOEXCEPTION E) {// ioException is thrown from any file / stream operation, // Like FileInputStream's Constructor Throw New BuildException ("Unable to read manifest file:" manifestfile, e); Finally {// Since We're Done Reading The File Into An Object, Let's Close /// The Stream. IF (IS! = NULL) {Try {is.close ();} catch (ioexception e) {// DO Nothing But Log this Exception Log ("Failed to Close Manifest Input", Project.msg_debug);}}}} 5.4.4 Implementing the embedded element handling the embedded element is the most complex part of the completion of a task. Similar to attributes, processing embedded elements are named by compliance with the agreement naming rules. And to read the task objects related to the embedded element and try to call one of the three methods. In this example, the method naming rule is AddXXX (), addConfiguredxxx (), and createxxx (), where xxx is a string of uppercase letters of the uppercase of the embedded element (for example, addFileSet () handles a task AddXXX () When you "add" an embedder element, you actually tell ANT to instantiate this class before calling your addXxx () method. If the class corresponding to the embedder does not have the default constructor, Ant will not complete This matter, an error will be thrown. If there is, Ant will pass instantiated objects to your task object so you can handle this object according to your will (for example, save it in a collection Mid way. We recommend that you can wait until your implementation phase of your task really uses embedded objects (call methods or values), if it prevents the possibility that the inline element attribute is not set, it is very Ok. AddConfiguredxxx () Now you are thinking, "I need to use embedded elements before the execution phase!". Fortunately, Ant provides an alternative to add an object. AddConfigureDXXXX () method indicates that Ant is not only instantified this class, but To configure this object to the task. In other words, Ant ensures that the attributes and embedded elements in the given embedded element are set well before it arrives at the task object. Such technical breaks The life process of the task is not dangerous, although it is not affected. Although Ant is configured to configure this node, Ant does not immediately complete the configuration. You will find that the parent task properties are calling addconfiguredxxx () is null empty space. Value. If you try to use these properties, you will have an error, causing the work to end. The parameter type of the method is limited, just like the AddXXX method, if there is no problem with this object, you can't Take it as a parameter of the AddConfigureDxxx method. CREATEXXX () If an Ant calls the createxxxxx () method, it gives the task object to parse enough control of the embedded element. Not to pass the object to the task, Ant wants task to return this embedded element object. This will bring some marginal benefits The most significant, it eliminates the requirements of the inline element with the default constructor. Unfavorable (Downside) is the responsibility of your understanding of element object initialization. You may have no document or source code in hand, so this may be A terrible thing (Formidable). These are some loose definitions because there is no programming that allows you to use them. As long as you implement one of these functions, Ant can make your task and its embedded elements. But when you view Ant's source code, especially other users, you will find developers to violate these definitions, in fact, it is mixed. There is no strict and fast rule to handle elemental methods, there is always existence Alternative methods to violate the definitions set here. JAR Tasks requires a designation of a set of modes to include and does not contain various files and directories. It also requires a method of providing a manifest file to add JAR. In our design, we choose the ability to implement embedded elements. The first requirement, mode processing, is already a part of MatchingTask is implemented. Second requirement, specify attributes for the manifest file, need to have obvious processing in our JAR implementation. Re-look at this task XML Special attention to embedded elements: At first, we seem to need ANT to process the Manifest node in the normal "embedded element" process. Then it is a general task life process. However, waiting for the Manifest node means that the value and data from this node will wait until the execution phase of the life process. It is only available. This requires us to actually implement the Execute () method of JAR task objects. This is all we avoided. We need to let Ant to process the manifest node before processing phase. Enter the AddConfigureDManifest () method (JAR class : Public void addconfiguredmanifest (manifest newmanifest) throws buildexception {i (manifest == null) {throw new buildexception ();} manifest.merge (newmanifest);} AddConfigureDXXXX () The family method tells ANT to handle nodes when passing the node instead of the running process. In our example, the Newmanifest parameter should be a full set (Fully Populate)'s Manifest object. This method is nothing just what is only Complete the checkup of the fundamental error and merge the existing list file content with the parameter file content. Exested inventory files come from the Manifest property in the JAR task. If there is no existing manifest file, Merge method enforces Manifest Generate a new one. This method is the feature of the Manifest object. File mode matching features exist in the large number of tasks of Ant, so understanding his implementation is very important. You don't need to write code to process file mode (File Pattern). To think Learn about the processing of file modes, please participate in the source code of ZIP and MatchingTask in the ANT release. The following is the processing method of Fileset embedded elements, addFileSet (): / ** * Adds a set of files (NESTED FileSet Attribute) * / Public void address {// add the fileset object to the instance variable // filesets, a vector of fileset Objects. FileSets.addeElet (SET);} Talking about the complexity of life flow and embedded elements, You must do something more complicated, is it? The only simple thing is that Ant strictly rely on object-oriented design and internal provincial mechanism. The characteristics of object-oriented programming means that the design is sometimes complex, but it is more easy to encode and The concept of tag-off. The concept of tag-to-class is convenient in the XML. The concept of tag-to-class is makes the previous code short. When you write a task similar to JAR, you can imagine FileSet objects. Contains all things. You just need to pay attention to this design of this design. Since the JAR class needs to maintain a group of FileSet objects, what is needed to save them. Thank you, Java has a rich collection class - in this In the example, we use a vector. Of course, we actually have quite complicated to the processing of the Vector of the FileSet object. Fortunately, we must only write this implementation in one place, that is, in the execute () method For JAR tasks, we don't even need to complete it. 5.4.5 Implementing the EXECUTE () Method EXECUTE () method implements the core logic of any task. When writing a task, implement the EXECUTE () method section is the easiest part .ant will call it during the last phase of the task. The execute () method has no parameters nor return value. The call is called on any task, which is the last method. So, at this time, your task class should have all the information you need to handle the job. In the earlier chapter, we mentioned that ZIP has perfectly implemented an Execute () method. We don't need to write anything for the JAR class. It is not what we have to avoid, this is exactly a good example of a high-efficiency code. To explain why we don't You need to write your own execute () method, we further analyze the ZIP's Execute () method. We don't design zip unique operation in our analysis, because we focus on how to write Ant tasks, not the construction and management of programming nature JARS. We divide the analysis of the execute () method into three parts: check, implement actual work, error handling. This is a simple and general method to describe how to implement a task core operation. When writing your own task, please keep in mind These three parts, because they help you design a better task. Before entering the EXECUTE () method, let's take a look at this method. Public void execute () throws buildexception {Nothing special No parameters and return values can be followed. Error is the same as the other interface method of the task, and the other interface method of the task is the same. 5.4.5.1 Check the first part of our analysis About (CONCERNS) check. We need to check the value of the JAR task properties In addition, we must verify the value above these attributes, and our task can run completely. The effective parameters are non-empty, which can represent the parameter values of the attributes of the task. For most cases, this verification occurs In the setter () method. And the setter method is disorderly, saying that it is the first to be set first. The relationship verification between any properties must be completed in the execute () method. All running periods also You must be done in the Execute () method. In the following code snippet, we verify the properties and elements necessary for the task. In our example, we only need the basedir property and FileSet elements. If (Basedir == Null && FileSets .size () == 0) {throw new buildexception ("Basedir Attribute Must Be set" "OR AT LEAST One Fileset Must Be Given!");} Below, we check the name of the ZIP file is effective (non-empty) - or, our example is JAR file. If (zipfile == null) {throw new buildexception ("You Must Specify THE" / ArchiveType "File to Create!");} This is the verification, there is nothing more Do it, in fact, but these small problems can prevent future mistakes. If the verification of the task is good, hours of hours can save. 5.4.5.2 Do the actual work Our second part is using Ant The object of the function of creating a file collection is created. Here, we introduce two helper objects, FileSet and FileScanner. Both represent different ways to store files and purposes Collection of records, but they do not have the same. The FileSet object is directly related to the FileSet element node and its subtracks. The FileScanner is an object that can be plated in the current file system. His objects. He Compare the file collection or comparison with other scanners to determine if the file changes or lost. Once the Ant handles the Fileset node, the FileSet object has a lot of functionality to get information from setting up objects. The following part uses the base catalog property. (BaseDir) and file collection to create a set of scanners (SCANERS). In this example, we create a set of scanners and file comparisons, if they exist. He is a real-time check, if possible, if possible, can be eliminated Unnecessary work. GetDirectoryScanner method from the MatchingTask class. // Create the scanners to pass to isuptodate (). Vector dss = new vector (); // create a "checkable" list of the files / directories under the base // Directory. If (basedir! = Null) {///////// getDirectoryScanner is available from the MatchingTask object dss.addElement (getDirectoryScanner (baseDir));} // Create a "checkable" list of the files / directories // from the FileSet, using the FileSet's characteristics // We pass the project object in so THE LIST CAN INCLUDE // Global Filters Set in The Project's Properties. for (INT i = 0; I 5.4.5.3 The third part of the error handling analysis is about the error handling. You may think that our previous verification has handled all the mistakes, but it is not the case. Since we want to deal with the file and stream, the threat of ioException appears. We return to Ant through BuildException, so, such as representing an error, empty object, and IO unusual, eventually become a buildexception. For more accurate and better and user interactions, you should analyze your mistakes and generate Descriptive error message. These messages will appear in the work log, so they should be readily read, you can search by providing a consistent text structure, so you and users search in the log. The following piece corresponds to The Catch block of the TRY block. Do IOException occurs when the flow or file occurs, this code generates a descriptive message. The display of some test results of the file before the file is deleted. BuildException by the message, original Error exception and abnormal position composition. From the new call, Ant will maintain a target called Loc as an execution pointer. It contains the line number of the XML file and the wrong place for error occurrence.} Catch (ioException ie) {// Some IO (Probably File) HAS Failed. Let's Check It Out. // Create A Descriptive Message String Msg = "Problem Creating" ArchiveType ":" IoE.getMessage (); // delete a bogus zip file // this essentially rids us of the partially created zip / jar if (! zipFile.delete ()) {msg = "(and the archive is probably corrupt but I could not delete it)";} // This functionality deals with updating jars if (ReallyDoupdate) {if (! RenamedFile.Renameto (zipfile) {msg = "(and i couldn't rename the temporary File " renamedfile.getname () " back);}} // The message has been built. Send it back to ant. throw new buildexception (MSG, IOE, location); 5.4.6 Compiling This task Compiles a task includes using the current Ant library file, Ant.jar, and some basic package structure. Many people put their tasks under org.apache.tools.nt.taskdefs.optional package, Although Ant does not require this. Choose a package and engineering structure that best suits you. Unless you write a lot of tasks, you will change the package structure in the future. You can always write a work file to compile your task. Here is a simple, you can help you start. This compilation file finds your task object in the subfolder SRC and the corresponding package directory. Then copy the class file of the compile result to the appropriate package structure in the dist directory. Once we have class, we only need to deploy And define the task, so that he is visible for Ant. We use the TaskDef tag to complete this matter. For the JAR version of this chapter, a project is built like this: MyTasks / Build.xml Dist / Build / (Temp Build Directory Src / org / myorg / tasks / *. Java remains simple. If you just write a task, there is nothing to manage your project like this. Once we compile the JAR task, we can play it. It is easy to make a new JAR to pack your task than a directory and job, creating a new JAR to package your task is an easy thing. The rest is to deploy the task so that your work file can be used. 5.4.7 Deployment and Disclaimer Tasks Our Tasks There are two deployments, class files, or the JAR files that are packed. The difference between them is only different. To give some comparisons, all built-in ( The build-in) task is deployed as a JAR. They are part of Ant.jar. There is a file in that file, default.properties. In this, the maintor declares each available task for Ant. As a Attribute file, he is a list of name value pairs. We can extend this list to declare our task. If you want to add tasks to Ant's source tree, you can modify the default.properties file, add your new Task. In this example, it is not compiling your task separately. You must recompile the entire Ant, generate new Ant's JAR package. This method is best suited for the release of the ANT system, so you need all developments in a group. To maintain these codes and require an identical work environment. Your team must maintain its own internal version, but there may be other tools, so adding a task will not lead to a big change. This has an example, If you want to add task foo (related objects is org.apache.tools.ant.taskdefs.Optional.foo) to Ant's core task group, open file default.properties, this file is in src / main / org / apache / Tools / Ant / taskdefs, add a line in the file: foo = org.apache.tools.ant.taskdefs.optional.foo result is, next time you compile Ant, your task class and its declaration will become in the core task list One member. If you want to know more about compilation Ant, see DOCS / Manual / Install.html # buildingant in the Ant source release. If you don't use the above method, you must use it in each work file. The method of the TaskDef node is to declare this task. You can put this statement in the project level or target level of your work file, depending on your task's functionality. Equipment level tasks are in each goal You can use, and the target level task is only available in this target. In this destination, the location of the declaration is also important. You can't use it before declaring it. Below is an example to define task JAR And the location of the implementation class for the JAR task: 5.5 Various task topics are changed once every six months, and Ant will never be in the most perfect state. Some behaviors will not see clearly. There are bugs, and there are some documents. Can't see the characteristics. The following chapter introduces some topics that you need to pay attention to when you write your own task. If you want to try (Live Danger ", implement your task, deploy it, see what will happen. When you encounter some you Explain the problem, return to this section to see if these topics can help you. Some topics, such as system.exit () issues, unless the JVM features change, other issues are like strange properties ( Magic Properties, as some new task models will disappear. Of course, when you try, try to avoid these issues. 5.5.1 Weird attributes have been a few months ago, the Javac mission appears. Many people say It's great, there are many other people nod. At this time, there are at least three different compilers on the mainstream Java platform (Solaris, Linus, Windows) available. These compilers have Javac (and their different compilation modes), IBM's JIKES and SYMANTEC's SJ. Not the properties of the compiler as the