/* $Id: GsXMLSaver.java 715 2013-07-22 03:02:33Z ohura $ */
package smart_gs.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

import smart_gs.dictionary.DictionaryXML;

public class GsXMLSaver {
	private Document document;
	private String filename;

	public GsXMLSaver(Document document, String filename) {
		this.document = document;
		this.filename = filename;
	}

	public synchronized void save() {
		TransformerFactory factory = TransformerFactory.newInstance();
		try {
			Transformer transformer = factory.newTransformer();
			transformer.setOutputProperty("encoding", "UTF-8");
			transformer.setOutputProperty("standalone", "yes");
			transformer.setOutputProperty("indent", "yes");

			DOMSource source = new DOMSource(document);
			File file = new File(filename);

			/*
			 * @memo StreamResultにfileを渡した場合、segfo2dsc.exeの実行に失敗する。
			 * おそらく、ファイルがロックされたままになっているのだろう。
			 * この問題に対処する為、Writerを引数として渡し、close()を呼び出している。 こうするとうまくいく。
			 */
			
			// 2007/11/30 kazuhiro kobayashi
			//DOCTYPE宣言を行う。
			//ただ、gsファイル以外のxmlファイルにも書き込んでしまう。
			StringWriter output = new StringWriter();
			transformer.transform(source, new StreamResult(output));
			String string = output.toString();
			int p = string.indexOf("?>") + 2;
			String former = string.substring(0, p);
			String latter = string.substring(p + 1);
//			shayashi 2011.05.26
			String newstring = former + "\n<!DOCTYPE rootElement>" + latter;

			if(file.getName().endsWith(".gs")) { // old .gs file
				OutputStreamWriter writer = new OutputStreamWriter(
						new FileOutputStream(file), "UTF-8");
				writer.write(newstring);
				writer.close();
			} else {
				ZipOutputStream writer = new ZipOutputStream(new FileOutputStream(file));
				writer.putNextEntry(new ZipEntry("spread.xml"));
				writer.write(newstring.getBytes("UTF-8"));
				writer.closeEntry();

				writer.putNextEntry(new ZipEntry("dictionary/default.xml"));
				writer.write(DictionaryXML.getInstance().getDictionaryString().getBytes("UTF-8"));
				writer.close();
			}
			transformer = null;
			file = null;
			source = null;
		} catch (TransformerConfigurationException e1) {
			e1.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		factory = null;
	}
}
