back to blog index..

Ilybra: aspects battlefield

May 29, 2005

Great people like Ron Bodkin talk about the pragmatic way of doing software. So why don't me, when I have this experience and I'm just hot to tell the world to look at the other side of this matrix..

Ilybra is a battlefield when it comes to aspects. Ther first aspect was tracing of course, the rest you see below, and today I got an idea on another one to my collection. Some people will even call my aspects "enterprise"! As you wish :) I don't know the meaning of that word. I just develop an application for my library ladies.. ;)

Like it was said in the Ilybra: introduction, Ilybra utilizes some custom made aspects. They are:

Many! lines of code has just disappeared from my classes. This is the core value of aspects. My code is cleaner.

I will demonstrate you my Struts' action code with: tracing, authorization, persistence, returning empty String instead of null, resetting forms and measuring time of invocation of action - ufff, a lot :) :

My full, original code (without any cheating or removal lines of code for the sake of the presentation of the example) of user story: Prolong copy on reader's account: enter new date, accept choice, view confirmation.
Note: of course, there exists one, additional, global ilybra-aop.xml AOP configuration file for defining pointcuts.

public class ProlongCopy
       extends IlybraAction
{
    public ActionForward execute(ActionMapping mapping, 
                                 ActionForm form,
                                 HttpServletRequest request, 
                                 HttpServletResponse response)
    {
        BookForm bookForm = (BookForm) form;
        String prolongDate = bookForm.getReturnDate();
        Library library = getWorld().getLibrary(); //the first reason for
                                                   //the base IlybraAction class

        Copy copy = library.getCopies().getCopyById(
                    bookForm.getCopyId()
        );
        Utils.notNullAssertion("Copy: ", copy);  
                                //I wait for this to become an aspect :)

        library.prolongCopy(copy, Dates.someDateByString(prolongDate));
        saveOneMessage(request, "message.prolong.change.success", 
                                copy.getSignature());
                                //second reason for IlybraAction

        return mapping.findForward("success");
    }
}

Interested in library.prolongCopy(..) or library.getCopyById(..)??
/** @@pat.transaction */
public void prolongCopy(Copy copy, DateRepresentation newReturnDate)
{
    copy.returnDate = newReturnDate;
}

public Copy getCopyById(Long id) {
    return (Copy) copies.get(id);     //copies is java.util.Map
}

..Authorization and authentification are common in applications. And so it is with Ilybra. It is 2 years now, I started to work on the application, but only from the last week the system must authorize a reader to access his account.

What is important here I've managed to add this concern - orthogonal concern - after the application was finished. I've done it with one simple aspect listening on all Struts actions, which checks if there is a User object in a session. Implementation is trivial. And aspect oriented way turned out to work. (This implementation could also be done using "servlet's filters", as they also crosscut expected behaviour in this particular example).

Code of the aspect on the plate:

<bind pointcut="execution(* $instanceof{Action}->execute(*))"
          cflow="(notInLoginAction AND notInLogoutAction)">
    <advice aspect="AuthorizingAspect" name="checkUserLoggedIn"/>
</bind>
public class AuthorizingAspect
{
    public Object checkUserLoggedIn(Invocation invocation) 
    throws Throwable
    {
        MethodInvocation mi = (MethodInvocation) invocation;
        ActionMapping mapping = (ActionMapping) mi.getArguments()[0];
        HttpServletRequest request = (HttpServletRequest) mi.getArguments()[2];

        User sessionUser = getUserFromSession(request);
        String servletPath = request.getServletPath();

        if (servletPath.startsWith("/anonymous/"))
        {
            return letThrough_becauseAnonymousCall(invocation);
        }
        
        if (null == sessionUser)
        {
            storeUserRequestInSession(request, mapping);
            return redirectToLoginPage(mapping);
        }
        else
        {
            if (userIsAuthorizedToAction(servletPath, sessionUser))
                return letThrough_becauseIsAuthorized(invocation, sessionUser);
            else
                return redirectToHomePage(mapping, sessionUser);
        }            
    }
    private ....
}

I hope those examplets will clear your mind for a moment :)

Take care,
Tomasz Nazar

Interested in How do I test the Ilybra application with aspects applied?"

Designed with CSS| Get Firefox!| | Opel Omega Forum|

Copyright © Tomasz Nazar 2007
Revision: $Id: blog_ilybra_aspects_battlefield.gtml 3768 2005-07-25 23:47:33Z nthx $