Another lovely day with Tapestry! Inspired by Taha's blog entry on Tapestry Magic, our app instead of this mess:
public class OrderHistoryPage extends AuthenticatedPage looks sexy like never before with this: @RequiresLogin(ssoClass= UserUiBean.class, pageClass= Login.class) public class OrderHistoryPage extends BasePage Here are the pieces: Custom Annotation /** * Tells Tapestry that a page requires authenticated user. If a page is * annotated with this, and user is not logged in, that page shall redirect * to a login screen instead of rendering itself. * * @author Adam Zimowski */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RequiresLogin { /** * Class whose instance lives in session and represents authenticated user. */ Class<?> ssoClass(); /** * Page class to which Tapestry should redirect guests instead of * displaying secured page */ Class<? extends BasePage> pageClass(); } Annotation Worker /** * Transforms page classes annotated with {@link RequiresLogin} adding advice * which tests if the user is logged in, then redirects to login page if user * is guest. * * @author Adam Zimowski */ public class RequiresLoginAnnotationWorker implements ComponentClassTransformWorker { private final TransformMethodSignature ONACTIVATE_SIGNATURE = new TransformMethodSignature( 0, "java.lang.Object", "onActivate", null, null); private Logger log = LoggerFactory.getLogger(RequiresLoginAnnotationWorker.class); private ApplicationStateManager asm; public RequiresLoginAnnotationWorker(ApplicationStateManager aAsm) { asm = aAsm; } @Override public void transform(ClassTransformation aTransformation, MutableComponentModel aModel) { RequiresLogin annotation = aTransformation .getAnnotation(RequiresLogin.class); if (annotation == null) { return; } final Class<?> ssoClass = annotation.ssoClass(); final Class<?> pageClass = annotation.pageClass(); if(log.isDebugEnabled()) { log.debug(".. transforming {} ..", aTransformation.getClassName()); } TransformMethod methodTransformer = null; try { methodTransformer = aTransformation.getOrCreateMethod(ONACTIVATE_SIGNATURE); } catch(Throwable t) { throw new RuntimeException(RequiresLogin.class.getSimpleName() + " annotation requires package scope " + "[ Object onActivate() ] method.", t); } methodTransformer.addAdvice( new ComponentMethodAdvice() { public void advise(ComponentMethodInvocation invocation) { invocation.proceed(); if(!asm.exists(ssoClass)) { if(log.isDebugEnabled()) { log.debug( "redirecting to {} page ...", pageClass.getSimpleName()); } invocation.overrideResult(pageClass); } } } ); } } Service Contribution @Contribute(ComponentClassTransformWorker.class) public void contributeComponentClassTransformWorker( OrderedConfiguration<ComponentClassTransformWorker> aWorkers) { aWorkers.addInstance( RequiresLogin.class.getSimpleName(), RequiresLoginAnnotationWorker.class, "before:OnEvent"); } Page class usage: @RequiresLogin(ssoClass = UserUiBean.class, pageClass = Login.class) public class UserProfilePage extends BasePage { ... Feel free to re-use! Para-Ta-Ta-Taaaaa ........... I'M LOVIN' IT !!!!! Adam --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org