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