You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2003/04/08 11:00:26 UTC
cvs commit: avalon-sandbox/merlin/merlin-smp/xdocs/starting/examples/afs/simple servlet.xml interfaces.xml implementation.xml
mcconnell 2003/04/08 02:00:26
Added: merlin/merlin-smp/xdocs/starting/examples/afs/simple
servlet.xml interfaces.xml implementation.xml
Log:
Addition to AFS to include a servlet based variant.
Revision Changes Path
1.1 avalon-sandbox/merlin/merlin-smp/xdocs/starting/examples/afs/simple/servlet.xml
Index: servlet.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Getting Started</title>
<authors>
<person name="Stephen McConnell" email="mcconnell@apache.org"/>
</authors>
</header>
<body>
<section name="Apache Financial Services">
<subsection name="Simple Bank Servlet">
<p>
The Simple Servlet example demonstrates the embedding of a
Merlin Kernel within a servlet and the mechanisms used to
get the intial reference to the Apache Financial Service Bank.
</p>
<p><img src="../../../../images/simple-servlet.gif"/></p>
</subsection>
<subsection name="Servlet Implementation">
<p>
The servlet implemenmtation extends the Merlin servlet extension.
The servlet extension establishes the Merlin Kernel and the servlet
implementation includes the logic for extracting the Bank service
from the kernel.
</p>
<p><i>SimpleServlet.java (init method)</i></p>
<source><![CDATA[
/**
* Servlet example containing an embedded Merlin Kernel.
*
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
*/
public class SimpleServlet extends MerlinServlet
{
private Bank m_bank;
public void init()
throws ServletException
{
super.init();
try
{
//
// get the bank
//
Block block = super.getRootBlock();
URL banking = block.getURL();
URL url = new URL( banking, banking.getPath() + "bank" );
Appliance manager = (Appliance) url.getContent();
m_bank = (Bank) manager.resolve( this );
log( "Bank established: " + m_bank );
//
// ok - we have bank so we can now create and destroy
// accounts - need to think about the best way to move on
// from here
//
}
catch( Exception e )
{
throw new ServletException( "Bank initialization error.", e );
}
}
// etc.
}
]]></source>
</subsection>
</section>
</body>
</document>
1.1 avalon-sandbox/merlin/merlin-smp/xdocs/starting/examples/afs/simple/interfaces.xml
Index: interfaces.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Apache Financial Services</title>
<authors>
<person name="Stephen McConnell" email="mcconnell@apache.org"/>
</authors>
</header>
<body>
<section name="Apache Financial Services">
<subsection name="Simple Bank : Interfaces">
<p>
The Simple Bank interfaces define a simplistic Bank from which
multiple Account instances can be created and removed.
</p>
</subsection>
<subsection name="Bank Interface">
<p>
The Bank interface services as a factory for accounts. Using the
Bank, clients can create and destroy accounts.
</p>
<p><i>Bank.java</i></p>
<source><![CDATA[
package org.apache.bank;
public interface Bank
{
/**
* Create, register and return a new account.
* @param name the name of the account holder
* @return Account the account
*/
Account createAccount( String name );
/**
* Returns an account based on a supplied account number.
* @param id the account number
* @return Account the bank account
*/
Account getAccount( int id ) throws NoSuchAccountException;
/**
* Close an account.
* @param id the account number
*/
void closeAccount( int id ) throws PolicyException, NoSuchAccountException;
/**
* Get the number of accounts managed by the bank.
* @return the number of accounts
*/
int accounts();
}
]]></source>
</subsection>
<subsection name="Account Interface">
<p>
The Account interface encapsulates the services that a client can
perform against an account - deposit of funds, withdrawls, and
account balance queries.
</p>
<p><i>Account.java</i></p>
<source><![CDATA[
package org.apache.bank;
public interface Account
{
/**
* Get the account name.
* @return the account name
*/
String getName();
/**
* Get the account number.
* @return the account number
*/
int getID();
/**
* Get the account balance.
* @return the account balance
*/
float getBalance();
/**
* Deposit funds into the account.
* @param amount the amount of funds to deposit
*/
void deposit( float amount );
/**
* Withdraw funds from the account.
* @param amount the amount of funds to withdraw
*/
void withdraw( float amount ) throws InsufficientFundsException;
}
]]></source>
</subsection>
</section>
</body>
</document>
1.1 avalon-sandbox/merlin/merlin-smp/xdocs/starting/examples/afs/simple/implementation.xml
Index: implementation.xml
===================================================================
<?xml version="1.0"?>
<document>
<header>
<title>Apache Financial Services</title>
<authors>
<person name="Stephen McConnell" email="mcconnell@apache.org"/>
</authors>
</header>
<body>
<section name="Apache Financial Services">
<subsection name="Simple Bank">
<p>
The Simple Bank implementation aims to establish a minimal
implementation - unsecure, very simplistic, but funtional.
</p>
</subsection>
<subsection name="Block Directive">
<p>
Bank has no service dependencies (after all, its a rather simple
implementation). The block.xml simply establishes the Bank instance
ready to handle account creation and removal requests.
</p>
<source><![CDATA[
<block name="banking">
<container>
<component name="bank" class="org.apache.bank.impl.BankProvider" activation="startup"/>
</container>
</block>
]]></source>
</subsection>
<subsection name="Bank Implementation">
<p>
BankProvider is a simple component with dependecies on the supplied runtime
context. It uses the supplied context to retrieve a working directory
from which it can internalize and externalize a serializable set of
accounts. With an established set of accounts, the Bank can handle
requests for new account creation and account removal.
</p>
<p><i>Bank.java</i></p>
<source><![CDATA[
package org.apache.bank.impl;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.framework.activity.Initializable;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.bank.Bank;
import org.apache.bank.Account;
import org.apache.bank.PolicyException;
import org.apache.bank.NoSuchAccountException;
public class BankProvider extends AbstractLogEnabled
implements Contextualizable, Initializable, Disposable, Bank
{
private File m_home = null;
/**
* The persistant account registry.
*/
private Accounts m_accounts;
/**
* Supply of the runtime context to the component by the container. The
* component uses the supplied home directory to store accounts.
* @param context the runtime context
* @exception ContextException if the container does not supply the
* home directory under the "urn:avalon:home" key.
*/
public void contextualize( Context context ) throws ContextException
{
m_home = (File) context.get( "urn:avalon:home" );
getLogger().info( "setting home directory: " + m_home );
}
/**
* Initialization of the component by the container.
* @exception if an initialization error occurs
*/
public void initialize() throws Exception
{
File file = new File( m_home, "accounts.ser" );
getLogger().info( "initialization" );
if( file.exists() )
{
getLogger().info( "loading store: " + file );
InputStream stream = new FileInputStream( file );
final ObjectInputStream ois = new ObjectInputStream( stream );
m_accounts = (Accounts) ois.readObject();
getLogger().info( "accounts established: " + m_accounts.accounts() );
}
else
{
getLogger().info( "creating new account registry" );
m_accounts = new Accounts();
}
}
/**
* Disposal of the bank by the container.
*/
public void dispose()
{
getLogger().info( "initiating bank disposal" );
try
{
File file = new File( m_home, "accounts.ser" );
File parent = file.getParentFile();
parent.mkdirs();
file.createNewFile();
FileOutputStream stream = new FileOutputStream( file );
final ObjectOutputStream output = new ObjectOutputStream( stream );
output.writeObject( m_accounts );
output.flush();
getLogger().info( "accounts saved to " + file );
}
catch( Throwable e )
{
final String error =
"Unable to write accounts to file.";
getLogger().error( error, e );
}
}
/**
* Get the number of accounts managed by the bank.
* @return the number of accounts
*/
public int accounts()
{
return m_accounts.accounts();
}
/**
* Create, register and return a new account.
* @param name the name of the account holder
* @return Account the account
*/
public Account createAccount( String name )
{
Account account = m_accounts.createAccount( name );
getLogger().info(
"created new account for: " + name
+ " with id: " + account.getID() );
return account;
}
/**
* Close an account.
* @param id the account number
*/
public void closeAccount( int id ) throws PolicyException, NoSuchAccountException
{
getLogger().info( "closing account: " + id );
m_accounts.closeAccount( id );
}
/**
* Returns an account based on a supplied account number.
* @param id the account number
* @return Account the bank account
*/
public Account getAccount( int id ) throws NoSuchAccountException
{
Account account = m_accounts.getAccount( id );
getLogger().info(
"retrieving account: " + id
+ " for " + account.getName() );
return account;
}
}
]]></source>
</subsection>
<subsection name="Bank Implementation">
<p>
The DefaultAccount implementation provides support for functional
operations including the deposit and withdrawl of funds and provision
of the standing account balance.
</p>
<p><i>Bank.java</i></p>
<source><![CDATA[
package org.apache.bank.impl;
import java.io.Serializable;
import org.apache.bank.Account;
import org.apache.bank.InsufficientFundsException;
public class DefaultAccount implements Account, Serializable
{
private int m_id;
private String m_name;
private float m_balance;
public DefaultAccount( String name, int id )
{
m_id = id;
m_name = name;
}
/**
* Deposit funds into the account.
* @param amount the amount of funds to deposit
*/
public synchronized void deposit( float amount )
{
m_balance = m_balance + amount;
}
/**
* Withdraw funds from the account.
* @param amount the amount of funds to withdraw
*/
public synchronized void withdraw( float amount ) throws InsufficientFundsException
{
if( amount > m_balance )
{
final String message =
"Request withdrawl of " + amount
+ " exceeds balance of " + m_balance + ".";
throw new InsufficientFundsException( message );
}
m_balance = m_balance - amount;
}
/**
* Get the account balance.
* @return the account balance
*/
public float getBalance()
{
return m_balance;
}
/**
* Get the account name.
* @return the account name
*/
public String getName()
{
return m_name;
}
/**
* Get the account number.
* @return the account number
*/
public int getID()
{
return m_id;
}
public int hashcode()
{
return getID();
}
}
]]></source>
</subsection>
</section>
</body>
</document>
---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org