
package qms.util;
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import org.xml.sax.*;
/**
 * Utilità per lettura/scrittura DOM XML
 * @author  Enrico
 */
public class DOMUtils implements ErrorHandler {
    
    public static Document newDocument() {
        try {
            DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = fact.newDocumentBuilder();            
            Document doc = builder.newDocument();            
            return doc;
        } catch (Exception e) {
            throw new IllegalStateException("Configurazione XML non corretta:"+e);
        }
    }
    public static Document parseStream(InputStream in) throws IOException {
        try {
            DocumentBuilderFactory fact = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = fact.newDocumentBuilder();
            builder.setErrorHandler( new DOMUtils());
            return builder.parse(in);
        } catch (ParserConfigurationException pe) {
            throw new IllegalStateException("Libreria XML configurata male:"+pe);
        } catch (SAXException pe) {
            throw new IOException("Errore durante la lettura del documento XML:"+pe);
        }
    }
    public static void serialize(Document doc, OutputStream out) throws IOException {
        try {
            Transformer trans = TransformerFactory.newInstance().newTransformer();
            if (doc == null) throw new IOException("Documento DOM XML nullo");
            DOMSource ds = new DOMSource(doc);
            StreamResult sr = new StreamResult(out);
            trans.transform( ds,  sr);
        } catch (TransformerFactoryConfigurationError e) {
            throw new IllegalStateException("Libreria XML configurata male:"+e);
        } catch (TransformerConfigurationException e) {
            throw new IllegalStateException("Libreria XML configurata male:"+e);
        } catch (TransformerException e) {
            throw new IllegalStateException("Errore durante la scrittura del documento XML:"+e);
        }
    }   
    public static String asString(Document doc) {
        try {
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            serialize(doc,out);
            return new String( out.toByteArray());
        } catch (Throwable t) {
            return "Error while converting DOM to string "+t;
        }
    }
    /**
     * Copia un intero sotto albero DON 
     * @param parent_owner radice del Nuovo Documento (se null significa che deve essere creato addirittura il nodo radice)
     * @param parent radice del documento originale
     */
    public static void copyTree(Document parent_owner,Element parent, Element external_element_root) throws DOMException {        
        //System.out.println("Coping element "+external_element_root);
        
        String ns = external_element_root.getNamespaceURI();
        Element copy = null;
        if (ns != null) copy = parent_owner.createElementNS(ns, external_element_root.getTagName());
                   else copy= parent_owner.createElement(external_element_root.getTagName());
        NamedNodeMap nnm = external_element_root.getAttributes();
        for (int i = 0; i < nnm.getLength(); i++) {
            Attr a = (Attr) nnm.item(i);
            copy.setAttribute(a.getNodeName(), a.getNodeValue());
        }
        if (parent == null) {
                parent = copy;
                parent_owner.appendChild(parent);
        }
        else {
               parent.appendChild(copy);
           }
        NodeList childs  =external_element_root.getChildNodes();
        for (int i = 0; i < childs.getLength(); i++) {            
            Node n = childs.item(i);
            //System.out.println("Child #"+i+":"+n);
            if (n instanceof Element) {
                copyTree(parent_owner,copy,(Element) n);                
            } else {
                if (n instanceof Text) {
                    copy.appendChild( parent_owner.createTextNode(n.getNodeValue()));
                } else {
                    /*System.out.println("****************************************");
                    System.out.println("Discarding NODE "+n);
                    System.out.println("****************************************");*/
                }
            }
        }
    }
    
    public void error(SAXParseException exception) throws SAXException {
        System.out.println("SAX Exception:"+exception);
    }
    
    public void fatalError(SAXParseException exception) throws SAXException {
        System.out.println("SAX Error :"+exception);
    }
    
    public void warning(SAXParseException exception) throws SAXException {
        System.out.println("SAX Warning:"+exception);
    }
    
}
