content: package ro.isdc.wro.extensions.support.lint;
  
  import static org.apache.commons.lang3.Validate.notNull;
  
  import java.io.OutputStream;
  
  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.ParserConfigurationException;
  import javax.xml.transform.Transformer;
  import javax.xml.transform.TransformerFactory;
  import javax.xml.transform.dom.DOMSource;
  import javax.xml.transform.stream.StreamResult;
  
  import org.w3c.dom.Document;
  
  import ro.isdc.wro.WroRuntimeException;
  import ro.isdc.wro.extensions.processor.support.linter.LinterError;
  
  
  /**
   * Builds an XML report for lint errors based on provided collection of {@link LinterError}'s.
   * 
   * @author Alex Objelean
   * @since 1.5.0
   * @created 15 Sep 2012
   */
  public abstract class AbstractReportXmlFormatter<T> {
    private Document doc;
    private LintReport<T> lintReport;
    /**
     * @param lintReport
     *          a not null collection of {@link LinterError} used to build an XML report from.
     */
    protected AbstractReportXmlFormatter(final LintReport<T> lintReport) {
      notNull(lintReport);
      this.lintReport = lintReport;
      initDocument();
    }
    
    private void initDocument() {
      try {
        final DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        final DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        this.doc = docBuilder.newDocument();
      } catch (ParserConfigurationException e) {
        throw new WroRuntimeException("Unexpected problem while XML Document", e);
      }
    }
    
    /**
     * @param outputStream
     *          the {@link OutputStream} where the xml representation of the report is written.
     */
    public final void write(final OutputStream outputStream) {
      buildDocument();
      writeReport(outputStream);
    }
  
    /**
     * Populates document with required DOM elements.
     */
    protected abstract void buildDocument();
    
    /**
     * @return {@link LintReport} used to build the xml lint report from.
     */
    protected final LintReport<T> getLintReport() {
      return this.lintReport;
    }
    
    /**
     * @return the {@link Document} used to build xml report.
     */
    protected final Document getDocument() {
      return doc;
    }
  
    /**
     * write the content to the {@link OutputStream}
     */
    private void writeReport(final OutputStream outputStream) {
      Transformer transformer;
      try {
        transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(new DOMSource(doc), new StreamResult(outputStream));
      } catch (Exception e) {
        throw WroRuntimeException.wrap(e, "Problem during Document transformation").logError();
      }
    }
  }
  