XMLParser.java revision 1472:c18cbe5936b8
1237263Snp/*
2237263Snp * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
3237263Snp * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4237263Snp *
5237263Snp * This code is free software; you can redistribute it and/or modify it
6237263Snp * under the terms of the GNU General Public License version 2 only, as
7237263Snp * published by the Free Software Foundation.
8237263Snp *
9237263Snp * This code is distributed in the hope that it will be useful, but WITHOUT
10237263Snp * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11237263Snp * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12237263Snp * version 2 for more details (a copy is included in the LICENSE file that
13237263Snp * accompanied this code).
14237263Snp *
15237263Snp * You should have received a copy of the GNU General Public License version
16237263Snp * 2 along with this work; if not, write to the Free Software Foundation,
17237263Snp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18237263Snp *
19237263Snp * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20237263Snp * or visit www.oracle.com if you need additional information or have any
21237263Snp * questions.
22237263Snp *
23237263Snp */
24237263Snppackage com.sun.hotspot.igv.data.serialization;
25237263Snp
26174641Skmacyimport com.sun.hotspot.igv.data.Property;
27174641Skmacyimport com.sun.hotspot.igv.data.Properties;
28174641Skmacyimport java.util.HashMap;
29174641Skmacyimport java.util.Stack;
30237263Snpimport org.xml.sax.Attributes;
31237263Snpimport org.xml.sax.ContentHandler;
32237263Snpimport org.xml.sax.Locator;
33174641Skmacyimport org.xml.sax.SAXException;
34174641Skmacy
35174641Skmacy/**
36174641Skmacy *
37174641Skmacy * @author Thomas Wuerthinger
38176472Skmacy */
39174641Skmacypublic class XMLParser implements ContentHandler {
40174641Skmacy
41174641Skmacy    public static interface ParseMonitor {
42181011Skmacy
43181011Skmacy        public void setProgress(double d);
44174641Skmacy
45237263Snp        public void setState(String state);
46181039Sps    }
47174641Skmacy
48174641Skmacy    public static class MissingAttributeException extends SAXException {
49174641Skmacy
50174641Skmacy        private String name;
51237263Snp
52237263Snp        public MissingAttributeException(String name) {
53183289Skmacy            super("Missing attribute \"" + name + "\"");
54174641Skmacy            this.name = name;
55237263Snp        }
56174641Skmacy
57174641Skmacy        public String getAttributeName() {
58174641Skmacy            return this.getMessage();
59174641Skmacy        }
60174641Skmacy    }
61174641Skmacy
62174641Skmacy    public static class HandoverElementHandler<P> extends ElementHandler<P, P> {
63174641Skmacy
64174641Skmacy        @Override
65237263Snp        protected P start() throws SAXException {
66174641Skmacy            return getParentObject();
67237263Snp        }
68174641Skmacy
69176472Skmacy        public HandoverElementHandler(String name) {
70174641Skmacy            super(name);
71174641Skmacy        }
72237263Snp
73237263Snp        public HandoverElementHandler(String name, boolean needsText) {
74237263Snp            super(name, needsText);
75237263Snp        }
76174641Skmacy    }
77237263Snp
78237263Snp    public static class TopElementHandler<P> extends ElementHandler<P, Object> {
79237263Snp
80237263Snp        public TopElementHandler() {
81237263Snp            super(null);
82237263Snp        }
83237263Snp    }
84237263Snp
85237263Snp    public static class ElementHandler<T, P> {
86237263Snp
87237263Snp        private String name;
88237263Snp        private T object;
89237263Snp        private Attributes attr;
90237263Snp        private StringBuilder currentText;
91174641Skmacy        private ParseMonitor monitor;
92174641Skmacy        private HashMap<String, ElementHandler<?, ? super T>> hashtable;
93174641Skmacy        private boolean needsText;
94174641Skmacy        private ElementHandler<P, ?> parentElement;
95174641Skmacy
96174641Skmacy        public ElementHandler(String name) {
97174641Skmacy            this(name, false);
98174641Skmacy        }
99174641Skmacy
100174641Skmacy        public ElementHandler<P, ?> getParentElement() {
101174641Skmacy            return parentElement;
102174641Skmacy        }
103174641Skmacy
104174641Skmacy        public P getParentObject() {
105174641Skmacy            return getParentElement().getObject();
106174641Skmacy        }
107174641Skmacy
108174641Skmacy        protected boolean needsText() {
109174641Skmacy            return needsText;
110174641Skmacy        }
111174641Skmacy
112174641Skmacy        public ElementHandler(String name, boolean needsText) {
113178302Skmacy            this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
114174641Skmacy            this.name = name;
115237263Snp            this.needsText = needsText;
116237263Snp        }
117174641Skmacy
118237263Snp        public ParseMonitor getMonitor() {
119237263Snp            return monitor;
120237263Snp        }
121237263Snp
122237263Snp        public ElementHandler<?, ? super T> getChild(String name) {
123237263Snp            return hashtable.get(name);
124237263Snp        }
125237263Snp
126237263Snp        public void addChild(ElementHandler<?, ? super T> handler) {
127237263Snp            assert handler != null;
128237263Snp            hashtable.put(handler.getName(), handler);
129237263Snp        }
130237263Snp
131178302Skmacy        public String getName() {
132237263Snp            return name;
133237263Snp        }
134237263Snp
135174641Skmacy        public T getObject() {
136237263Snp            return object;
137174641Skmacy        }
138237263Snp
139237263Snp        public String readAttribute(String name) {
140178302Skmacy            return attr.getValue(name);
141237263Snp        }
142237263Snp
143237263Snp        public String readRequiredAttribute(String name) throws SAXException {
144176472Skmacy            String s = readAttribute(name);
145237263Snp            if (s == null) {
146237263Snp                throw new MissingAttributeException(name);
147237263Snp            }
148237263Snp            return s;
149237263Snp        }
150237263Snp
151237263Snp        public void processAttributesAsProperties(Properties p) {
152174641Skmacy            int length = attr.getLength();
153174641Skmacy            for (int i = 0; i < length; i++) {
154237263Snp                String val = attr.getValue(i).intern();
155237263Snp                String localName = attr.getLocalName(i).intern();
156237263Snp                p.setProperty(val, localName);
157237263Snp            }
158237263Snp        }
159174641Skmacy
160237263Snp        public void startElement(ElementHandler<P, ?> parentElement, Attributes attr, ParseMonitor monitor) throws SAXException {
161174641Skmacy            this.currentText = new StringBuilder();
162237263Snp            this.attr = attr;
163237263Snp            this.monitor = monitor;
164174641Skmacy            this.parentElement = parentElement;
165237263Snp            object = start();
166237263Snp        }
167174641Skmacy
168237263Snp        protected T start() throws SAXException {
169237263Snp            return null;
170174641Skmacy        }
171237263Snp
172237263Snp        protected void end(String text) throws SAXException {
173178302Skmacy
174237263Snp        }
175237263Snp
176237263Snp        public void endElement() throws SAXException {
177174641Skmacy            end(currentText.toString());
178237263Snp        }
179237263Snp
180237263Snp        protected void text(char[] c, int start, int length) {
181174641Skmacy            assert currentText != null;
182237263Snp            currentText.append(c, start, length);
183237263Snp        }
184174641Skmacy    }
185174641Skmacy    private Stack<ElementHandler> stack;
186237263Snp    private ParseMonitor monitor;
187237263Snp
188174641Skmacy    public XMLParser(TopElementHandler rootHandler, ParseMonitor monitor) {
189174641Skmacy        this.stack = new Stack<ElementHandler>();
190237263Snp        this.monitor = monitor;
191174641Skmacy        this.stack.push(rootHandler);
192174641Skmacy    }
193237263Snp
194237263Snp    public void setDocumentLocator(Locator locator) {
195174641Skmacy        if (monitor != null) {
196237263Snp            monitor.setState("Starting parsing");
197174641Skmacy        }
198237263Snp    }
199237263Snp
200237263Snp    public void startDocument() throws SAXException {
201176472Skmacy    }
202237263Snp
203237263Snp    public void endDocument() throws SAXException {
204237263Snp    }
205237263Snp
206174641Skmacy    public void startPrefixMapping(String prefix, String uri) throws SAXException {
207237263Snp    }
208174641Skmacy
209237263Snp    public void endPrefixMapping(String prefix) throws SAXException {
210237263Snp    }
211178302Skmacy
212237263Snp    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
213237263Snp
214237263Snp        assert !stack.isEmpty();
215237263Snp        ElementHandler parent = stack.peek();
216178302Skmacy        if (parent != null) {
217237263Snp            ElementHandler child = parent.getChild(qName);
218237263Snp            if (child != null) {
219237263Snp                child.startElement(parent, atts, monitor);
220237263Snp                stack.push(child);
221237263Snp                return;
222237263Snp            }
223178302Skmacy        }
224237263Snp
225237263Snp        stack.push(null);
226237263Snp    }
227237263Snp
228178302Skmacy    public void endElement(String uri, String localName, String qName) throws SAXException {
229237263Snp        ElementHandler handler = stack.pop();
230237263Snp        if (handler != null) {
231237263Snp            handler.endElement();
232174641Skmacy        }
233237263Snp    }
234237263Snp
235237263Snp    public void characters(char[] ch, int start, int length) throws SAXException {
236237263Snp
237174641Skmacy        assert !stack.isEmpty();
238237263Snp
239237263Snp
240178302Skmacy        ElementHandler top = stack.peek();
241237263Snp        if (top != null && top.needsText()) {
242237263Snp            top.text(ch, start, length);
243178302Skmacy        }
244237263Snp    }
245178302Skmacy
246237263Snp    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
247237263Snp    }
248178302Skmacy
249174641Skmacy    public void processingInstruction(String target, String data) throws SAXException {
250237263Snp    }
251237263Snp
252237263Snp    public void skippedEntity(String name) throws SAXException {
253174641Skmacy    }
254237263Snp}
255237263Snp