XML JavaBeans, Part 2

Automatically convert JavaBeans to XML documents

1 2 3 4 Page 3
Page 3 of 4

In Figure 7, the new method getAsDOM() actually builds a DOM subdocument in code, and returns it as a DocumentFragment. Note that it ignores the gradePointAverage property that the standard mechanism would have output. It also calls PersonName.getAsDOM(). The XML that results from printing the entire document tree appears in Figure 8 below. (Bean1.xml, which is provided with the source in Resources below, is the input for this run.)

 
<JavaBean CLASS="Player">
  <!--XML for this Player created by Player.getAsDOM()-->
  <Properties>
    <Property NAME="highSchool">Eaton</Property>
    <Property NAME="number">12</Property>
    <Property NAME="name">
      <!--XML for this PersonName created by PersonName.getAsDOM()-->
First: Jonas, Last: Grumby
</Property>
    <Property NAME="stats">
      <JavaBean CLASS="Statistics">
        <Properties>
          <Property NAME="year">1997</Property>
          <Property NAME="atBats">69</Property>
          <Property NAME="hits">30</Property>
          <Property NAME="homeRuns">2</Property>
          <Property NAME="runsBattedIn">15</Property>
          <Property NAME="runs">31</Property>
        </Properties>
      </JavaBean>
    </Property>
  </Properties>
</JavaBean>

Figure 8. The result of running XMLBeanWriter

Note how the comment included in

Player.getAsDOM()

resulted in a comment in the output. Note also the absence of any grade point average. This technique is powerful because it gives the programmer using

XMLBeanWriter

complete control over the structure of the output. A more elegant way of doing this, involving

PropertyDescriptors

, will appear in next month's column. Let's get back to looking at the code. Referring to Figure 5 again, lines 54 to 55 introspect the bean by getting its

BeanInfo

object, and asking the

BeanInfo

for the bean's list of

PropertyDescriptor

objects. At this point, the program knows what properties it is going to add to the

Document

. Lines 58 to 64 are our first example of creating DOM document objects and adding them to the tree:

058         // Add an Element indicating that this is a JavaBean.
059         // The element has a single attribute, which is that Element's class.
060         Element eBean = doc.createElement("JavaBean");
061         dfResult.appendChild(eBean);
062         eBean.setAttribute("CLASS", classOfBean.getName());
063         Element eProperties = doc.createElement("Properties");
064         eBean.appendChild(eProperties);

Line 60 creates an element that looks like

<JavaBean>

in XML. The next line (line 61) adds it to the resulting tree. The method then sets the

CLASS

attribute of the

JavaBean

element to the classname of the bean (line 62), so the resulting XML would look like

<JavaBean CLASS="classname">

. The next two lines (lines 63 to 64) create a

<Properties>

element and append it to the

<JavaBean>

element. So at this point, the tree looks like this:

<JavaBean CLASS="classname">
  <Properties>
  </Properties>
</JavaBean>

Of course, the document doesn't "really" look like this. In reality, it's just a data structure. The XML above is what you'd see if you printed the document fragment at this point.

The loop at the bottom of the method (lines 69-86) iterates through the list of property descriptors, and for each property, it:

  • gets the XML for each property by calling the overloaded getAsDOM() for properties

  • creates a <Property> element for the property

  • sets the <Property> element's NAME attribute to the property name

  • appends the DOM subtree for the property to the <Property> element

  • adds the new <Property> element to the <Properties> element

The resulting structure is the DOM representation of the JavaBean. Now, all that's left is to understand how a property is represented as XML.

Representing properties as XML

The code for the second version of getAsDOM() appears in Figure 9. This method generates the XML for the JavaBean property indicated by the method's third argument, a PropertyDescriptor. This method may return null, though, to indicate that it couldn't figure out how to represent the property as XML.

Figure 9. getAsDOM determines the XML for properties

Let's go through this three-argument version of getAsDOM() and see what it does:

1 2 3 4 Page 3
Page 3 of 4