You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Rationale

ServiceMix users typically build solutions declaratively, using fragments of XML to configure endpoints in xbean files. This development process can be made all the more productive by making use of IDE support for XML editting. For example, Eclipse lets you import XML schema into an "XML Catalog", and then will do neat things like auto-completion of attribute or element names.

Additionally, IDEs can make use of any XSD schema annotations to provide context sensitive help. Can't remember exactly what the period attribute is for the file component? Is it specified in seconds? Milliseconds? Good context sensitive help will increase productivity, remove confusion, minimize errors, and, in general give a better overall experience when creating solutions with ServiceMix.

Understanding how xbean generates schema from endpoint code

In ServiceMix we currently generate schema from Java code, using the Maven xbean plugin. The plugin looks for xdoclet tags like {{@org.apache.xbean.XBean }} in the JavaDoc for a class, and then generates an appropriate XML schema for the attributes of that class. Using the usual bean conventions (i.e. presence of get* and set* methods), the plugin will generate appropriate attributes & elements in the schema definition. Additionally, the plugin will insert XSD documentation annotations if required. It can get this documentation from one of three places, in the following order:

  1. From the contents of the description tag of the @org.apache.xbean.Property annotation, for example:
    /**
     * @org.apache.xbean.Property description="here's my documentation!"
     */
    
    This approach works nice and makes it explicit where the documentation comes from. However, the documentation must appear on the same line: this is not good, as it discourages developers from writing detailed documentation and can lead to massively long lines in the code.
  2. From the JavaDoc contents of the setter method. In the absence of a @org.apache.xbean.Property description tag, xbean will use the JavaDoc of the getter method. This is good, as it means you can have multi-line documentation commentary. However, the kind of documentation most coders put on a getter is typically quite basic, like "returns the delay": this is not going to be appropriate for an XML editting user who wants to know what they are setting.
  3. From the JavaDoc contents of the getter method. This is arguably the best approach to use: here, you can write multi-line javadoc documentation, that matches the semantics of someone who wants to "set" some value and wants to know more about it.

Recommended best practice

With the above points in mind, we recommend:

  1. Do not use the @org.apache.xbean.Property description tag, prefer to use JavaDoc.
  2. Do not provide JavaDoc for the getter method - typically comments on a getter don't add any value anyway.
  3. Do provide JavaDoc on the setter method - this will be picked up and put into the annotations.

Example:

Here's an example of how to annotate an endpoint, annotating the FilePollerEndpoint in the servicemix-file directory.

 
/**
 * Specifies the file or directory to be polled. If it is a directory, all
 * files in the directory or its sub-directories will be processed by the
 * endpoint. If it is a file, only files matching the filename will be
 * processed."
 * 
 * @param file
 *            a <code>File</code> object representing the directory or file
 *            to poll
 */
public void setFile(File file) {
    this.file = file;
}

public File getFile() {
	return file;
}

Consequences

This approach works well; it allows you to specify documentation once that will appear in the xbean generated XSD, HTML & WIKI files, and in any JavaDoc we create.

One issue to resolve is what happens when your class inherits from another class, and the source is not available as part of the xbean generation stage. For example, the FilePollerEndpoint in servicemix-file inherits from PollingEndpoint in servicemix-common. As a result, xbean can detect the inherited attributes but cannot locate the xdoclet documentation tags. To get around this I've wrapped the inherited setters to provide the documentation. It's not desirable as a solution (if only xbean used true Java 5 annotations instead of xdoclet); however, it gets the job done.

An example of how to wrap an inherited property is shown below for the FilePollerEndpoint in servicemix-file.

/**
 * Sets the number of milliseconds between polling attempts.
 *
 * @param        period  a long specifying the gap between polling attempts
 */
@Override
public void setPeriod(long period) {
	// Note: we only override this method so that we can specify suitable javadoc (above) that can be used
	// to auto-generate XSD document annotations in the resulting XSD file.
	//
	super.setPeriod(period);
}
  • No labels