JasperReports 5 0 tutorial with iReport 5 0 part 2



The part 1 was a comprehensive beginner style  Jasper Reports tutorial. This extends that to demonstrate how to pass parameters via a Map using name/value pairs to the Jasper Reports.


Step 1: Add a new custom parameter named "footerText" to display some value in the page footer section. Right-click on "Parameters" and select "Add Parameter" and then rename it to "footerText" as shown below. Also, note than the Text Field in the page footer is mapped to $P{footerText} by right clicking on the "Text Field" and then select "Edit expression" to select the parameter "footerText" from the list.





Step 2: Compile this to the jrxml file and then you can pass the value for "footerText" via Java as shown below in the Main.java file. Take note of the getParameters( ) method.

package com.mycompany.app.jasper; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import java.util.LinkedList; import java.util.List; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JasperCompileManager; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.design.JasperDesign; import net.sf.jasperreports.engine.xml.JRXmlLoader;
package com.mycompany.app.jasper;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.view.JasperViewer;

public class Main
{

public static JasperDesign jasperDesign;
public static JasperPrint jasperPrint;
public static JasperReport jasperReport;
public static String reportTemplateUrl = "person-template.jrxml";

public static void main(String[] args) throws IOException
{
try
{
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(reportTemplateUrl);
//get report file and then load into jasperDesign
jasperDesign = JRXmlLoader.load(resourceAsStream);
//compile the jasperDesign
jasperReport = JasperCompileManager.compileReport(jasperDesign);
//fill the ready report with data and parameter
jasperPrint = JasperFillManager.fillReport(jasperReport, getParameters(),
new JRBeanCollectionDataSource(
findReportData()));
//view the report using JasperViewer
JasperViewer.viewReport(jasperPrint);
}
catch (JRException e)
{
e.printStackTrace();
}
}

private static Collection findReportData()
{
//declare a list of object
List<Person> data = new LinkedList<Person>();
Person p1 = new Person();
p1.setFirstName("John");
p1.setSurname("Smith");
p1.setAge(Integer.valueOf(5));
data.add(p1);
return data;
}

private static Map<String, Object> getParameters()
{
Map<String, Object> params = new HashMap<String, Object>();
params.put("footerText", "Just to demonstrate how to pass parameters to report");
return params;
}

}


Step 3: Finally, run the Main.java to see the value "Just to demonstrate how to pass parameters to report" in the report footer. The parameters are handy to pass any arbitary name/value pairs to the report.





Read More..

Java ExecutorService for multi threading coding question and tutorial

Q. Can you code in Java for the following scenario?

Write a multi-threaded SumEngine, which takes  SumRequest with 2 operands (or input numbers to add) as shown below:

package com.mycompany.metrics;

import java.util.UUID;

public class SumRequest {

private String id = UUID.randomUUID().toString();
private int operand1;
private int operand2;

protected int getOperand1() {
return operand1;
}
protected void setOperand1(int operand1) {
this.operand1 = operand1;
}
protected int getOperand2() {
return operand2;
}
protected void setOperand2(int operand2) {
this.operand2 = operand2;
}
protected String getId() {
return id;
}

@Override
public String toString() {
return "SumRequest [id=" + id + ", operand1=" + operand1 + ", operand2=" + operand2 + "]";
}
}

and returns a  SumResponse with a result.

package com.mycompany.metrics;

public class SumResponse {

private String requestId;
private int result;

protected String getRequestId() {
return requestId;
}
protected void setRequestId(String requestId) {
this.requestId = requestId;
}
protected int getResult() {
return result;
}
protected void setResult(int result) {
this.result = result;
}

@Override
public String toString() {
return "SumResponse [requestId=" + requestId + ", result=" + result + "]";
}
}

A. Processing a request and returning a response is a very common programming task. Here is a basic sample code to get started.This interface can take any type of object as request and response.

package com.mycompany.metrics;

/**
* R -- Generic request type, S -- Generic response type
*/
public interface SumProcessor<R,S> {

abstract S sum(R request);
}

Step 1: Define the interface that performs the sum operation. Take note that generics is used .

package com.mycompany.metrics;

/**
* R -- Generic request type, S -- Generic response type
*/
public interface SumProcessor<R,S> {

abstract S sum(R request);
}

Step 2: Define the implementation for the above interface. Takes SumRequest and returns SumResponse. 

package com.mycompany.metrics;

public class SumProcessorImpl<R,S> implements SumProcessor<SumRequest, SumResponse> {

@Override
public SumResponse sum(SumRequest request) {
System.out.println(Thread.currentThread().getName() + " processing request .... " + request);
SumResponse resp= new SumResponse();
resp.setRequestId(request.getId());
resp.setResult(request.getOperand1() + request.getOperand2());
return resp;
}
}

Step 3: Write the multi-threaded  SumEngine. The entry point is the public method execute(SumRequest... request ) that takes 1 or more SumRequest as input via varargs. ExecutorService is the thread pool and closure of Callable interface is the executable task that can be submitted to the pool to be executed by the available thread.


package com.mycompany.metrics;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

public class SumEngine {

private final AtomicInteger requestsCount = new AtomicInteger();

ExecutorService executionService = null;

//executes requests to sum
public void execute(SumRequest... request) {
executionService = Executors.newFixedThreadPool(5); //create a thread pool
List<Callable<SumResponse>> tasks = createExecuteTasks(request);
List<Future<SumResponse>> results = execute(tasks);
for (Future<SumResponse> result : results) {

try {
System.out.println(Thread.currentThread().getName() + ": Response = " + result.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}

//initiates an orderly shutdown of thread pool
executionService.shutdown();
}

//create tasks
private List<Callable<SumResponse>> createExecuteTasks(SumRequest[] requests) {
List<Callable<SumResponse>> tasks = new LinkedList<Callable<SumResponse>>();
executingRequests(requests.length);
for (SumRequest req : requests) {
Callable<SumResponse> task = createTask(req);
tasks.add(task);
}

return tasks;
}

//increment the requests counter
private void executingRequests(int count) {
requestsCount.addAndGet(count);
}

//creates callable (i.e executable or runnable tasks)
private Callable<SumResponse> createTask(final SumRequest request) {
// anonymous implementation of Callable.
// Pre Java 8s way of creating closures
Callable<SumResponse> task = new Callable<SumResponse>() {

@Override
public SumResponse call() throws Exception {
System.out.println(Thread.currentThread().getName() + ": Request = " + request);
SumProcessor<SumRequest, SumResponse> processor = new SumProcessorImpl<>();
SumResponse result = processor.sum(request);
return result;
}

};

return task;
}

//executes the tasks
private <T> List<Future<T>> execute(List<Callable<T>> tasks) {

List<Future<T>> result = null;
try {
//invokes the sum(sumRequest) method by executing the closure call() inside createTask
result = executionService.invokeAll(tasks);
} catch (InterruptedException e) {
e.printStackTrace();
}

return result;

}

public int getRequestsCount(){
return requestsCount.get();
}
}

Step 4: Write the SumEngineTest to run the engine with the main method. Loops through numbers 1 to 5 and adds each consecutive numbers like 1+2=3, 2+3=5, 3+4=7, 4+5=9, and 5+6 = 11.

package com.mycompany.metrics;

import java.util.ArrayList;
import java.util.List;

public class SumEngineTest {

public static void main(String[] args) throws Exception {

SumEngine se = new SumEngine();

List<SumRequest> list = new ArrayList<>();

// sums 1+2, 2+3, 3+4, etc
for (int i = 1; i <= 5; i++) {
SumRequest req = new SumRequest();
req.setOperand1(i);
req.setOperand2(i + 1);
list.add(req);
}

SumRequest[] req = new SumRequest[list.size()];
se.execute((SumRequest[]) list.toArray(req));

}
}

The output is:

pool-1-thread-2: Request = SumRequest [id=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, operand1=2, operand2=3]
pool-1-thread-4: Request = SumRequest [id=36d95b35-09f0-4e93-99e4-715ea7cb33c9, operand1=4, operand2=5]
pool-1-thread-3: Request = SumRequest [id=31ccd137-349a-4b7a-93b1-e51f62c11ba9, operand1=3, operand2=4]
pool-1-thread-1: Request = SumRequest [id=4bfa782a-c695-4de6-9593-cbfd357c3535, operand1=1, operand2=2]
pool-1-thread-5: Request = SumRequest [id=c653f469-6a6f-45b6-99f2-ed58620fd144, operand1=5, operand2=6]
pool-1-thread-4 processing request .... SumRequest [id=36d95b35-09f0-4e93-99e4-715ea7cb33c9, operand1=4, operand2=5]
pool-1-thread-2 processing request .... SumRequest [id=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, operand1=2, operand2=3]
pool-1-thread-1 processing request .... SumRequest [id=4bfa782a-c695-4de6-9593-cbfd357c3535, operand1=1, operand2=2]
pool-1-thread-3 processing request .... SumRequest [id=31ccd137-349a-4b7a-93b1-e51f62c11ba9, operand1=3, operand2=4]
pool-1-thread-5 processing request .... SumRequest [id=c653f469-6a6f-45b6-99f2-ed58620fd144, operand1=5, operand2=6]
main: Response = SumResponse [requestId=4bfa782a-c695-4de6-9593-cbfd357c3535, result=3]
main: Response = SumResponse [requestId=bca23e97-3a6f-4e42-aff4-5ed5f7de2783, result=5]
main: Response = SumResponse [requestId=31ccd137-349a-4b7a-93b1-e51f62c11ba9, result=7]
main: Response = SumResponse [requestId=36d95b35-09f0-4e93-99e4-715ea7cb33c9, result=9]
main: Response = SumResponse [requestId=c653f469-6a6f-45b6-99f2-ed58620fd144, result=11]

Read More..

Recursion in Java with example – Programming Techniques Tutorial

Recursion is one of the tough programming technique to master. Many programmers working on both Java and other programming language like C or C++ struggles to think recursively and figure out recursive pattern in problem statement, which makes it is one of the favorite topic of any programming interview. If you are new in Java or just started learning Java programming language and you are looking for some exercise to learn concept of recursion than this tutorial is for you. In this programming tutorial we will see couple of example of recursion in Java programs and some programming exercise which will help you to write recursive code in Java e.g. calculating Factorial, reversing String and printing Fibonacci series using recursion technique. For those who are not familiar with recursion programming technique here is the short introduction: "Recursion is a programming technique on which a method call itself to calculate result". Its not as simple as it look and mainly depends upon your ability to think recursively. One of the common trait of recursive problem is that they repeat itself, if you can break a big problem into small junk of repetitive steps then you are on your way to solve it using recursion.
Read more »
Read More..

Blog Archive

Powered by Blogger.