FileDocCategorySizeDatePackage
Account.javaAPI DocExample6178Fri Jun 27 18:33:52 BST 1997bank.server

Account.java

/**
 * The Account class represents any kind of bank account.
 * It stores information like which customer owns it and what
 * the balance is.  This should get subclasses to implement rules
 * specific to different types of accounts.
 */
package bank.server;

import imaginary.persist.LockException;
import imaginary.persist.PersistenceException;
import imaginary.persist.Persistent;
import imaginary.persist.PersistentPeer;
import imaginary.persist.RemoteLockHolder;
import imaginary.persist.Transaction;
import java.rmi.RemoteException;
import java.util.Hashtable;

public class Account extends Persistent implements RemoteAccount {
    // Just need one account peer for all accounts to share
    static final AccountPeer    peer     = new AccountPeer();

    // How much money is in the account
    private float               balance  = 0;
    // The customer that owns this account (no join accounts)
    private Customer            customer = null;
    // The account type
    private String              type     = "C";

    public Account() throws RemoteException {
	super();
    }
    
    /**
     * The account balance is how much money is currently in the account
     * @return the account balance
     */
    public synchronized float getBalance() {
	return balance;
    }

    /**
     * @return the Customer object that owns this account
     */
    public synchronized RemoteCustomer getCustomer() {
	return customer;
    }
    
    /**
     * The customer ID is an attribute that unique identifies the owning
     * customer.
     * @return the customer ID owning this account
     */
    public synchronized int getCustomerId() {
	return customer.getId();
    }

    /**
     * Implementation of the Persistent method setId(Hashtable).
     * Allows this object to pick the account ID out of a Hashtable
     * and set the ID using that value.
     * @param h a Hashtable of values taken from a data store
     */
    public synchronized void setId(Hashtable h) {
	setId(((Integer)h.get("t_accounts.account_id")).intValue());
    }

    /**
     * Implementation of the Persistent method that specifies what
     * PersistentPeer to use for data store operations.
     * @return the PersistentPeer for this class
     */
    protected synchronized PersistentPeer getPersistentPeer() {
	return Account.peer;
    }

    /**
     * The account type can be "S" for savings and "C" for checking.
     * @return the account type for this account
     */
    public synchronized String getAccountType() {
	return type;
    }

    /**
     * Deposits the specified amount of money into the account.
     * @param trans the Transaction used to perform the modification
     * @param amount the amount being deposited
     * @exception AccountException An attempt to deposit a negative amount
     * @exception LockException Another Transaction is holding a lock
     */
    public synchronized void deposit(RemoteLockHolder h, float amount)
    throws AccountException, LockException {
	// will throw a LockException if another lock is held
	modify(h); 
	if( amount < 0 ) {
	    throw new AccountException("Deposits may not be negative.");
	}
	balance += amount;
    }
    
    /**
     * Implementation of the Persistent method for filling in
     * object attributes based on a Hashtable of values from
     * a data store.
     * @param trans the Transaction for this restore
     * @param h the Hashtable containing values from the data store
     * @exception imaginary.persist.PersistenceException An error occurred
     * restoring the object attributes
     */
    public synchronized void restore(Transaction t, Hashtable h)
    throws PersistenceException{
	Integer i = (Integer)h.get("t_accounts.account_id"); 
	Float f = (Float)h.get("t_accounts.balance");
	
	setId(i.intValue()); // Set the ID
	i = (Integer)h.get("t_accounts.cust_id");
	// Get the customer object for this account
	customer =
	    (Customer)Persistent.getPersistent(t, i.intValue(),
						      "bank.server.Customer");
	// Set the account type
	type = (String)h.get("t_accounts.account_type");
	// Set the balance
	balance = f.floatValue();
    }
    
    /**
     * Transfers the specified amount of money from this account to another
     * This is done as a withdraw from this account followed by a
     * deposit into the remote account.
     * @param trans the Transaction used to perform the modification
     * @param amount the amount being withdrawn
     * @exception AccountException A deposit or withdrawal failed
     * @exception LockException Another Transaction is holding a lock
     */
    public synchronized void transfer(RemoteLockHolder h, float amount,
				      RemoteAccount acct)
    throws AccountException, LockException, RemoteException {
	float current_balance = getBalance();
	
	try {
	    withdraw(h, amount);
	    acct.deposit(h, amount);
	}
	catch( AccountException e ) {
	    balance = current_balance; // restore the balance here!
	    throw e;
	}
	catch( LockException e ) {
	    balance = current_balance; // restore the balance here!
	    throw e;
	}
	catch( RemoteException e ) {
	    balance = current_balance; // you know the routine
	    throw e;
	}
    }

    /**
     * Withdraws the specified amount of money from the account.
     * This method places no restrictions on what may or may not be
     * withdrawn (negative balances allowed).
     * @param trans the Transaction used to perform the modification
     * @param amount the amount being withdrawn
     * @exception AccountException An attempt to withdraw a negative amount
     * @exception LockException Another Transaction is holding a lock
     */
    public synchronized void withdraw(RemoteLockHolder h, float amount)
	 throws AccountException, LockException, RemoteException {
	// will throw a LockException if another lock is held
	modify(h); 
	if( amount < 0 ) {
	    throw new AccountException("Attempt to withdraw a negative " +
				       "amount of money.");
	}
	balance -= amount;
    }
}