/*
 * @(#)ResourceUtils.java
 *
 * Copyright (C) 2005 Infocity Inc. All Rights Reserved.
 */
package info.dragonlady.sso.util;

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * リソースアクセスユーティリティクラス
 * 
 * @author Hiroshi.Ebata(INFOCITY)
 * @version $Revision: 1.1 $ $Date: 2005/11/11 14:08:42 $
 */
public class ResourceUtils {

	/**
	 * XMLリソースからXPath式で指定した文字列を取得
	 * 
	 * @param resourcePath XMLリソースのパス
	 * @param expression XPath式
	 * @return String 該当文字列
	 * @throws ResourceParseException
	 */
	public static final String getString(String resourcePath, String expression) throws ResourceParseException {
		try {
			return (String)ResourceUtils.evaluate(resourcePath, expression, XPathConstants.STRING);
		} catch(ResourceParseException e) {
			throw e;
		} catch(Exception e) {
			throw new ResourceParseException(e);
		}
	}

	/**
	 * XMLリソースからXPath式で指定したノードリストを取得
	 * 
	 * @param resourcePath XMLリソースのパス
	 * @param expression XPath式
	 * @return String 該当ノードリスト
	 * @throws ResourceParseException
	 */
	public static final NodeList getNodeSet(String resourcePath, String expression) throws ResourceParseException {
		try {
			return (NodeList)ResourceUtils.evaluate(resourcePath, expression, XPathConstants.NODESET);
		} catch(ResourceParseException e) {
			throw e;
		} catch(Exception e) {
			throw new ResourceParseException(e);
		}
	}

	/**
	 * XMLリソースからXPath式とQNameで指定したオブジェクトを取得
	 * 
	 * @param resourcePath XMLリソースのパス
	 * @param expression XPath式
	 * @param returnType 目的の戻り値の型
	 * @return Object 該当オブジェクト
	 * @throws ResourceParseException
	 */
	public static final Object evaluate(String resourcePath, String expression, QName returnType) throws ResourceParseException {
		try {
			URL url = ResourceUtils.class.getClassLoader().getResource(resourcePath);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document dom = db.parse(url.openStream());
			XPathFactory factory = XPathFactory.newInstance();
			XPath xpath = factory.newXPath();
			return xpath.evaluate(expression, dom, returnType);
		} catch(Exception e) {
			throw new ResourceParseException(e);
		}
	}

	/**
	 * バイト配列をBase64でエンコードした文字列に変換
	 * 
	 * @param src バイト配列
	 * @return Base64でエンコードされた文字列
	 */
	public static final String toBase64String(byte[] src) {
		return new String(Base64.encodeBase64(src));
	}

	/**
	 * バイト配列を16進数で表した文字列に変換
	 * 
	 * @param src バイト配列
	 * @return 16進数で表された文字列
	 */
	public static final String toHexString(byte[] src) {
		return new String(Hex.encodeHex(src));
	}

	/**
	 * Base64でエンコードされた文字列をバイト配列に変換
	 * 
	 * @param src Base64でエンコードされた文字列
	 * @return byte[] バイト配列
	 */
	public static final byte[] toBase64ByteArray(String src) {
		return Base64.decodeBase64(src.getBytes());
	}

	/**
	 * 16進表現文字列をバイト配列に変換
	 * 
	 * @param src 16進表現文字列
	 * @return byte[] バイト配列
	 * @throws DecoderException 
	 */
	public static final byte[] toHexByteArray(String src) throws DecoderException {
		return Hex.decodeHex(src.toCharArray());
	}

	/**
	 * XMLノードからテキストを取得。
	 * 
	 * @param node ノード
	 * @return String テキスト
	 */
	public static final String getTextContent(Node node) {
		String content = null;
		NodeList list = node.getChildNodes();
		for(int i = 0; i < list.getLength(); i++) {
			Node child = (Node)list.item(i);
			if(child.getNodeType() == Node.TEXT_NODE) {
				content = ((Text)child).getData();
				break;
			}
		}
		return content;
	}

}
