/*
 * $Id: OQSConnectionImpl.java,v 1.4 2005/10/18 16:22:05 rampil Exp $
 * Copyright (c) 2004 LOGICAL-PARADOX.ORG
 */
package org.logical_paradox.rss.oqs4r;

import java.io.Serializable;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * キューサーバーに接続して操作するための接続インターフェース
 * @author  satoshi akabane@logical-paradox.org
 * @version $Revision: 1.4 $
 */
public class OQSConnectionImpl extends UnicastRemoteObject implements OQSConnection {
	/** ロガー */
	private static final Log log = LogFactory.getLog(OQSConnectionImpl.class);
	/** サーバー */
	private ObjectQueueServerImpl parent;

	/**
	 * コンストラクタ
	 * 関連付けされているサーバーの参照を保持している
	 * @param parent キューサーバー
	 * @throws RemoteException インスタンスの生成に失敗した
	 */
	public OQSConnectionImpl(ObjectQueueServerImpl parent) throws RemoteException {
		this.parent = parent;
	}
	/**
	 * キューにオブジェクトを追加する
	 * @param o キューに追加するオブジェクト
	 * @throws RemoteException 追加中に発生した例外
	 */
	public void add(Serializable o) throws RemoteException {
		try {
			parent.add(o);
		} catch(RemoteException re) {
			throw re;
		} catch(Exception e) {
			e.printStackTrace();
			throw new RemoteException(e.getMessage());
		}
	}
	/**
	 * 次のオブジェクトを取得する
	 * 次のオブジェクトが存在しない場合はnullを返す
	 * 
	 * @return 取得できたオブジェクト
	 * @throws RemoteException 取得中に発生した例外
	 */
	public Serializable next() throws RemoteException {
		try {
			Serializable rc = parent.next();
			return rc;
		} catch(RemoteException re) {
			throw re;
		} catch(Exception e) {
			throw new RemoteException(e.getMessage());
		}
	}
	/**
	 * 次のオブジェクトを取得する
	 * 
	 * @param blocking true:取得可能なオブジェクトが追加されるまで待機 / false:取り出すオブジェクトがない場合はすぐ処理を返す
	 * @return 取得できたオブジェクト
	 * @throws RemoteException 取得中に発生した例外
	 */
	public Serializable next(boolean blocking) throws RemoteException {
		try {
			Serializable rc = parent.next(blocking);
			return rc;
		} catch(RemoteException re) {
			throw re;
		} catch(Exception e) {
			throw new RemoteException(e.getMessage());
		}
	}
	/**
	 * キューに次の要素があるかどうかを調べる
	 * @return true:ある / false:ない
	 * @throws RemoteException 調査中に発生した例外
	 */
	public boolean hasNext() throws RemoteException {
		return parent.getCache().size() > 0;
	}
	/**
	 * キューにオブジェクトを追加する
	 * @param objs キューに追加するオブジェクトの配列
	 * @throws RemoteException 追加中に発生した例外
	 */
	public void add(Serializable[] objs) throws RemoteException {
		for(int i = 0; i < objs.length; i++) {
			add(objs[i]);
		}
	}
	/**
	 * 次のオブジェクトを取得する
	 * 次のオブジェクトが存在しない場合はnullを返す
	 * @param count 一度に取得するオブジェクト数
	 * @return 取得できたオブジェクト
	 * @throws RemoteException 取得中に発生した例外
	 */
	public Serializable[] next(int count) throws RemoteException {
		return next(count, false);
	}
	/**
	 * 次のオブジェクトを取得する
	 * @param count 一度に取得するオブジェクト数
	 * @param blocking true:取得可能なオブジェクトが追加されるまで待機 / false:取り出すオブジェクトがない場合はすぐ処理を返す
	 * @return 取得できたオブジェクト
	 * @throws RemoteException 取得中に発生した例外
	 */
	public Serializable[] next(int count, boolean blocking) throws RemoteException {
		ArrayList objects = new ArrayList();
		for(int i = 0; i < count; i++) {
			Serializable o = next(blocking);
			if(o != null) {
				objects.add(o);
			} else {
				// 取り出すものがもうない場合，取り出し処理を中止する
				break;
			}
		}
		return (Serializable[])objects.toArray(new Serializable[0]);
	}
	/**
	 * この接続を破棄する．
	 * @throws RemoteException 破棄に失敗した(しかし接続はちゃんと破棄される)
	 */
	public void close() throws RemoteException {
		// このオブジェクトをunexportする
		UnicastRemoteObject.unexportObject(this, true);

		log.info("クライアントにリースしていたリモートオブジェクトを回収しました");
	}
}

// end of OQSConnectionImpl.java
