rebuilding head
[mir.git] / source / mir / util / xml / XMLParserEngine.java
diff --git a/source/mir/util/xml/XMLParserEngine.java b/source/mir/util/xml/XMLParserEngine.java
new file mode 100755 (executable)
index 0000000..ee70a13
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2001, 2002 The Mir-coders group
+ *
+ * This file is part of Mir.
+ *
+ * Mir is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Mir 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mir; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * In addition, as a special exception, The Mir-coders gives permission to link
+ * the code of this program with  any library licensed under the Apache Software License,
+ * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
+ * (or with modified versions of the above that use the same license as the above),
+ * and distribute linked combinations including the two.  You must obey the
+ * GNU General Public License in all respects for all of the code used other than
+ * the above mentioned libraries.  If you modify this file, you may extend this
+ * exception to your version of the file, but you are not obligated to do so.
+ * If you do not wish to do so, delete this exception statement from your version.
+ */
+
+package mir.util.xml;
+
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.File;
+import java.io.Reader;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.Map;
+
+import java.util.Stack;
+
+import mir.util.ExceptionFunctions;
+import mir.util.xml.html.XMLHTMLParserProvider;
+
+public class XMLParserEngine {
+  private Map providers;
+  private XMLParserProvider defaultProvider;
+
+  private static XMLParserEngine instance = new XMLParserEngine();
+
+  public static XMLParserEngine getInstance() {
+    return instance;
+  }
+
+  private XMLParserEngine() {
+    providers = new HashMap();
+    defaultProvider = new XMLSAXParserProvider(false);
+    providers.put("xml", defaultProvider);
+    providers.put("xml.namespaceaware", new XMLSAXParserProvider(true));
+    providers.put("html", new XMLHTMLParserProvider());
+  }
+
+  /**
+   *
+   * @param aString
+   * @param aRootHandler
+   * @throws XMLParserFailure
+   * @throws XMLParserExc
+   */
+  public void parseString(String aProvider, String aString, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
+    try {
+      parse(aProvider, new StringReader(aString), aRootHandler);
+    }
+    catch (Throwable t) {
+      throw new XMLParserFailure(t);
+    }
+  }
+
+  /**
+   *
+   * @param aFile
+   * @param aRootHandler
+   */
+  public void parse(String aProvider, File aFile, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc {
+//    filename = aFileName;
+
+    try {
+      parse(aProvider, new BufferedInputStream(new FileInputStream(aFile), 8192), aRootHandler);
+    }
+    catch (XMLParserExc e) {
+      throw e;
+    }
+    catch (Throwable t) {
+      throw new XMLParserFailure(t);
+    }
+  }
+
+  /**
+   * Parse xml coming from an input stream with the system default encoding
+   */
+  public void parse(String aProvider, InputStream anInputStream, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
+    parse(aProvider, new InputStreamReader(anInputStream), aRootHandler);
+  }
+
+  /**
+   * Parse xml coming from an input stream according to the given encoding
+   */
+  public void parse(String aProvider, InputStream anInputStream, String anEncoding, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
+    try {
+      parse(aProvider, new InputStreamReader(anInputStream, anEncoding), aRootHandler);
+    }
+    catch (UnsupportedEncodingException e) {
+      throw new XMLParserExc("Unsupported encoding: " + anEncoding);
+    }
+  }
+
+
+  /**
+   *
+   * @param aRootHandler
+   * @throws mir.util.xml.XMLParserFailure
+   * @throws mir.util.xml.XMLParserExc
+   */
+  public void parse(String aProvider, Reader aReader, SectionHandler aRootHandler) throws XMLParserFailure, XMLParserExc{
+    XMLParserProvider provider = (XMLParserProvider) providers.get(aProvider);
+
+    if (provider==null)
+      provider = defaultProvider;
+
+    XMLParserRunner runner = new XMLParserRunner(aRootHandler);
+
+    try {
+      provider.parse(aReader, runner);
+    }
+    catch (Throwable e) {
+      Throwable t = ExceptionFunctions.traceCauseException(e);
+
+      if (t instanceof XMLParserExc && runner.getLocator()!=null) {
+        ((XMLParserExc) t).setLocation(runner.getLocator().getLineNr(), runner.getLocator().getColumnNr());
+      }
+
+      if (t instanceof XMLParserExc) {
+        throw (XMLParserExc) t;
+      }
+
+      if (t instanceof XMLParserFailure) {
+        throw (XMLParserFailure) t;
+      }
+
+      throw new XMLParserFailure(t);
+    }
+  }
+
+  public interface XMLLocator {
+    public int getLineNr();
+    public int getColumnNr();
+  }
+
+  public interface XMLParserReceiver {
+    /**
+     * Provides an object with which it's possible to track the parser's
+     *    position.
+     */
+    public void setLocator(XMLLocator aLocator);
+
+    /**
+     * Extra document data, outside of tags and CDATA, will be passed verbatim
+     * to this method. This may include comments, DTDs, XML specifications,
+     * etc.
+     */
+    public void extra(String aPreAmble) throws XMLParserExc, XMLParserFailure;
+
+    public void startElement(XMLName anElement, Map anAttributes) throws XMLParserExc, XMLParserFailure;
+    public void endElement(XMLName anElement) throws XMLParserExc, XMLParserFailure;
+    public void startDocument() throws XMLParserExc, XMLParserFailure;
+    public void endDocument() throws XMLParserExc, XMLParserFailure;
+    public void text(String aText) throws XMLParserExc, XMLParserFailure;
+  }
+
+  public interface XMLParserProvider {
+    public void parse(Reader aReader, XMLParserReceiver aReceiver) throws XMLParserExc, XMLParserFailure;
+  }
+
+  private class XMLParserRunner implements XMLParserReceiver {
+    private SectionsManager manager;
+    private XMLLocator locator;
+    private SectionHandler rootHandler;
+
+    public XMLParserRunner(SectionHandler aRootHandler) {
+      super();
+
+      locator = null;
+      manager = new SectionsManager();
+      rootHandler = aRootHandler;
+    }
+
+    public void setLocator(XMLLocator aLocator) {
+      locator=aLocator;
+    }
+
+    public void extra(String anExtraData) throws XMLParserExc, XMLParserFailure {
+      SectionHandler handler = manager.currentHandler();
+
+      handler.extra(anExtraData);
+    }
+
+    public void startElement(XMLName anElement, Map anAttributes) throws XMLParserExc, XMLParserFailure {
+      SectionHandler handler = manager.currentHandler().startElement(anElement, anAttributes);
+
+      handler.startSection();
+
+      manager.pushHandler(handler);
+    }
+
+    public void endElement(XMLName anElement) throws XMLParserExc, XMLParserFailure {
+      SectionHandler handler = manager.popHandler();
+
+      handler.finishSection();
+
+      manager.currentHandler().endElement(handler);
+    }
+
+    public void startDocument() throws XMLParserExc, XMLParserFailure {
+      rootHandler.startSection();
+      manager.pushHandler(rootHandler);
+    }
+
+    public void endDocument() throws XMLParserExc, XMLParserFailure {
+      SectionHandler handler = manager.popHandler();
+
+      handler.finishSection();
+    }
+
+    public void text(String aText) throws XMLParserExc, XMLParserFailure {
+      manager.currentHandler().characters(aText);
+    }
+
+    public XMLLocator getLocator() {
+      return locator;
+    }
+  }
+
+  /**
+   *
+   * <p>Title: </p>
+   * <p>Description: </p>
+   * <p>Copyright: Copyright (c) 2003</p>
+   * <p>Company: </p>
+   * @author not attributable
+   * @version 1.0
+   */
+  private class SectionsManager {
+    private Stack handlerStack;
+
+    public SectionsManager() {
+      handlerStack = new Stack();
+    }
+
+    public void pushHandler(SectionHandler aSectionHandler) {
+      handlerStack.push(aSectionHandler);
+    }
+
+    public SectionHandler popHandler() {
+      return (SectionHandler) handlerStack.pop();
+    }
+
+    public SectionHandler currentHandler() {
+      return (SectionHandler) handlerStack.peek();
+    }
+
+    public boolean isEmpty() {
+      return handlerStack.isEmpty();
+    }
+  }
+
+}
\ No newline at end of file