001    /*
002     $Id: SAXBuilder.java,v 1.4 2004/04/27 02:25:29 spullara Exp $
003    
004     Copyright 2003 (C) James Strachan and Bob Mcwhirter. All Rights Reserved.
005    
006     Redistribution and use of this software and associated documentation
007     ("Software"), with or without modification, are permitted provided
008     that the following conditions are met:
009    
010     1. Redistributions of source code must retain copyright
011        statements and notices.  Redistributions must also contain a
012        copy of this document.
013    
014     2. Redistributions in binary form must reproduce the
015        above copyright notice, this list of conditions and the
016        following disclaimer in the documentation and/or other
017        materials provided with the distribution.
018    
019     3. The name "groovy" must not be used to endorse or promote
020        products derived from this Software without prior written
021        permission of The Codehaus.  For written permission,
022        please contact info@codehaus.org.
023    
024     4. Products derived from this Software may not be called "groovy"
025        nor may "groovy" appear in their names without prior written
026        permission of The Codehaus. "groovy" is a registered
027        trademark of The Codehaus.
028    
029     5. Due credit should be given to The Codehaus -
030        http://groovy.codehaus.org/
031    
032     THIS SOFTWARE IS PROVIDED BY THE CODEHAUS AND CONTRIBUTORS
033     ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
034     NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
035     FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
036     THE CODEHAUS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
037     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
038     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
039     SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
040     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
041     STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
042     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
043     OF THE POSSIBILITY OF SUCH DAMAGE.
044    
045     */
046    package groovy.xml;
047    
048    import groovy.util.BuilderSupport;
049    
050    import java.util.Iterator;
051    import java.util.Map;
052    
053    import org.xml.sax.Attributes;
054    import org.xml.sax.ContentHandler;
055    import org.xml.sax.SAXException;
056    import org.xml.sax.helpers.AttributesImpl;
057    
058    /**
059     * A helper class for creating a W3C D
060     * 
061     * @author <a href="mailto:james@coredevelopers.net">James Strachan</a>
062     * @version $Revision: 1.4 $
063     */
064    public class SAXBuilder extends BuilderSupport {
065    
066        private ContentHandler handler;
067        private Attributes emptyAttributes = new AttributesImpl();
068    
069        public SAXBuilder(ContentHandler handler) {
070            this.handler = handler;
071        }
072    
073        protected void setParent(Object parent, Object child) {
074        }
075    
076        protected Object createNode(Object name) {
077            doStartElement(name, emptyAttributes);
078            return name;
079        }
080    
081        protected Object createNode(Object name, Object value) {
082            doStartElement(name, emptyAttributes);
083            doText(value);
084            return name;
085        }
086    
087        /**
088         * @param value
089         */
090        private void doText(Object value) {
091            try {
092                char[] text = value.toString().toCharArray();
093                handler.characters(text, 0, text.length);
094            }
095            catch (SAXException e) {
096                handleException(e);
097            }
098        }
099    
100        protected Object createNode(Object name, Map attributeMap, Object text) {
101            AttributesImpl attributes = new AttributesImpl();
102            for (Iterator iter = attributeMap.entrySet().iterator(); iter.hasNext();) {
103                Map.Entry entry = (Map.Entry) iter.next();
104                Object key = entry.getKey();
105                Object value = entry.getValue();
106                String uri = "";
107                String localName = null;
108                String qualifiedName = "";
109                String valueText = (value != null) ? value.toString() : "";
110                if (key instanceof QName) {
111                    QName qname = (QName) key;
112                    uri = qname.getNamespaceURI();
113                    localName = qname.getLocalPart();
114                    qualifiedName = qname.getQualifiedName();
115                }
116                else {
117                    localName = key.toString();
118                    qualifiedName = localName;
119                }
120    
121                attributes.addAttribute(uri, localName, qualifiedName, "CDATA", valueText);
122            }
123            doStartElement(name, attributes);
124            if (text != null) {
125                doText(text);
126            }
127            return name;
128        }
129    
130        protected void doStartElement(Object name, Attributes attributes) {
131            String uri = "";
132            String localName = null;
133            String qualifiedName = "";
134            if (name instanceof QName) {
135                QName qname = (QName) name;
136                uri = qname.getNamespaceURI();
137                localName = qname.getLocalPart();
138                qualifiedName = qname.getQualifiedName();
139            }
140            else {
141                localName = name.toString();
142                qualifiedName = localName;
143            }
144            try {
145                handler.startElement(uri, localName, qualifiedName, attributes);
146            }
147            catch (SAXException e) {
148                handleException(e);
149            }
150        }
151    
152        protected void nodeCompleted(Object parent, Object name) {
153            String uri = "";
154            String localName = null;
155            String qualifiedName = "";
156            if (name instanceof QName) {
157                QName qname = (QName) name;
158                uri = qname.getNamespaceURI();
159                localName = qname.getLocalPart();
160                qualifiedName = qname.getQualifiedName();
161            }
162            else {
163                localName = name.toString();
164                qualifiedName = localName;
165            }
166            try {
167                handler.endElement(uri, localName, qualifiedName);
168            }
169            catch (SAXException e) {
170                handleException(e);
171            }
172        }
173    
174        protected void handleException(SAXException e) {
175            throw new RuntimeException(e);
176        }
177    
178        /* (non-Javadoc)
179         * @see groovy.util.BuilderSupport#createNode(java.lang.Object, java.util.Map, java.lang.Object)
180         */
181        protected Object createNode(Object name, Map attributes) {
182            return createNode(name, attributes, null);
183        }
184    }