Liz Douglass

Posts Tagged ‘Java

Being a trainer at the JAMS 2012 Workshop

leave a comment »

Image

At the end of March I had the pleasure of being one of 5 trainers at the JAMS 2012 Workshop at the Makerere University in Kampala, Uganda. The workshop was run by ThoughtWorks in partnership with the Grameen Foundation, with further sponsorship from Yo and SMS Media

Most of the 50 workshop participants were second or third year students from the university. For many of them their only prior experience with Java was from a single semester subject. Before we arrived we thought that the ratio of 50 participants to only 5 trainers was going to be quite challenging. We needn’t have worried though because all the participants were very patient and very switched on. 

The curriculum of the workshop was a combination of agile business analysis, project management and, for the majority of it, hands on developer skill training. As part of the course we ran quite a few of the object boot camp exercises. These exercises, put together by ThoughtWorkers several years back, are often used for internal training. They aim to reinforce the principles of object orientation and introduce some design techniques and patterns. The bootcamp was run in Java, as is often the case. 

Despite never having heard of JUnit and not being clear on language essentials like constructors and equals methods, the participants really impressed us with how they applied themselves. The bootcamp exercises intentionally give participants bandwidth to try things out for themselves and discover what works and what doesn’t. Group discussion is used to drive out the learning points and as instructors we look for code smells like YAGNI. Interestingly with the JAMs group we rarely found that we needed raise the same point twice – even where we expected to. Writing unit tests first and implementing value objects are just two examples of concepts that the students picked up immediately and just started using.

In the last 2 days of the workshop we worked on a web application with the group. The app uses the Java Play framework. It’s called MakVibes and it’s intended help Makerere students track what’s happening on campus. The idea for the app came from one of the workshop participants – Alex. It’s already deployed on Heroku and it’ll be extended in the monthly code jams that are currently being planned. The jams will also involve the attendees working on some code kata problems as well as tech talks. There is a lot of fantastic enthusiasm in Kampala for this kind of ongoing learning as well as a desire to increase the use of technology in business. Uganda is an exciting place to be!

Written by lizdouglass

April 22, 2012 at 11:30 am

Posted in Uncategorized

Tagged with ,

Scala Multiple Constructors

with 3 comments

A couple of weeks ago I created a new type of exception for use in our application. If I’d been using Java I would have written something simple like this:

public class MyException extends RuntimeException {

    public MyException(String message) {
        super(message);
    }

    public MyException(String message, Throwable throwable) {
        super(message, throwable);
    }
}

The Scala multiple constructor model is different to the Java one, as described in this article. In Scala, only the primary class constructor can call a superclass constructor, meaning that it’s only possible to invoke only one superclass constructor. The code above makes calls to two constructors on the RuntimeException class. So how can we write a Scala equivalent? Fortunately one of the answers posted to this question explains a pattern for how to do this:

object MyException {
  private def create(message: String): RuntimeException = new RuntimeException(message)

  private def create(message: String, throwable: Throwable): RuntimeException = new RuntimeException(message, throwable)
}

class MyException private (exception: RuntimeException) {
  def this(message: String) = this (MyException.create(message))

  def this(message: String, throwable: Throwable) = this (MyException.create(message, throwable))
}

I think the pattern is really neat but certainly a lot more complicated that the Java equivalent. I guess this is one of the cases where using Java classes in Scala can be tricky.

Written by lizdouglass

December 15, 2010 at 9:24 am

Posted in Uncategorized

Tagged with ,

Part 3: Recursive menu building

leave a comment »

Part 3 of the Freemarker cleanup involved refactoring menu creation. The application has several menus that appear on the left side of the browser window. These menus are either nested inside eachother or stacked on top of one another.

Before part 3, the creation of the menus was done by one template called main.ftl. This template included other templates (and so on). This was main.ftl:

 
[#ftl]

[#if user.member]
	[#include "/member-menu.ftl"]
[#else]
	[#include "/cross-role-menu.ftl"]
[/#if]
[#if someCondition?? ]
	[#include "/some-menu.ftl"]
[/#if ]
	[#if foo.id !=  user.id]
		[#include "/foo-menu.ftl"]
[/#if ]

All of the menu templates had some conditional logical statements in them – in fact, there was probably an average of about a dozen per template. The only place that these logic statements were tested was in the Selenium tests – obviously not ideal.

The aim of this refactoring was to get rid of all the conditional logic in the templates. The logic would be replaced with tested Java code. This made it possible to render the menus from one single recursive menu template:

 
[#ftl]
[#import "/spring.ftl" as spring /]

[#if menu??]
    [@buildMenu menu=menu depth=0/]
[/#if]

[#macro buildMenu menu depth]
    [#list menu.menuEntries as menuEntry]
        [#if menuEntry.type == "LINK"]
            <div>
                <a href="[@spring.url menuEntry.link?html /]">${menuEntry.caption?html}</a>
            </div>
        [#else]
            [#if menuEntry.menuEntries?size > 0]
                [#if depth > 0]
                    <h3>${menuEntry.caption}</h3>
                    <div id="${menuEntry.name}" class="menu_sub_block">
                [#else]
                    <div id="${menuEntry.name}" class="menu_block">
                    <h5>${menuEntry.caption}</h5>
                [/#if]
                [@buildMenu menu=menuEntry depth=depth+1/]
                </div>
            [/#if]
        [/#if]
    [/#list]
[/#macro]

The new template builds all the menus from the menu model entry. This is added into the model in the MenuInterceptor. This interceptor has dependencies on four factories that create the required menus. The postHandle method creates a rootMenu that contains the other menus:

 
public class MenuInterceptor extends HandlerInterceptorAdapter {
    private FooMenuFactory fooMenuFactory;
    private CrossRoleMenuFactory crossRoleMenuFactory;
    private MemberMenuFactory memberMenuFactory;
    private SomeMenuFactory someMenuFactory;

    @Autowired
    public void setFooMenuFactory(FooMenuFactory fooMenuFactory) {
        this.fooMenuFactory = fooMenuFactory;
    }

    // omitted setters for the other factories

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv)
            throws Exception {

        if (mv != null) {
            User user = (User) request.getAttribute(RequestAttributeNames.user.name());

            Menu rootMenu = new Menu("menu");
            Menu memberMenu = memberMenuFactory.createMemberMenu(user);
            Menu crossRoleMenu = crossRoleMenuFactory.createCrossRoleMenu(user);
            Menu someMenu = someMenuFactory.createSomeMenu(user);
            Menu fooMenu = fooMenuFactory.createFooMenu(user);
            rootMenu.addEntries(memberMenu, crossRoleMenu, someMenu, fooMenu);

            mv.addObject("menu", rootMenu);
        }
    }
}

Each of the menu factories creates a Menu object. The Menu class has a list of MenuEntry objects. There are two implementations of the MenuEntry interface: Link and Menu:

The MenuEntry interface:

 
public interface MenuEntry {

    String getCaption();

    MenuEntryType getType();
}

Menu:

 
public class Menu implements MenuEntry {
    private String caption = "";

    private List<MenuEntry> menuEntries;
    private final String name;

    public Menu(String name) {
        this.name = name;
        menuEntries = Lists.create();
    }

    public void setCaption(String caption) {
        this.caption = caption;
    }

    public void addEntry(MenuEntry menuItem) {
        menuEntries.add(menuItem);
    }

    public String getCaption() {
        return caption;
    }

    public List<MenuEntry> getMenuEntries() {
        return menuEntries;
    }

    public void addEntries(MenuEntry... links) {
        menuEntries.addAll(Arrays.asList(links));
    }

    public MenuEntryType getType() {
        return MenuEntryType.MENU;
    }

    public String getName() {
        return name;
    }
}

… and Link:

 
public class Link implements MenuEntry {

    private final String captionText;
    private final SecureLinks.Link link;

    public SecureContextLink(String captionText, SecureContextLinks.Link link) {
        this.captionText = captionText;
        this.link = link;
    }

    public String getCaption() {
        return captionText;
    }

    public String getLink() {
        return link.toString();
    }

    public MenuEntryType getType() {
        return MenuEntryType.LINK;
    }
}

Each of the factories creates a menu using the logic that was previously in the Freemarker templates. Each factory was developed using TDD and looks a bit like this:

 
public class FooMenuFactory {
    private FooRepository fooRepository;
    private final SecureContextLinks links = new SecureContextLinks();

    public FooMenuFactory(FooRepository fooRepository) {
        this.fooRepository = fooRepository;
    }

    public Menu createFooMenu(User user) {
        Menu fooMenu = new Menu("foo_menu");

        fooMenu.setCaption(user.getDisplayName());

        if (context.isMember()) {
           fooMenu.addEntry(new SecureContextLink("Summary", links.getSomeSummary()));
        }

        // add other links

        return fooMenu;
    }
}

Moving to this style of menu creation reduced 7 templates down to one recursive template. All of the logic that was previously in the templates was moved into Java and was unit tested. (Yay!)

Written by lizdouglass

January 11, 2010 at 6:19 am

Posted in Uncategorized

Tagged with ,

Part 2: SecureLinks

leave a comment »

Part two of the Freemarker cleanup came about when we noticed that we were adding the same links many times into various models. This repetition was eliminated by adding the most common links into the model using an interceptor.

The interceptor has a postHandle method that adds an instance of our new SecureLinks class (below) into the model:

 
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mv)
        throws Exception {

    if (mv != null) {
        mv.addObject("links", new SecureLinks());
    }
}

The SecureLinks class provides the most commonly used links in our application:

 
import my.app.LinkBuilder;
import my.app.QueryString;
import my.app.controller.secure.foo.FooController;
import my.app.controller.secure.bar.BarController;

public class SecureLinks {

    private static final LinkBuilder BUILDER = new SecureLinkBuilder();

    public Link getFooSearch() {
        return new PlainLink(FooController.class);
    }

    public Link getBarList() {
        return new LinkWithQueryString(BarController.class, QueryString().add("letter", "A"));
    }
    
    // other methods omitted for brevity

    public static interface Link {
    }

    public static class PlainLink implements Link {
        private final Class<?> controller;
        private final String methodName;

        public PlainLink(Class<?> controller) {
            this(controller, null);
        }

        public PlainLink(Class<?> controller, String methodName) {
            this.controller = controller;
            this.methodName = methodName;
        }

        @Override
        public String toString() {
            if (methodName != null) {
                return BUILDER.linkTo(controller, methodName);
            }
            return BUILDER.linkToGet(controller);
        }
    }

    public static class LinkWithQueryString implements Link {
        private final Class<?> controller;
        private final String methodName;
        private final QueryString query;

        public LinkWithQueryString(Class<?> controller, String methodName, QueryString query) {
            this.controller = controller;
            this.methodName = methodName;
            this.query = query;
        }

        public LinkWithQueryString(Class<?> controller, QueryString query) {
            this(controller, null, query);
        }

        @Override
        public String toString() {
            if (methodName != null) {
                return BUILDER.linkTo(controller, methodName, query);
            }
            return BUILDER.linkToGet(controller, query);
        }
    }
}

Adding the links into the model in the interceptor means that there is something extra in each ModelMap that may not necessarily be used/required, but we thought that it was worth it to remove the repetition.

Written by lizdouglass

January 6, 2010 at 5:29 am

Posted in Uncategorized

Tagged with ,

Java LinkBuilder

with one comment

Shortly before Christmas Tom and I decided to try to remove logic from some project Freemarker templates. Our first step was to move away from building up URIs inside templates, by creating some sort of Java URI builder.

Background:
We had lots of Freemarker template snippets that looked like this:

[#if member.someType.value != 'Foo']
     <div>[@macros.link_to 'Bar reports' 'member/report?id=${id}&amp;type=M&amp;database=${database}' /]</div>
[/#if]

All of them used the link_to Freemarker macro, which was defined as:

[#macro link_to caption path target='_top']
    [#if path?starts_with("/")]
        [#assign newPath=path?substring(1) /]
    [#else]
        [#assign newPath=path /]
    [/#if]
    <a href="[@spring.url '/appSecureServletPath/${newPath}' /]" target="${target}">${caption}</a>
[/#macro]

What we wanted to achieve first up:

Our aim was to replace all the uses of the link_to macro and instead generate all the URIs in Java and then add them to the model. We wanted to move a template usage like this:

<a href="[@spring.url contactDetailsChange?html /]">Change your contact details</a>

Where the link is added in the controller like so:

modelAndView.addObject("contactDetailsChange", linkBuilder.linkTo(ContactDetailsController.class));

Creating the LinkBuilder:

We did an assessment of all the URI endpoints in our project and realised that:
– We have some controller classes with a request mapping, some controllers that have methods with request mappings and some controllers with a combination of both class and method mappings.
– We have some controllers with more than one GET request method mapping and therefore could not assume only one request method mapping per controller.

We test drove a LinkBuilder interface and a DefaultLinkBuilder implementation for all the combinations we found in the controllers. The idea was to link from one handler class/method to another without being concerned about the specific URI mapped paths.

We also included methods that return a ModelAndView for redirecting and forward from a controller. Some of the methods also take a QueryString microtype (see below).

This is the LinkBuilder interface:

import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

public interface LinkBuilder {

    String linkTo(Class<?> controller, String methodName);

    String linkTo(Class<?> controller, RequestMethod method);

    String linkTo(Class<?> controller, String methodName, QueryString query);

    String linkTo(Class<?> controller, RequestMethod method, QueryString query);

    String linkToGet(Class<?> controller);

    String linkToGet(Class<?> controller, QueryString query);

    String forwardTo(Class<?> controller, String methodName);

    ModelAndView redirectTo(Class<?> controller, String method);

    ModelAndView redirectTo(Class<?> controller);

    ModelAndView redirectTo(Class<?> controller, String method, QueryString query);

    ModelAndView redirectTo(Class<?> controller, QueryString query);
}

And the DefaultLinkBuilder:

import org.apache.commons.lang.ArrayUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import java.lang.reflect.Method;

public class DefaultLinkBuilder implements LinkBuilder {

    private final String prefix;

    public DefaultLinkBuilder() {
        this("");
    }

    public DefaultLinkBuilder(String prefix) {
        this.prefix = prefix;
    }

    public String linkTo(Class<?> controller, String methodName) {
        return prefix + getControllerUrl(controller) + getMethodUrl(controller, methodName);
    }

    public String linkTo(Class<?> controller, RequestMethod method) {
        return prefix + getControllerUrl(controller) + getMethodUrl(controller, method);
    }

    public String linkTo(Class<?> controller, String methodName, QueryString query) {
        return linkTo(controller, methodName) + "?" + query;
    }

    public String linkTo(Class<?> controller, RequestMethod method, QueryString query) {
        return linkTo(controller, method) + "?" + query;
    }

    public String linkToGet(Class<?> controller) {
        return linkTo(controller, RequestMethod.GET);
    }

    public String linkToGet(Class<?> controller, QueryString query) {
        return linkTo(controller, RequestMethod.GET, query);
    }

    public String forwardTo(Class<?> controller, String methodName) {
        return "forward:" + linkTo(controller, methodName);
    }

    public ModelAndView redirectTo(Class<?> controller, String method) {
        return new ModelAndView("redirect:" + linkTo(controller, method));
    }

    public ModelAndView redirectTo(Class<?> controller) {
        return new ModelAndView("redirect:" + linkTo(controller, RequestMethod.GET));
    }

    public ModelAndView redirectTo(Class<?> controller, String method, QueryString query) {
        ModelAndView mv = redirectTo(controller, method);
        query.addToModel(mv.getModel());
        return mv;
    }

    public ModelAndView redirectTo(Class<?> controller, Context context) {
        QueryString queryString = context.asQueryString();
        return redirectTo(controller, queryString);
    }

    public ModelAndView redirectTo(Class<?> controller, QueryString query) {
        ModelAndView mv = redirectTo(controller);
        query.addToModel(mv.getModel());
        return mv;
    }

    private String getControllerUrl(Class<?> controller) {
        RequestMapping annotation = AnnotationUtils.findAnnotation(controller, RequestMapping.class);
        if (annotation != null) {
            return getFirstValue(annotation);
        }
        return "";
    }

    private String getMethodUrl(Class<?> controller, String methodName) {
        Method[] methods = controller.getMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
                if (annotation != null) {
                    return getFirstValue(annotation);
                }
            }
        }
        throw new IllegalArgumentException("Cannot find method with name " + methodName
                + " with a RequestMapping annotation on controller " + controller.getName());
    }

    private String getMethodUrl(Class<?> controller, RequestMethod requestMethod) {
        Method[] methods = controller.getMethods();
        for (Method method : methods) {
            RequestMapping annotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
            if (annotation != null) {
                if (ArrayUtils.contains(annotation.method(), requestMethod)) {
                    return getFirstValue(annotation);
                }
            }
        }
        throw new IllegalArgumentException("Cannot find method that can handle " + requestMethod
                + " requests on controller " + controller.getName());
    }

    private String getFirstValue(RequestMapping annotation) {
        String[] value = annotation.value();
        if (value.length > 0) {
            return value[0];
        }
        return "";
    }
}

We have two subclasses of the DefaultLinkBuilder the SecureLinkBuilder and the UnsecureLinkBuilder. These classes simply set the appropriate servlet path as the prefix.

The QueryString class knows how to add itself into the model:

import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.util.EncodingUtil;

import java.util.List;
import java.util.Map;

public class QueryString {

    private final List<NameValuePair> pairs = Lists.create();

    public QueryString add(String name, String value) {
        pairs.add(new NameValuePair(name, value));
        return this;
    }

    public boolean isEmpty() {
        return pairs.isEmpty();
    }

    public NameValuePair[] toArray() {
        return pairs.toArray(new NameValuePair[pairs.size()]);
    }

    public void addToModel(Map<String, Object> model) {
        for (NameValuePair pair : pairs) {
            model.put(pair.getName(), pair.getValue());
        }
    }

    @Override
    public String toString() {
        return EncodingUtil.formUrlEncode(toArray(), "UTF-8");
    }
}

The creation of the LinkBuilder and the implementations allowed us to go through all the controllers and add links into the models. We removed a lot of string concatenation in templates doing this.

Written by lizdouglass

January 5, 2010 at 10:13 am

Posted in Uncategorized

Tagged with , ,

Refactoring using an Effect Sketch

with one comment

Today I worked on my own rather than pairing. What made the day even more unusual was that there were no other developers in the room – oddly enough lots of people have taken leave at the same time.

I spent a good part of the day refactoring the one class. This refactoring was the last chunk of work for a story that Silvio and I paired on for a couple of days last week. This morning the code looked a bit like this:

@Component
public class FooStrategyModelFactory {

    private final MemberRepository memberRepository;
    private final BarRepository barRepository;
    private final FooStrategyRepository fooRepository;
    private final BarViewFactory barViewFactory;
    private final JsonConverter jsonConverter;

    @Autowired
    public FooStrategyModelFactory(MemberRepository memberRepository,
                                   BarRepository barRepository,
                                   FooStrategyRepository fooRepository,
                                   BarViewFactory barViewFactory,
                                   JsonConverter jsonConverter) {

        this.memberRepository = memberRepository;
        this.barRepository = barRepository;
        this.fooRepository = fooRepository;
        this.barViewFactory = barViewFactory;
        this.jsonConverter = jsonConverter;
    }

    public ModelMap createViewModel(UserAccount userAccount, Context context, HttpServletRequest request,
                                    List changeData) {

        ModelMap model = new ModelMap();

        Member member = memberRepository.getMember(userAccount, context);

        List availableBars = getAvailableBarsForMember(context, changeData);

        List availableWidgetBars = Lists.select(availableBars, new WidgetBarMatcher());

        List BarViews = barViewFactory.createBarViews(availableWidgetBars, member.getAccountType());

        model.addAttribute("Bars", jsonConverter.toJson(BarViews));

        addBarStrategiesToModel(userAccount, context, request, model, member, availableBars);

        return model;
    }

    private void addBarStrategiesToModel(UserAccount userAccount, Context context,
                                         HttpServletRequest request,
                                         ModelMap model,
                                         Member member,
                                         List availableBars) {

        List strategies = getCurrentStrategiesForMember(userAccount, context, availableBars, request);

        List strategyViews = barViewFactory.createBarStrategyViews(
                strategies, availableBars, member.getAccountType());

        model.addAttribute("cashFlowStrategyItems", jsonConverter.toJson(strategyViews));
    }

    protected List getAvailableBarsForMember(Context context, List changeData) {
        List thing = barRepository.getThingsForMember(context);

        List memberBars = Lists.map(things, new Function() {
            public Bar apply(Thing thing) {
                return thing.getBar();
            }
        });

        List newlyAddedChangeData = Lists.select(changeData, new NewlyAddedChangeDataMatcher());
        for (ChangeData changeDataItem : newlyAddedChangeData) {
            memberBars.add(barRepository.getBarByBarNumber(changeDataItem.getBarNumber()));
        }

        List newChangeData = Lists.select(changeData, new NewChangeDataMatcher());

        return Lists.reject(memberBars, new OtherChangeDataMatcher(newChangeData));
    }

    protected List getCurrentStrategiesForMember(UserAccount userAccount, Context context,
                                                              List Bars, HttpServletRequest request) {

        String json = (String) WebUtils.getSessionAttribute(request, UpdatedBarStrategy.SESSION_KEY);
        if (StringUtils.isNotEmpty(json)) {
            List strategies = jsonConverter.fromJsonArray(json, UpdatedBarStrategy.class);
            return Lists.map(strategies, new BarStrategyFactory(Bars));
        }
        return fooRepository.load(userAccount, context);
    }
}

Hmmm, where to begin?….. I decided to try to tackle this class by drawing an effect sketch in my notebook. This idea is detailed by Michael Feathers in his book Working Effectively With Legacy Code. We’ve been reading this book at book club and have had several group discussions about the approach. On my diagram I drew nodes for each of the class fields as well as the methods, plus the arguments that are passed into createViewModel. I ended up with loads of lines criss-crossing the page connecting them. I won’t even attempt to reproduce what I wound up with here. I did clarify a few things by doing this though:

  • The factory was doing lots of data retrieval and manipulation as well as creating the ModelMap.
  • The getAvailableBarsForMember method was assembling query information from several sources. It had protected scope and there were three unit tests in place that were testing this method.
  • The getCurrentStrategiesForMember method was also querying information from multiple sources. This was the only method that used the fooRepository. It also had a protected scope and a number of dedicated unit tests.
  • The addBarStrategiesToModel method was extracted from the createViewModel method during an earlier refactoring. At one point there was also an addInvestmentsToView method that had since been in-lined. We were left with an inconsistent abstraction level in the createViewModel method.

I refactored this class in a few steps. First up I moved the getAvailableBarsForMember method into its own class called the FooBarRepository. I also kept the method on FooStrategyModelFactory as a wrapper so that all my unit tests would still compile and run. Then I moved the three unit tests for this logic into a test class for my new FooBarRepository.

It took me a little while to come up with a name for this class because I debated over whether this was a service or a repository. I ended up going with a repository name because it does retrieve domain objects.

@Component
public class FooBarRepository {
    private BarRepository barRepository;

    @Autowired
    public FooBarRepository(BarRepository BarRepository) {
        this.barRepository = BarRepository;
    }

    protected List getAvailableBarsForMember(Context context, List changeData) {
        List thing = barRepository.getThingsForMember(context);

        List memberBars = Lists.map(things, new Function() {
            public Bar apply(Thing thing) {
                return thing.getBar();
            }
        });

        List newlyAddedChangeData = Lists.select(changeData, new NewlyAddedChangeDataMatcher());
        for (ChangeData changeDataItem : newlyAddedChangeData) {
            memberBars.add(barRepository.getBarByBarNumber(reweightDataItem.getBarNumber()));
        }

        List newChangeData = Lists.select(changeData, new ChangeDataMatcher());

        return Lists.reject(memberBars, new OtherChangeDataMatcher(newChangeData));
    }

    public List getAvailableWidgetBarsForMember(List availableBarsForMember) {
        return Lists.select(availableBarsForMember, new WidgetBarMatcher());
    }
}

I did something similar with the getCurrentStrategiesForMember method. I moved it into a class called FooBarStrategyRepository and moved the relevant unit tests from the FooStrategyModelFactory test class.

@Component
public class FooBarStrategyRepository {
    private JsonConverter jsonConverter;
    private BarRepository barRepository;
    private FooStrategyRepository fooRepository;

    @Autowired
    public FooBarStrategyRepository(JsonConverter jsonConverter,
                                    BarRepository BarRepository,
                                    FooStrategyRepository fooRepository) {
        this.jsonConverter = jsonConverter;
        this.barRepository = BarRepository;
        this.fooRepository = fooRepository;
    }

    protected List getBarStrategiesForMember(UserAccount userAccount, Context context,
                                                          List candidateBars,
                                                          HttpServletRequest request) {

        String json = (String) WebUtils.getSessionAttribute(request, UpdatedBarStrategy.SESSION_KEY);
        if (StringUtils.isNotEmpty(json)) {
            List strategies = jsonConverter.fromJsonArray(json, UpdatedBarStrategy.class);
            return Lists.map(strategies, new BarStrategyFactory(candidateBars, barRepository));
        }
        return fooRepository.load(userAccount, context);
    }
}

My final step was to assess what was left in the FooStrategyModelFactory. I inlined the addBarStrategiesToModel method and then noticed that I really had two themes:
– Gathering and manipulation of data
– Creating and populating a model using that data

I decided to extract out the model creation and population into a separate method. This is the how FooStrategyModelFactory ended up looking:

@Component
public class FooStrategyModelFactory {

    private final MemberRepository memberRepository;
    private final BarViewFactory barViewFactory;
    private final JsonConverter jsonConverter;
    private FooBarRepository fooBarRepository;
    private FooBarStrategyRepository fooStrategyRepository;

    @Autowired
    public FooStrategyModelFactory(MemberRepository memberRepository,
                                   BarViewFactory barViewFactory,
                                   JsonConverter jsonConverter,
                                   FooBarRepository fooBarRepository,
                                   FooBarStrategyRepository fooStrategyRepository) {

        this.memberRepository = memberRepository;
        this.barViewFactory = barViewFactory;
        this.jsonConverter = jsonConverter;
        this.fooBarRepository = fooBarRepository;
        this.fooStrategyRepository = fooStrategyRepository;
    }

    public ModelMap createViewModel(OnlineUserAccount userAccount, Context context, HttpServletRequest request,
                                    List changeData) {

        Member member = memberRepository.getMember(userAccount, context);

        List availableBars = fooBarRepository.getAvailableBarsForMember(context, changeData);

        List availableWidgetBars = fooBarRepository.getAvailableWidgetBarsForMember(availableBars);

        List strategies = fooStrategyRepository.getBarStrategiesForMember(userAccount, context, availableBars, request);

        return createModel(member.getAccountType(), availableBars, availableWidgetBars, strategies);
    }

    private ModelMap createModel(AccountType membersAccountType, List availableBars,
                                 List availableWidgetBars, List membersFooBarStrategies) {

        ModelMap model = new ModelMap();

        List BarViews = barViewFactory.createBarViews(availableWidgetBars, membersAccountType);

        model.addAttribute("Bars", jsonConverter.toJson(BarViews));

        List strategyViews = barViewFactory.createBarStrategyViews(membersFooBarStrategies,
                availableBars, membersAccountType);

        model.addAttribute("cashFlowStrategyItems", jsonConverter.toJson(strategyViews));

        return model;
    }

}

I think the code is now cleaner than it was at the beginning of the day, although I’m sure there could be more done to it. The effect sketch did help and I think I would use it again, perhaps even when pairing.

(Please note that WordPress removed all the Java generics ‘tags’ from the code in this post)

Written by lizdouglass

December 7, 2009 at 7:23 am

Posted in Uncategorized

Tagged with ,

Log4j SMTPAppender

with one comment

Our current project is due for another release to production very soon. Last week Tom added another appender into our log4j configuration for our UAT enviroment. This appender is an SMTPAppender and it sends emails to a group list for our project team. This new appender is set to the ERROR severity. The configuration for this appender looks like this:

log4j.appender.email=org.apache.log4j.net.SMTPAppender
log4j.appender.email.From=me@email
log4j.appender.email.To=us@email
log4j.appender.email.Subject=[AppName] UAT Exception
log4j.appender.email.SMTPHost=host
log4j.appender.email.SMTPUsername=user
log4j.appender.email.SMTPPassword=pass
log4j.appender.email.layout=org.apache.log4j.PatternLayout
log4j.appender.email.layout.ConversionPattern=%d{ISO8601} %-5p [%t %x] [%c{1}] – %m%n
log4j.appender.email.Threshold=ERROR

As of this morning we had recevied 17 emails from UAT. There were 8 types of errors and  the most occurrences of any one type of error was 6. We always had access to this information in the log files of course, but getting the emails has had several advantages:

  • The emails draw your attention – the visibility of problems in UAT has been increase.
  • We’re more inclined to investigate the cause of the error/exception earlier. Previously the devs would generally only become aware of exceptions in UAT when one of our QAs asked one of us to take a look. Having the email going to all the devs also means that more people look at the exception and we are able to troubleshoot it more easily.
  • It’s easier to group exception types – we can collect data about the exceptions more easily.

The plan is to include an SMTPAppender in the log4j configuration for our production environment. I think this is a very good idea and would recommend doing it.

Written by lizdouglass

October 20, 2009 at 9:02 am

Posted in Java

Tagged with ,

iBATIS

leave a comment »

We are using iBATIS on my current project for XML-based object relational mapping. I downloaded the developer guide recently because I was interested to learn about the tool and how this part of our code works. This is what I found out:

1. Repositories
We have ten or so repositories in our code base that all look something like this:

import my.common.util.Maps;
import my.domain.Account;
import my.domain.OrderInfo;
import my.domain.OrderInfoState;
import org.springframework.orm.ibatis.SqlMapClientOperations;

import java.util.List;
import java.util.Map;

public class OrderRepository {

    private final SqlMapClientOperations template;

    public OrderRepository(SqlMapClientOperations template) {
        this.template = template;
    }

    public void insert(OrderInfo orderInfo) {
        template.insert("insertOrder", orderInfo);
    }

    @SuppressWarnings({"unchecked"})
    public List findOtherPendingOrdersForAccount(Account account, String orderIdToExclude) {
        Map params = Maps.create();
        params.put("accountNumber", account.getNumber());
        params.put("orderIdToExclude", orderIdToExclude);
        params.put("orderRequestPendingStates", OrderInfoState.PENDINGSTATES);

        return template.queryForList("findPendingOrdersForAccount", params);
    }

    public void setCompletedNotificationSent(String orderId) {
        template.update("setOrderAccountType", orderId);
    }
}

Each repository has a dependency on SqlMapClientTemplate which according to the Spring API is a “helper class that simplifies data access via the iBATIS SqlMapClient API, converting checked SQLExceptions into unchecked DataAccessExceptions”. We use the template to execute SQL statements that are defined in XML SQL Map files – but let’s get back to that in a moment.

2. Next let’s have a look at how this is all wired together in Spring:

<bean id="OrderRepository">
 <constructor-arg ref="sqlMapClientTemplateForApp"/>
</bean>

<bean id="sqlMapClientTemplateForApp">
 <property name="sqlMapClient" ref="sqlMapClientForApp"/>
</bean>

<bean id="sqlMapClientForApp">
 <property name="configLocation" value="classpath:/sqlmap.xml"/>
 <property name="dataSource" ref="appDataSource"/>
</bean>

<bean id="appDataSource" destroy-method="close">
 <property name="driverClassName" value="${my.datasource.driver}"/>
 <property name="url" value="${my.datasource.url}"/>
 <property name="username" value="${my.datasource.username}"/>
 <property name="password" value="${my.datasource.password}"/>
</bean>

Bean sqlMapClientForApp has a property configLocation which has been set to "classpath:/sqlmap.xml". Inside sqlmap.xml we have a few custom handlers (more on that later too) as well as a list of XML SQL Map files (one for each repository):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig PUBLIC "-//batis.apache.org/DTD SQL Map Config 2.0//EN"
 "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
 <typeHandler javaType="my.domain.Money"
 callback="my.domain.MoneyTypeHandlerCallback"/>

 <sqlMap resource="sqlmaps/orderinfo.xml"/>

</sqlMapConfig>

4. The juicy bit – the SQL Map files

These are XML descriptor files that are used by the iBATIS Data Mapper to map JavaBeans to SQL prepared statements. As explained in the developer guide, iBATIS accepts parameters as input into prepared statements and builds result objects from the ResultSet returned. Below is a cut down version of a typical iBATIS SQL Map configuration file from our code. It has three statements defined – each corresponding to the methods in the repository class above. I have annotated the file with comments explaining the iBATIS syntax:

<sqlMap namespace="orderInfo">

 <!-- Type aliases for fully qualified class names. -->
 <typeAlias alias="orderInfo" type="my.domain.OrderInfo"/>
 <typeAlias alias="account" type="my.domain.Account"/>

 <resultMap id="orderInfoResult" class="orderInfo"> <!-- This class will be instantiated and populated from the data in the ResultSet -->
 <!-- This controls that data that is taken from the ResultSet and how it maps to columns -->
 <result property="orderId" column="order_id"/>
 <result property="orderDate" column="order_date"/>
 <result property="userId" column="user_id"/>
 <result property="account.number" column="account_id"/>
 <result property="account.type" column="account_type"/>
 <result property="account.name" column="account_name"/>
 </resultMap>

 <sql id="order_info_attributes"> <!-- This fragment can be included in the SQL statements. See below -->
 order_info.id,
 order_info.order_id,
 order_info.order_date,
 order_info.user_id,
 order_info.account_id,
 order_info.account_type,
 order_info.account_name
 </sql>

 <!-- This select query uses the resultMap declared above-->
 <!-- This is a mapped statement. These can have param maps as input and result maps as output -->
 <select id="findPendingOrdersForAccount"
 parameterClass="map"
 resultMap="orderInfoResult"> <!--The parameterClass "map" is an alias for a java.util.Map -->
 <!--The SQL can be anything that is valid for the JDBC driver -->
 SELECT DISTINCT
 <include refid="order_info_attributes"/> <!-- This includes the order_info_attributes fragment above -->
 FROM order_info INNER JOIN order_request ON order_info.order_id = order_request.order_id
 WHERE order_info.account_id = #accountNumber#  <!-- This is an inline parameter map reference-->
 AND order_info.order_id != #orderIdToExclude#
 AND (
 order_request.state IN (
 <iterate property="orderRequestPendingStates" conjunction=",">
 #orderRequestPendingStates[]#
 </iterate> <!-- This is an iterate dynamic element. The property attribute defines the array or java.util.Collection or java.util.Iterator type to be iterated over -->
 )
 </select>

 <insert id="insertOrder"
 parameterClass="orderInfo">  <!-- The parameterClass is used to restrict the objects that can be passed as an input parameter -->
 INSERT INTO order_info(order_id, order_date, user_id, account_id, account_type, account_name)
 VALUES(#orderId#, #orderDate#, #userId#, #account.number#, #account.type#, #account.name#)
 <selectKey resultClass="int" keyProperty="id">  <!-- iBATIS supports auto-generated keys -->
 SELECT LAST_INSERT_ID() AS id
 </selectKey>
 </insert>

 <update id="setOrderAccountType" parameterClass="string">
 UPDATE order_info SET account_type = blah WHERE order_id = #value#
 </update>

</sqlMap>

5. Custom type handlers

Some of our repositories use the iBATIS custom type handlers declared in the sqlmap.xml file (above) to map columns to specific types in our domain. For example the sellPrice field on Product is Money type:

<resultMap id="productMapping">
 <result property="sellPrice" column="sell_price"/>
 <result property="status" column="status"/>
</resultMap>

iBATIS will use the MoneyTypeHandler below to create a Money instance from the sell_price value. Each one of these handlers implements the TypeHandlerCallback interface.

import my.domain.Money;
import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Types;

public class MoneyTypeHandler implements TypeHandlerCallback {

    public void setParameter(ParameterSetter parameterSetter, Object obj) throws SQLException {
        if (obj == null) {
            parameterSetter.setNull(Types.DECIMAL);
        } else {
            Money money = (Money) obj;
            parameterSetter.setBigDecimal(money.toBigDecimal());
        }
    }

    public Object getResult(ResultGetter resultGetter) throws SQLException {
        BigDecimal value = resultGetter.getBigDecimal();
        return (value != null) ? new Money(value) : Money.ZERO;
    }

    public Object valueOf(String value) {
        return value;
    }
}

Written by lizdouglass

September 13, 2009 at 7:09 am

Posted in Uncategorized

Tagged with , ,

On mocking and Spring

with one comment

Two weeks ago I was pairing with Alex on some Java integration tests for an application that uses Spring for dependency injection. Whilst writing one of the tests we realised that we needed to mock some behaviour on one of our Spring configured classes. Instinctively the simplest way to do this would be to replace the bean in our application context with another one, but alas after some brief investigation we discovered this is not an option.We ended up using the same pattern that was already in use in our code base, and I’m sure it’s one that some people will be familiar with:

First up we extracted an interface from the class that whose behaviour we wanted to mock:

public interface FooRepository {
    Foo loadFor(XYZ xyz);
}

Next we created a new Application Context XML configuration file to use for the test and included the ‘real’ one from our application. We also defined a stub class that implemented our new interface. It also had the same id as the class that we wanted to mock behaviour for meaning that the pre-existing definition would be overridden:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd">
 <bean id="FooRepository" class="FooRepositoryStub"/>
 <import resource="applicationContext.xml"/>
</beans>

Now for the behaviour that we want in the test…. Singleton scoped Spring beans are loaded at start-up (unless you have lazy loading which we do not). Hence if we want to be able to define specific behaviour inside a test we can’t use on our stub implementation alone – rather we need to use the stub as a wrapper for a delegate:

public class FooRepositoryStub implements FooRepository {

    private FooRepository delegate;

    public Foo loadFor(XYZ xyz) {
        return delegate.loadFor(xyz);
    }

    public void setDelegate(FooRepository delegate) {
        this.delegate = delegate;
    }
}

The delegate can then be used to provide the mocking that we wanted all along:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext-test.xml")

public class ValidationIntegrationTest {

    @Autowired
    private FooRepository FooRepository;
    private FooRepository FooRepositoryDelegate = mock(FooRepository.class);

    @Before
    public void initializeRepositoryDelegates() {
        ((FooRepositoryStub) FooRepository).setDelegate(FooRepositoryDelegate);
    }

    @Test
    public void shouldInvalidateXYZWhenTheABCRuleIsViolated() {
        XYZ xyz = givenSomeContext();
        andTheUserHoldsFoo(xyz);
        whenSomethingHappends(xyz);
        thenItShouldFailWithReasons(xyz, "XYZ failed because of the ABC rule was violated");
    }

    private void andTheUserHoldsFoo(XYZ xyz) {
        Foo foo = mock(Foo.class);
        when(FooRepositoryDelegate.loadFor(xyz)).thenReturn(foo);
    }
    ....
}

So, with only an interface, another ApplicationContext XML file, a stub and a mock, we can define the behaviour in the test that we wanted (phew)! I’ve used PicoContainer before and only just now realise how easy with had it in setting up tests. Of course there may be an easier way to do all this – and if you have one then I’d love to hear from you.

Written by lizdouglass

August 20, 2009 at 9:47 pm

Posted in Java

Tagged with , , ,

Melbourne Scala Users Group

with 3 comments

On Monday night I braved a blustery wet Melbourne night to go to the first Scala Melbourne Users Group meeting at IBS.

The first speaker was Ben Hutchison. Ben presented Combining Object-Oriented and Functional programming, focusing on the features of the language that stand out for him. Ben said that he has really enjoyed what he’s been doing in Scala although he admits it has been a bit of a steep learning curve.
Here’s some things that Ben mentioned that I learnt from the presentation:

  • Functions are first class objects in Scala. From the example Ben showed it appears that you do have to know a little about the syntax in order to understand what the arguments to a method are and what its return type is.
  • You can override methods with fields and all operators are just methods.
  • You can declare a variable as mutable or immutable using the keyword var (mutable) or val (immutable).
  • Ben spent quite a bit of time on traits, which I basically understand from him to be not unlike modules in Ruby. It is possible for a class to inherit multiple traits, and traits can even inherit from other traits (and even classes in unusual circumstances!).The traits concept seems very powerful – for example Ben mentioned one trait called Ordered that when applied to a class effectively gives your class a group of methods like < (less than) and > (greater than) and all you have to do is implement the compare method.
  • Ben talked about mixing OO and functional programming – something that Nick taught me on my last project. In particular Ben spoke about how functions should be side effect free – an idea that Eric Evans talks about in Chapter 10 in Domain Driven Design.

Mark Ryall was the next presenter and he spoke about Scala’s XML support as well as a bit about using Lift on the Google App Engine. From Mark’s presentation I learnt:

  • It is possible to assign some XML to a variable in Scala
  • You can do either DOM or SAX style parsing of XML, and if your not happy with those options there are some pretty cool extraction operators, that look a bit like XPath when they’re used as Mark pointed out.
  • There’s also XML pattern matchers that can match on XML nodes, but will not work on element attributes at the moment at least.
  • You can generate an XML document by calling savefull. It’s also possible to insert Scala code into an XML document and then write that out.
  • Mark has got a Lift application working on the Google App Engine although apparently it was tricky to get going. One of the really impressive things about what he showed was the really concise user authentication that used the Google Accounts.

Jeremy Mawson was the third speaker for the evening and he focused on testing and more specifically on using specs, which I’d not heard of before. In a lot of ways the tests that he showed us looked like RSpec tests but the syntax does not read quite as nicely as RSpec does.

  • Jeremy showed us how you can nest expectations in specs.
  • Apparently there are over 100 matchers already in specs – and if that’s not enough you can write your own
  • spec makes use of implicit function definition to write the tests
  • specs is one of a handful of Scala testing frameworks 
  • You can use JMock and Mockito in Scala

Overall I’d say it was a really successful meeting. I certainly learnt a lot from the three speakers. I would recommend getting along to the next meeting if you’re in Melbourne. Ben did mention that he was thinking of making the next meeting a practical one. Perhaps he can check out Mark’s blog entries about the TW Sydney Wednesday Night Dojo for some ideas.

Written by lizdouglass

May 3, 2009 at 12:17 pm

Posted in Scala

Tagged with , , ,