SAXTreeViewer requires java 1.5 or later.
authorjprocter <jprocter@compbio.dundee.ac.uk>
Thu, 18 Feb 2010 13:46:17 +0000 (13:46 +0000)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Thu, 18 Feb 2010 13:46:17 +0000 (13:46 +0000)
git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@512 be28352e-c001-0410-b1a7-c7978e42abec

build.xml
docs/SAXTreeViewer.txt [new file with mode: 0644]
src/uk/ac/vamsas/test/document/SAXTreeViewer.java [new file with mode: 0644]

index 9302dfc..54cb360 100644 (file)
--- a/build.xml
+++ b/build.xml
 <project name="vamsas-client" default="build" basedir=".">
 
        <target name="init">
-               <property name="libDir" value="lib"/>
-               <property name="toolsDir" value="tools"/>
-               <property name="resourceDir" value="resources"/>
+               <!--<property name="target1.4" value="true"> -->
+               <property name="libDir" value="lib" />
+               <property name="toolsDir" value="tools" />
+               <property name="resourceDir" value="resources" />
                <property name="sourceDir" value="src" />
                <property name="outputDir" value="classes" />
                <property name="packageDir" value="packages" />
                <property name="vamsas.doc.schema" value="schemas/vamsasDocument.xsd" />
                <property name="vamsas.schema.package" value="uk.ac.vamsas.objects.core" />
                <property name="vamsas.schema.package.src" value="uk/ac/vamsas/objects/core" />
-               <property name="vamsas.schema.sourcegen.properties" value="schemas/castorbuilder.properties"/>
+               <property name="vamsas.schema.sourcegen.properties" value="schemas/castorbuilder.properties" />
                <path id="castor.classpath">
                        <fileset dir="tools">
-                               <include name="*.jar"/>
-                               <include name="**/*.jar"/>
+                               <include name="*.jar" />
+                               <include name="**/*.jar" />
                        </fileset>
                        <fileset dir="lib">
-                               <include name="*.jar"/>
-                               <include name="**/*.jar"/>
+                               <include name="*.jar" />
+                               <include name="**/*.jar" />
                        </fileset>
                </path>
-                       
+
                <!--
                Build classpath
                -->
                <path id="build.classpath">
                        <fileset dir="${toolsDir}">
-                               <include name="*.jar"/>
-                               <include name="**/*.jar"/>
+                               <include name="*.jar" />
+                               <include name="**/*.jar" />
                        </fileset>
 
                        <fileset dir="${libDir}">
-                               <include name="*.jar"/>
-                               <include name="**/*.jar"/>
+                               <include name="*.jar" />
+                               <include name="**/*.jar" />
                        </fileset>
                        <!--            path refid="axis.classpath"  -->
                </path>
        <target name="cleancoresource" depends="init" description="Clean automatically generated packages">
                <delete>
                        <fileset dir="${sourceDir}/${vamsas.schema.package.src}">
-                               <include name="*.java"/>
-                               <include name="descriptors/*.java"/>
+                               <include name="*.java" />
+                               <include name="descriptors/*.java" />
                        </fileset>
                </delete>
        </target>
        <target name="makecoresource" depends="init, cleancoresource" description="Generate Java source files from XSD.">
-       <taskdef name="castor-srcgen"
-                 classname="org.castor.anttask.CastorCodeGenTask"
-             classpathref="castor.classpath" />
-       <!-- Should apply this to every schema file in ${vamsas.schemas} directory -->
-               <castor-srcgen file="${vamsas.schema}"
-             todir="${sourceDir}"
-             package="${vamsas.schema.package}"
-             warnings="true" 
-                 nodesc="false"
-               properties="${vamsas.schema.sourcegen.properties}"
-       />      
-               <castor-srcgen file="${vamsas.doc.schema}"
-                             todir="${sourceDir}"
-                             package="${vamsas.schema.package}"
-                             warnings="true" 
-                                 nodesc="false"
-                               properties="${vamsas.schema.sourcegen.properties}"
-                       />      
+               <taskdef name="castor-srcgen" classname="org.castor.anttask.CastorCodeGenTask" classpathref="castor.classpath" />
+               <!-- Should apply this to every schema file in ${vamsas.schemas} directory -->
+               <castor-srcgen file="${vamsas.schema}" todir="${sourceDir}" package="${vamsas.schema.package}" warnings="true" nodesc="false" properties="${vamsas.schema.sourcegen.properties}" />
+               <castor-srcgen file="${vamsas.doc.schema}" todir="${sourceDir}" package="${vamsas.schema.package}" warnings="true" nodesc="false" properties="${vamsas.schema.sourcegen.properties}" />
        </target>
        <target name="prepare" depends="init">
-               <mkdir dir="${packageDir}"/>
-               <mkdir dir="${outputDir}"/>
+               <mkdir dir="${packageDir}" />
+               <mkdir dir="${outputDir}" />
                <copy todir="${outputDir}">
                        <fileset dir="${resourceDir}" />
                        <fileset dir="${basedir}">
-                               <include name="LICENS*"/>
-                               <include name="COPYING*"/>
-                               <include name="CONTRIB"/>
-                               <include name="README"/>
+                               <include name="LICENS*" />
+                               <include name="COPYING*" />
+                               <include name="CONTRIB" />
+                               <include name="README" />
                        </fileset>
                </copy>
        </target>
        <target name="clean" depends="init">
                <delete>
                        <fileset dir="${outputDir}">
-                               <include name="*"/>
-                               <include name="*.*"/>
-                               <include name="**/*"/>
-                               <include name="**/*.*"/>
+                               <include name="*" />
+                               <include name="*.*" />
+                               <include name="**/*" />
+                               <include name="**/*.*" />
                        </fileset>
                </delete>
-               <delete dir="${axisbuild}"/>
+               <delete dir="${axisbuild}" />
                <!--    <ant dir="test" antfile="build.xml" target="clean"
 inheritRefs="true"/> -->
        </target>
        <target name="realclean" depends="init, clean">
-               <delete dir="${packageDir}"/>
+               <delete dir="${packageDir}" />
        </target>
        <target name="distclean" depends="init, realclean">
-               <echo message="REMOVING ALL BACKUP/AUTOSAVES!"/>
+               <echo message="REMOVING ALL BACKUP/AUTOSAVES!" />
                <delete>
                        <fileset dir=".">
-                               <include name="#*#"/>
-                               <include name="#*.*#"/>
-                               <include name="**/#*#"/>
-                               <include name="**/#*.*#"/>
-                               <include name="*~"/>
-                               <include name="*.*~"/>
-                               <include name="**/*~"/>
-                               <include name="**/*.*~"/>
+                               <include name="#*#" />
+                               <include name="#*.*#" />
+                               <include name="**/#*#" />
+                               <include name="**/#*.*#" />
+                               <include name="*~" />
+                               <include name="*.*~" />
+                               <include name="**/*~" />
+                               <include name="**/*.*~" />
                        </fileset>
                </delete>
        </target>
-
-       <target name="build" depends="init, prepare">
-               <!-- not efficient yet. : use excludes="*/localtest/*.java" if local tests are not building -->
+       <target name="build1.4" depends="init,prepare" if="target1.4">
                <javac classpathref="build.classpath" debug="on" srcdir="${sourceDir}" destdir="${outputDir}" deprecation="on" source="1.4" target="1.4">
-       <exclude name="uk/ac/ebi/msd/vamsas/**"/>
+                       <exclude name="uk/ac/ebi/msd/vamsas/**" />
+                       <exclude name="uk/ac/vamsas/test/document/SAXTreeViewer.*"/>
+               </javac>
+       </target>
+       <target name="build1.5" depends="init,prepare" unless="target1.4">
+               <javac classpathref="build.classpath" debug="on" srcdir="${sourceDir}" destdir="${outputDir}" deprecation="on" source="1.5" target="1.5">
+                       <exclude name="uk/ac/ebi/msd/vamsas/**" />
                </javac>
        </target>
+       <target name="build" depends="build1.4,build1.5">
+               <echo message="Finished building" />
+       </target>
        <target name="jar" depends="build, javadoc">
                <jar destfile="${packageDir}/${vamsasClient.jar}">
-               <fileset dir="${outputDir}">
-                 <exclude name="cache*/**"/>
-                 <include name="**/*" />
-                         <exclude name="*.jar.*" />
-                 <exclude name="**/*.jar" />
-                 <exclude name="**/*.jar.*" />
-                         <exclude name="*.java"/>
-                         <exclude name="**/*.java"/>
-                         <exclude name="uk/*.class"/>
-                         <exclude name="log4j.properties"/>
-                       <exclude name="commons-logging.properties"/>
-               </fileset>
+                       <fileset dir="${outputDir}">
+                               <exclude name="cache*/**" />
+                               <include name="**/*" />
+                               <exclude name="*.jar.*" />
+                               <exclude name="**/*.jar" />
+                               <exclude name="**/*.jar.*" />
+                               <exclude name="*.java" />
+                               <exclude name="**/*.java" />
+                               <exclude name="uk/*.class" />
+                               <exclude name="log4j.properties" />
+                               <exclude name="commons-logging.properties" />
+                       </fileset>
                </jar>
                <jar destfile="${packageDir}/${vamsasClientDoc.jar}">
                        <fileset dir="docs/api">
-                               <include name="**/*"/>
+                               <include name="**/*" />
                        </fileset>
                        <fileset dir="${basedir}">
-                               <include name="README"/>
-                               <include name="CONTRIB"/>
-                               <include name="LICEN*"/>
-                               <include name="COPYING*"/>
+                               <include name="README" />
+                               <include name="CONTRIB" />
+                               <include name="LICEN*" />
+                               <include name="COPYING*" />
                        </fileset>
                </jar>
                <jar destfile="${packageDir}/${vamsasSchemaDocs.jar}">
                        <fileset dir="${basedir}/schemas">
-                               <include name="*.xsd"/>
+                               <include name="*.xsd" />
                        </fileset>
                        <fileset dir="${basedir}/docs/schema">
-                               <include name="**/*"/>
+                               <include name="**/*" />
                        </fileset>
                        <fileset dir="${basedir}">
-                               <include name="COPYING*"/>
+                               <include name="COPYING*" />
                        </fileset>
-               </jar>          
+               </jar>
                <jar destfile="${packageDir}/${vamsasClientSource.jar}">
                        <fileset dir="${basedir}">
-                               <include name="src/**/*.java"/>
-                               <include name="src/**/*.cdr"/>
-                               <exclude name="*~"/>
-                               <exclude name="**/*.java~"/>
-                               <include name="resources/**"/>
-                               <include name="utils/**"/>
-                               <include name="tools/**"/>
-                               <include name="schemas/**"/>
-                               <include name="test"/>
-                               <include name="docs/**"/>
-                               <include name="tools/**"/>
-                               <include name="lib/**"/>
-                               <include name="README"/>
-                               <include name="CONTRIB"/>
-                               <include name="LICEN*"/>
-                               <include name="COPYING*"/>
-                               <include name="*.eclipse*"/>
-                               <include name="*.launch"/>
-                               <include name="build.xml"/>
-                       </fileset>
-                       </jar>
+                               <include name="src/**/*.java" />
+                               <include name="src/**/*.cdr" />
+                               <exclude name="*~" />
+                               <exclude name="**/*.java~" />
+                               <include name="resources/**" />
+                               <include name="utils/**" />
+                               <include name="tools/**" />
+                               <include name="schemas/**" />
+                               <include name="test" />
+                               <include name="docs/**" />
+                               <include name="tools/**" />
+                               <include name="lib/**" />
+                               <include name="README" />
+                               <include name="CONTRIB" />
+                               <include name="LICEN*" />
+                               <include name="COPYING*" />
+                               <include name="*.eclipse*" />
+                               <include name="*.launch" />
+                               <include name="build.xml" />
+                       </fileset>
+               </jar>
        </target>
-       
+
        <target name="javadoc" depends="init">
-       <javadoc destdir="docs/api"  classpathref="build.classpath" author="true" version="true" use="true">      
-      <fileset dir="${sourceDir}" defaultexcludes="yes">
-       <exclude name="**/.castor.cdr"/>
-       <!-- this was for the old ebi packages.
+               <javadoc destdir="docs/api" classpathref="build.classpath" author="true" version="true" use="true">
+                       <fileset dir="${sourceDir}" defaultexcludes="yes">
+                               <exclude name="**/.castor.cdr" />
+                               <!-- this was for the old ebi packages.
        <exclude name="uk/**"/>
        <exclude name="uk/*.java"/> -->
-           </fileset>
-    </javadoc>
-  </target>
-       
+                       </fileset>
+               </javadoc>
+       </target>
+
 </project>
 
 
diff --git a/docs/SAXTreeViewer.txt b/docs/SAXTreeViewer.txt
new file mode 100644 (file)
index 0000000..08439dd
--- /dev/null
@@ -0,0 +1,10 @@
+uk.ac.vamsas.test.document.SAXTreeViewer\r
+----------------------------------------\r
+\r
+Instructions.\r
+1. Compile using java 1.5 or later. \r
+2. Execute the main method a single argument: the path to a vamsas document archive that you want to monitor.\r
+\r
+This is a class useful for debugging VAMSAS enabled programs. It uses the VAMSAS document low-level file monitoring mechanism to monitor accesses to the given file, and after each update to the document, it will update a tree representation of the VAMSAS document's XML.\r
+\r
\ No newline at end of file
diff --git a/src/uk/ac/vamsas/test/document/SAXTreeViewer.java b/src/uk/ac/vamsas/test/document/SAXTreeViewer.java
new file mode 100644 (file)
index 0000000..59c2313
--- /dev/null
@@ -0,0 +1,601 @@
+package uk.ac.vamsas.test.document;\r
+\r
+\r
+/*-- \r
+\r
+ Copyright (C) 2001 Brett McLaughlin.\r
+ All rights reserved.\r
\r
+ Redistribution and use in source and binary forms, with or without\r
+ modification, are permitted provided that the following conditions\r
+ are met:\r
\r
+ 1. Redistributions of source code must retain the above copyright\r
+    notice, this list of conditions, and the following disclaimer.\r
\r
+ 2. Redistributions in binary form must reproduce the above copyright\r
+    notice, this list of conditions, and the disclaimer that follows \r
+    these conditions in the documentation and/or other materials \r
+    provided with the distribution.\r
+\r
+ 3. The name "Java and XML" must not be used to endorse or promote products\r
+    derived from this software without prior written permission.  For\r
+    written permission, please contact brett@newInstance.com.\r
\r
+ In addition, we request (but do not require) that you include in the \r
+ end-user documentation provided with the redistribution and/or in the \r
+ software itself an acknowledgement equivalent to the following:\r
+     "This product includes software developed for the\r
+      'Java and XML' book, by Brett McLaughlin (O'Reilly & Associates)."\r
+\r
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED\r
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ DISCLAIMED.  IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT\r
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF\r
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\r
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ SUCH DAMAGE.\r
+\r
+ */\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.HashMap;\r
+import java.util.Iterator;\r
+import java.util.Map;\r
+import org.xml.sax.Attributes;\r
+import org.xml.sax.ContentHandler;\r
+import org.xml.sax.ErrorHandler;\r
+import org.xml.sax.InputSource;\r
+import org.xml.sax.Locator;\r
+import org.xml.sax.SAXException;\r
+import org.xml.sax.SAXParseException;\r
+import org.xml.sax.XMLReader;\r
+import org.xml.sax.helpers.XMLReaderFactory;\r
+\r
+import uk.ac.vamsas.client.simpleclient.FileWatcher;\r
+import uk.ac.vamsas.client.simpleclient.Lock;\r
+import uk.ac.vamsas.client.simpleclient.SimpleDocument;\r
+import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader;\r
+\r
+// This is an XML book - no need for explicit Swing imports\r
+import java.awt.*;\r
+import javax.swing.*;\r
+import javax.swing.tree.*;\r
+\r
+/**\r
+ * <b><code>SAXTreeViewer</code></b> uses Swing to graphically\r
+ *   display an XML document.\r
+ */\r
+public class SAXTreeViewer extends JFrame {\r
+  /** Default parser to use */\r
+private String vendorParserClass = \r
+    "org.apache.xerces.parsers.SAXParser";\r
+\r
+/** The base tree to render */\r
+private JTree jTree;\r
+\r
+/** Tree model to use */\r
+DefaultTreeModel defaultTreeModel;\r
+\r
+/**\r
+ * <p> This initializes the needed Swing settings. </p>\r
+ */\r
+public SAXTreeViewer() {\r
+    // Handle Swing setup\r
+    super("SAX Tree Viewer");\r
+    setSize(600, 450);\r
+}\r
+\r
+/**\r
+ * <p> This will construct the tree using Swing. </p>\r
+ *\r
+ * @param filename <code>String</code> path to XML document.\r
+ */\r
+public void init(String xmlURI) throws IOException, SAXException {\r
+  init(xmlURI, null);\r
+}\r
+/**\r
+ * <p> This will construct the tree using Swing. </p>\r
+ *\r
+ * @param filename <code>String</code> apparent path to XML document.\r
+ * @param inputSource <code>InputSource</code> content of XML document\r
+ */\r
+  public void init(String xmlURI, InputSource inputSource) throws IOException, SAXException {\r
+    \r
+    DefaultMutableTreeNode base = \r
+        new DefaultMutableTreeNode("XML Document: " + \r
+            xmlURI);\r
+    \r
+    // Build the tree model\r
+    defaultTreeModel = new DefaultTreeModel(base);\r
+    jTree = new JTree(defaultTreeModel);\r
+\r
+    // Construct the tree hierarchy\r
+    if (inputSource==null) {\r
+      buildTree(defaultTreeModel, base, xmlURI);\r
+    } else {\r
+      buildTree(defaultTreeModel, base, xmlURI,inputSource);\r
+    }\r
+    // Display the results\r
+    getContentPane().add(new JScrollPane(jTree), \r
+        BorderLayout.CENTER);\r
+}\r
+\r
+/**\r
+ * <p>This handles building the Swing UI tree.</p>\r
+ *\r
+ * @param treeModel Swing component to build upon.\r
+ * @param base tree node to build on.\r
+ * @param xmlURI URI to build XML document from.\r
+ * @throws <code>IOException</code> - when reading the XML URI fails.\r
+ * @throws <code>SAXException</code> - when errors in parsing occur.\r
+ */\r
+public void buildTree(DefaultTreeModel treeModel, \r
+                      DefaultMutableTreeNode base, String xmlURI) \r
+    throws IOException, SAXException {\r
+  // Parse\r
+  InputSource inputSource = \r
+      new InputSource(xmlURI);\r
+  buildTree(treeModel,base,xmlURI,inputSource);\r
+}\r
+/**\r
+ * <p>This handles building the Swing UI tree.</p>\r
+ *\r
+ * @param treeModel Swing component to build upon.\r
+ * @param base tree node to build on.\r
+ * @param xmlURI apparent URI to build XML document from.\r
+ * @param inputSource the xml datasource to get the content from\r
+ * @throws SAXException \r
+ * @throws IOException \r
+ * @throws <code>IOException</code> - when reading the XML URI fails.\r
+ * @throws <code>SAXException</code> - when errors in parsing occur.\r
+ */\r
+public void buildTree(DefaultTreeModel treeModel, \r
+    DefaultMutableTreeNode base, String xmlURI, InputSource inputSource) throws IOException, SAXException {\r
+\r
+    // Create instances needed for parsing\r
+    XMLReader reader = \r
+        XMLReaderFactory.createXMLReader(vendorParserClass);\r
+    ContentHandler jTreeContentHandler = \r
+        new JTreeContentHandler(treeModel, base);\r
+    ErrorHandler jTreeErrorHandler = new JTreeErrorHandler();\r
+\r
+    // Register content handler\r
+    reader.setContentHandler(jTreeContentHandler);\r
+\r
+    // Register error handler\r
+    reader.setErrorHandler(jTreeErrorHandler);\r
+\r
+    reader.parse(inputSource);\r
+}\r
+private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(SAXTreeViewer.class);\r
+\r
+/**\r
+ * <p> Static entry point for running the viewer. </p>\r
+ */\r
+public static void main(String[] args) {\r
+    try {\r
+      File archive = new File(args[0]);\r
+      // start watching a vamsas document archive\r
+      // watch\r
+      log.info("Endlessly Watching file " + archive);\r
+      /*\r
+       * if (!archive.exists()) archive.createNewFile();\r
+       */// watch the new file... - taken straight from ClientsFileTest\r
+      FileWatcher w = new FileWatcher(archive);\r
+      SAXTreeViewer currentview = null;\r
+      boolean first=true;\r
+      while (true) {\r
+        // get watcher's lock to ensure state change is fixed for\r
+        // retrieval\r
+        Lock chlock = w.getChangedState();\r
+        if (first || chlock != null) {\r
+          log.info("Got lock on "\r
+              + archive\r
+              + (archive.exists() ? " exists l=" + archive.length()\r
+                  : "(non existant)"));\r
+          first = false;\r
+          if (archive.length() > 0) {\r
+            VamsasArchiveReader vreader = new VamsasArchiveReader(archive);\r
+            SimpleDocument sdoc = new SimpleDocument(\r
+                "testing vamsas watcher");\r
+            try {\r
+              // pass the archive XML content to the xml viewer.\r
+              SAXTreeViewer newview = new SAXTreeViewer();\r
+              newview.init(archive.toURI().toString(), new org.xml.sax.InputSource(vreader.getVamsasDocumentStream()));\r
+              if (currentview != null)\r
+              {\r
+                newview.setBounds(currentview.getBounds());\r
+                // somehow copy over expanded state for existing objects and scroll state.\r
+                // could also highlight new / modified nodes.\r
+                newview.setVisible(true);\r
+                currentview.setVisible(false);\r
+                currentview.dispose();\r
+              } else {\r
+                newview.setVisible(true);\r
+              }\r
+              currentview = newview;\r
+              \r
+              /* VamsasDocument d = sdoc.getVamsasDocument(vreader);\r
+              if (d != null) {\r
+                ArchiveReports.reportDocument(d, vreader, false,\r
+                    System.out);\r
+              }*/\r
+              System.out\r
+                  .println("Update at "\r
+                      + System.currentTimeMillis()\r
+                      + "\n\n********************************************************\n");\r
+            } catch (Exception e) {\r
+              log.error("Unmarshalling failed.", e);\r
+            }\r
+            vreader.close();\r
+            w.setState();\r
+          } \r
+        }\r
+        Thread.sleep(2000);\r
+      }\r
+    } catch (Exception e) {\r
+      log.info("Going away now.",e);\r
+    }\r
+}\r
+}\r
+\r
+/**\r
+* <b><code>JTreeContentHandler</code></b> implements the SAX\r
+*   <code>ContentHandler</code> interface and defines callback\r
+*   behavior for the SAX callbacks associated with an XML\r
+*   document's content, bulding up JTree nodes.\r
+*/\r
+class JTreeContentHandler implements ContentHandler {\r
+\r
+/** Hold onto the locator for location information */\r
+private Locator locator;\r
+\r
+/** Store URI to prefix mappings */\r
+private Map namespaceMappings;\r
+\r
+/** Tree Model to add nodes to */\r
+private DefaultTreeModel treeModel;\r
+\r
+/** Current node to add sub-nodes to */\r
+private DefaultMutableTreeNode current;\r
+\r
+/**\r
+ * <p> Set up for working with the JTree. </p>\r
+ *\r
+ * @param treeModel tree to add nodes to.\r
+ * @param base node to start adding sub-nodes to.\r
+ */\r
+public JTreeContentHandler(DefaultTreeModel treeModel, \r
+                           DefaultMutableTreeNode base) {\r
+    this.treeModel = treeModel;\r
+    this.current = base;\r
+    this.namespaceMappings = new HashMap();\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *  Provide reference to <code>Locator</code> which provides\r
+ *    information about where in a document callbacks occur.\r
+ * </p>\r
+ *\r
+ * @param locator <code>Locator</code> object tied to callback\r
+ *        process\r
+ */\r
+public void setDocumentLocator(Locator locator) {\r
+    // Save this for later use\r
+    this.locator = locator;\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *  This indicates the start of a Document parse-this precedes\r
+ *    all callbacks in all SAX Handlers with the sole exception\r
+ *    of <code>{@link #setDocumentLocator}</code>.\r
+ * </p>\r
+ *\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void startDocument() throws SAXException {\r
+    // No visual events occur here\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *  This indicates the end of a Document parse-this occurs after\r
+ *    all callbacks in all SAX Handlers.</code>.\r
+ * </p>\r
+ *\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void endDocument() throws SAXException {\r
+    // No visual events occur here\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   This indicates that a processing instruction (other than\r
+ *     the XML declaration) has been encountered.\r
+ * </p>\r
+ *\r
+ * @param target <code>String</code> target of PI\r
+ * @param data <code>String</code containing all data sent to the PI.\r
+ *               This typically looks like one or more attribute value\r
+ *               pairs.\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void processingInstruction(String target, String data)\r
+    throws SAXException {\r
+\r
+    DefaultMutableTreeNode pi = \r
+        new DefaultMutableTreeNode("PI (target = '" + target +\r
+                                   "', data = '" + data + "')");\r
+    current.add(pi);\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   This indicates the beginning of an XML Namespace prefix\r
+ *     mapping. Although this typically occurs within the root element\r
+ *     of an XML document, it can occur at any point within the\r
+ *     document. Note that a prefix mapping on an element triggers\r
+ *     this callback <i>before</i> the callback for the actual element\r
+ *     itself (<code>{@link #startElement}</code>) occurs.\r
+ * </p>\r
+ *\r
+ * @param prefix <code>String</code> prefix used for the namespace\r
+ *                being reported\r
+ * @param uri <code>String</code> URI for the namespace\r
+ *               being reported\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void startPrefixMapping(String prefix, String uri) {\r
+    // No visual events occur here.\r
+    namespaceMappings.put(uri, prefix);\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   This indicates the end of a prefix mapping, when the namespace\r
+ *     reported in a <code>{@link #startPrefixMapping}</code> callback\r
+ *     is no longer available.\r
+ * </p>\r
+ *\r
+ * @param prefix <code>String</code> of namespace being reported\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void endPrefixMapping(String prefix) {\r
+    // No visual events occur here.\r
+    for (Iterator i = namespaceMappings.keySet().iterator(); \r
+         i.hasNext(); ) {\r
+\r
+        String uri = (String)i.next();\r
+        String thisPrefix = (String)namespaceMappings.get(uri);\r
+        if (prefix.equals(thisPrefix)) {\r
+            namespaceMappings.remove(uri);\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   This reports the occurrence of an actual element. It includes\r
+ *     the element's attributes, with the exception of XML vocabulary\r
+ *     specific attributes, such as\r
+ *     <code>xmlns:[namespace prefix]</code> and\r
+ *     <code>xsi:schemaLocation</code>.\r
+ * </p>\r
+ *\r
+ * @param namespaceURI <code>String</code> namespace URI this element\r
+ *               is associated with, or an empty <code>String</code>\r
+ * @param localName <code>String</code> name of element (with no\r
+ *               namespace prefix, if one is present)\r
+ * @param qName <code>String</code> XML 1.0 version of element name:\r
+ *                [namespace prefix]:[localName]\r
+ * @param atts <code>Attributes</code> list for this element\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void startElement(String namespaceURI, String localName,\r
+                         String qName, Attributes atts)\r
+    throws SAXException {\r
+\r
+    DefaultMutableTreeNode element = \r
+        new DefaultMutableTreeNode("Element: " + localName);\r
+    current.add(element);\r
+    current = element;\r
+\r
+    // Determine namespace\r
+    if (namespaceURI.length() > 0) {\r
+        String prefix = \r
+            (String)namespaceMappings.get(namespaceURI);\r
+        if (prefix.equals("")) {\r
+            prefix = "[None]";\r
+        }\r
+        DefaultMutableTreeNode namespace =\r
+            new DefaultMutableTreeNode("Namespace: prefix = '" +\r
+                prefix + "', URI = '" + namespaceURI + "'");\r
+        current.add(namespace);\r
+    }\r
+\r
+    // Process attributes\r
+    for (int i=0; i<atts.getLength(); i++) {\r
+        DefaultMutableTreeNode attribute =\r
+            new DefaultMutableTreeNode("Attribute (name = '" +\r
+                                       atts.getLocalName(i) + \r
+                                       "', value = '" +\r
+                                       atts.getValue(i) + "')");\r
+        String attURI = atts.getURI(i);\r
+        if (attURI.length() > 0) {\r
+            String attPrefix = \r
+                (String)namespaceMappings.get(namespaceURI);\r
+            if (attPrefix.equals("")) {\r
+                attPrefix = "[None]";\r
+            }\r
+            DefaultMutableTreeNode attNamespace =\r
+                new DefaultMutableTreeNode("Namespace: prefix = '" +\r
+                    attPrefix + "', URI = '" + attURI + "'");\r
+            attribute.add(attNamespace);            \r
+        }\r
+        current.add(attribute);\r
+    }\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   Indicates the end of an element\r
+ *     (<code>&lt;/[element name]&gt;</code>) is reached. Note that\r
+ *     the parser does not distinguish between empty\r
+ *     elements and non-empty elements, so this occurs uniformly.\r
+ * </p>\r
+ *\r
+ * @param namespaceURI <code>String</code> URI of namespace this\r
+ *                element is associated with\r
+ * @param localName <code>String</code> name of element without prefix\r
+ * @param qName <code>String</code> name of element in XML 1.0 form\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void endElement(String namespaceURI, String localName,\r
+                       String qName)\r
+    throws SAXException {\r
+\r
+    // Walk back up the tree\r
+    current = (DefaultMutableTreeNode)current.getParent();\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   This reports character data (within an element).\r
+ * </p>\r
+ *\r
+ * @param ch <code>char[]</code> character array with character data\r
+ * @param start <code>int</code> index in array where data starts.\r
+ * @param length <code>int</code> index in array where data ends.\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void characters(char[] ch, int start, int length)\r
+    throws SAXException {\r
+\r
+    String s = new String(ch, start, length);\r
+    DefaultMutableTreeNode data =\r
+        new DefaultMutableTreeNode("Character Data: '" + s + "'");\r
+    current.add(data);\r
+}\r
+\r
+/**\r
+ * <p>\r
+ * This reports whitespace that can be ignored in the\r
+ * originating document. This is typically invoked only when\r
+ * validation is ocurring in the parsing process.\r
+ * </p>\r
+ *\r
+ * @param ch <code>char[]</code> character array with character data\r
+ * @param start <code>int</code> index in array where data starts.\r
+ * @param end <code>int</code> index in array where data ends.\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void ignorableWhitespace(char[] ch, int start, int length)\r
+    throws SAXException {\r
+    \r
+    // This is ignorable, so don't display it\r
+}\r
+\r
+/**\r
+ * <p>\r
+ *   This reports an entity that is skipped by the parser. This\r
+ *     should only occur for non-validating parsers, and then is still\r
+ *     implementation-dependent behavior.\r
+ * </p>\r
+ *\r
+ * @param name <code>String</code> name of entity being skipped\r
+ * @throws <code>SAXException</code> when things go wrong\r
+ */\r
+public void skippedEntity(String name) throws SAXException {\r
+    DefaultMutableTreeNode skipped =\r
+        new DefaultMutableTreeNode("Skipped Entity: '" + name + "'");\r
+    current.add(skipped);\r
+}\r
+}\r
+\r
+/**\r
+* <b><code>JTreeErrorHandler</code></b> implements the SAX\r
+*   <code>ErrorHandler</code> interface and defines callback\r
+*   behavior for the SAX callbacks associated with an XML\r
+*   document's warnings and errors.\r
+*/\r
+class JTreeErrorHandler implements ErrorHandler {\r
+\r
+/**\r
+ * <p>\r
+ * This will report a warning that has occurred; this indicates\r
+ *   that while no XML rules were "broken", something appears\r
+ *   to be incorrect or missing.\r
+ * </p>\r
+ *\r
+ * @param exception <code>SAXParseException</code> that occurred.\r
+ * @throws <code>SAXException</code> when things go wrong \r
+ */\r
+public void warning(SAXParseException exception)\r
+    throws SAXException {\r
+        \r
+    System.out.println("**Parsing Warning**\n" +\r
+                       "  Line:    " + \r
+                          exception.getLineNumber() + "\n" +\r
+                       "  URI:     " + \r
+                          exception.getSystemId() + "\n" +\r
+                       "  Message: " + \r
+                          exception.getMessage());        \r
+    throw new SAXException("Warning encountered");\r
+}\r
+\r
+/**\r
+ * <p>\r
+ * This will report an error that has occurred; this indicates\r
+ *   that a rule was broken, typically in validation, but that\r
+ *   parsing can reasonably continue.\r
+ * </p>\r
+ *\r
+ * @param exception <code>SAXParseException</code> that occurred.\r
+ * @throws <code>SAXException</code> when things go wrong \r
+ */\r
+public void error(SAXParseException exception)\r
+    throws SAXException {\r
+    \r
+    System.out.println("**Parsing Error**\n" +\r
+                       "  Line:    " + \r
+                          exception.getLineNumber() + "\n" +\r
+                       "  URI:     " + \r
+                          exception.getSystemId() + "\n" +\r
+                       "  Message: " + \r
+                          exception.getMessage());\r
+    throw new SAXException("Error encountered");\r
+}\r
+\r
+/**\r
+ * <p>\r
+ * This will report a fatal error that has occurred; this indicates\r
+ *   that a rule has been broken that makes continued parsing either\r
+ *   impossible or an almost certain waste of time.\r
+ * </p>\r
+ *\r
+ * @param exception <code>SAXParseException</code> that occurred.\r
+ * @throws <code>SAXException</code> when things go wrong \r
+ */\r
+public void fatalError(SAXParseException exception)\r
+    throws SAXException {\r
+\r
+    System.out.println("**Parsing Fatal Error**\n" +\r
+                       "  Line:    " + \r
+                          exception.getLineNumber() + "\n" +\r
+                       "  URI:     " + \r
+                          exception.getSystemId() + "\n" +\r
+                       "  Message: " + \r
+                          exception.getMessage());        \r
+    throw new SAXException("Fatal Error encountered");\r
+}\r
+}
\ No newline at end of file