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. :)
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