package com.hammurapi.convert;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.transform.OutputKeys;
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 org.w3c.dom.Node;

import com.hammurapi.common.Pumper;

/**
 * Intuitive conversions.
 * @author Pavel
 *
 */
public class ReflectiveAtomicConvertersBundle extends AbstractReflectiveAtomicConvertersBundle {

	@ConverterMethod
	public InputStream byteArrayToInputStream(byte[] ba) {
		return new ByteArrayInputStream(ba);
	}
	
	@ConverterMethod
	public byte[] inputStreamToByteArray(InputStream in) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Pumper.pump(in, baos, true);
		return baos.toByteArray();
	}
	
	@ConverterMethod
	public byte[] fileToByteArray(File in) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Pumper.pump(new FileInputStream(in), baos, true);
		return baos.toByteArray();
	}
	
	@ConverterMethod
	public Document parseXml(InputStream in) throws Exception {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = dbf.newDocumentBuilder();
		return builder.parse(in);
	}
	
	@ConverterMethod
	public Document parseXml(File in) throws Exception {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = dbf.newDocumentBuilder();
		return builder.parse(in);
	}
	
	@ConverterMethod
	public Document parseXml(byte[] in) throws Exception {
		return parseXml(new ByteArrayInputStream(in));
	}
	
	
	@ConverterMethod
	public Document parseXml(String str) throws Exception {
		return parseXml(str.getBytes());
	}
	
	@ConverterMethod
	public String serialize(Node node) throws Exception {
		DOMSource src = new DOMSource(node);
		StringWriter sw = new StringWriter();
		StreamResult result = new StreamResult(sw);
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer serializer = tf.newTransformer();
		serializer.setOutputProperty(OutputKeys.INDENT,"yes");
		serializer.transform(src, result);
		sw.close();
		return sw.toString();
	}
	
	@ConverterMethod
	public XMLEventReader inputStreamToXmlEventReader(InputStream in) throws Exception {
		XMLInputFactory xif = XMLInputFactory.newInstance();
		return xif.createXMLEventReader(in);
	}

	@ConverterMethod
	public XMLEventReader readerToXmlEventReader(Reader in) throws Exception {
		XMLInputFactory xif = XMLInputFactory.newInstance();
		return xif.createXMLEventReader(in);
	}
	
	@ConverterMethod
	public XMLEventReader byteArrayToXmlEventReader(byte[] in) throws Exception {
		XMLInputFactory xif = XMLInputFactory.newInstance();
		return xif.createXMLEventReader(new ByteArrayInputStream(in));
	}
		
	@ConverterMethod
	public XMLEventReader fileToXmlEventReader(File in) throws Exception {
		XMLInputFactory xif = XMLInputFactory.newInstance();
		return xif.createXMLEventReader(new FileInputStream(in));
	}
	
	@ConverterMethod
	public XMLEventReader stringToXmlEventReader(String in) throws Exception {
		XMLInputFactory xif = XMLInputFactory.newInstance();
		return xif.createXMLEventReader(new StringReader(in));
	}
	
}
