Saturday, December 09, 2006

Eclipse: Graphical XML Schema Building using WTP also known as JaxB Article Part 1

While I know I said I was going to have a second article about adding onto my RCP application, but I got sidetracked. My boss got me interested in working with JaxB (Java Architecture for XML Binding) to build Java code to marshal (handle writing to) and unmarshal (reading from) XML files. The basic theory is this, you write an XML schema, run JaxB against said schema, and it will generate the code you need to handle information in said data structure. So, over the next few articles, I will discuss how to do so, which may benefit the RCP application as well as I may incorporate some example of that into the final product to save results or something.

Now, I personally don’t really care to write out tons of ridiculous XML structures by hand. I had read several suggestions, such as using commercial products like XMLSpy, but the best solution was suggested in a conversation with Scott Rosenbaum of the BIRT PMC. His suggestion, why not build the schema using the schema designer in the Eclipse Web Tools Project. Lo and behold, this solution works like a charm.

The idea behind the following example will build off of the Java recursive file system retrieval code I showed in my last article, get relevant information (name, path, size, date last modified) from the local file system (using Windows C:\ as my example), and build an XML data file using JaxB generated code to marshal the building of that file. For this example, I used the Web Tools Project All-in-One distribution of Eclipse, available here. I got that, extracted into a local folder (C:\WTP), and was ready to go.While I could have just installed WTP into my existing Eclipse instance, considering the problems I have had in the past with Eclipse plug-ins, and how the BIRT All-in-One saved me from hours of headaches with the Callisto release, I decided to stick with a formula that works.

The design of my file is like so. I want a key element called LFile, which is built like:

Name : String
Path: String
File_date: Date
Size: long
Read-Only : Boolean
IsDirectory : Boolean
SubFiles: FilesInFolder

On top of that is the structure FilesInFolder, which is basically a List of LFiles. I called my structre Lfile so as to not have to worry about naming convention conflicts between my structure and the java.io.File object.

My first step is to create my Eclipse Project. I open up Eclipse in the Java perspective. I go to File / New /Project, choose new Java project, and follow the wizard. I call my project FileStructureXML. Once my new project is created, I go to File/New/Other/XML/XML Schema. This will create a new XSD document. I called my file FileStructure.XSD. I choose to open my newly created in the XML Schema Editor.

Once open, the XML Schema Editor is a graphical schema design tool, which in my opinion is much easier than writing code by hand. So, the first thing I need to do is create my custom types. I go over to the Types section, Right-mouse click and choose Add Complex Type. I call my new Type Lfile, and add Elements (add elements, not attributes) as indicated above, with the exception of the SubFiles element. Once completed, I save my design, click on the little square in the upper left hand corner of the XML designer to go up to my top-most design, and create a type called FilesInFolder. I create a single element, called Files, and specify the type to be Lfile. In order to do this, I had to select the files element, and in the property editor, choose browse, and select Lfile from the list of types. I hit OK. Back in the editor for the FilesInFolder type, I select the files element. I then specify the min occurance to be 0, and the max to be unbounded. This will create a List of Files when I generate the Java code. Now, I go back to my top most design, select the Lfile type, double-click to go into its, and add an element called subFiles. I specify the type to be Lfile and set the min and max elements appropriately. I go back to my top-most design again, and create a single element called DirectoryStructure and set the type to be FilesInFolder. I probably could have just as easily create an element called RootFile and specified it to be a Sequence of Files, but I always seem to have problems with that. So, although this will generate an extra invocation in my resulting Java class, I will live with the DirectoryStructure element instead. Since this is just a demonstration, this will work just file. I save this as my design schema. Once complete, my resulting XML Schema Design looks like so:


Figure 1. The Schema Designer

And the actual Schemas XML is in Figure 2.


<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/FileStructure" xmlns:tns="http://www.example.org/FileStructure" elementFormDefault="qualified">
<complexType name="Lfile">
<sequence>
<element name="name" type="string"></element>
<element name="size" type="long"></element>
<element name="path" type="string"></element>
<element name="date_last_update" type="date"></element>
<element name="isDirectory" type="boolean"></element>
<element name="readOnly" type="boolean"></element>
<element name="subFiles" type="tns:FilesInFolder"></element>
</sequence>
</complexType>

<complexType name="FilesInFolder">
<sequence>
<element name="files" type="tns:Lfile" minOccurs="0" maxOccurs="unbounded"></element>
</sequence>
</complexType>

<element name="DirectoryStructure" type="tns:FilesInFolder"></element>
</schema>
Figure 2. XML Schema Code

Of course, the above illustrates why having some sort of Class Diagram or high-level design becomes necessary. Especially when the data structures get more complicated, and you are dealing with a system with lots of complex data structures of this type.

Next step will be to generate the Java classes from this schema, which I will discuss in my next article.

No comments: