Sunday 31 December 2017

Chain of Responsibility Design Pattern

It’s one of behavior design pattern


Chain of responsibility pattern is used to achieve loose coupling in software design where a request from client is passed to a chain of objects to process them. Then the object in the chain will decide themselves who will be processing the request and whether the request is required to be sent to the next object in the chain or not.

Example: - We know that we can have multiple catch blocks in a try-catch block code. Here every catch block is kind of a processor to process that particular exception.

Another real-time scenario was request approval process




Components in diagram are:
  • Handler: An abstract class or Interface which defines request handling behavior which handles request
  • ConcreteHandlers: Define more specific behavior for handling request, if they can’t handle it, they will simply call super class handle method.
  • Client: Instantiates all concrete handlers and chains them dynamically.

DPRequest.java
package dp;

public class DPRequest {
       private String requestType;
       private String isItApprovedByLevel2;
       private String isItApprovedByLevel1;

       public String getRequestType() {
              return requestType;
       }

       public void setRequestType(String requestType) {
              this.requestType = requestType;
       }

       public String getIsItApprovedByLevel2() {
              return isItApprovedByLevel2;
       }

       public void setIsItApprovedByLevel2(String isItApprovedByLevel2) {
              this.isItApprovedByLevel2 = isItApprovedByLevel2;
       }

       public String getIsItApprovedByLevel1() {
              return isItApprovedByLevel1;
       }

       public void setIsItApprovedByLevel1(String isItApprovedByLevel1) {
              this.isItApprovedByLevel1 = isItApprovedByLevel1;
       }
      

}

Approvals.java
package dp;

public interface Approvals {
       public void nextAction(Approvals next);
       public void process(DPRequest request);

}

Supervisor.java
package dp;

public class Supervisor implements Approvals{
       private Approvals next;
       @Override
       public void nextAction(Approvals next) {
              // TODO Auto-generated method stub
              this.next=next;
       }

       @Override
       public void process(DPRequest request) {
              // TODO Auto-generated method stub
              if("Service Type".equals(request.getRequestType())){
                     System.out.println("Supervisor accepted Service Type");
                     request.setIsItApprovedByLevel1("Y");
              }else if("Leave".equals(request.getRequestType())){
                     System.out.println("Supervisor accepted Leave Type");
                     request.setIsItApprovedByLevel1("Y");
              }
                     next.process(request);
             
       }

      

}

Accountant.java
package dp;

public class Accountant implements Approvals{
       private Approvals next;
       @Override
       public void nextAction(Approvals next) {
              // TODO Auto-generated method stub
              this.next=next;
       }

       @Override
       public void process(DPRequest request) {
              // TODO Auto-generated method stub
              if("Salary Advance".equals(request.getRequestType()) && "Y".equals(request.getIsItApprovedByLevel2())){
                     System.out.println("Accountant accepted Service Type");
                    
              }else{
                     System.out.println("Salary Advance request is not approved by Manager");
                     request.setIsItApprovedByLevel1("N");
                     next.process(request);
              }
       }

}


Manager.java
package dp;

public class Manager implements Approvals{

       private Approvals next;
       @Override
       public void nextAction(Approvals next) {
              // TODO Auto-generated method stub
              this.next=next;
       }


       @Override
       public void process(DPRequest request) {
              // TODO Auto-generated method stub
              if("Salary Advance".equals(request.getRequestType()) && "N".equals(request.getIsItApprovedByLevel1())){
                     request.setIsItApprovedByLevel2("Y");
                     System.out.println("Manager accepted Service Type");
              }else if(!"Salary Advance".equals(request.getRequestType()) && "Y".equals(request.getIsItApprovedByLevel1())){
                     System.out.println("Manager accepted Service Type");
              }
              if(null!=request){
                     next.process(request);
              }
                    
             
       }

}

ChainResponEx.java
package dp;

public class ChainResponEx{

       public static void main(String args[]){
              DPRequest request=new DPRequest();
              Approvals s=new Supervisor();
              Approvals a=new Accountant();
              Approvals m=new Manager();
              request.setRequestType("Salary Advance");
       //     s.nextAction(m);
              a.nextAction(m);
              m.nextAction(a);
              //s.process(request);
              a.process(request);
              m.process(request);
       }
}


Output:-

Salary Advance request is not approved by Manager
Manager accepted Service Type
Accountant accepted Service Type

  • DPRequest is the actual request object that will be created by client and passed to chain of responsibilities.
  • Approvals an interface which nextAction method, to handling behavior which handles request.
  • Supervisor ,Accountant and Manager are concrete sub classes of Approver, which provide their own specific behavior based on our conditions for approval authorization. If they can’t handle Request, they simply call next.process(request);, which in turn calls method from nextProcess.
  • ChainResponEx is actual client which instantiates all responsibilities and create a chain by setting next approver for each responsibility.

Sunday 17 September 2017

Sunday 10 April 2016

iReport Tutorial-Passing collections to List/Table Component with JRBeanCollectionDataSource/Parameter

Now we can learn, how to pass collections from Java to Jasper reports using iReport tutorial. We can use different data sources i.e.
  1.  JREmptyDataSource
  2. JRBeanCollectionDataSource
Using JREmptyDataSource:-
Now we are discussing about how to pass collection to Table Component.
Create a bean
public class Customer implements Serializable {

       private static final long serialVersionUID = 1L;
       private String custName;
       private int status;
       private String isSameAddress;
       private String floorNo;
       private String buildingName;
       private String City,reportCity;
       private String streetName;
       private String remarks;
       private int postalCode;
       private int custPhone;
      
/*
* Create setter and getters
*/
      
}
Create a JRxml file and file name Customer.jrxml using  iReport [5.6.0]

Select table component from palate panel. Create dataset and rename dataset name as customerdataset.


Select create an empty dataset then click on next button.


Select the data source as Empty datasource in Query wizard. 


No need to define fields and group by tabs, then click on finish button. If required create table style then click on Finish button.


Then getting below screenshot and add labels to table header

Create fields in customerdataset dataset. What you defined properties in Customer bean ,the same properties to be created here.

Add a parameter for customer list and give name as “CustomerCollection” and class type :java.utila.collection  in main report

Then go to table component .Select edit table datasource menu and change expression new net.sf.jasperreports.engine.JREmptyDataSource(1) to new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{CustomerCollection}) then save and compile jrxml file.
And Back with the code. In Eclipse, import the compiled jrxml into the root project. Here is

public class JasperTableBeanListExample{
       public static void main(String args[]){
               InputStream inputStream = JasperTableBeanListExample.class
                          .getResourceAsStream("/Customer.jrxml");
              Collection custList=new ArrayList<CustomerForm>();
              CustomerForm form=new CustomerForm();
              form.setCustName("Chun");
              form.setBuildingName("Riggers building");
              form.setReportCity("New Jersey");
              form.setRemarks("Test");
              custList.add(form);
              form.setCustName("williams");
              form.setBuildingName("Riggers building");
              form.setReportCity("washington");
              form.setRemarks("Test2");
              custList.add(form);
              form=new CustomerForm();
              form.setCustName("Chun williams");
              form.setBuildingName("MRiggers building");
              form.setReportCity("London");
              form.setRemarks("Test23");
              custList.add(form);
              Map parameters = new HashMap();
              parameters.put("CustomerCollection", custList);
             
              JasperDesign jasperDesign;
              try {
                     jasperDesign = JRXmlLoader.load(inputStream);
                      JasperReport jasperReport = JasperCompileManager
                                 .compileReport(jasperDesign);
                      
                           JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
                                 parameters, new JREmptyDataSource());
                    
                           JasperViewer.viewReport(jasperPrint);
              } catch (JRException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              }
         
       }

}
Then just Run the code, the result should be like this.



Using JRBeanCollectionDataSource:-

Two different ways to create data source using javabean.
1.       Collection of java beans
2.       Arrays of java beans

We can continue same above customer bean and create a factory class for return of collection of Customer objects.

public class JasperJavaBeansDataSourceFactory {
       public JasperJavaBeansDataSourceFactory() {
              // TODO Auto-generated constructor stub
       }
public static Collection getCustomerBean(){
       List<Customer> custCollection=new ArrayList<Customer>();
       Customer form=new Customer();
       form.setCustName("Chun");
       form.setBuildingName("Riggers building");
       form.setReportCity("New Jersey");
       form.setRemarks("Test");
       custCollection.add(form);
       form.setCustName("williams");
       form.setBuildingName("Riggers building");
       form.setReportCity("washington");
       form.setRemarks("Test2");
       custCollection.add(form);
       return custCollection;
}

Create a reportJavabean. jar file and add this jar into class path in iReport.



Please enter name of datasource, Factory class and static method then click on Test button then get alert message “Connection test successfully” and save bean datasource.



Select table component from palate panel. Create dataset and rename dataset name as JRBeanCollectionTable. Complete all wizards then create fields in same datasource.


Change datasource expression to $P {REPORT_DATA_SOURCE} then click on ok button. Run and compile jrxml

And Back with the code. In Eclipse, import the compiled jrxml into the root project. Here is

public class JasperJRBeanCollectionExamples {
       public static void main(String args[]){
               InputStream inputStream = JasperJRBeanCollectionExamples.class
                          .getResourceAsStream("/JRBeanSourceTableExample.jrxml");
              Collection custList=new ArrayList<Customer>();
              Customer form=new Customer();
              form.setCustName("Chun");
              form.setBuildingName("Riggers building");
              form.setReportCity("New Jersey");
              form.setRemarks("Test");
              custList.add(form);
              form.setCustName("williams");
              form.setBuildingName("Riggers building");
              form.setReportCity("washington");
              form.setRemarks("Test2");
              custList.add(form);
              form=new CustomerForm();
              form.setCustName("Chun williams");
              form.setBuildingName("MRiggers building");
              form.setReportCity("London");
              form.setRemarks("Test23");
              custList.add(form);
              Map parameters = new HashMap();
              JRDataSource cDataSource=new JRBeanCollectionDataSource(custList);
              JasperDesign jasperDesign;
              try {
                     jasperDesign = JRXmlLoader.load(inputStream);
                      JasperReport jasperReport = JasperCompileManager
                                 .compileReport(jasperDesign);
                      
                       JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
                                 parameters, cDataSource);
                           JasperViewer.viewReport(jasperPrint);
              } catch (JRException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              }
         
       }

}
Then just Run the code, the result should be like this.


But here missed out the one record. So we can do it alternative way instead of setting JRBeanCollectionDataSource Use JREmptyDatasource() and pass  arraylist through parameters.Change to new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{custList}) or add parameter <parameter name="custds" class="net.sf.jasperreports.engine.JRBeanCollectionDataSource"/> and this parameter add into datasource expression.