Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/omaha/XMLParser.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/XMLParser.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/XMLParser.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d02587f20540ac71d3b884ab2b05818b95ff5a4d |
| --- /dev/null |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/XMLParser.java |
| @@ -0,0 +1,106 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.chrome.browser.omaha; |
| + |
| +import android.text.TextUtils; |
| + |
| +import org.xml.sax.Attributes; |
| +import org.xml.sax.InputSource; |
| +import org.xml.sax.SAXException; |
| +import org.xml.sax.SAXParseException; |
| +import org.xml.sax.helpers.DefaultHandler; |
| + |
| +import java.io.IOException; |
| +import java.io.StringReader; |
| +import java.util.ArrayList; |
| +import java.util.HashMap; |
| +import java.util.List; |
| +import java.util.Map; |
| +import java.util.Stack; |
| + |
| +import javax.xml.parsers.ParserConfigurationException; |
| +import javax.xml.parsers.SAXParser; |
| +import javax.xml.parsers.SAXParserFactory; |
| + |
| +/** |
| + * Breaks XML down into its constituent elements and attributes. |
| + */ |
| +public class XMLParser extends DefaultHandler { |
| + static final class Node { |
| + public final String tag; |
| + public final Map<String, String> attributes; |
| + public final List<Node> children; |
| + |
| + public Node(String tagName) { |
| + tag = tagName; |
| + attributes = new HashMap<String, String>(); |
| + children = new ArrayList<Node>(); |
| + } |
| + } |
| + |
| + private final Node mRootNode; |
| + private final Stack<Node> mTagStack; |
| + |
| + public XMLParser(String serverResponse) throws RequestFailureException { |
| + mRootNode = new Node(null); |
| + mTagStack = new Stack<Node>(); |
| + mTagStack.push(mRootNode); |
| + |
| + try { |
| + SAXParserFactory factory = SAXParserFactory.newInstance(); |
| + SAXParser saxParser = factory.newSAXParser(); |
| + saxParser.parse(new InputSource(new StringReader(serverResponse)), this); |
| + } catch (IOException e) { |
| + throw new RequestFailureException( |
| + "Hit IOException", e, RequestFailureException.ERROR_MALFORMED_XML); |
| + } catch (ParserConfigurationException e) { |
| + throw new RequestFailureException("Hit ParserConfigurationException", e, |
| + RequestFailureException.ERROR_MALFORMED_XML); |
| + } catch (SAXParseException e) { |
| + throw new RequestFailureException( |
| + "Hit SAXParseException", e, RequestFailureException.ERROR_MALFORMED_XML); |
| + } catch (SAXException e) { |
| + throw new RequestFailureException( |
| + "Hit SAXException", e, RequestFailureException.ERROR_MALFORMED_XML); |
| + } |
| + |
| + if (mTagStack.peek() != mRootNode) { |
| + throw new RequestFailureException( |
| + "XML was malformed.", RequestFailureException.ERROR_MALFORMED_XML); |
| + } |
| + } |
| + |
| + public Node getRootNode() { |
| + return mRootNode; |
| + } |
| + |
| + @Override |
| + public void startElement(String uri, String localName, String qName, Attributes attributes) |
| + throws SAXException { |
| + if (mTagStack.empty()) { |
| + throw new SAXException("Tag stack is empty when it shouldn't be."); |
|
nyquist
2014/01/23 00:54:02
single line?
gone
2014/01/24 07:43:12
Done.
|
| + } |
| + |
| + Node currentNode = new Node(qName); |
| + mTagStack.peek().children.add(currentNode); |
| + mTagStack.push(currentNode); |
| + |
| + for (int i = 0; i < attributes.getLength(); ++i) { |
| + String attributeName = attributes.getLocalName(i); |
| + String attributeValue = attributes.getValue(attributeName); |
| + currentNode.attributes.put(attributeName, attributeValue); |
| + } |
| + } |
| + |
| + @Override |
| + public void endElement(String uri, String localName, String qName) throws SAXException { |
| + if (mTagStack.empty()) { |
| + throw new SAXException("Tried closing empty stack with " + qName); |
| + } else if (!TextUtils.equals(qName, mTagStack.peek().tag)) { |
| + throw new SAXException("Tried closing " + mTagStack.peek().tag + " with " + qName); |
| + } |
| + mTagStack.pop(); |
| + } |
| +} |