Monday 10 February 2014

Simple Calculator Using JSF MVC Primefaces and Ajax

In this tutorial, we will understand how to use MVC Pattern when developing JSF Applications.
Agenda:
1)        @ManagedBean: The Model
2)        @ManagedProperty: The injection of model into controller and achieve loose coupling
3)        @SessionScoped: The controller
4)        Composite Views: Create reusable view components
5)        The view page using primefaces and AJAX
Directory Structure:
1)        Let’s get Start with Model Layer:
Interface:
public interface CalculatorIntf {
    public int add(int a, int b);
    public int sub(int a, int b);
}
Implementing Class:
@ManagedBean(name="calc")
@SessionScoped
public class Calculator implements CalculatorIntf{
    @Override
    public int add(int a, int b) {        return a + b;     }
   @Override
    public int sub(int a, int b) {        return a - b;    }
}
And the Value Object Class:
public class CalculatorVO {
    private int a;
    private int b;
    private int c;
// getters and setters for a, b, c
}
2nd And 3rd steps)The controller Class with Dependency Injection
@ManagedBean
@SessionScoped
public class CalculatorController {
   public void add() {        calculatorVO.setC(calculatorIntf.add(calculatorVO.getA(), calculatorVO.getB()));    }
   public void sub() {        calculatorVO.setC(calculatorIntf.sub(calculatorVO.getA(), calculatorVO.getB()));    }
    public CalculatorIntf getCalculatorIntf() {  return calculatorIntf;     }
    public void setCalculatorIntf(CalculatorIntf calculatorIntf) {     this.calculatorIntf = calculatorIntf;    }

    public CalculatorVO getCalculatorVO() {       
if (calculatorVO == null) {   calculatorVO = new CalculatorVO();        }        return calculatorVO;
    }
    private CalculatorVO calculatorVO;
    @ManagedProperty(value = "#{calc}")    private CalculatorIntf calculatorIntf;}
4)  The Composite View component

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:p="http://primefaces.org/ui"
      xmlns:h="http://java.sun.com/jsf/html">
     <cc:interface>
        <cc:attribute name="a" required="true" />
        <cc:attribute name="b" required="true" />
        <cc:attribute name="c" required="true" />
        <cc:attribute name="add" required="true" method-signature="void add()"/>
        <cc:attribute name="subtract" required="true" method-signature="void sub()"/>
    </cc:interface>

    <!-- IMPLEMENTATION -->
    <cc:implementation>
        <p:panel header="Maths Operations">
                <p:panelGrid columns="2">
                    <h:outputText value="Num 1: " />
                    <h:inputText value="#{cc.attrs.a}">
                        <p:ajax event="blur" />
                    </h:inputText>
                    <h:outputText value="Num 2: " />
                    <h:inputText value="#{cc.attrs.b}">
                        <p:ajax event="blur" />
                    </h:inputText>
                    <h:commandButton value="Add" >
                        <p:ajax event="click" listener="#{cc.attrs.add}" update="result" />
                    </h:commandButton>
                    <h:commandButton value="Sub" >
                        <p:ajax event="click" listener="#{cc.attrs.subtract}" update="result" />
                    </h:commandButton>
                    <h:outputText value="Result: "/>
                    <h:outputText id="result" value="#{cc.attrs.c}"/>
                </p:panelGrid>
            </p:panel>
    </cc:implementation>
</html>
Note: Do remember that <cc:attribute name="sub" .... ... /> will not work. so made it subtract
5) The View Page:
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:m="http://java.sun.com/jsf/composite/com/shared">
    <h:head>
        <title>Calculator App</title>
    </h:head>
    <h:body>
        <h:form>
<m:mathsComponent a="#{calculatorController.calculatorVO.a}"
                  b="#{calculatorController.calculatorVO.b}"
                  c="#{calculatorController.calculatorVO.c}"
                  add="#{calculatorController.add}"
                  subtract="#{calculatorController.sub}"/>
                            
        </h:form>
    </h:body>
     </html> 
Conclusion:
1) Controllers can depend upon interface references than direct implementations with the help of @ManagedProperty Attribute. Thus making our application Loosely coupled.
2) Do not use sub as attribute, because sub seems to be a reserved word in JSF
3) Creating composites will help us reuse the components at many places.