2 * Copyright (C) 2001, 2002 The Mir-coders group
4 * This file is part of Mir.
6 * Mir is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * Mir is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Mir; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * In addition, as a special exception, The Mir-coders gives permission to link
21 * the code of this program with any library licensed under the Apache Software License,
22 * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23 * (or with modified versions of the above that use the same license as the above),
24 * and distribute linked combinations including the two. You must obey the
25 * GNU General Public License in all respects for all of the code used other than
26 * the above mentioned libraries. If you modify this file, you may extend this
27 * exception to your version of the file, but you are not obligated to do so.
28 * If you do not wish to do so, delete this exception statement from your version.
32 import java.io.FileInputStream;
33 import java.io.InputStream;
34 import java.util.HashMap;
36 import java.util.Stack;
38 import javax.xml.parsers.ParserConfigurationException;
39 import javax.xml.parsers.SAXParser;
40 import javax.xml.parsers.SAXParserFactory;
43 import multex.Failure;
45 import org.xml.sax.Attributes;
46 import org.xml.sax.InputSource;
47 import org.xml.sax.Locator;
48 import org.xml.sax.SAXException;
49 import org.xml.sax.SAXParseException;
50 import org.xml.sax.helpers.DefaultHandler;
52 public class XMLReader {
53 private Locator locator;
54 private String filename;
55 private boolean namespaceAware;
61 public XMLReader(boolean aNameSpaceAware) {
62 namespaceAware = aNameSpaceAware;
66 public void parseFile(String aFileName, SectionHandler aRootHandler) throws XMLReaderFailure, XMLReaderExc {
69 parseInputStream(new FileInputStream(aFileName), aRootHandler);
72 throw new XMLReaderFailure(t);
76 public void parseInputStream(InputStream anInputStream, SectionHandler aRootHandler) throws XMLReaderFailure, XMLReaderExc {
78 SAXParserFactory parserFactory = SAXParserFactory.newInstance();
80 parserFactory.setNamespaceAware(namespaceAware);
81 parserFactory.setValidating(true);
83 XMLReaderHandler handler = new XMLReaderHandler(parserFactory, aRootHandler);
85 handler.processInputStream(anInputStream);
88 Throwable t = ExceptionFunctions.traceCauseException(e);
90 if (t instanceof XMLReaderExc) {
91 if (locator!=null && filename!=null)
92 ((XMLReaderExc) t).setLocation(filename, locator.getLineNumber(), locator.getColumnNumber());
93 throw (XMLReaderExc) t;
96 if (t instanceof XMLReaderFailure) {
97 throw (XMLReaderFailure) t;
100 throw new XMLReaderFailure(t);
104 private class XMLReaderHandler extends DefaultHandler {
105 private SAXParserFactory parserFactory;
106 private SectionsManager manager;
107 private InputSource inputSource;
109 public XMLReaderHandler(SAXParserFactory aParserFactory, SectionHandler aRootHandler) {
112 parserFactory=aParserFactory;
113 manager = new SectionsManager();
114 manager.pushHandler(aRootHandler);
117 public void setDocumentLocator(Locator aLocator) {
121 private void processInputStream(InputStream anInputStream) throws XMLReaderExc, XMLReaderFailure {
123 SAXParser parser=parserFactory.newSAXParser();
125 inputSource = new InputSource(anInputStream);
126 parser.parse(inputSource, this);
128 catch (ParserConfigurationException e) {
129 throw new XMLReaderExc("Internal exception: "+e.getMessage());
131 catch (Throwable e) {
132 throw new XMLReaderFailure(e);
136 public void startElement(String aUri, String aTag, String aQualifiedName, Attributes anAttributes) throws SAXException {
141 attributesMap = new HashMap();
142 for (i=0; i<anAttributes.getLength(); i++)
143 attributesMap.put(anAttributes.getQName(i), anAttributes.getValue(i));
145 SectionHandler handler = manager.currentHandler().startElement(aQualifiedName, attributesMap);
147 manager.pushHandler( handler );
149 catch (XMLReaderExc e) {
150 throw new SAXParseException(e.getMessage(), null, e);
152 catch (Exception e) {
153 throw new SAXException(e);
157 public void endElement(String aUri, String aTag, String aQualifiedName) throws SAXException {
160 if (!aQualifiedName.equals("include")) {
161 SectionHandler handler = manager.popHandler();
163 handler.finishSection();
165 if (!manager.isEmpty()) {
166 manager.currentHandler().endElement(handler);
170 catch (XMLReaderExc e) {
171 throw new SAXParseException(e.getMessage(), null, e);
173 catch (Exception e) {
174 throw new SAXException(e);
178 public void characters(char[] aBuffer, int aStart, int anEnd) throws SAXException {
180 String text = new String(aBuffer, aStart, anEnd);
182 manager.currentHandler().characters(text);
184 catch (XMLReaderExc e) {
185 throw new SAXParseException(e.getMessage(), null, e);
187 catch (Exception e) {
188 throw new SAXException(e);
193 private class SectionsManager {
196 public SectionsManager() {
197 handlerStack = new Stack();
200 public void pushHandler(SectionHandler aSectionHandler) {
201 handlerStack.push(aSectionHandler);
204 public SectionHandler popHandler() {
205 return (SectionHandler) handlerStack.pop();
208 public SectionHandler currentHandler() {
209 return (SectionHandler) handlerStack.peek();
212 public boolean isEmpty() {
213 return handlerStack.isEmpty();
217 public static interface SectionHandler {
218 public abstract SectionHandler startElement(String aTag, Map anAttributes) throws XMLReaderExc;
220 public abstract void endElement(SectionHandler aHandler) throws XMLReaderExc;
222 public void characters(String aCharacters) throws XMLReaderExc;
224 public void finishSection() throws XMLReaderExc;
227 public static abstract class AbstractSectionHandler implements SectionHandler {
228 public SectionHandler startElement(String aTag, Map anAttributes) throws XMLReaderExc {
232 public void endElement(SectionHandler aHandler) throws XMLReaderExc {
235 public void finishSection() throws XMLReaderExc {
238 public void characters(String aCharacters) throws XMLReaderExc {
239 if ( aCharacters.trim().length() > 0) {
240 throw new XMLReaderExc("Text not allowed");
245 public static class XMLReaderExc extends Exc {
246 private boolean hasLocation;
247 private String filename;
249 private int columnNr;
251 public XMLReaderExc(String aMessage) {
256 protected void setLocation(String aFilename, int aLineNr, int aColumnNr) {
257 filename = aFilename;
259 columnNr = aColumnNr;
263 public boolean getHasLocation() {
267 public int getLineNr() {
271 public int getColumnNr() {
275 public String getFilename() {
280 public static class XMLReaderFailure extends Failure {
281 public XMLReaderFailure(String aMessage, Throwable aCause) {
282 super(aMessage, aCause);
285 public XMLReaderFailure(Throwable aCause) {
286 super(aCause.getMessage(), aCause);