On Wed, May 4, 2011 at 11:42 AM, Thiago H. de Paula Figueiredo
<thiag...@gmail.com> wrote:
> I wouldn't call this composition (IMHO it's a class transformation), but
> this is really cool and shows how flexible, reusable and all-around awesome
> Tapestry is. :)

Semantics.  The class transformation, informed by the annotation,
drives the composition, just as the Java extends keyword drives
inheritance.

>
> On Wed, 04 May 2011 15:34:48 -0300, Adam Zimowski <zimowsk...@gmail.com>
> wrote:
>
>> 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
>>
>
>
> --
> Thiago H. de Paula Figueiredo
> Independent Java, Apache Tapestry 5 and Hibernate consultant, developer, and
> instructor
> Owner, Ars Machina Tecnologia da Informação Ltda.
> Consultor, desenvolvedor e instrutor em Java, Tapestry e Hibernate
> Coordenador e professor da Especialização em Engenharia de Software com
> Ênfase em Java da Faculdade Pitágoras
> http://www.arsmachina.com.br
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
> For additional commands, e-mail: users-h...@tapestry.apache.org
>
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org
For additional commands, e-mail: users-h...@tapestry.apache.org

Reply via email to