Section 2.5. Defining Custom Properties


2.5. Defining Custom Properties

The 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.

If generate.tests is set to TRue, you might think that the following code fragment would evaluate the reference to ${generate.tests} to true, and would evaluate the ant:echo tag:

<j:if test="${generate.tests}">   <ant:echo>Generate Tests is True</ant:echo> </j:if>

If you write this Jelly script, the ant:echo tag will execute, but it won't execute for the reason you think. The shorthand notation, ${generate.tests}, evaluates to TRue if a property named generate.tests is available on the Jelly context and that variable is not null. The "." in a Jelly expression can be interpreted in one of two ways. If there is a variable on the Jelly context which matches the name generate.tests, it will be returned. If there is no matching variable, Jelly will consider the "." to signify a method call on a property; ${generate.tests} will evaluate to ${generate.getTests( )}, which returns null, as the generated object does not exist. So, ant:echo would execute even if generate.tests was set to the string false, because ${generate.tests} evaluates to TRue if the content of the variable is nonnull. For this reason, you should always reference a variable using the context.getVariable( ) method.


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.

Table 2-1. A selection of Maven's built-in properties

Built-in property

Resolves to...

${basedir}

Root of a given project. The directory which contains project.xml and maven.xml.

${maven.build.dir}

${basedir}/target directory. Destination directory for intermediate files and generated artifacts.

${maven.build.dest}

${basedir}/classes directory. Destination directory for class files.

${user.home}

A user's home directory. On Unix, this is usually something like /home/tobrien, and on Windows this is C:\Documents and Settings\tobrien.

${maven.home.local}

${user.home}/.maven directory.

${maven.repo.remote}

The remote repository from which Maven will download artifacts. Defaults to http://www.ibiblio.org/maven/. This property is a comma-delimited list of remote repositories. If an artifact isn't found in the first repository listed, it will try the next repository in the list until either the artifact is located or the end of the list is reached.

${maven.repo.local}

${maven.home.local}/repository directory.

${context}

This is a built-in variable in all Jelly scripts, and it is of type JellyContext. This object provides access to the variables a Jelly script has access to. For more information about this object, see http://jakarta.apache.org/commons/jelly/apidocs.

${pom}

Exposes an org.apache.maven.project.Project object for the current project. Use this object to access project paths and resolve dependency paths.

All System properties

The System class exposes a set of properties which can also be accessed. Properties such as java.home, os.arch, and file.separator are among the many System properties exposed.


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.



Maven. A Developer's Notebook
Maven: A Developers Notebook (Developers Notebooks)
ISBN: 0596007507
EAN: 2147483647
Year: 2003
Pages: 125

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net