View Javadoc

1   /*
2    * Copyright 2002 - 2007 JEuclid, http://jeuclid.sf.net
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  /* $Id: SAXBuilder.java 422 2007-08-16 09:36:52Z maxberger $ */
18  
19  package net.sourceforge.jeuclid;
20  
21  import java.util.Stack;
22  
23  import net.sourceforge.jeuclid.elements.AbstractJEuclidElement;
24  import net.sourceforge.jeuclid.elements.JEuclidElementFactory;
25  import net.sourceforge.jeuclid.elements.generic.DocumentElement;
26  import net.sourceforge.jeuclid.elements.support.attributes.AttributeMap;
27  import net.sourceforge.jeuclid.elements.support.attributes.SAXAttributeMap;
28  
29  import org.w3c.dom.Node;
30  import org.w3c.dom.mathml.MathMLElement;
31  import org.xml.sax.Attributes;
32  import org.xml.sax.ContentHandler;
33  import org.xml.sax.Locator;
34  
35  /**
36   * Generator for creating a MathElement tree from SAX events.
37   * 
38   * @author <a href="mailto:stephan@vern.chem.tu-berlin.de">Stephan Michels</a>
39   * @author Max Berger
40   * @version $Revision: 422 $
41   */
42  public class SAXBuilder implements ContentHandler {
43      private DocumentElement rootElement;
44  
45      private final Stack<Node> stack = new Stack<Node>();;
46  
47      private final MathBase mbase;
48  
49      /**
50       * Logger for this class.
51       */
52      // unused
53      // private static final Log LOGGER =
54      // LogFactory.getLog(SAXMathBuilder.class);
55      /**
56       * default constructor.
57       */
58      public SAXBuilder() {
59          this.mbase = new MathBase(MathBase.getDefaultParameters());
60      }
61  
62      /**
63       * Returns the created math root element.
64       * 
65       * @return Math root element
66       */
67      public DocumentElement getMathRootElement() {
68          return this.rootElement;
69      }
70  
71      /**
72       * Receive notification of character data.
73       * 
74       * @param ch
75       *            The characters from the XML document.
76       * @param start
77       *            The start position in the array.
78       * @param length
79       *            The number of characters to read from the array.
80       */
81      public void characters(final char[] ch, final int start, final int length) {
82          if (!this.stack.empty()) {
83              ((AbstractJEuclidElement) this.stack.peek()).addText(new String(
84                      ch, start, length));
85          }
86      }
87  
88      /**
89       * Receive notification of the end of a document.
90       */
91      public void endDocument() {
92          this.rootElement.fireChangeForSubTree();
93      }
94  
95      /**
96       * Receive notification of the end of an element.
97       * 
98       * @param namespaceURI
99       *            The Namespace URI, or the empty string if the element has no
100      *            Namespace URI or if Namespace processing is not being
101      *            performed.
102      * @param localName
103      *            The local name (without prefix), or the empty string if
104      *            Namespace processing is not being performed.
105      * @param qName
106      *            The qualified XML 1.0 name (with prefix), or the empty
107      *            string if qualified names are not available.
108      */
109     public void endElement(final String namespaceURI, final String localName,
110             final String qName) {
111         if (!this.stack.empty()) {
112             this.stack.pop();
113 
114         }
115     }
116 
117     /**
118      * Receive notification of the beginning of a document.
119      */
120     public void startDocument() {
121         this.rootElement = null;
122         this.stack.clear();
123         this.rootElement = new DocumentElement(this.mbase);
124         this.mbase.setRootElement(this.rootElement);
125         this.stack.push(this.rootElement);
126     }
127 
128     /**
129      * Receive notification of the beginning of an element.
130      * 
131      * @param namespaceURI
132      *            The Namespace URI, or the empty string if the element has no
133      *            Namespace URI or if Namespace processing is not being
134      *            performed.
135      * @param localName
136      *            The local name (without prefix), or the empty string if
137      *            Namespace processing is not being performed.
138      * @param qName
139      *            The qualified name (with prefix), or the empty string if
140      *            qualified names are not available.
141      * @param attributes
142      *            The attributes attached to the element. If there are no
143      *            attributes, it shall be an empty Attributes object.
144      */
145     public void startElement(final String namespaceURI,
146             final String localName, final String qName,
147             final Attributes attributes) {
148         if (this.stack.empty()) {
149             return;
150         }
151 
152         final AttributeMap aMap = new SAXAttributeMap(attributes);
153         final MathMLElement element = JEuclidElementFactory.elementFromName(
154                 localName, aMap, this.mbase);
155 
156         if (!this.stack.empty()) {
157             this.stack.peek().appendChild(element);
158         }
159 
160         this.stack.push(element);
161     }
162 
163     /**
164      * End the scope of a prefix-URI mapping.
165      * 
166      * @param prefix
167      *            Prefix
168      */
169     public void endPrefixMapping(final String prefix) {
170     }
171 
172     /**
173      * Receive notification of ignorable whitespace in element content.
174      * 
175      * @param ch
176      *            Space char
177      * @param start
178      *            Start position
179      * @param length
180      *            Length
181      */
182     public void ignorableWhitespace(final char[] ch, final int start,
183             final int length) {
184     }
185 
186     /**
187      * Receive notification of a processing instruction.
188      * 
189      * @param target
190      *            Target
191      * @param data
192      *            Data
193      */
194     public void processingInstruction(final String target, final String data) {
195     }
196 
197     /**
198      * Receive an object for locating the origin of SAX document events.
199      * 
200      * @param locator
201      *            Locator
202      */
203     public void setDocumentLocator(final Locator locator) {
204     }
205 
206     /**
207      * Receive notification of a skipped entity.
208      * 
209      * @param name
210      *            Entity name
211      */
212     public void skippedEntity(final String name) {
213     }
214 
215     /**
216      * Begin the scope of a prefix-URI Namespace mapping.
217      * 
218      * @param prefix
219      *            Prefix
220      * @param uri
221      *            Uri
222      */
223     public void startPrefixMapping(final String prefix, final String uri) {
224     }
225 
226 }