From 36deaa6002a0e85d7da6efd7e569d91f976d9949 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 31 Dec 2015 16:08:16 +0000 Subject: Move XML parsing code into its own package --- src/main/java/org/zwobble/mammoth/Mammoth.java | 2 +- .../java/org/zwobble/mammoth/xml/ElementName.java | 19 ----- .../java/org/zwobble/mammoth/xml/SimpleSax.java | 64 ----------------- .../org/zwobble/mammoth/xml/SimpleSaxHandler.java | 9 --- .../org/zwobble/mammoth/xml/XmlElementBuilder.java | 25 ------- .../java/org/zwobble/mammoth/xml/XmlParser.java | 79 --------------------- .../zwobble/mammoth/xml/parsing/ElementName.java | 19 +++++ .../org/zwobble/mammoth/xml/parsing/SimpleSax.java | 64 +++++++++++++++++ .../mammoth/xml/parsing/SimpleSaxHandler.java | 9 +++ .../mammoth/xml/parsing/XmlElementBuilder.java | 28 ++++++++ .../org/zwobble/mammoth/xml/parsing/XmlParser.java | 81 ++++++++++++++++++++++ 11 files changed, 202 insertions(+), 197 deletions(-) delete mode 100644 src/main/java/org/zwobble/mammoth/xml/ElementName.java delete mode 100644 src/main/java/org/zwobble/mammoth/xml/SimpleSax.java delete mode 100644 src/main/java/org/zwobble/mammoth/xml/SimpleSaxHandler.java delete mode 100644 src/main/java/org/zwobble/mammoth/xml/XmlElementBuilder.java delete mode 100644 src/main/java/org/zwobble/mammoth/xml/XmlParser.java create mode 100644 src/main/java/org/zwobble/mammoth/xml/parsing/ElementName.java create mode 100644 src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSax.java create mode 100644 src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSaxHandler.java create mode 100644 src/main/java/org/zwobble/mammoth/xml/parsing/XmlElementBuilder.java create mode 100644 src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java (limited to 'src/main/java/org/zwobble') diff --git a/src/main/java/org/zwobble/mammoth/Mammoth.java b/src/main/java/org/zwobble/mammoth/Mammoth.java index 7dcce95..e266f77 100644 --- a/src/main/java/org/zwobble/mammoth/Mammoth.java +++ b/src/main/java/org/zwobble/mammoth/Mammoth.java @@ -8,7 +8,7 @@ import java.util.zip.ZipFile; import org.zwobble.mammoth.xml.XmlElement; import org.zwobble.mammoth.xml.XmlNodeVisitor; -import org.zwobble.mammoth.xml.XmlParser; +import org.zwobble.mammoth.xml.parsing.XmlParser; import org.zwobble.mammoth.xml.XmlTextNode; import com.google.common.base.Joiner; diff --git a/src/main/java/org/zwobble/mammoth/xml/ElementName.java b/src/main/java/org/zwobble/mammoth/xml/ElementName.java deleted file mode 100644 index 76b1c93..0000000 --- a/src/main/java/org/zwobble/mammoth/xml/ElementName.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.zwobble.mammoth.xml; - -public class ElementName { - private final String uri; - private final String localName; - - public ElementName(String uri, String localName) { - this.uri = uri; - this.localName = localName; - } - - public String getUri() { - return uri; - } - - public String getLocalName() { - return localName; - } -} diff --git a/src/main/java/org/zwobble/mammoth/xml/SimpleSax.java b/src/main/java/org/zwobble/mammoth/xml/SimpleSax.java deleted file mode 100644 index 54bd614..0000000 --- a/src/main/java/org/zwobble/mammoth/xml/SimpleSax.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.zwobble.mammoth.xml; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringReader; -import java.util.Map; -import java.util.stream.IntStream; - -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.xml.sax.Attributes; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.DefaultHandler; - -import static java.util.stream.Collectors.toMap; - -public class SimpleSax { - public static void parseStream(InputStream input, SimpleSaxHandler handler) { - parseInputSource(new InputSource(input), handler); - } - - public static void parseString(String value, SimpleSaxHandler handler) { - parseInputSource(new InputSource(new StringReader(value)), handler); - } - - private static void parseInputSource(InputSource inputSource, SimpleSaxHandler handler) { - SAXParserFactory parserFactory = SAXParserFactory.newInstance(); - parserFactory.setNamespaceAware(true); - try { - SAXParser saxParser = parserFactory.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); - xmlReader.setContentHandler(new DefaultHandler() { - @Override - public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { - ElementName name = new ElementName(uri, localName); - Map attributesMap = IntStream.range(0, attributes.getLength()) - .boxed() - .collect(toMap( - index -> new ElementName(attributes.getURI(index), attributes.getLocalName(index)), - attributes::getValue - )); - handler.startElement(name, attributesMap); - } - - @Override - public void endElement(String uri, String localName, String qName) throws SAXException { - handler.endElement(); - } - - @Override - public void characters(char[] ch, int start, int length) throws SAXException { - handler.characters(new String(ch, start, length)); - } - }); - xmlReader.parse(inputSource); - } catch (ParserConfigurationException | SAXException | IOException exception) { - throw new RuntimeException(exception); - } - } -} diff --git a/src/main/java/org/zwobble/mammoth/xml/SimpleSaxHandler.java b/src/main/java/org/zwobble/mammoth/xml/SimpleSaxHandler.java deleted file mode 100644 index f56a940..0000000 --- a/src/main/java/org/zwobble/mammoth/xml/SimpleSaxHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package org.zwobble.mammoth.xml; - -import java.util.Map; - -public interface SimpleSaxHandler { - void startElement(ElementName name, Map attributes); - void endElement(); - void characters(String string); -} diff --git a/src/main/java/org/zwobble/mammoth/xml/XmlElementBuilder.java b/src/main/java/org/zwobble/mammoth/xml/XmlElementBuilder.java deleted file mode 100644 index 16b4865..0000000 --- a/src/main/java/org/zwobble/mammoth/xml/XmlElementBuilder.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.zwobble.mammoth.xml; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -class XmlElementBuilder { - private final String name; - private final Map attributes; - private final List children; - - XmlElementBuilder(String name, Map attributes) { - this.name = name; - this.attributes = attributes; - this.children = new ArrayList<>(); - } - - XmlElement build() { - return new XmlElement(name, attributes, children); - } - - void addChild(XmlNode node) { - children.add(node); - } -} diff --git a/src/main/java/org/zwobble/mammoth/xml/XmlParser.java b/src/main/java/org/zwobble/mammoth/xml/XmlParser.java deleted file mode 100644 index cf00586..0000000 --- a/src/main/java/org/zwobble/mammoth/xml/XmlParser.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.zwobble.mammoth.xml; - -import java.io.InputStream; -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.Map; - -import com.google.common.base.Strings; -import com.google.common.collect.BiMap; - -import static java.util.stream.Collectors.toMap; - -public class XmlParser { - private final BiMap namespaces; - - public XmlParser(BiMap namespaces) { - this.namespaces = namespaces; - } - - public XmlElement parseStream(InputStream inputStream) { - NodeGenerator nodeGenerator = new NodeGenerator(); - SimpleSax.parseStream(inputStream, nodeGenerator); - return nodeGenerator.getRoot(); - } - - public XmlElement parseString(String value) { - NodeGenerator nodeGenerator = new NodeGenerator(); - SimpleSax.parseString(value, nodeGenerator); - return nodeGenerator.getRoot(); - } - - private class NodeGenerator implements SimpleSaxHandler { - private final Deque elementStack; - - public NodeGenerator() { - elementStack = new ArrayDeque<>(); - } - - public XmlElement getRoot() { - return elementStack.getFirst().build(); - } - - @Override - public void startElement(ElementName name, Map attributes) { - Map simpleAttributes = attributes - .entrySet() - .stream() - .collect(toMap( - entry -> readName(entry.getKey()), - entry -> entry.getValue())); - XmlElementBuilder element = new XmlElementBuilder(readName(name), simpleAttributes); - elementStack.add(element); - } - - private String readName(ElementName name) { - if (Strings.isNullOrEmpty(name.getUri())) { - return name.getLocalName(); - } else if (namespaces.containsValue(name.getUri())) { - return namespaces.inverse().get(name.getUri()) + ":" + name.getLocalName(); - } else { - return "{" + name.getUri() + "}" + name.getLocalName(); - } - - } - - @Override - public void endElement() { - if (elementStack.size() > 1) { - XmlElementBuilder element = elementStack.removeLast(); - elementStack.getLast().addChild(element.build()); - } - } - - @Override - public void characters(String string) { - elementStack.getLast().addChild(new XmlTextNode(string)); - } - } -} diff --git a/src/main/java/org/zwobble/mammoth/xml/parsing/ElementName.java b/src/main/java/org/zwobble/mammoth/xml/parsing/ElementName.java new file mode 100644 index 0000000..a0f5f8e --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/xml/parsing/ElementName.java @@ -0,0 +1,19 @@ +package org.zwobble.mammoth.xml.parsing; + +class ElementName { + private final String uri; + private final String localName; + + ElementName(String uri, String localName) { + this.uri = uri; + this.localName = localName; + } + + String getUri() { + return uri; + } + + String getLocalName() { + return localName; + } +} diff --git a/src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSax.java b/src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSax.java new file mode 100644 index 0000000..5b7957d --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSax.java @@ -0,0 +1,64 @@ +package org.zwobble.mammoth.xml.parsing; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.util.Map; +import java.util.stream.IntStream; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; + +import static java.util.stream.Collectors.toMap; + +class SimpleSax { + static void parseStream(InputStream input, SimpleSaxHandler handler) { + parseInputSource(new InputSource(input), handler); + } + + static void parseString(String value, SimpleSaxHandler handler) { + parseInputSource(new InputSource(new StringReader(value)), handler); + } + + private static void parseInputSource(InputSource inputSource, SimpleSaxHandler handler) { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + parserFactory.setNamespaceAware(true); + try { + SAXParser saxParser = parserFactory.newSAXParser(); + XMLReader xmlReader = saxParser.getXMLReader(); + xmlReader.setContentHandler(new DefaultHandler() { + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { + ElementName name = new ElementName(uri, localName); + Map attributesMap = IntStream.range(0, attributes.getLength()) + .boxed() + .collect(toMap( + index -> new ElementName(attributes.getURI(index), attributes.getLocalName(index)), + attributes::getValue + )); + handler.startElement(name, attributesMap); + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + handler.endElement(); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + handler.characters(new String(ch, start, length)); + } + }); + xmlReader.parse(inputSource); + } catch (ParserConfigurationException | SAXException | IOException exception) { + throw new RuntimeException(exception); + } + } +} diff --git a/src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSaxHandler.java b/src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSaxHandler.java new file mode 100644 index 0000000..ed0af31 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/xml/parsing/SimpleSaxHandler.java @@ -0,0 +1,9 @@ +package org.zwobble.mammoth.xml.parsing; + +import java.util.Map; + +interface SimpleSaxHandler { + void startElement(ElementName name, Map attributes); + void endElement(); + void characters(String string); +} diff --git a/src/main/java/org/zwobble/mammoth/xml/parsing/XmlElementBuilder.java b/src/main/java/org/zwobble/mammoth/xml/parsing/XmlElementBuilder.java new file mode 100644 index 0000000..1115cfb --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/xml/parsing/XmlElementBuilder.java @@ -0,0 +1,28 @@ +package org.zwobble.mammoth.xml.parsing; + +import org.zwobble.mammoth.xml.XmlElement; +import org.zwobble.mammoth.xml.XmlNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +class XmlElementBuilder { + private final String name; + private final Map attributes; + private final List children; + + XmlElementBuilder(String name, Map attributes) { + this.name = name; + this.attributes = attributes; + this.children = new ArrayList<>(); + } + + XmlElement build() { + return new XmlElement(name, attributes, children); + } + + void addChild(XmlNode node) { + children.add(node); + } +} diff --git a/src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java b/src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java new file mode 100644 index 0000000..5354f07 --- /dev/null +++ b/src/main/java/org/zwobble/mammoth/xml/parsing/XmlParser.java @@ -0,0 +1,81 @@ +package org.zwobble.mammoth.xml.parsing; + +import java.io.InputStream; +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.Map; + +import com.google.common.base.Strings; +import com.google.common.collect.BiMap; +import org.zwobble.mammoth.xml.XmlElement; +import org.zwobble.mammoth.xml.XmlTextNode; + +import static java.util.stream.Collectors.toMap; + +public class XmlParser { + private final BiMap namespaces; + + public XmlParser(BiMap namespaces) { + this.namespaces = namespaces; + } + + public XmlElement parseStream(InputStream inputStream) { + NodeGenerator nodeGenerator = new NodeGenerator(); + SimpleSax.parseStream(inputStream, nodeGenerator); + return nodeGenerator.getRoot(); + } + + public XmlElement parseString(String value) { + NodeGenerator nodeGenerator = new NodeGenerator(); + SimpleSax.parseString(value, nodeGenerator); + return nodeGenerator.getRoot(); + } + + private class NodeGenerator implements SimpleSaxHandler { + private final Deque elementStack; + + public NodeGenerator() { + elementStack = new ArrayDeque<>(); + } + + public XmlElement getRoot() { + return elementStack.getFirst().build(); + } + + @Override + public void startElement(ElementName name, Map attributes) { + Map simpleAttributes = attributes + .entrySet() + .stream() + .collect(toMap( + entry -> readName(entry.getKey()), + entry -> entry.getValue())); + XmlElementBuilder element = new XmlElementBuilder(readName(name), simpleAttributes); + elementStack.add(element); + } + + private String readName(ElementName name) { + if (Strings.isNullOrEmpty(name.getUri())) { + return name.getLocalName(); + } else if (namespaces.containsValue(name.getUri())) { + return namespaces.inverse().get(name.getUri()) + ":" + name.getLocalName(); + } else { + return "{" + name.getUri() + "}" + name.getLocalName(); + } + + } + + @Override + public void endElement() { + if (elementStack.size() > 1) { + XmlElementBuilder element = elementStack.removeLast(); + elementStack.getLast().addChild(element.build()); + } + } + + @Override + public void characters(String string) { + elementStack.getLast().addChild(new XmlTextNode(string)); + } + } +} -- cgit v1.2.3