View Javadoc

1   /*
2    * File: SAXDOMHandler.java
3    * Created: 15-dub-06 9:48:01 
4    *
5    * Copyright 2006 Michal Burda.
6    *
7    * This program is free software; you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation; either version 2 of the License, or
10   * (at your option) any later version.
11   *
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with this program; if not, write to the Free Software
19   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20   */
21  package net.sf.webmancer.util.xml.sax;
22  
23  import net.sf.webmancer.util.ContractChecker;
24  import net.sf.webmancer.util.xml.dom.DOMSemanticException;
25  import net.sf.webmancer.util.xml.dom.IDOMProcessor;
26  
27  import org.w3c.dom.Document;
28  import org.w3c.dom.Element;
29  import org.w3c.dom.Node;
30  import org.w3c.dom.Text;
31  import org.xml.sax.Attributes;
32  import org.xml.sax.SAXException;
33  
34  /**
35   * @author Michal Burda
36   */
37  public class SAXDOMHandler extends DefaultHandler {
38      private IDOMProcessor processor;
39  
40      private Document document;
41  
42      private Node current;
43  
44      /**
45       * @param documentToBeCreated
46       */
47      public SAXDOMHandler(final IDOMProcessor processor) {
48          super();
49          ContractChecker.mustNotBeNull(processor, "processor");
50          ContractChecker.mustNotBeNull(processor.getDOMImplementation(), "processor.getDOMImplementation()");
51          this.processor = processor;
52          this.document = null;
53          this.current = null;
54      }
55  
56      /**
57       * @see cz.vsb.cs.ruleminer.util.xml.sax.DefaultHandler#characters(char[], int, int)
58       */
59      @Override
60      @SuppressWarnings("unused")
61      public void characters(final char[] ch, final int start, final int length) throws SAXException {
62          assert this.processor != null;
63          ContractChecker
64                  .checkState(this.document != null && this.current != null, "Element expected but text was found");
65          Text text = createText(ch, start, length);
66          this.current.appendChild(text);
67          text.setUserData("locator", this.locator, null);
68      }
69  
70      /**
71       * @see cz.vsb.cs.ruleminer.util.xml.sax.DefaultHandler#startElement(java.lang.String, java.lang.String,
72       *      java.lang.String, org.xml.sax.Attributes)
73       */
74      @Override
75      @SuppressWarnings("unused")
76      public void startElement(final String uri, final String localName, final String qName, final Attributes atts) throws SAXException {
77          assert this.processor != null;
78          if (this.document == null) {
79              assert this.current == null;
80              this.document = this.processor.getDOMImplementation().createDocument(uri, qName, null);
81              this.current = this.document.getDocumentElement();
82          } else {
83              assert this.current != null;
84              Element element = createElement(uri, localName, qName);
85              assert element != null;
86              this.current.appendChild(element);
87              this.current = element;
88          }
89          assert this.current instanceof Element;
90          setElementAttributes((Element) this.current, atts);
91          this.current.setUserData("locator", this.locator, null);
92      }
93  
94      /**
95       * @see cz.vsb.cs.ruleminer.util.xml.sax.DefaultHandler#endElement(java.lang.String, java.lang.String,
96       *      java.lang.String)
97       */
98      @Override
99      @SuppressWarnings("unused")
100     public void endElement(final String uri, final String localName, final String qName) throws SAXException {
101         assert this.processor != null;
102         ContractChecker.checkState(this.document != null && this.current != this.document, "Unexpected end of element");
103         assert this.current != null;
104         this.current = this.current.getParentNode();
105         if (this.current == this.document) {
106             try {
107                 this.processor.process(this.document);
108             } catch (DOMSemanticException e) {
109                 throw new SAXSemanticException("", null, e);
110             } finally {
111                 this.document = null;
112                 this.current = null;
113             }
114         }
115     }
116 
117     /**
118      * @param uri
119      * @param localName
120      * @param qName
121      * @return
122      */
123     protected Element createElement(final String uri, final String localName, final String qName) {
124         return this.document.createElementNS(uri, qName);
125     }
126 
127     /**
128      * @param element
129      * @param atts
130      */
131     protected void setElementAttributes(final Element element, final Attributes atts) {
132         for (int i = 0; i < atts.getLength(); i++) {
133             element.setAttributeNS(atts.getURI(i), atts.getQName(i), atts.getValue(i));
134         }
135     }
136 
137     /**
138      * @param ch
139      * @param start
140      * @param length
141      * @return
142      */
143     protected Text createText(final char[] ch, final int start, final int length) {
144         return this.document.createTextNode(new String(ch, start, length));
145     }
146 }