Author: xor
Date: 2009-01-12 19:03:18 +0000 (Mon, 12 Jan 2009)
New Revision: 25028
Added:
trunk/freenet/src/freenet/support/XMLTree.java
Log:
Move XML tree generator to a separate class in freenet.support
Added: trunk/freenet/src/freenet/support/XMLTree.java
===================================================================
--- trunk/freenet/src/freenet/support/XMLTree.java
(rev 0)
+++ trunk/freenet/src/freenet/support/XMLTree.java 2009-01-12 19:03:18 UTC
(rev 25028)
@@ -0,0 +1,105 @@
+package freenet.support;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.EmptyStackException;
+import java.util.Set;
+import java.util.Stack;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+import org.xml.sax.ext.DefaultHandler2;
+
+
+/**
+ * A class which parses an input stream as XML and builds a tree structure of
the XML.
+ * Use getRoot() to access the tree.
+ *
+ * FIXME: Also use this class in the WoT plugin XML parsers.
+ */
+public class XMLTree extends DefaultHandler2 {
+ private final Set<String> mAllowedElementNames;
+
+ public XMLTree(Set<String> allowedElementNames, InputStream
inputStream) throws SAXException, IOException, ParserConfigurationException {
+ mAllowedElementNames = allowedElementNames;
+
SAXParserFactory.newInstance().newSAXParser().parse(inputStream, this);
+ }
+
+ public XMLElement getRoot() {
+ return rootElement;
+ }
+
+ public class XMLElement {
+ public final String name;
+ public final Attributes attrs;
+ public String cdata = null;
+ public MultiValueTable<String, XMLElement> children = new
MultiValueTable<String, XMLElement>();
+
+ public XMLElement(String newName, Attributes newAttributes)
throws Exception {
+ name = newName;
+ attrs = newAttributes;
+
+ if(!mAllowedElementNames.contains(name))
+ throw new Exception("Unknown element in
Message: " + name);
+ }
+ }
+
+ private XMLElement rootElement = null;
+
+ private final Stack<XMLElement> elements = new Stack<XMLElement>();
+
+ @Override
+ public void startElement(String nameSpaceURI, String localName, String
qName, Attributes attrs) throws SAXException {
+ String name = (qName == null ? localName : qName);
+
+ try {
+ XMLElement element = new XMLElement(name, attrs);
+
+ if(rootElement == null)
+ rootElement = element;
+
+ try {
+ elements.peek().children.put(name, element);
+ }
+ catch(EmptyStackException e) { }
+ elements.push(element);
+
+ /* FIXME: A speedup would be to only store CDATA for
elements selected by the creator of the XMLTreeGenerator. */
+ /* Alternatively the <Date> and <Time> elements could
be changed to also contain a CDATA tag, then the following
+ * line could be removed because all CDATA in the
message XML is also labeled as CDATA. We should ask SomeDude
+ * whether FMS can be modified to also do that, we want
to stay compatible to FMS message XML. */
+ cdata = new StringBuffer(10 * 1024);
+ } catch (Exception e) {
+ Logger.error(this, "Parsing error", e);
+ }
+ }
+
+ StringBuffer cdata;
+
+ public void beginCDATA() {
+ cdata = new StringBuffer(10 * 1024);
+ }
+
+ public void characters(char[] ch, int start, int length) {
+ if(cdata != null)
+ cdata.append(ch, start, length);
+ }
+
+ public void endCDATA() {
+ elements.peek().cdata = cdata.toString();
+ cdata = null;
+ }
+
+ @Override
+ public void endElement(String uri, String localName, String qName) {
+ try {
+ XMLElement newElement = elements.pop(); /* This can
fail because we do not push elements with invalid name */
+ if(cdata != null)
+ newElement.cdata = cdata.toString();
+ }
+ catch(EmptyStackException e) {}
+ cdata = null;
+ }
+}
\ No newline at end of file
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs