Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 2 of 7
module bank {
enum AccountType { NIL, Checking, Saving };
struct AccountInformation
{
string accNum;
AccountType accType;
};
exception NoSuchAccountException
{
};
exception UnknownException
{
string reason;
};
exception InvalidOperationException
{
string reason;
};
interface Account
{
readonly attribute float balance;
readonly attribute string accountNumber;
readonly attribute AccountType accountType;
void deposit(in float amt) raises(InvalidOperationException, UnknownException);
void withdraw(in float amt) raises(InvalidOperationException, UnknownException);
};
typedef sequence<Account> Accounts;
interface Bank {
Account openAccount(in AccountInformation accInfo) raises(UnknownException);
void closeAccount(in string accNum) raises(UnknownException);
Accounts findAccounts(in AccountInformation accInfo) raises(UnknownException);
};
};
We will store the account information in a database. I use SQL Server 2000 on my Windows 2000 machine. You can use any database of your choice. Here is the SQL script that I run to create the Account table in a database called Bank (consult your database vendor's documentation for instructions on creating a new database instance or add this table to an existing instance):
CREATE TABLE Account(
AccountNumber CHAR(15) NOT NULL PRIMARY KEY,
AccountType CHAR(1) NOT NULL,
Balance FLOAT NOT NULL
)
Now implement the servant that implements the Bank interface. As you learned in Part 1, the idlj compiler, used to compile the IDL, generates a class that you extend to create your servant implementation. This
compiler-generated class mainly contains marshalling code. The bank servant will extend the BankPOA class, which is (you guessed it) generated by idlj. The bank servant implementation is fairly straightforward with the exception
of some noteworthy points:
DBUtils class to access data from the database. For example, to create a new account record in the database, the openAccount() method calls the createAccount() method on DBUtils. DBUtils is an implementation of the Data Access Object pattern. To fulfill the data access function, you must configure DBUtils. Do that by placing the bank.properties file (available for download from Resources) in the classpath along with the DBUtils.class file—they should be in the same directory (or jarred from the same directory). You may need to change bank.properties's contents to match your database access parameters.
AccountPOA (more about that POA later). You obtain a reference to AccountPOA by calling the find_POA() method on the root POA as shown below: POA accountPOA = this._poa().the_parent().find_POA("AccountPOA",true);
openAccount() and findAccounts() methods to speed request processing and because we do not know if the client really wants to call methods on the account
object. We defer actual object creation to client method invocation. You create an account reference with the create_reference_with_id() method on the AccountPOA and use the account number as the reference's object ID. For example, look at the code fragment from the openAccount() method, which creates and returns a reference to a new account object: Account theAccount =
AccountHelper.narrow(accountPOA.create_reference_with_id(accNum.getBytes(),
"IDL:bank/Account:1.0"));
return theAccount;
closeAccount() method closes an account, the account information is removed from the database, a reference to the AccountPOA is obtained, and the CORBA object is deactivated by calling the deactivate_object() method on the AccountPOA. Calling this method causes two things to happen:etherialize() method is called on the servant activator (discussed in the following section) if one has been registered with the AccountPOAThe complete bank servant implementation is shown below for reference: