Home

Need help in the bundle jungle...

less is more :)

A few weeks ago i introduced in DRY iBatis DAOs build an UserDetailsService an iBatis based UserService. To reduce the required number of seven bundles and additional infrastructural requirements like a database we want to use a simple stupid stub implementation.

In the first step we extract bundle No. eight userservice.api and implement bundle No. nine the userservice.stub. Ups we did it again - even more bundles in the jungle. Out of the now nine bundles we choose the following four to escape the bundle jungle during the time of development.

  1. userservice.model - yeah right, a User;-)
  2. userservice.api - the new bundle in the jungle, the UserService API
  3. userservice.stub - a HashMap based UserService stub implementation
  4. userservice.security - a thin adapter implementation publishing the service as UserDetailsService inside the OSGi container

We removed all database/iBatis dependencies from the development workspace. With the userservice.api bundle we opened the door for other implementations: e.g. LDAP, ADS, ...

The API could look like this:

public interface UserService {

	/**
	 * Register a new {@link User}.
	 * @param newUser the new user's data.
	 */
	void registerUser(User newUser);

	/**
	 * Load registered {@link User} by a given id.
	 * @param username of the {@link User} to load.
	 * @return the {@link User} identified by the given id.
	 */
	User loadUserByUsername(String username);
...

Let's write some Groovy test cases.

public class UserServiceStubGroovyTests {

	UserService userService = new UserServiceStub()

	@Test
	public void testGetEmptyList() {
		assertTrue(userService.getList().isEmpty())
	}

	@Test
	public void testLoadUserByUsername() {
		userService.registerUser(new UserImpl("J.Unit", "junit@invalid.com"))
		assertNotNull(userService.loadUserByUsername("J.Unit"))
	}

	@Test
	public void testRemoval() {
		userService.registerUser(new UserImpl("J.Unit", "junit@invalid.com"))
		userService.remove(42)
		assertTrue(userService.getList().isEmpty())
	}

}

Now go for the green bar! With a HashMap based stub implementation:

public class UserServiceStub implements UserService {

	private static final AtomicInteger COUNTER = new AtomicInteger(41);
	private final Map users = new ConcurrentHashMap();

	@Override
	public void registerUser(User newUser) {
		users.put(COUNTER.getAndIncrement(), newUser);
	}

	@Override
	public User loadUserByUsername(String username) {
		for (User user : users.values()) {
			if (user.getUsername().equals(username)) {
				return user;
			}
		}
		throw new IllegalArgumentException();
	}

	@Override
	public void remove(Integer id) {
		users.remove(id);
	}
...

Wasn't it easy as pie to escape the bundle jungle?




Add a comment