Designing RMI Applications

Client Maintains Lock

import java.rmi.*;
import java.rmi.server.*;

public class Account2_Impl extends UnicastRemoteObject
  implements Account2 {
  private Money _balance;
  private String _currentClient;

  public Account2_Impl(Money startingBalance)
    throws RemoteException {
    _balance = startingBalance;
  }

  /** The client can use this to get a lock on the account */
  public synchronized void getLock()
    throws RemoteException, LockedAccountException {
    if (false == becomeOwner()) {
      throw new LockedAccountException();
    }
    return;
  }

  /** The client can use this to release a lock on the account */
  public synchronized void releaseLock() throws RemoteException {
    String clientHost = wrapperAroundGetClientHost();

    if ((null != _currentClient) && (_currentClient.equals(clientHost))) {
      _currentClient = null;
    }
  }

  private boolean becomeOwner() {
    String clientHost = wrapperAroundGetClientHost();

    if (null != _currentClient) {
      if (_currentClient.equals(clientHost)) {
        return true;
      }
    } else {
      _currentClient = clientHost;
      return true;
    }
    return false;
  }

  private void checkAccess() throws LockedAccountException {
    String clientHost = wrapperAroundGetClientHost();

    if ((null != _currentClient) && (_currentClient.equals(clientHost))) {
      return;
    }
    throw new LockedAccountException();
  }

  private String wrapperAroundGetClientHost() {
    String clientHost = null;

    try {
      clientHost = getClientHost();
    } catch (ServerNotActiveException ignored) {
    }
    return clientHost;
  }

  public synchronized Money getBalance()
    throws RemoteException, LockedAccountException {
    checkAccess();
    return _balance;
  }

  public synchronized void makeDeposit(Money amount)
    throws RemoteException, LockedAccountException, NegativeAmountException {
    checkAccess();
    checkForNegativeAmount(amount);
    _balance.add(amount);
    return;
  }

  public synchronized void makeWithdrawal(Money amount)
    throws RemoteException, OverdraftException, LockedAccountException, NegativeAmountException {
    checkAccess();
    checkForNegativeAmount(amount);
    checkForOverdraft(amount);
    _balance.subtract(amount);
    return;
  }

  private void checkForNegativeAmount(Money amount)
    throws NegativeAmountException {
    int cents = amount.getCents();

    if (0 > cents) {
      throw new NegativeAmountException();
    }
  }

  private void checkForOverdraft(Money amount)
    throws OverdraftException {
    if (amount.greaterThan(_balance)) {
      throw new OverdraftException(false);
    }
    return;
  }
} 


José M. Vidal .

34 of 49