X-Git-Url: http://source.jalview.org/gitweb/?p=vamsas.git;a=blobdiff_plain;f=src%2Fuk%2Fac%2Fvamsas%2Ftest%2Fdocument%2FSAXTreeViewer.java;fp=src%2Fuk%2Fac%2Fvamsas%2Ftest%2Fdocument%2FSAXTreeViewer.java;h=59c2313c0238d5b6569923a7b2d534071863c9e0;hp=0000000000000000000000000000000000000000;hb=bb723cfb0bdf3404c9776605995dfa993fe83c73;hpb=2e9acb15a289a317f04e6161bace75de35884e01
diff --git a/src/uk/ac/vamsas/test/document/SAXTreeViewer.java b/src/uk/ac/vamsas/test/document/SAXTreeViewer.java
new file mode 100644
index 0000000..59c2313
--- /dev/null
+++ b/src/uk/ac/vamsas/test/document/SAXTreeViewer.java
@@ -0,0 +1,601 @@
+package uk.ac.vamsas.test.document;
+
+
+/*--
+
+ Copyright (C) 2001 Brett McLaughlin.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions, and the disclaimer that follows
+ these conditions in the documentation and/or other materials
+ provided with the distribution.
+
+ 3. The name "Java and XML" must not be used to endorse or promote products
+ derived from this software without prior written permission. For
+ written permission, please contact brett@newInstance.com.
+
+ In addition, we request (but do not require) that you include in the
+ end-user documentation provided with the redistribution and/or in the
+ software itself an acknowledgement equivalent to the following:
+ "This product includes software developed for the
+ 'Java and XML' book, by Brett McLaughlin (O'Reilly & Associates)."
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+ */
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+import uk.ac.vamsas.client.simpleclient.FileWatcher;
+import uk.ac.vamsas.client.simpleclient.Lock;
+import uk.ac.vamsas.client.simpleclient.SimpleDocument;
+import uk.ac.vamsas.client.simpleclient.VamsasArchiveReader;
+
+// This is an XML book - no need for explicit Swing imports
+import java.awt.*;
+import javax.swing.*;
+import javax.swing.tree.*;
+
+/**
+ * SAXTreeViewer
uses Swing to graphically
+ * display an XML document.
+ */
+public class SAXTreeViewer extends JFrame {
+ /** Default parser to use */
+private String vendorParserClass =
+ "org.apache.xerces.parsers.SAXParser";
+
+/** The base tree to render */
+private JTree jTree;
+
+/** Tree model to use */
+DefaultTreeModel defaultTreeModel;
+
+/**
+ *
This initializes the needed Swing settings.
+ */ +public SAXTreeViewer() { + // Handle Swing setup + super("SAX Tree Viewer"); + setSize(600, 450); +} + +/** + *This will construct the tree using Swing.
+ * + * @param filenameString
path to XML document.
+ */
+public void init(String xmlURI) throws IOException, SAXException {
+ init(xmlURI, null);
+}
+/**
+ * This will construct the tree using Swing.
+ * + * @param filenameString
apparent path to XML document.
+ * @param inputSource InputSource
content of XML document
+ */
+ public void init(String xmlURI, InputSource inputSource) throws IOException, SAXException {
+
+ DefaultMutableTreeNode base =
+ new DefaultMutableTreeNode("XML Document: " +
+ xmlURI);
+
+ // Build the tree model
+ defaultTreeModel = new DefaultTreeModel(base);
+ jTree = new JTree(defaultTreeModel);
+
+ // Construct the tree hierarchy
+ if (inputSource==null) {
+ buildTree(defaultTreeModel, base, xmlURI);
+ } else {
+ buildTree(defaultTreeModel, base, xmlURI,inputSource);
+ }
+ // Display the results
+ getContentPane().add(new JScrollPane(jTree),
+ BorderLayout.CENTER);
+}
+
+/**
+ * This handles building the Swing UI tree.
+ * + * @param treeModel Swing component to build upon. + * @param base tree node to build on. + * @param xmlURI URI to build XML document from. + * @throwsIOException
- when reading the XML URI fails.
+ * @throws SAXException
- when errors in parsing occur.
+ */
+public void buildTree(DefaultTreeModel treeModel,
+ DefaultMutableTreeNode base, String xmlURI)
+ throws IOException, SAXException {
+ // Parse
+ InputSource inputSource =
+ new InputSource(xmlURI);
+ buildTree(treeModel,base,xmlURI,inputSource);
+}
+/**
+ * This handles building the Swing UI tree.
+ * + * @param treeModel Swing component to build upon. + * @param base tree node to build on. + * @param xmlURI apparent URI to build XML document from. + * @param inputSource the xml datasource to get the content from + * @throws SAXException + * @throws IOException + * @throwsIOException
- when reading the XML URI fails.
+ * @throws SAXException
- when errors in parsing occur.
+ */
+public void buildTree(DefaultTreeModel treeModel,
+ DefaultMutableTreeNode base, String xmlURI, InputSource inputSource) throws IOException, SAXException {
+
+ // Create instances needed for parsing
+ XMLReader reader =
+ XMLReaderFactory.createXMLReader(vendorParserClass);
+ ContentHandler jTreeContentHandler =
+ new JTreeContentHandler(treeModel, base);
+ ErrorHandler jTreeErrorHandler = new JTreeErrorHandler();
+
+ // Register content handler
+ reader.setContentHandler(jTreeContentHandler);
+
+ // Register error handler
+ reader.setErrorHandler(jTreeErrorHandler);
+
+ reader.parse(inputSource);
+}
+private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(SAXTreeViewer.class);
+
+/**
+ * Static entry point for running the viewer.
+ */ +public static void main(String[] args) { + try { + File archive = new File(args[0]); + // start watching a vamsas document archive + // watch + log.info("Endlessly Watching file " + archive); + /* + * if (!archive.exists()) archive.createNewFile(); + */// watch the new file... - taken straight from ClientsFileTest + FileWatcher w = new FileWatcher(archive); + SAXTreeViewer currentview = null; + boolean first=true; + while (true) { + // get watcher's lock to ensure state change is fixed for + // retrieval + Lock chlock = w.getChangedState(); + if (first || chlock != null) { + log.info("Got lock on " + + archive + + (archive.exists() ? " exists l=" + archive.length() + : "(non existant)")); + first = false; + if (archive.length() > 0) { + VamsasArchiveReader vreader = new VamsasArchiveReader(archive); + SimpleDocument sdoc = new SimpleDocument( + "testing vamsas watcher"); + try { + // pass the archive XML content to the xml viewer. + SAXTreeViewer newview = new SAXTreeViewer(); + newview.init(archive.toURI().toString(), new org.xml.sax.InputSource(vreader.getVamsasDocumentStream())); + if (currentview != null) + { + newview.setBounds(currentview.getBounds()); + // somehow copy over expanded state for existing objects and scroll state. + // could also highlight new / modified nodes. + newview.setVisible(true); + currentview.setVisible(false); + currentview.dispose(); + } else { + newview.setVisible(true); + } + currentview = newview; + + /* VamsasDocument d = sdoc.getVamsasDocument(vreader); + if (d != null) { + ArchiveReports.reportDocument(d, vreader, false, + System.out); + }*/ + System.out + .println("Update at " + + System.currentTimeMillis() + + "\n\n********************************************************\n"); + } catch (Exception e) { + log.error("Unmarshalling failed.", e); + } + vreader.close(); + w.setState(); + } + } + Thread.sleep(2000); + } + } catch (Exception e) { + log.info("Going away now.",e); + } +} +} + +/** +*JTreeContentHandler
implements the SAX
+* ContentHandler
interface and defines callback
+* behavior for the SAX callbacks associated with an XML
+* document's content, bulding up JTree nodes.
+*/
+class JTreeContentHandler implements ContentHandler {
+
+/** Hold onto the locator for location information */
+private Locator locator;
+
+/** Store URI to prefix mappings */
+private Map namespaceMappings;
+
+/** Tree Model to add nodes to */
+private DefaultTreeModel treeModel;
+
+/** Current node to add sub-nodes to */
+private DefaultMutableTreeNode current;
+
+/**
+ * Set up for working with the JTree.
+ * + * @param treeModel tree to add nodes to. + * @param base node to start adding sub-nodes to. + */ +public JTreeContentHandler(DefaultTreeModel treeModel, + DefaultMutableTreeNode base) { + this.treeModel = treeModel; + this.current = base; + this.namespaceMappings = new HashMap(); +} + +/** + *
+ * Provide reference to Locator
which provides
+ * information about where in a document callbacks occur.
+ *
Locator
object tied to callback
+ * process
+ */
+public void setDocumentLocator(Locator locator) {
+ // Save this for later use
+ this.locator = locator;
+}
+
+/**
+ *
+ * This indicates the start of a Document parse-this precedes
+ * all callbacks in all SAX Handlers with the sole exception
+ * of {@link #setDocumentLocator}
.
+ *
SAXException
when things go wrong
+ */
+public void startDocument() throws SAXException {
+ // No visual events occur here
+}
+
+/**
+ * + * This indicates the end of a Document parse-this occurs after + * all callbacks in all SAX Handlers.. + *
+ * + * @throwsSAXException
when things go wrong
+ */
+public void endDocument() throws SAXException {
+ // No visual events occur here
+}
+
+/**
+ * + * This indicates that a processing instruction (other than + * the XML declaration) has been encountered. + *
+ * + * @param targetString
target of PI
+ * @param data String
SAXException when things go wrong
+ */
+public void processingInstruction(String target, String data)
+ throws SAXException {
+
+ DefaultMutableTreeNode pi =
+ new DefaultMutableTreeNode("PI (target = '" + target +
+ "', data = '" + data + "')");
+ current.add(pi);
+}
+
+/**
+ *
+ * This indicates the beginning of an XML Namespace prefix
+ * mapping. Although this typically occurs within the root element
+ * of an XML document, it can occur at any point within the
+ * document. Note that a prefix mapping on an element triggers
+ * this callback before the callback for the actual element
+ * itself ({@link #startElement}
) occurs.
+ *
String
prefix used for the namespace
+ * being reported
+ * @param uri String
URI for the namespace
+ * being reported
+ * @throws SAXException
when things go wrong
+ */
+public void startPrefixMapping(String prefix, String uri) {
+ // No visual events occur here.
+ namespaceMappings.put(uri, prefix);
+}
+
+/**
+ *
+ * This indicates the end of a prefix mapping, when the namespace
+ * reported in a {@link #startPrefixMapping}
callback
+ * is no longer available.
+ *
String
of namespace being reported
+ * @throws SAXException
when things go wrong
+ */
+public void endPrefixMapping(String prefix) {
+ // No visual events occur here.
+ for (Iterator i = namespaceMappings.keySet().iterator();
+ i.hasNext(); ) {
+
+ String uri = (String)i.next();
+ String thisPrefix = (String)namespaceMappings.get(uri);
+ if (prefix.equals(thisPrefix)) {
+ namespaceMappings.remove(uri);
+ break;
+ }
+ }
+}
+
+/**
+ *
+ * This reports the occurrence of an actual element. It includes
+ * the element's attributes, with the exception of XML vocabulary
+ * specific attributes, such as
+ * xmlns:[namespace prefix]
and
+ * xsi:schemaLocation
.
+ *
String
namespace URI this element
+ * is associated with, or an empty String
+ * @param localName String
name of element (with no
+ * namespace prefix, if one is present)
+ * @param qName String
XML 1.0 version of element name:
+ * [namespace prefix]:[localName]
+ * @param atts Attributes
list for this element
+ * @throws SAXException
when things go wrong
+ */
+public void startElement(String namespaceURI, String localName,
+ String qName, Attributes atts)
+ throws SAXException {
+
+ DefaultMutableTreeNode element =
+ new DefaultMutableTreeNode("Element: " + localName);
+ current.add(element);
+ current = element;
+
+ // Determine namespace
+ if (namespaceURI.length() > 0) {
+ String prefix =
+ (String)namespaceMappings.get(namespaceURI);
+ if (prefix.equals("")) {
+ prefix = "[None]";
+ }
+ DefaultMutableTreeNode namespace =
+ new DefaultMutableTreeNode("Namespace: prefix = '" +
+ prefix + "', URI = '" + namespaceURI + "'");
+ current.add(namespace);
+ }
+
+ // Process attributes
+ for (int i=0; i
+ * Indicates the end of an element
+ * (</[element name]>
) is reached. Note that
+ * the parser does not distinguish between empty
+ * elements and non-empty elements, so this occurs uniformly.
+ *
String
URI of namespace this
+ * element is associated with
+ * @param localName String
name of element without prefix
+ * @param qName String
name of element in XML 1.0 form
+ * @throws SAXException
when things go wrong
+ */
+public void endElement(String namespaceURI, String localName,
+ String qName)
+ throws SAXException {
+
+ // Walk back up the tree
+ current = (DefaultMutableTreeNode)current.getParent();
+}
+
+/**
+ * + * This reports character data (within an element). + *
+ * + * @param chchar[]
character array with character data
+ * @param start int
index in array where data starts.
+ * @param length int
index in array where data ends.
+ * @throws SAXException
when things go wrong
+ */
+public void characters(char[] ch, int start, int length)
+ throws SAXException {
+
+ String s = new String(ch, start, length);
+ DefaultMutableTreeNode data =
+ new DefaultMutableTreeNode("Character Data: '" + s + "'");
+ current.add(data);
+}
+
+/**
+ * + * This reports whitespace that can be ignored in the + * originating document. This is typically invoked only when + * validation is ocurring in the parsing process. + *
+ * + * @param chchar[]
character array with character data
+ * @param start int
index in array where data starts.
+ * @param end int
index in array where data ends.
+ * @throws SAXException
when things go wrong
+ */
+public void ignorableWhitespace(char[] ch, int start, int length)
+ throws SAXException {
+
+ // This is ignorable, so don't display it
+}
+
+/**
+ * + * This reports an entity that is skipped by the parser. This + * should only occur for non-validating parsers, and then is still + * implementation-dependent behavior. + *
+ * + * @param nameString
name of entity being skipped
+ * @throws SAXException
when things go wrong
+ */
+public void skippedEntity(String name) throws SAXException {
+ DefaultMutableTreeNode skipped =
+ new DefaultMutableTreeNode("Skipped Entity: '" + name + "'");
+ current.add(skipped);
+}
+}
+
+/**
+* JTreeErrorHandler
implements the SAX
+* ErrorHandler
interface and defines callback
+* behavior for the SAX callbacks associated with an XML
+* document's warnings and errors.
+*/
+class JTreeErrorHandler implements ErrorHandler {
+
+/**
+ * + * This will report a warning that has occurred; this indicates + * that while no XML rules were "broken", something appears + * to be incorrect or missing. + *
+ * + * @param exceptionSAXParseException
that occurred.
+ * @throws SAXException
when things go wrong
+ */
+public void warning(SAXParseException exception)
+ throws SAXException {
+
+ System.out.println("**Parsing Warning**\n" +
+ " Line: " +
+ exception.getLineNumber() + "\n" +
+ " URI: " +
+ exception.getSystemId() + "\n" +
+ " Message: " +
+ exception.getMessage());
+ throw new SAXException("Warning encountered");
+}
+
+/**
+ * + * This will report an error that has occurred; this indicates + * that a rule was broken, typically in validation, but that + * parsing can reasonably continue. + *
+ * + * @param exceptionSAXParseException
that occurred.
+ * @throws SAXException
when things go wrong
+ */
+public void error(SAXParseException exception)
+ throws SAXException {
+
+ System.out.println("**Parsing Error**\n" +
+ " Line: " +
+ exception.getLineNumber() + "\n" +
+ " URI: " +
+ exception.getSystemId() + "\n" +
+ " Message: " +
+ exception.getMessage());
+ throw new SAXException("Error encountered");
+}
+
+/**
+ * + * This will report a fatal error that has occurred; this indicates + * that a rule has been broken that makes continued parsing either + * impossible or an almost certain waste of time. + *
+ * + * @param exceptionSAXParseException
that occurred.
+ * @throws SAXException
when things go wrong
+ */
+public void fatalError(SAXParseException exception)
+ throws SAXException {
+
+ System.out.println("**Parsing Fatal Error**\n" +
+ " Line: " +
+ exception.getLineNumber() + "\n" +
+ " URI: " +
+ exception.getSystemId() + "\n" +
+ " Message: " +
+ exception.getMessage());
+ throw new SAXException("Fatal Error encountered");
+}
+}
\ No newline at end of file