Phil Surette wrote:
> Thanks very much Tom, the beginResponse thing was exactly
> what I needed. I'll have to go through and remove misguided
> references to the attach method.
Phil,
To confuse you again I don't use beginResponse in real applications when
a page is called from another page. I do this: (pseudocode)
/* function in calling page */
/* choose the next page and give it its parameters */
public void gotoNextPage(IRequestCycle cycle)
{
cycle.setPage("NameOfNextPage");
InitializablePage page = (InitializablePage)cycle.getPage();
page.init(keyOfThing);
}
...
/* init function in called page */
/* accept parameters from calling page and set them as
* persistent page state */
public void init(KeyType keyOfThing)
{
setKey(keyOfThing);
fireObservedChange("key", keyOfThing);
// use the key to get data to be shown from the DB
// and set that as persistent page state too
}
/* listener function in called page */
public void someListener(...)
{
try
{
// save the data to the DB/do business logic
...
gotoNextPage(cycle); // move to another page
}
catch (BusinessException be)
{
// something bad happened in the business logic,
// set a property of this page to show an error message
// and *don't* move to a new one
}
}
In fact these are all functions in my base page class, and they are more
general. Most of my pages use exactly the same Java class, and hold
their state and behaviour in a Command object.
The interface of a command is:
/*
* (c) Copyright 2002 Oakton Computing
* All Rights Reserved.
*/
package au.com.oakton.wf;
import java.io.Serializable;
import java.util.Locale;
import javax.jdo.PersistenceManager;
import au.com.oakton.authentication.User;
import au.com.oakton.security.Capability;
/**
* @version 1.0
* @author
*/
public interface Command extends Serializable
{
/**
* Get the command ready to interact with the user interface.
* This involves loading any data to be displayed from the
* back end, and setting any defaults. This takes place here
* rather than when the Command is created because it may be
* an expensive process.
*
* This method is executed in the middle tier.
*
* @param user The User who will be viewing the user interface.
* @param l The Locale of the user.
* @param pm The PersistenceManager to be used.
*/
public void init(User user, Locale l, PersistenceManager pm);
/**
* Carry out the task the command implements.
* Load any items which have been edited, apply the changes to
* them, and call business methods to perform this command.
*
* This method is executed in the middle tier.
*
* @param user The User on whose behalf the command is being executed.
* @param l The Locale this user is currently operating in.
* @param pm The PersistenceManager to be used.
* <b>Does this need to be visible here?</b>
*/
public void execute(User user, Locale l, PersistenceManager pm);
/**
* Get the description of this command for display to the user.
* Uses the locale set for this command.
*
* @return a String describing the function of this command.
*/
public String getDescription();
/**
* Get the name of this command.
* This is a short description of the nature of the command which
* may be used to get an appropriate command for a heterogeneous
* collection of items. Examples would include "Edit", "Delete" etc.
*
* @return a String containing a 'symbolic' description of the command.
*/
public String getName();
/**
* Get the type of display form this command uses.
* This is a name which may be mapped to a user interface component
* by the user interface tier. Two commands which use the same form
* elements will return the same string.
*
* @return a String naming the type of form required by this command.
*/
public String getFormType();
/**
* Set the Locale to be used to create the description of this command.
*
* @param l The Locale to use to create the description.
*/
public void setLocale(Locale l);
/**
* Get the command to execute next.
* This is called after execute() has been called, and returns the
* next command to perform. It is an error to call this before
* calling execute. This is called from the user interface tier.
*
* @return the next command
*/
public Command getNextCommand();
/**
* Get the Capability which a user must have to execute this command.
*/
public Capability getCapability();
}
My page class looks like this:
Note that Command.init() and Command.execute() are executed in the
middle tier via an EJB because this is where DB access and updates happen.
import au.com.oakton.authentication.User;
import au.com.oakton.common.BusinessException;
import au.com.oakton.common.ui.SecuredPage;
import au.com.oakton.wf.Command;
import au.com.oakton.wf.ItemManagerFacade;
import com.primix.tapestry.IRequestCycle;
/**
* @version 1.0
* @author
*/
public class CommandPage extends SecuredPage
{
public void init(Command command, User user)
{
ItemManagerFacade im = new ItemManagerFacade(getUser(), getLocale());
command = im.initCommand(command);
setCommand(command);
fireObservedChange("command", _command);
}
public void setCommand(Command command)
{
_command = command;
}
public Command getCommand()
{
return _command;
}
public void execute(IRequestCycle cycle)
{
// first check for validation errors
if (getDelegate().getHasErrors())
{
return;
}
try
{
ItemManagerFacade im = new ItemManagerFacade(getUser(), getLocale());
setCommand(im.executeCommand(getCommand()));
gotoNextPage(cycle);
}
catch (BusinessException e)
{
handleException(e);
}
}
public void detach()
{
_command = null;
super.detach();
}
public void gotoNextPage(IRequestCycle cycle)
{
Command c = getCommand().getNextCommand();
if (c != null)
{
cycle.setPage(c.getFormType());
CommandPage page = (CommandPage)cycle.getPage();
page.init(c, getUser());
}
}
private Command _command;
}
_______________________________________________________________
Have big pipes? SourceForge.net is looking for download mirrors. We supply
the hardware. You get the recognition. Email Us: [EMAIL PROTECTED]
_______________________________________________
Tapestry-developer mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/tapestry-developer