2.5. Defining Custom PropertiesThe Axis plug-in also generates a unit test for your web service, but this generated unit test needs to be customized. For example, the weather SOAP service requires a latitude and longitude to work properly, and the generated unit test uses an invalid value. You need to define a preGoal and postGoal on the axis:wsdl2java goal which copies the unit test to your src/test/java directory and excludes it from axis:compile. Because you don't want to overwrite your unit tests every time you run axis:wsdl2java, you need to define a custom property, generate.tests. 2.5.1. How do I do that?Define a generate.tests property in your project.properties file which you will reference in your preGoal and postGoal. Add the following to project.properties: # Custom properties generate.tests = false Now modify your preGoal and postGoal in maven.xml to use this new variable to overwrite unit tests only if generate.tests is set to TRue: <preGoal name="axis:wsdl2java"> <j:if test="${context.getVariable('generate.tests') = = 'true'}"> <ant:delete dir="${pom.build.unitTestSourceDirectory}/gov"/> </j:if> </preGoal> <postGoal name="axis:wsdl2java"> <maven:get var="axis.test" plugin="maven-axis-plugin" property="maven.axis.test.dir"/> <j:if test="${context.getVariable('generate.tests') = = 'true'}"> <ant:copy todir="${pom.build.unitTestSourceDirectory}"> <fileset dir="${ axis.test }"/> </ant:copy> </j:if> <ant:delete dir="${maven.axis.test.dir}/gov"/> </postGoal> When you execute maven axis:wsdl2java, Maven will read the properties from project.properties and will use the default value of false for the generate.tests variable, which is set to false. By default, the axis:wsdl2java goal does not alter the unit tests in ${pom.build.unitTestSource}. To replace your unit tests with the generated test, execute maven axis:wsdl2java -Dgenerate.tests=true. This should generate the following output for the axis:wsdl2java goal: axis:wsdl2java: [copy] Copying 1 file to C:\dev\mavenbook\code\weather\src\test [delete] Deleting directory C:\dev\mavenbook\code\weather\target\axis\test\gov 2.5.2. What just happened?What you are doing here is passive code generation (one-off generation). While you don't need to modify the source code generated from the WSDL document, you do need to customize the unit test to set an appropriate latitude and longitude. When you need to generate this unit test, you set the generate.tests property to true. The preGoal on axis:wsdl2java deletes your unit tests from src/test only if the generate.tests property is set to true, and you should also notice that the end of the postGoal on axis:wsdl2java always deletes the generated unit tests. Note: Maven 2 does away with both the maven.xml and the project.properties files. In Maven 2 all behavior will be customized through the Project Object Model (POM), which will be stored in pom.xml. In this lab you defined a variable in project.properties. The variablegenerate.testsprovides default behavior, that you can override by specifying a variable value on the command line. When you ran maven axis:wsdl2java -Dgenerate.tests=true, you specified a value of generate.tests which takes precedence over the value defined in project.properties.You also used j:if to test the value of the generate.tests variable in maven.xml: <j:if test="${context.getVariable('generate.tests') = = 'true'}"> <ant:echo>Generate Tests is True</ant:echo> </j:if> In this example, you are accessing the generate.tests variable by calling the context.getVariable( ) function. The context variable is of type JellyContext, and it provides access to the variables made available to a Maven project. The generate.tests variable is compared to a string literal TRue. If generate.tests matches TRue, the ant:echo tag is evaluated.
The generated unit tests will fail unless they are modified, as they reference a latitude and longitude of 0,0. If you ran axis:wsdl2java and inadvertently removed your NdfdXMLTestCase.java test, you will need to restore the original copy from the example source code. In this lab, you referenced the ${pom} variable. ${pom} allows you to access everything that was defined in the project.xml file, and more. When Jelly encounters an expression, it checks to see if there is a matching property name. If there is no matching property in the Jelly context, Jelly will evaluate the expression as a series of calls to property accessor methods. For example, when you reference a property of the pom variable, you are executing a get method; ${pom.build.sourceDirectory} is equivalent to calling ${pom.getBuild( ).getSourceDirectory( )}. Here is another goal which demonstrates some of the other properties you can access through the ${pom} variable: <goal name="pom-example"> <ant:echo>Project Name: ${pom.name}</ant:echo> <ant:echo>Description: ${pom.description}</ant:echo> <ant:echo>Source Directory: ${pom.build.sourceDirectory}</ant:echo> <ant:echo> Unit Test Directory: ${pom.build.unitTestSourceDirectory} </ant:echo> </goal> The previous goal simply prints the name and the description of a project, followed by the source directory and unit test directory as captured by the org.apache.maven.project.Build object obtained by calling getBuild( ) on org.apache.maven.project.Project. This goal produces the following output: build:start: pom-example: [echo] Project Name: Test Application [echo] Description: An example project [echo] Source Directory: C:\dev\mavenbook\code\genapp\test-application\src\java [echo] Unit Test Directory: C:\dev\mavenbook\code\genapp\test-application\src\test BUILD SUCCESSFUL Total time: 1 seconds For a list of the properties accessible from the ${pom} variable, see the Project class JavaDoc at http://maven.apache.org/apidocs/org/apache/maven/project/Project.html. For a list of the properties accessible from the Dependency and Build objects, see the following JavaDocs: http://maven.apache.org/apidocs/org/apache/maven/project/Dependency.html and http://maven.apache.org/apidocs/org/apache/maven/project/Build.html. You also used the maven:get tag to retrieve a property from the Axis plug-in. When referencing plug-in properties, you should always use maven:get rather than ${maven.axis.test.dir}. If a plug-in has not been initialized, a reference to maven.axis.generated.dir will cause an error. When you reference a plug-in property with maven:get, Maven will initialize the referenced plug-in if it has not already been initialized. You can also set a plug-in property with maven:set. Here are two examples of using maven:get and maven:set: the first call to maven:get retrieves the maven.axis.generated.dir property from the Axis plug-in, and the second call to maven:set sets the value of maven.axis.generated.dir: <maven:get var="axis.src" plugin="maven-axis-plugin" property="maven.axis.generated.dir"/> <maven:set plugin="maven-axis-plugin" property="maven.axis.generated.dir" value="${basedir}/src/axis"/> To use the Maven tag library, the Maven namespace must be mapped to jelly:maven. For more information about the Maven Jelly tag library, see http://maven.apache.org/reference/maven-jelly-tags/tags.html. For more information about plug-ins, see Chapter 6. 2.5.3. What about......these built-in variables, like ${basedir} and ${pom}? Is there a list? Yes, there is. Table 2-1 lists some frequently used Maven properties which are made available to goals defined in the maven.xml file. The previously defined postGoal and preGoal referenced the ${pom.build.sourceDirectory} variable to get to the directory holding Java source, and the ${pom} variable contains the various pieces of information available from the POM. ${basedir} is another common built-in property which resolves to the root directory of a project.
For a more comprehensive list of Maven properties, see Maven's online reference at http://maven.apache.org/reference/properties.html. Chapter 6 delves into the details of how a Maven plug-in can access these properties, and properties specific to a Maven plug-in. |