package org.phosphoresce.commons.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;

/**
 * オブジェクトに対する操作を行うメソッドを提供するクラス<br>
 *
 * @author Kitagawa<br>
 *
 *<!--
 * 更新日		更新者			更新内容
 * 2005/07/02	Kitagawa		新規作成
 * 2007/09/24	Kitagawa		オブジェクトファイル入出力メソッド追加
 * 2009/05/13	Kitagawa		equalsメソッド追加
 *-->
 */
public final class ObjectUtil {

	/**
	 * コンストラクタ<br>
	 */
	private ObjectUtil() {
		//
	}

	/**
	 * 指定されたオブジェクト同士が同一であるか判定します。<br>
	 * オブジェクトが両者ともnullの場合も同一として判定します。<br>
	 * @param object1 比較対象オブジェクト
	 * @param object2 比較対象オブジェクト
	 * @return 同一のオブジェクトの場合にtrueを返却
	 */
	public static boolean equals(Object object1, Object object2) {
		if (object1 == null || object2 == null) {
			return true;
		} else if (object1 != null) {
			return object1.equals(object2);
		} else {
			return object2.equals(object1);
		}
	}

	/**
	 * シリアライズインタフェースを実装されているオブジェクトのディープコピーを行います。<br>
	 * @param object ディープコピー対象オブジェクト
	 * @return ディープコピーされたオブジェクト
	 * @throws IOException 正常にディープコピーが行えなかった場合に発生します
	 * @throws ClassNotFoundException シリアライズ化されたバイト配列からオブジェクトに復帰できなかった場合に発生します
	 */
	public static Serializable deepCopy(Serializable object) throws IOException, ClassNotFoundException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);

		oos.writeObject(object);
		oos.flush();

		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);

		Serializable copyedObject = (Serializable) ois.readObject();

		oos.close();
		ois.close();

		return copyedObject;
	}

	/**
	 * 指定されたSerializableオブジェクトをOutputStreamオブジェクトに出力します。<br>
	 * @param object Serializableオブジェクト
	 * @param stream OutputStreamオブジェクト
	 * @throws IOException 正常に出力が行えなかった場合に発生
	 */
	public static void saveSerializableObject(Serializable object, OutputStream stream) throws IOException {
		ObjectOutputStream oos = new ObjectOutputStream(stream);
		oos.writeObject(object);
		oos.flush();
		oos.close();
	}

	/**
	 * 指定されたSerializableオブジェクトをFileオブジェクトに出力します。<br>
	 * @param object Serializableオブジェクト
	 * @param file Fileオブジェクト
	 * @throws IOException 正常に出力が行えなかった場合に発生
	 */
	public static void saveSerializableObject(Serializable object, File file) throws IOException {
		FileOutputStream stream = new FileOutputStream(file);
		saveSerializableObject(object, stream);
		stream.close();
	}

	/**
	 * 指定されたSerializableオブジェクトをファイルに出力します。<br>
	 * @param object Serializableオブジェクト
	 * @param filename ファイル名
	 * @throws IOException 正常に出力が行えなかった場合に発生
	 */
	public static void saveSerializableObject(Serializable object, String filename) throws IOException {
		saveSerializableObject(object, new File(filename));
	}

	/**
	 * 指定されたInputStreamオブジェクトからオブジェクトを読み込みます。<br>
	 * @param stream InputStreamオブジェクト
	 * @return 読み込んだオブジェクト
	 * @throws IOException 正常に読み込めなかった場合に発生
	 * @throws ClassNotFoundException 読み込んだオブジェクトのクラスが見つからなかった場合に発生
	 */
	public static Object loadSerializableObject(InputStream stream) throws IOException, ClassNotFoundException {
		ObjectInputStream ois = new ObjectInputStream(stream);
		Object object = ois.readObject();
		ois.close();
		return object;
	}

	/**
	 * 指定されたFileオブジェクトからオブジェクトを読み込みます。<br>
	 * @param file Fileオブジェクト
	 * @return 読み込んだオブジェクト
	 * @throws IOException 正常に読み込めなかった場合に発生
	 * @throws ClassNotFoundException 読み込んだオブジェクトのクラスが見つからなかった場合に発生
	 */
	public static Object loadSerializableObject(File file) throws IOException, ClassNotFoundException {
		FileInputStream stream = new FileInputStream(file);
		Object object = loadSerializableObject(stream);
		stream.close();
		return object;
	}

	/**
	 * 指定されたファイルからオブジェクトを読み込みます。<br>
	 * @param filename ファイル名
	 * @return 読み込んだオブジェクト
	 * @throws IOException 正常に読み込めなかった場合に発生
	 * @throws ClassNotFoundException 読み込んだオブジェクトのクラスが見つからなかった場合に発生
	 */
	public static Object loadSerializableObject(String filename) throws IOException, ClassNotFoundException {
		return loadSerializableObject(new File(filename));
	}
}
