Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

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

J2SE 1.4 breathes new life into the CORBA community, Part 3

Create enterprise-level apps with the POA

  • Print
  • Feedback

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


Create the database

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
)


Implement the Bank object

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:

  1. All the servant's methods use the static methods on the 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.
  2. All account objects are created using a special POA called 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);
    
  3. References, not actual objects, return from both the 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;
    
  4. When a call to the 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:

    1. The entry corresponding to this servant and object ID drops from the active object map
    2. The etherialize() method is called on the servant activator (discussed in the following section) if one has been registered with the AccountPOA


The complete bank servant implementation is shown below for reference:

  • Print
  • Feedback

Resources