/* $Id: SMLParser.java 125 2011-03-09 09:49:51Z ohura $ */
/*
 * 作成日： 2004/09/20
 *
 */
package sml_editor.parser;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * @author kawamura
 *
 */
public class SMLParser {
	public static Document parse(String source) throws SAXException {
     	StringReader reader = new StringReader(source);
		InputSource in = new InputSource(reader);
		return parse(in);
	}

	public static Document parse(File file) throws SAXException, FileNotFoundException {
		FileInputStream input = new FileInputStream(file);
		InputSource in = new InputSource(input);
		return parse(in);
	}
	
	private static Document parse(InputSource in) throws SAXException{
		try {
			Document document = DocumentBuilderFactory
			.newInstance()
			.newDocumentBuilder()
			.parse(in);
			
			if(document == null) {
				return null;
			}
			
			Element root = document.getDocumentElement();
			convert(root, document);
			
			return document;
		} catch (SAXException e) {
			throw(e);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/*
	 * SMLに都合がいいようにDOMを少しいじっておく。
	 * <br>以外に空要素はなし。空要素の場合は空のTextを挿入
	 * また、Textの改行を空白に置換している (TODO 改行、空白の取り扱い)
	 */
	private static void convert(Element elem, Document doc) {
		Node child = elem.getFirstChild();

		if(child == null) {
			elem.appendChild(doc.createTextNode(""));
			return;
		}

		while(child != null) {
			switch(child.getNodeType()) {
			case Node.ELEMENT_NODE :
				if(!((Element)child).getTagName().equalsIgnoreCase("br")) {
					convert(((Element)child), doc);
				}
				break;
			case Node.TEXT_NODE :
				String str = child.getNodeValue();
				str = str.replace('\n' , ' ');
				child.setNodeValue(str);
				break;
			}
			child = child.getNextSibling();
		}
	}
}
