「4. Borland Enterprise Server VisiBrokerによるサンプルアプリケーションの開発」で説明したアカウントアプリケーションを拡張して,accountオブジェクトが例外を発生させるようにしたい場合,accountオブジェクトの資金が不十分なら,AccountFrozenという名前のユーザ例外を発生させる必要があります。AcoountインタフェースのIDL指定にユーザ例外を追加するために必要な追加コードを,ボールド体で示します。
// Bank.idl
module Bank {
interface Account {
exception AccountFrozen {
};
float balance() raises(AccountFrozen);
};
};
idl2cppコンパイラ(C++)またはidl2java(Java)コンパイラは,AccountFrozen例外クラスに対して次に示すコードを生成します。
class Account : public virtual CORBA::Object {
. . .
class AccountFrozen: public CORBA_UserException {
public:
static const CORBA_Exception::Description description;
AccountFrozen() {}
static CORBA::Exception *_factory() {
return new AccountFrozen();
}
~AccountFrozen() {}
virtual const CORBA_Exception::Description& _desc()
const;
static AccountFrozen *_downcast(CORBA::Exception *exc);
CORBA::Exception *_deep_copy() const {
return new AccountFrozen(*this);
}
void _raise() const {
raise *this;
}
}
. . .
}
package Bank;
public interface Account extends
com.inprise.vbroker.CORBA.Object,
Bank.AccountOperations, org.omg.CORBA.portable.IDLEntity {
}
package Bank;
public interface AccountOperations {
public float balance () throws
Bank.AccountPackage.AccountFrozen;
}
package Bank.AccountPackage;
public final class AccountFrozen extends
org.omg.CORBA.UserException {
public AccountFrozen (){...}
public AccountFrozen (java.lang.String _reason){...}
public synchronized java.lang.String toString(){...}
}
適切なエラー条件下で例外を発生させることによって例外を使用するように,AccountImplオブジェクトを修正する必要があります。
CORBA::Float AccountImpl::balance()
{
if( _balance < 50 ) {
throw Account::AccountFrozen();
} else {
return _balance;
}
}
public class AccountImpl extends Bank.AccountPOA {
public AccountImpl(float balance) {
_balance = balance;
}
public float balance()throw new AccountFrozen {
if (_balance < 50) {
throw new AccountFrozen();
}else {
return _balance;
}
}
private float _balance;
}
オブジェクトインプリメンテーションが例外を発生させる場合,ORBは例外をクライアントプログラムに反映させる責任を負います。UserExceptionについてのチェックはSystemExceptionについてのチェックと同様です。AccountFrozen例外をキャッチするようにアカウントのクライアントプログラムを修正するには,コードサンプル5-19および5-20で示すようにコードの修正をしてください。
. . .
try {
// Initialize the ORB.
CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv);
// Bind to an account.
Account_var account = Account::_bind();
// Get the balance of the account.
CORBA::Float acct_balance = account->balance();
}
catch(const Account::AccountFrozen& e) {
cerr << "AccountFrozen returned:" << endl;
cerr << e << endl;
return(0);
}
// Check for system errors
catch(const CORBA::SystemException& sys_excep) {
}
. . .
public class Client {
public static void main(String[ ] args) {
try {
// Initialize the ORB
org.omg.CORBA.ORB orb =
org.omg.CORBA.ORB.init(args, null);
// Bind to an account
Account account = AccountHelper.bind(orb, "/bank_poa",
"BankAccount".getBytes());
// Get the balance of the account
float balance = account.balance();
// Print the account balance
System.out.println("The account balance is $" +
balance);
}
// Check for AccountFrozen exception
catch(Account.AccountFrozen e) {
System.err.println("AccountFrozen returned:");
System.err.println(e);
}
// Check for system error
catch(org.omg.CORBA.SystemException sys_excep) {
. . .
}
}
}
ユーザ例外に特定の値を対応させることができます。理由コードをAccountFrozenユーザ例外に追加するようにIDLインタフェース定義を修正する方法をコードサンプル5-21に示します。例外を発生させるオブジェクトインプリメンテーションは,理由コードの設定に責任を負います。理由コードは,例外が出力ストリームにあると自動的に出力されます。
// Bank.idl
module Bank {
interface Account {
exception AccountFrozen {
int reason;
};
float balance() raises(AccountFrozen);
};
};