The new factory Building on the Account-Locking Mechanism

public ServerList getAccountsStr ing[] accountNames throws RemoteException; public void serverNoLongerActiveString accountName throws RemoteException; } If we require the clients to get all the relevant account stubs before they perform any transactions, we have, albeit in a fairly clumsy fashion, enabled the implementation of transferMoney functionality.

17.4.2.1 The new factory

Because it no longer maintains a count of the number of times it has vended a server, our new factory is a bit simpler than the basic factory. Heres the code for the abstract superclass, LockingFactory_Impl : public abstract class LockingFactory_Impl extends UnicastRemoteObject implements LockingFactory { protected abstract Remote _getAccountString accountName; private HashMap _lockedaccountNames ; public LockingFactory_Impl throws RemoteException { _lockedaccountNames = new HashMap ; } public synchronized Remote getAccountString accountName throws RemoteException, LockedServerException { Remote returnValue = getAccountac countName; _lockedaccountNames.putaccountName, accountName; return returnValue; } public synchronized Remote[] getAccountsString[] accountNames throws RemoteException, LockedServerException { Remote[] returnValue = new Remote[account Names.length]; int counter; for counter = 0; counter accountNames.length; counter ++ { try { checkLockaccountNames[counter]; Remote nextServer = getAccountaccountNames[counter]; returnValue[counter] = nextServer; } catch LockedServerException serverLocked { int returnCounter; for returnCounter = 0; returnCounter counter; returnCounter ++ { serverNoLongerActiveaccountNames[returnCounter]; } } throw serverLocked; } return returnValue; } public synchronized void serverNoLongerActiveString accountName throws RemoteException { _lockedaccountNames.removeaccountName; } private synchronized void checkLockString accountName throws LockedServerException { if null=_lockedaccountNames.getaccountName { throw new LockedServerExceptionaccountName; } return; } } Theres one important subtlety in how this works. Because the entire locking mechanism relies upon the Unreferenced interface, the factory can never store a stub on any account servers. If the factory held a stub to an account server, the factory would maintain a lease to the server and, therefore, unreferenced would never be called. Hence, the account would never be unlocked. This means that the protected method _getAccount actually needs to create the account servers or cause them to be created, when it is called. For now, well ignore this issue and simply hardwire the server creation code in a concrete subclass; the Activation Framework provides a convenient way to handle automatically launching servers. Heres the code for LockingAccountFactory_Impl , a concrete subclass of LockingFactory_Impl that simply creates accounts with random balances: public class LockingAccountFactory_Impl extends LockingFactory_Impl { public LockingAccountFactory_Impl throws RemoteException { } protected Remote _getAccountString accountName { try { Account returnValue = new Account_ImplgetRandomMoney , accountName; returnValue.setFactorythis; return returnValue; } catch Exception ignored { Creation of a local object should never fail} return null; } private Money getRandomMoney { int cents = int Math.random 100000; return new Moneycents; } }

17.4.2.2 The new account