package com.ora.rmibook.chapter15.bank;
import com.ora.rmibook.chapter15.bank.valueobjects.*;
import java.rmi.*;
import java.rmi.server.*;
/*
Has timer-based lock management on server-side
*/
public class Account_Impl extends UnicastRemoteObject implements Account {
private static final int TIMER_DURATION = 10000; // Rather short
private Money _balance;
private String _currentClient;
private int _timeLeftUntilLockIsReleased;
public Account_Impl(Money startingBalance)
throws RemoteException {
_balance = startingBalance;
_timeLeftUntilLockIsReleased = 0;
(Account_Impl_LockThread.getSingleton()).addAccount(this);
// register with the lock-expiration thread
}
public synchronized Money getBalance(String clientIDNumber)
throws RemoteException, LockedAccountException {
checkAccess(clientIDNumber);
return _balance;
}
public synchronized void makeDeposit(String clientIDNumber, Money amount)
throws RemoteException, LockedAccountException, NegativeAmountException {
checkAccess(clientIDNumber);
checkForNegativeAmount(amount);
_balance = _balance.add(amount);
return;
}
public synchronized void makeWithdrawal(String clientIDNumber, Money amount)
throws RemoteException, OverdraftException, LockedAccountException, NegativeAmountException {
checkAccess(clientIDNumber);
checkForNegativeAmount(amount);
checkForOverdraft(amount);
_balance = _balance.subtract(amount);
return;
}
private void checkAccess(String clientIDNumber) throws LockedAccountException {
if (null == _currentClient) {
_currentClient = clientIDNumber;
} else {
if (!_currentClient.equals(clientIDNumber)) {
throw new LockedAccountException();
}
}
resetCounter();
return;
}
private void resetCounter() {
_timeLeftUntilLockIsReleased = TIMER_DURATION;
}
protected synchronized void decrementLockTimer(int amountToDecrement) {
_timeLeftUntilLockIsReleased -= amountToDecrement;
if (_timeLeftUntilLockIsReleased < 0) {
_currentClient = null;
}
}
private String wrapperAroundGetClientHost() {
String clientHost = null;
try {
clientHost = getClientHost();
} catch (ServerNotActiveException ignored) {
}
return clientHost;
}
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;
}
}
|