The aim of this short ‘How To’ guide is to help migrate existing users of the DeltaXML compare API to migrate to the new com.deltaxml.core.PipelinedComparator. Note that there is absolutely no necessity for this as the XML Compare API is still current and indeed might be needed for the 5% (or so) of cases not covered by the new PipelinedComparator class.
However, the PipelinedComparator makes it extremely easy to create pipelines to accomplish complex pre and post processing activities and as such is worthy of consideration.
The aim of the com.deltaxml.core.PipelinedComparator class is to provide a simple way to create complex pipelines that covers the commonest 95% of scenarios encountered by most developers using DeltaXML.
It provides a simple to use interface that consists of overloaded set and get methods that allow filters defines in a range of ways to be easily added to the comparator pipeline. These include:
void setInputFilters(Class filters)Allows SAX event filters to be specified in terms of classes which implement the XMLFilter interface.
void setInputFilters(File filters)Allows SAX event filters to be specified in terms of File objects that reference XSL filters.
void setInputFilters(List filters)Allows SAX event filters to be specified in a mixed List of any of the valid object types: Class, File, URL, or Templates.
void setInputFilters(Templates templates)Allows SAX event filters to be specified in terms of Templates objects.
void setInputFilters(URL filters)Allows SAX event filters to be specified in terms of URL pointers that reference XSL filters.
void setOutputFilters(Class filters)Allows SAX event filters to be specified in terms of classes.
void setOutputFilters(File filters)Allows SAX event filters to be specified in terms of File objects that reference XSL filters.
void setOutputFilters(List filters)Allows SAX event filters to be specified in a mixed List of any of the valid object types: Class, File, URL, or Templates.
void setOutputFilters(Templates templates)Allows SAX event filters to be specified in terms of Templates objects.
void setOutputFilters(URL filters)Allows SAX event filters to be specified in terms of URL pointers that reference XSL filters.
Thus a PipelinedComparator based comparison involves setting any input or output filters then calling the PipelinedComparators compare method.
3. Comparing using PipelinedComparator
The PipelinedComparator also provides a number of compare methods, that take their data form a number of different sources. The intention here is to make it as simple as possible to read data from XML files, input streams, java.io.readers, URL references, strings as well as javax.xml.transform.Source objects. In turn it aims to make it very simple to output the results of a comparison to a file and output stream, a java.io.Writer, a javax.xml.transform.Result object, a StringBuffer or URL resource.
The actual list of compare options is presented below:
void compare(File f1, File f2, File result)Compares two File inputs and writes the result to a File.
void compare(InputStream is1, InputStream is2, OutputStream result)Compares two InputStream inputs and writes the result to an OutputStream.
void compare(Reader r1, Reader r2, Writer result)Compares two Reader inputs and writes the result to a Writer.
void compare(Source s1, Source s2, Result r)Compares two Source inputs and writes the result to a Result.
void compare(String s1, String s2, StringBuffer result)Compares two String inputs and writes the result to a StringBuffer.
void compare(URL u1, URL u2, File result)Compares two URL inputs and writes the result to a File.
void compare(URL u1, URL u2, URL result)Compares two URL inputs and writes the result to a URL.
4. Configuration using the PipelinedComparator
The PipelinedComparator also provides a number of methods that allow the programmer to configure the DeltaXML comparator as well as the undelrying parser. This can be done by setting properties and / or features on the PipelinedComparator that either relate to the DeltaXML comparator or the underlying parser. These methods are:
For the DeltaXML comparison:
void setComparatorFeature(String name, boolean value)Sets a Feature (or option) associated with the comparator at the centre of the pipeline.
void setComparatorProperty(String name, Object value)Configures comparator properties for the pipeline.
For the Parser:
void setParserFeature(String featureName, boolean value)Modifies the parsing behaviour of a pipeline.
void setParserProperty(String name, Object value)Configures parser properties for the pipeline input parsers.
In addition there are equivalent get methods to obtain such information.
Finally, the setOutputProperty method on the Pipelined Comparator allows the programmer to configure output formatting. Current properties are
public void setOutputProperty(String name, String value) throws IllegalArgumentException
Output properties should be set using the OutputKeys static fields as follows:
For guidance on the properties and features accepted see the Javadoc reference documentation for the PipelinedComparator class.
5. Using the PipelinedComparator
To illustrate the use of the PipelinedComparator we shall look at how the
Advanced.java program, often used as a reference for creating pipelines prior to the advent of the PipelinedComparator class, can be migrated.
Advanced.java program is presented below:
As the purpose of this guide is to explain how to move form programs such as Advanced.java to using PipelinedComparator we shall not provide a detailed explanation of this program. Instead we will explain what it is trying to do at the abstract level.
The intention of this program is that it sets up a relatively simple XML processing pipeline that applies
infilter.xsl to both the files read in before they are compared by DeltaXML. It then applies another filter,
outfilter.xsl to the changes file generated by DeltaXML.
Thus the processing pipeline can be represented as:
However, although this is quite a simple pipeline the
Advanced.java program is quite long.
In contrast the PipelinedComparator version is quite short. For example:
As you can see form this program, all that we have to do is to tell the PipelinedComparator object that we wish to apply the infilter.xsl filter and the outfilter.xsl filter as input and output filters.
This is simply done by calling the appropriate set*Filter method with an array of the XSL files to use.
Of course these filters do not need to be XSL files, they could also just as easily be Java classes (that implement the XMLFilter interface), templates or references via URLs to filters. If you wish to learn more about Java based filters then please see our tutorial on implementing Java XML Filters for use with DeltaXML.
It is, however, worth noting that the Java filters appear faster and have lower memory overheads than their equivalent XSL filters and are thus preferable in many situations.
From this you can see that the use of PipelinedComparator can make your programs a great deal simpler and less cluttered. Indeed to convert to PipelinedComparator is as simple as identifying the input and output filters that you are using, their order and how they should be implemented. Next you need to add them to the PipelinedComparator, call compare, and there you have it!