toniBlog

November 20, 2008

Controllers and validation with Waffle

Filed under: General Stuff — toni @ 1:21 pm

One of the nicest features of Waffle are the Validators.
In order to have server side validation on some controller logic you don’t need to extend or write any fluff.
Given a method on your controller like this one:

package waffle.controllers;

import org.codehaus.waffle.view.RedirectView;
import org.codehaus.waffle.view.View;

public class UserLoginController {

	public View login(String username, String password) {
		return new RedirectView("homepage.waffle");
	}
}

All you have to do is write a class named UserLoginControllerValidator (just for convention, not strictly necessary) and a method with the same syntax as the action on the Controller with also the ErrorsContext parameter in the signature.

For a simple application login it will look more or less like this:

package waffle.validators;

import org.codehaus.waffle.validation.ErrorsContext;
import org.codehaus.waffle.validation.FieldErrorMessage;

import waffle.services.AuthenticationExeption;
import waffle.services.AuthenticationService;

public class UserLoginControllerValidator {

	private final AuthenticationService authenticationService;

	public UserLoginControllerValidator(AuthenticationService authenticationService) {
		this.authenticationService = authenticationService;
	}

	public void login(ErrorsContext errors, String username, String password) {
		try {
			authenticationService.login(username, password);
		} catch (AuthenticationExeption exeption) {
			errors.addErrorMessage(new FieldErrorMessage("name", username, exeption.getMessage()));
		}
	}
}

Well the design is pretty clean right?
There’s no coupling, there is no inheritance involved and the responsibilities of the classes are well isolated: the controller controls, redirects, the validator validates.

With such an easy design also testing becomes easier.
Here a sample test to check that the proper message has been added to the ErrorContext.

package waffle.controllers;

import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

import org.codehaus.waffle.validation.ErrorsContext;
import org.codehaus.waffle.validation.FieldErrorMessage;
import org.junit.Test;

import waffle.services.AuthenticationExeption;
import waffle.services.AuthenticationService;
import waffle.validators.UserLoginControllerValidator;

public class UserLoginControllerValidatorTest {

	private static final String username = "test";
	private static final String password = "test";

	@Test
	public void shouldAddAnUserNotFoundErrorWhenUserNotFoundWithTheService() throws Exception {
		// given
		AuthenticationService service = mock(AuthenticationService.class);
		UserLoginControllerValidator validator = new UserLoginControllerValidator(service);
		ErrorsContext errors = mock(ErrorsContext.class);

		// when
		doThrow(new AuthenticationExeption("User not found")).when(service).login(username, password);
		validator.login(errors, username, password);

		// then
		FieldErrorMessage expectedErrorMessage = new FieldErrorMessage("name", username, "User not found");
		verify(errors).addErrorMessage(argThat(new IsAnErrorMessageLike(expectedErrorMessage)));
	}

}

I’m, indeed, using Mockito and IsAnErrorMessageLike is a custom Hamcrest Matcher, it looks like:

package waffle.controllers;

import org.codehaus.waffle.validation.ErrorMessage;
import org.codehaus.waffle.validation.FieldErrorMessage;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;

public class IsAnErrorMessageLike extends BaseMatcher {

	private final FieldErrorMessage fieldErrorMessage;

	public IsAnErrorMessageLike(FieldErrorMessage fieldErrorMessage) {
		this.fieldErrorMessage = fieldErrorMessage;
	}

	@Override
	public boolean matches(Object object) {
		if (object == null)
			return false;
		if (!(object instanceof FieldErrorMessage))
			return false;

		FieldErrorMessage other = (FieldErrorMessage) object;

		if (other.getMessage().equals(fieldErrorMessage.getMessage())
				&& (other.getName().equals(fieldErrorMessage.getName()))
				&& (other.getType().equals(fieldErrorMessage.getType()))
				&& (other.getMessage().equals(fieldErrorMessage.getMessage()))
				&& (other.getValue().equals(fieldErrorMessage.getValue())))
			return true;

		return false;
	}

	@Override
	public void describeTo(Description description) {
		description.appendText(fieldErrorMessage.toString());
	}
}

November 19, 2008

A cool guy, a cool software: Balsamiq application mockups

Filed under: General Stuff — Tags: , , , , — toni @ 5:03 pm

Balsamiq mockups is a cool application to quickly, easily write applications mockups and share them on the web, some benefits taken from its website: 

  • Improve your Usability
  • Explore Different Designs in Minutes
  • Get to Agreement Early with a tool everyone can use
  • Cut down spec-writing time
  • Spend your time coding, not churning
  • Use it with your clients, Letting them help you bring their vision to life
  • Integrated in the way you work, Web, Desktop or Web Office

Thanks to Alberto that forwarded me this blog post about the creator of this nice piece of software:

The story is about Giacomo ‘Peldi’ Guilizzoni, a former Senior Software Engineering Lead at Adobe in San Francisco, who moved back to Italy and started a company called Balsamiq

His company is actually a “Micro-ISV” or a single-employee company. That is, a guy in a studio. A guy who wrote a product called “Balsamiq Mockups” which allows anyone to build a mockup of a GUI: the genius is that the mockup resembles one you would scribble on a piece of paper, rather than a computer one. It sells online for $79.

To make the story short, the product is fantastic and he grossed over $100k in five months. And the business is growing fast.

Why do I know? Because he made it all public in his blog. He promised he would do it. And you have all the measures of his business (and how much he is donating to non-profits).

Waffles are good, do you fancy a Waffle?

Filed under: General Stuff — Tags: , , , , — toni @ 12:35 pm

During ThoughtWorks University XI we took the decision to introduce to the trainees Waffle as an example of MVC framework

I’ve been impressed by the simplicity of the framework. It has been a while since the last time I’ve played with any Java Web Framework ( I think it was around 6 years ago the last time, using the super hated Struts 1.0! )

So the first good news is the Java world is alive and some good people are writing great frameworks ( with also the big help of all the knowledge/experience gained using other languages) 

I’ve a very personal opinion on this: many people moved to Ruby and have such a bad remembering of the old times in Java, well I think that frameworks like Waffle keeps the name of Java high. 

In addition to that Waffle has a nicer design compared to Rails, no command line scripting ( you might like it, I don’t ), it’s not annotation heavy and you don’t have to write a line of xml ( ok, just one but in the web.xml! )

The only bad thing of Waffle is that there’s not that much documentation on the web ( I’ve to say that it’s so simple to use that you don’t need it! ) so my goal for the next months will be blog as much as possible about it and prepare some speeches too.

When I find something good I definitely want to spread it, and this is the case.

 

 

Waffle is different from the multitude of web frameworks that exist today, in that Waffle:

  • has no mandatory XML configuration files (beyond a minimalist web.xml required by any J2EE-compliant webapp)
  • is interoperable with best-of-breed UI templating technologies
  • does not have a base controller class to extend or interface to implement
  • has controller classes that can support multiple actions, each a single method rather than a sequence of initialiation/settter/execute methods
  • has a small learning curve

 

November 15, 2008

Comes a time…

Filed under: General Stuff — toni @ 10:39 am

After two+ smashing years I took the decision to leave ThoughtWorks, I’ve produced 16,766 kg of CO2 (at least that’s what dopplr says…) and I decided that it was the right moment to settle down a bit and give up with my gypsy life. 

I’m joining Erudine, a medium-small company located in Harrogate, I’ll work on their product, a behaviour engine (a very flexible knowledge acquisition application that uses ripple down rules… I Still have to properly figure out what the heck is that but it sounds cool no?)

Leaving drinks at the White Hart in London, 21st of this month.

Older Posts »

Powered by WordPress