001/*
002Copyright (c) 2011+, HL7, Inc
003All rights reserved.
004
005Redistribution and use in source and binary forms, with or without modification, 
006are permitted provided that the following conditions are met:
007
008 * Redistributions of source code must retain the above copyright notice, this 
009   list of conditions and the following disclaimer.
010 * Redistributions in binary form must reproduce the above copyright notice, 
011   this list of conditions and the following disclaimer in the documentation 
012   and/or other materials provided with the distribution.
013 * Neither the name of HL7 nor the names of its contributors may be used to 
014   endorse or promote products derived from this software without specific 
015   prior written permission.
016
017THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
018ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
019WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
020IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
021INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
022NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
023PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
024WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
025ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
026POSSIBILITY OF SUCH DAMAGE.
027
028*/
029package org.hl7.fhir.utilities.xml;
030
031import java.io.ByteArrayOutputStream;
032import java.io.File;
033import java.io.FileOutputStream;
034import java.io.IOException;
035import java.io.OutputStream;
036
037import org.hl7.fhir.exceptions.FHIRException;
038import org.w3c.dom.Comment;
039import org.w3c.dom.DOMException;
040import org.w3c.dom.Element;
041import org.w3c.dom.NamedNodeMap;
042import org.w3c.dom.Node;
043
044public class XmlGenerator {
045
046
047        private XMLWriter xml;
048        
049        public void generate(Element element, File file, String defaultNamespace, String elementName) throws FHIRException, IOException  {
050                
051                OutputStream stream = new FileOutputStream(file);
052                
053                
054                xml = new XMLWriter(stream, "UTF-8");
055                xml.start();
056                xml.setDefaultNamespace(defaultNamespace);
057
058                xml.enter(defaultNamespace, elementName);
059                processContents(element);
060                xml.exit();
061                xml.end();
062                xml.flush();
063                stream.close();
064        }
065        
066  public String generate(Element element) throws IOException, FHIRException  {
067    ByteArrayOutputStream stream = new ByteArrayOutputStream();
068    generate(element, stream);
069    return new String(stream.toByteArray());
070  } 
071  
072        public void generate(Element element, File file) throws IOException, FHIRException  {
073                OutputStream stream = new FileOutputStream(file);
074                generate(element, stream);
075        }       
076        
077        public void generate(Element element, OutputStream stream) throws IOException, FHIRException  {
078                xml = new XMLWriter(stream, "UTF-8");
079                xml.start();
080                xml.setDefaultNamespace(element.getNamespaceURI());
081                processElement(element);
082                xml.end();
083        }
084        
085        private void processContents(Element element) throws FHIRException, IOException  {
086                Node node = element.getFirstChild();
087                while (node != null) {
088                        switch (node.getNodeType()) {
089                        case Node.ELEMENT_NODE:
090                                processElement((Element) node);
091                                break;
092                        case Node.TEXT_NODE:
093                                processText(node);
094                                break;
095                        case Node.COMMENT_NODE:
096                                processComment((Comment) node);
097                                break;
098                        default:
099                                throw new FHIRException("unhandled node type "+Integer.toString(node.getNodeType()));
100                        }
101                                
102                    node = node.getNextSibling();
103                }
104        }
105        
106        private void processComment(Comment node) throws DOMException, IOException  {
107                xml.comment(node.getNodeValue(), true);
108        }
109
110        private void processElement(Element element) throws IOException, FHIRException  {
111                if (!xml.getDefaultNamespace().equals(element.getNamespaceURI()))
112                        xml.setDefaultNamespace(element.getNamespaceURI());
113
114                processAttributes(element);
115                xml.enter(element.getNamespaceURI(), element.getLocalName());
116        
117                processContents(element);
118                
119                xml.exit();
120        }
121
122        private void processText(Node node) throws DOMException, IOException  {
123                xml.text(node.getNodeValue());
124        }
125
126        private void processAttributes(Element element) throws DOMException, IOException  {
127                NamedNodeMap nodes = element.getAttributes();
128                for (int i = 0; i < nodes.getLength(); i++) {
129                        Node attr = nodes.item(i);
130                        if (attr.getNamespaceURI() != null) {
131                                //xml.namespace(attr.getNamespaceURI());
132                        //xml.attribute(attr.getNamespaceURI(), attr.getLocalName(), attr.getNodeValue());
133                        } else if (attr.getLocalName() != null)
134//        xml.attribute("xmlns", attr.getNodeValue());
135//                      else
136                        xml.attribute(attr.getLocalName(), attr.getNodeValue());
137                        else if (attr.getNodeName() != null && !"xmlns".equals(attr.getNodeName()))
138        xml.attribute(attr.getNodeName(), attr.getNodeValue());
139                }
140                
141        }
142
143
144}