First Adam, thanks for a quick reply. I realize that "callback" is used
almost exclusively in tapestry when invoking pages, and whyat I meant was
how to make and use a parameter to a component which refers to a mwthod in
another class (the component using class).
However, it's always nice to see examples of code I might actually need
anyway :) Thanks!
Cheers,
PS
On 3/4/06, Adam Zimowski <[EMAIL PROTECTED]> wrote:
>
> I use callbacks heavily, although not sure if that's exactly what you
> need. I have an Authenticate component for instance which validates
> itself against the database, submits itself and creates a member
> session on success. It uses a callback of a hosting page to find out
> what page to go to upon successfull login. I do that thru an interface
> which a hosting page can (although doesn't have to) implement. If
> IAuthenticate is implemented by a hosting page, then component will
> use a callback to delegate all the login responsibility (except the
> validation) onto the page. If ClassCastException occurs (when page
> does not implement IAuthenticate) the component uses its default
> logic.
>
> I have two pages that use Authenticate component: Home page and a
> Login page. Home page is happy with component's default behavior, so
> it does not implement IAuthenticate thus not proving a callback. Login
> page, on the other hand wants to control the Login process, and so it
> implements IAuthenticate.
>
> This works very nicely for me.
>
>
> -----------------------------------------------------------------------------------------------
>
> package org.opendating.tapestry.components.support;
>
> import org.apache.tapestry.IPage;
>
> /**
> * Allows to define custom Login behavior for pages that utilize
> Authenticate
> * component (which provides a Login feature). Implementing this interface
> * is not mandatory because by default, Authenticate will execute a
> standard
> * action which is to create a session and a member object (which gets put
> in
> * the session), and returning back to the same page.
> *
> * @author Adam Zimowski
> */
> public interface IAuthenticate {
>
> /**
> *
> * @param aError <i>true</i> if login error occurred, <i>false</i>
> otherwise.
> * @return destination page after successfull login.
> */
> public IPage onLogin(boolean aError);
>
> /**
> * If <i>true</i> is returned, then Authenticate component will
> automatically
> * create member object, and put it in session. If <i>false</i> is
> returned
> * the Authenticate component merely calls the implemented version
> of
> * onLogin(boolean) and returns the desitnation page.
> *
> * @return <i>true</i> if session and member object should be
> created,
> * <i>false</i> otherwise.
> */
> public boolean createMemberOnLogin();
> }
>
>
> -----------------------------------------------------------------------------------------------
>
> package org.opendating.tapestry.components;
>
> import org.apache.tapestry.IPage;
> import org.apache.tapestry.annotations.Bean;
> import org.apache.tapestry.valid.ValidationDelegate;
> import org.opendating.exceptions.MemberException;
> import org.opendating.model.Member;
> import org.opendating.tapestry.components.support.IAuthenticate;
> import org.opendating.tapestry.log.LoggableBaseComponent;
> import org.opendating.tapestry.state.IMember;
>
> public abstract class Authenticate extends LoggableBaseComponent
> implements IMember {
>
> @Bean
> public abstract ValidationDelegate getDelegate();
>
> public abstract String getLoginId();
>
> public abstract String getPassword();
>
> public IPage onLogin() {
>
> boolean isError = getDelegate().getHasErrors();
> if(aDbg()) _aLog.debug("error? " + isError);
>
> IAuthenticate loginPage = null;
> try {
> loginPage = (IAuthenticate)getPage();
> if(!loginPage.createMemberOnLogin())
> return loginPage.onLogin(isError);
> }
> catch(ClassCastException cce) {
> if(!isError) {
> String host = getPage().getPageName();
> _aLog.info("default login; page '" + host
> + "' did not implement " +
> IAuthenticate.class.getSimpleName
> ());
> }
> }
>
> if(!isError) {
> Member member = null;
> try { member = new Member(getLoginId()); }
> catch(MemberException me) {
> _aLog.error(me.getMessage());
> }
>
> if(aDbg()) {
> _aLog.debug("isLoggedIn: " +
> isLoggedIn());
> _aLog.debug("loginId: " + getLoginId());
> _aLog.debug("systemId: " +
> member.getSystemId());
> }
>
> setMember(member);
>
> if(aDbg())
> _aLog.debug("isLoggedIn: " +
> isLoggedIn());
> }
>
> try { return loginPage.onLogin(isError); }
> catch(NullPointerException npe) { return null; }
> }
>
> }
>
>
> -----------------------------------------------------------------------------------------------
>
> Note that Home page does not implement IAuthenticate:
>
> package org.opendating.tapestry.pages;
>
> import org.opendating.tapestry.log.LoggableBasePage;
> import org.opendating.tapestry.state.IMember;
>
> public abstract class Home extends LoggableBasePage implements IMember {
>
> public static final String NAME = "Home";
>
> public String getUserName() {
>
> String guest = "Guest";
>
> try {
> if(isLoggedIn())
> return getMember().getLoginId();
> else
> return guest;
> }
> catch(Exception e) { return guest; }
> }
> }
>
>
> -----------------------------------------------------------------------------------------------
>
> But Login page does because it wants custom Login logic:
>
> package org.opendating.tapestry.pages;
>
> import org.apache.tapestry.IPage;
> import org.apache.tapestry.annotations.InjectComponent;
> import org.apache.tapestry.annotations.Persist;
> import org.opendating.tapestry.components.Authenticate;
> import org.opendating.tapestry.components.support.IAuthenticate;
> import org.opendating.tapestry.log.LoggableBasePage;
>
> /**
> * Page designed specifically for Login only, which would be used in
> situations
> * when user forges a URL trying to access member-only pages. In such
> situations
> * instead of accessing page illegaly, this login page would be displayed.
> *
> * There is nothing that prevents from using this page as a main Login
> gateway,
> * however, a more flexible approach is available because any given page
> can
> * use "Authenticate" component which provides a Login feature.
> *
> * @author Adam Zimowski
> */
> public abstract class Login extends LoggableBasePage implements
> IAuthenticate {
>
> public static final String NAME = "Login";
>
> @Persist("client")
> public abstract String getReturnPage();
> public abstract void setReturnPage(String aPage);
>
> @InjectComponent("authenticator")
> public abstract Authenticate getLoginComponent();
>
> public IPage onLogin(boolean aError) {
>
> if(!aError) {
>
> String page = getReturnPage();
> if(aDbg()) _aLog.debug("returning to: " + page);
>
> return getRequestCycle().getPage(page);
> }
>
> return null;
> }
>
> public boolean createMemberOnLogin() {
> return true;
> }
> }
>
>
> Hope it helps.
>
>
> On 3/4/06, Peter Svensson <[EMAIL PROTECTED]> wrote:
> > Hi!
> >
> > I am making a small simple component which wraps contrib:Table but only
> > requires source, so it figures out names and ordering by reflection.
> > Anyway, it works great, and now I would like to make another component
> which
> > wraps it and adds delete buttons (Maybe with the T-deli checkbox groups
> to
> > select all and/or all shown (http://www.t-deli.com/)).
> >
> > But one thing I can't find either in Kens book or while googling
> heavily,
> > which is how to specify a method/callback function to be called when
> someone
> > does submit one or more deletions to the component.
> >
> > I think I should use some kind of listener, but since I'm quite new to
> all
> > this I'm hoping for directions.
> >
> > Cheers,
> > PS
> >
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>