
package de.ivu.elect.business.datei.control;

import java.io.InputStream;
import java.io.Serializable;

import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.helpers.DefaultHandler;

import de.ivu.elect.business.datei.entity.CsvZeichensatz;
import de.ivu.elect.business.datei.entity.Datei;
import de.ivu.elect.business.exchange.control.ImportExportStreamCreator;

public class XmlEncodingDetector extends DefaultHandler implements Serializable {

  private static final long serialVersionUID = 1L;

  private static final Logger LOG = LoggerFactory.getLogger(XmlEncodingDetector.class);

  @Inject
  private ImportExportStreamCreator streamCreator;

  /**
   * @return The Enconding of the XML-File or null.
   */
  @Nullable
  public CsvZeichensatz detectEncoding(Datei entity) {

    XMLStreamReader r;
    try {
      XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory();
      // ELECT-5566
      xmlInputFactory.setProperty(XMLInputFactory.SUPPORT_DTD, false); // This disables DTDs entirely for that factory
      xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); //  disable external entities

      r = xmlInputFactory.createXMLStreamReader(createInputStream(entity));
    } catch (XMLStreamException | FactoryConfigurationError e) {
      LOG.warn(e.getMessage(), e);
      return null;
    }
    String encoding = r.getEncoding();
    return CsvZeichensatz.valueOfOrNullIgnoreCase(encoding);
  }

  private InputStream createInputStream(Datei entity) {
    return entity.createInputStream(streamCreator);
  }

}
