5.3.1 ユーザ例外の定義

4. Borland Enterprise Server VisiBrokerによるサンプルアプリケーションの開発」で説明したアカウントアプリケーションを拡張して,accountオブジェクトが例外を発生させるようにしたい場合,accountオブジェクトの資金が不十分なら,AccountFrozenという名前のユーザ例外を発生させる必要があります。AcoountインタフェースのIDL指定にユーザ例外を追加するために必要な追加コードを,ボールド体で示します。

IDLサンプル5-2 ユーザ例外の定義

// Bank.idl
module Bank {
  interface Account {
     exception AccountFrozen {
     };
     float balance() raises(AccountFrozen);
  };
};

idl2cppコンパイラ(C++)またはidl2java(Java)コンパイラは,AccountFrozen例外クラスに対して次に示すコードを生成します。

コードサンプル5-15 idl2cppコンパイラが生成するAccountFrozenクラス(C++)

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;
       }
    }
  . . .
}

コードサンプル5-16 idl2javaコンパイラが生成するAccountFrozenクラス(Java)

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(){...}
}

<この項の構成>
(1) 例外を発生させるためのオブジェクトの修正
(2) ユーザ例外のキャッチ
(3) ユーザ例外へのフィールドの追加

(1) 例外を発生させるためのオブジェクトの修正

適切なエラー条件下で例外を発生させることによって例外を使用するように,AccountImplオブジェクトを修正する必要があります。

コードサンプル5-17 例外を発生させるためのオブジェクトインプリメンテーションの修正(C++)

CORBA::Float AccountImpl::balance()
{
     if( _balance < 50 ) {
            throw Account::AccountFrozen();
     } else {
           return _balance;
     }
}

コードサンプル5-18 例外を発生させるためのオブジェクトインプリメンテーションの修正(Java)

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;
}

(2) ユーザ例外のキャッチ

オブジェクトインプリメンテーションが例外を発生させる場合,ORBは例外をクライアントプログラムに反映させる責任を負います。UserExceptionについてのチェックはSystemExceptionについてのチェックと同様です。AccountFrozen例外をキャッチするようにアカウントのクライアントプログラムを修正するには,コードサンプル5-19および5-20で示すようにコードの修正をしてください。

コードサンプル5-19 UserExceptionのキャッチ(C++)

. . .
  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) {
  }
. . .

コードサンプル5-20 UserExceptionのキャッチ(Java)

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) {
    . . .
    }
  }
}

(3) ユーザ例外へのフィールドの追加

ユーザ例外に特定の値を対応させることができます。理由コードをAccountFrozenユーザ例外に追加するようにIDLインタフェース定義を修正する方法をコードサンプル5-21に示します。例外を発生させるオブジェクトインプリメンテーションは,理由コードの設定に責任を負います。理由コードは,例外が出力ストリームにあると自動的に出力されます。

コードサンプル5-21 AccountFrozen例外への理由コードの追加

// Bank.idl
module Bank {
  interface Account {
     exception AccountFrozen {
        int reason;
     };
     float balance() raises(AccountFrozen);
  };
};