As with the other chapters on APIs, I will address a few more tricky items that relate to the topics in this chapter. These are common problems that can cause you to beat your head against the wall, so try and avoid them.
8.4.1. More on Subclassing
Since I talked about factories and custom classes in this chapter, it's worth pointing out a few important things about subclassing that can be gotcha items. When you extend a class, and in particular the JDOM classes, you need to ensure that your custom behavior is going to be activated as you want it to. In other words, ensure that there is no path from an application through your subclass and to the superclass that isn't a path you are willing to live with. In almost every case, this involves ensuring that you override each constructor of the superclass. You'll notice that in Example 8-1, the ORAElement class, I overrode all four of the Element class's constructors. This ensured that any application using ORAElement would have to create the object with one of these constructors. While that might seem like a trivial detail, imagine if I had left out the constructor that took in a name and URI for the element. This step effectively reduces the number of ways to construct the object by one. That might seem trivial, but it's not!
Continuing with this hypothetical, you implement a CustomJDOMFactory class, like the one shown in Example 8-2, and override the various element( ) methods. However, you would probably forget to override element(String name, String uri), since you already forgot to override that constructor in your subclass. Suddenly, you've got a problem. Every time an element is requested by name and URI (which is quite often in the SAXBuilder process, by the way), you are going to get a plain, vanilla Element instance. However, the other element creation methods all return instances of ORAElement. Just like that, because of one lousy constructor, your document is going to have two element implementations, almost certainly not what you wanted. It is crucial to inspect every means of object creation in your subclasses, and generally make sure you override every constructor that is public in the superclass.
8.4.2. Creating Invalid XML
Another tricky case to watch out for when subclassing is inadvertently creating invalid XML. Using JDOM, it's more or less impossible to create XML that is not well-formed, but consider the ORAElement subclass again. This subclass added the ora prefix to every element, which alone could cause it to fail validation. This is probably not a big deal, but you do need to comment out or remove the DOCTYPE declaration to avoid problems when reading the document back in.
Even more importantly, you can get some unexpected results if you aren't careful. Look at this fragment of the XML generated using the ORAElement subclass, which only shows the last little bit of the serialized document:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE book SYSTEM "DTD/JavaXML.dtd"> <!-- Java and XML Contents --> <ora:book xmlns:ora="http://www.oreilly.com"> <ora:title ora:series="Java">Java and XML</ora:title> <!-- Other content --> <ora:copyright> <ora:copyright> <ora:year value="2001" /> <ora:content>All Rights Reserved, O'Reilly & Associates</ora:content> </ora:copyright> </ora:copyright> </ora:book>
Notice that there are now two ora:copyright elements! What happened is that an existing element was in place in the O'Reilly namespace (the original ora:copyright element). However, the copyright element nested within that, with no namespace, was also assigned the ora prefix and O'Reilly namespace through the ORAElement class. The result is two elements with the same name and namespace, but differing content models. This makes validation very tricky, and is probably not what you intended. These are simple examples, but in more complex documents with more complex subclasses, you'll need to watch carefully what results you are generating, particularly with respect to a DTD, XML Schema, or other form of document constraints.
Copyright © 2002 O'Reilly & Associates. All rights reserved.