blob: cc2743844bca73f848ca6c509889e370b56557e5 [file] [log] [blame]
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
package com.sun.hotspot.igv.data.serialization;
import com.sun.hotspot.igv.data.Property;
import com.sun.hotspot.igv.data.Properties;
import java.util.HashMap;
import java.util.Stack;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
/**
*
* @author Thomas Wuerthinger
*/
public class XMLParser implements ContentHandler {
public static interface ParseMonitor {
public void setProgress(double d);
public void setState(String state);
}
public static class MissingAttributeException extends SAXException {
private String name;
public MissingAttributeException(String name) {
super("Missing attribute \"" + name + "\"");
this.name = name;
}
public String getAttributeName() {
return this.getMessage();
}
}
public static class HandoverElementHandler<P> extends ElementHandler<P, P> {
@Override
protected P start() throws SAXException {
return getParentObject();
}
public HandoverElementHandler(String name) {
super(name);
}
public HandoverElementHandler(String name, boolean needsText) {
super(name, needsText);
}
}
public static class TopElementHandler<P> extends ElementHandler<P, Object> {
public TopElementHandler() {
super(null);
}
}
public static class ElementHandler<T, P> {
private String name;
private T object;
private Attributes attr;
private StringBuilder currentText;
private ParseMonitor monitor;
private HashMap<String, ElementHandler<?, ? super T>> hashtable;
private boolean needsText;
private ElementHandler<P, ?> parentElement;
public ElementHandler(String name) {
this(name, false);
}
public ElementHandler<P, ?> getParentElement() {
return parentElement;
}
public P getParentObject() {
return getParentElement().getObject();
}
protected boolean needsText() {
return needsText;
}
public ElementHandler(String name, boolean needsText) {
this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
this.name = name;
this.needsText = needsText;
}
public ParseMonitor getMonitor() {
return monitor;
}
public ElementHandler<?, ? super T> getChild(String name) {
return hashtable.get(name);
}
public void addChild(ElementHandler<?, ? super T> handler) {
assert handler != null;
hashtable.put(handler.getName(), handler);
}
public String getName() {
return name;
}
public T getObject() {
return object;
}
public String readAttribute(String name) {
return attr.getValue(name);
}
public String readRequiredAttribute(String name) throws SAXException {
String s = readAttribute(name);
if (s == null) {
throw new MissingAttributeException(name);
}
return s;
}
public void processAttributesAsProperties(Properties p) {
int length = attr.getLength();
for (int i = 0; i < length; i++) {
String val = attr.getValue(i).intern();
String localName = attr.getLocalName(i).intern();
p.setProperty(val, localName);
}
}
public void startElement(ElementHandler<P, ?> parentElement, Attributes attr, ParseMonitor monitor) throws SAXException {
this.currentText = new StringBuilder();
this.attr = attr;
this.monitor = monitor;
this.parentElement = parentElement;
object = start();
}
protected T start() throws SAXException {
return null;
}
protected void end(String text) throws SAXException {
}
public void endElement() throws SAXException {
end(currentText.toString());
}
protected void text(char[] c, int start, int length) {
assert currentText != null;
currentText.append(c, start, length);
}
}
private Stack<ElementHandler> stack;
private ParseMonitor monitor;
public XMLParser(TopElementHandler rootHandler, ParseMonitor monitor) {
this.stack = new Stack<ElementHandler>();
this.monitor = monitor;
this.stack.push(rootHandler);
}
public void setDocumentLocator(Locator locator) {
if (monitor != null) {
monitor.setState("Starting parsing");
}
}
public void startDocument() throws SAXException {
}
public void endDocument() throws SAXException {
}
public void startPrefixMapping(String prefix, String uri) throws SAXException {
}
public void endPrefixMapping(String prefix) throws SAXException {
}
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
assert !stack.isEmpty();
ElementHandler parent = stack.peek();
if (parent != null) {
ElementHandler child = parent.getChild(qName);
if (child != null) {
child.startElement(parent, atts, monitor);
stack.push(child);
return;
}
}
stack.push(null);
}
public void endElement(String uri, String localName, String qName) throws SAXException {
ElementHandler handler = stack.pop();
if (handler != null) {
handler.endElement();
}
}
public void characters(char[] ch, int start, int length) throws SAXException {
assert !stack.isEmpty();
ElementHandler top = stack.peek();
if (top != null && top.needsText()) {
top.text(ch, start, length);
}
}
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
}
public void processingInstruction(String target, String data) throws SAXException {
}
public void skippedEntity(String name) throws SAXException {
}
}