/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package woolpack.xml;

import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Node;

import woolpack.factory.FactoryUtils;
import woolpack.fn.Fn;
import woolpack.misc.MiscUtils;

/**
 * XMLを変換するユーティリティです。
 * 
 * @author nakamura
 *
 */
public final class XmlTransformerUtils {
	/**
	 * 恒等変換のデフォルト値です。複数のスレッドで同時に使用することができます。
	 */
	public static final Fn<XmlTransformerContext, Void, TransformerException> TRANSFORMER;
	
	static {
		Fn<XmlTransformerContext, Void, TransformerException> transformer = null;
		Exception exception = null;
		try {
			transformer = MiscUtils.loadBalancer(FactoryUtils.newInstance(XmlTransformer.class), 5);
		} catch (final Exception e) {
			exception = e;
		}
		TRANSFORMER = transformer;
		if (exception != null) {
			throw new IllegalStateException(exception);
		}
	}

	private XmlTransformerUtils() {
	}

	/**
	 * XMLの文字列表現をDOM表現に変換します。
	 * @param s 変換対象。
	 * @return 変換結果。
	 * @throws TransformerException 
	 */
	public static Node convert(final String s) throws TransformerException {
		final DOMResult result = new DOMResult();
		final XmlTransformerContext context = new XmlTransformerContext();
		context.setSource(new StreamSource(new StringReader(s)));
		context.setResult(result);
		TRANSFORMER.exec(context);
		return result.getNode();
	}

	/**
	 * XMLのDOM表現を文字列表現に変換します。
	 * @param node 変換対象。
	 * @return 変換結果。
	 * @throws TransformerException 
	 */
	public static String convert(final Node node) throws TransformerException {
		final Writer w = new StringWriter();
		final XmlTransformerContext context = new XmlTransformerContext();
		context.setSource(new DOMSource(node));
		context.setResult(new StreamResult(w));
		TRANSFORMER.exec(context);
		return w.toString();
	}
	
}
