/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package de.christofreichardt.jaxws.securitypriceservice;

import de.christofreichardt.diagnosis.AbstractTracer;
import de.christofreichardt.diagnosis.LogLevel;
import de.christofreichardt.diagnosis.Traceable;
import de.christofreichardt.diagnosis.TracerFactory;
import java.io.OutputStream;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;

/**
 *
 * @author Developer
 */
public class XMLSerializer implements Traceable {
  private final DOMImplementationRegistry domImplRegistry;
  private final LSOutput lsOutput;
  private final LSSerializer serializer;

  public XMLSerializer() {
    this.domImplRegistry = createDOMImplRegistry();
    DOMImplementationLS domImplLS = (DOMImplementationLS) this.domImplRegistry.getDOMImplementation("LS");
    if (domImplLS == null)
      throw new RuntimeException("No Load and Save DOM implementation found.");
    this.lsOutput = domImplLS.createLSOutput();
    this.serializer = domImplLS.createLSSerializer();
//    this.serializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
  }

  private DOMImplementationRegistry createDOMImplRegistry() {
    AbstractTracer tracer = getCurrentTracer();
    tracer.entry("DOMImplementationRegistry", this, "createDOMImplRegistry()");
    
    try {
      try {
        return DOMImplementationRegistry.newInstance();
      }
      catch (ClassNotFoundException | InstantiationException | IllegalAccessException | ClassCastException | DOMException ex) {
        tracer.logException(LogLevel.ERROR, ex, getClass(), "createDOMImplRegistry()");
        throw new RuntimeException("Cannot create DOMImplRegistry.");
      }
    }
    finally {
      tracer.wayout();
    }
  }
  
  public void serialize(Node node, OutputStream outputStream) {
    AbstractTracer tracer = getCurrentTracer();
    tracer.entry("void", this, "serialize(Node node, OutputStream outputStream)");
    
    try {
      this.lsOutput.setByteStream(outputStream);
      this.serializer.write(node, this.lsOutput);
    }
    finally {
      tracer.wayout();
    }
  }

  @Override
  public AbstractTracer getCurrentTracer() {
    return TracerFactory.getInstance().getCurrentPoolTracer();
  }
  
}
