Tapestry 5.4.3 Demos (in progress) : Implementation Of A Strategy

In this example, we shall use the Strategy builder service, in Tapestry IOC, to implement a strategy to compute the area of a shape (which is a square or circle). An appropriate strategy will be picked automatically according to the undelying type of the shape.
We first define a java class for a Circle and Square.

package com.man.testTapestry5.ioc.strategy;

public class Circle {

    private double radius;

    public double getRadius() {
            return radius;
    }

    public void setRadius(double radius) {
            this.radius = radius;
    }
}


package com.man.testTapestry5.ioc.strategy;

public class Square {
    // length of a side
    private double size;

    public double getSize() {
            return size;
    }

    public void setSize(double size) {
            this.size = size;
    }

}


We now create an interface for the strategy.
package com.man.testTapestry5.ioc.strategy;

public interface IComputeArea {

    /*
     * Compute the area of obj
     */
    public double compute(Object obj);
}
The following are the two strategies (one for each of Circle.java and Square.java) to compute the area.
package com.man.testTapestry5.ioc.strategy;

public class CircleArea implements IComputeArea {

    public double compute(Object obj) {
            Circle circle = (Circle) obj;
            return Math.PI*circle.getRadius()*circle.getRadius();

    }

}
package com.man.testTapestry5.ioc.strategy;

public class SquareArea implements IComputeArea {

    public double compute(Object obj) {
        Square sq = (Square) obj;
            return sq.getSize()*sq.getSize();
    }

}

Add the following to AppModule.java to create a strategy that computes the area of circle or square.
 
public static IComputeArea buildAreaCalculator(
			Map<Class, IComputeArea> configuration,
			@InjectService("StrategyBuilder")
			StrategyBuilder builder) {
		StrategyRegistry<IComputeArea> registry = StrategyRegistry.newInstance(
				IComputeArea.class, configuration);

		return builder.build(registry);
	}

	public static void contributeAreaCalculator(
			MappedConfiguration<Class, IComputeArea> configuration) {
		configuration.add(Circle.class, new CircleArea());
		configuration.add(Square.class, new SquareArea());
	}
A JUnit test to verify the strategy created by the service areaCalculator.

package com.man.testTapestry5.ioc.strategy;

import junit.framework.TestCase;

import org.apache.tapestry.ioc.Registry;
import org.apache.tapestry.ioc.RegistryBuilder;

import com.man.testTapestry5.services.AppModule;

public class ComputeAreaTest extends TestCase {

	public void testCompute() {
		
		RegistryBuilder builder = new RegistryBuilder();

		builder.add(AppModule.class);

		Registry registry = builder.build();

		registry.performRegistryStartup();

		IComputeArea calculator= registry.getService("areaCalculator", IComputeArea.class);
		
        Square square = new Square();
        square.setSize(1.5);
        assertEquals(2.25, calculator.compute(square));
        
        Circle circle = new Circle();
        circle.setRadius(2);
        assertEquals(4*Math.PI, calculator.compute(circle), 0.00000001);
        
        Object obj = new Object();
        try {
          calculator.compute(obj);
          assertFalse(false);
        }
        catch (IllegalArgumentException iae){
            // should get exception : Could not find strategy instance for class java.lang.Object
            assertTrue(true);
        }
        
	}

}


To use the areaCalculator strategy in a page .java, just inject it as a service.