Monday, 5 October 2015

IMPROVEMENTS OF SWITCH STATEMENT IN JAVA 7

This post discuss one of improvements of Switch statement in Java 7. Just before discussing about the improvements, Lets recapitulate the well known Switch statement. How it works.

Typical Syntax:

switch  (expression) {

    case label1:

                     statements;

    case label2:

                     statements;

    case label3:
                     statements;
         . . . 
    default:
                     statements;
}


Initially, the expression is evaluated. If the value of the expression is matched to any of the case labels, from the matched case label - its start executing the statements till the end of the switch statement. For example, if value matches to label2, then it executes all the statements from the case label2 till the end of the switch statement and even the optional default label statements are executed.

If the value of the expression is not matched to any of the case labels then it executes the statements under the optional default label.

Note: But generally, we use switch statement to execute one of many possibilities. so we use break statement to stop all other statements after that matched case. 

Example:
// without break;

 int age = 10;
 switch (age) {
 case 10: // Found the match
  System.out.println("Age 10"); // Execution starts here
 case 20:
  System.out.println("Age 20");
 default:
  System.out.println("AgeLess");
 }

Output:
             Age 10
             Age 20
             AgeLess


The expression must evaluate to a type : byte, short, char, int, enum.

In addition to these types, Java 7 added support for Strings in a SWITCH statement.

Expression : String Type

The expression uses a String type. If the expression is evaluating to a null, then a NullPointerException is thrown. The case labels must be String literals.

You cannot use String variables (non-final variables) in the case labels. Can use constants (final variables) as case labels.

Example:

String company = "alphabet";

 switch (company) {

 case "google":
  System.out.println("google");
  break;
 case "facebook":
  System.out.println("facebook");
  break;
 case "alphabet":
  System.out.println("alphabet");
  break;
 default:
  System.out.println("Company Not Found");
  break;

 }

Output:
            alphabet

(does not execute the default label statements because we have used break statement under matched case "alphabet")

Note: The above code fails to compile before java 1.7.
This feature works properly from java 1.7 and above.

Some variants of switch statements:

>> If expression does not match and expression is evaluating to a type int:
/*
  * expression evaluating to int type 
  * match does not match any case label
  */

 int num = 50;
 switch (num) {
 case 10:
  System.out.println("Ten");
 case 20:
  System.out.println("Twenty");
 default:
  System.out.println("No-match"); /* Execution starts here */
 }

Output:
       
No-match


>>You can place the optional default label any where in order. Its not mandatory to place as a last label. But as a convention, its better to place as a last option.

char currency = '$';
 switch (currency) {
 case '€':
  System.out.println("Euro");
 default:
  System.out.println("No Proper Currency"); 
 case '$': //As match is found
  System.out.println("Dollar"); // Execution starts here
 }

 Output:
        Dollar


/*
  * default label can be anywhere and is optional By convention, 
  * most of developers use as last label
  */

 char currency = '@';
 switch (currency) {
 case '€':
  System.out.println("Euro");
 default: //As No match is found
  System.out.println("No Proper Currency"); // Execution starts here
 case '$':
  System.out.println("Dollar");
 }

Output:
        No Proper Currency
        Dollar



>>When expression evaluating to a byte type. Important to remember the byte type value range is -128 to 127 only.

Possible compile-time errors:


//remember byte data type range is -128 to 127
   
  byte b = 10; 
  
  switch (b) {
  case 5:
   System.out.println("Its five");
  case 50:
   System.out.println("Its fifty");
 /* case 150:  fails : A compile-time error. 150 is greater than 127
   b--; */
     default: 
      System.out.println("Its Zero"); 
     }
Output:
         Its Zero

>>should not use duplicate case labels.
int num = 10;

    switch (num) {
    
    case 10: 
     num++; 
    
    case 10:   // fails: CE: same case label 
     num--; 
    
    default: 
     num =100; 
     } 
Output: 
         compile time error:  Duplicate Case

>>should not use variables in case labels. constants are allowed
/*
  * num2 is not a constant 
  * should not use a variable as case label
  */
 int num1 = 10;
 int num2 = 10;

 switch (num1) {
 case 20:
  System.out.println("num1 is 20");

 case num2: // A Compile-time error.
  System.out.println("num1 is 10");
 }

Output:
       compile time error: case expression must be a constant expressions

>> the expression can use an enum type. Here, the case labels must use unqualified enum values. 

Example:
/*
 * An enum defined with three values
 * This enum has to be given to switch
 * as expression
 */
public enum Facility {
 
 ORDINARY,
 
 SEMI_LUXUCY,
 
 LUXURY

}

public class EnumSwitch {

 public static void main(String[] args) {

  Facility fac = Facility.LUXURY; // passing this input param.

  String facility_code = getFacility(fac);
  System.out.println("Code of Facility.LUXURY is " + 
  facility_code);

 }

 private static String getFacility(Facility facility) {
  String fa_code = "";

  // passing Enum as expression
  switch (facility) {
  /*
   * Cannot use Must use Enum value only 
   * Must not quality with Enum i.e,
   * should not use Facility.ORDINARY in case labels
   */
  case ORDINARY:
   fa_code = "ORD";
   break;
  case SEMI_LUXUCY:
   fa_code = "SEM";
   break;
  case LUXURY:
   fa_code = "LUX";
   break;
  }
  return fa_code;
 }

}

 Output:
         Code of Facility.LUXURY is LUX 

Thanks for reading                         Hope u like it :)                               Please share :)

Wednesday, 1 July 2015

FULFILLING AN ORDER WITH MINIMUM NUMBER OF BOTTLES - A JAVA SOLUTION

A bottled water industry based in USA, Michigan serves packaged water bottles of various sizes. The bottle size could be 1 litre, 5 litre, 7 litre and 10 litre. The owner wants to supply maximum quantity using fewer water bottles.

Your objective is to find the minimum number of bottles required to supply the given demand of water.

Example: if the demand of water is 25 litre, it can be supplied with minimum of 3 bottles:  2 BOTTLES OF SIZES 10 LITRE + 1 BOTTLE OF SIZE 5 LITRE

INPUT SPECIFICATION:

   Input will be the demand of water in litre (Integer)

OUTPUT SPECIFICATION:

  Output will be the Minimum number of bottles required to full-fill given demand of water (Integer)

Example:

Input : 12             (provide as an cmd line argument)
output : 2

Explanation: The demand of water is 12 litre that can be supplied using minimum of 2 bottles of sizes 7 litre and 5 litre.

Note: For better understanding,  please download the code - which is properly commented

Source Download: MinimumBottlesCode.java

SOLUTION:

public class MinimumBottlesCode {

 public static void main(String[] args) {

  // pass in quantity through command-line arguments

  int quantity = Integer.parseInt(args[0]);
  System.out.println(minimumBottles(quantity));
 }

 public static int minimumBottles(int quantity) {

  /*
   * Company sells water bottles of 1litres, 5 litres, 7litres, & 10
   * litres
   */

  int nums[] = { 7, 5, 10 };
  int minBottles = 0;
  int result = 0;
  /*
   * Iterate the given bottles of sizes - 5 litres, 7litres, and
   * 10litres(without 1litres). For Each Iteration : It finds the number
   * of bottles required to fullfill the given quantity for the order. The
   * final result is the least number of bottles in all the iterations.
   */
  for (int i = 0; i < nums.length; i++) {

   /*
    * say first dividing the given quantity 43 with 7 gives a
    * perfectDivs of 6 and remaining as 1, if the remaining is less
    * than 5 - this quantity is satisfied by 1litre bottles so - 6
    * bottles of 7 litre + 1 bottle of 1 litre
    */

   int perfectDivs = quantity / nums[i];

   int remaining = quantity % nums[i];

   if (remaining == 0) {
    minBottles = perfectDivs;

   } else if (remaining == 5) {
    minBottles = perfectDivs + 1;

   } else if (remaining == 7) {
    minBottles = perfectDivs + 1;

   } else if (remaining > 7 && remaining < 10) {
    minBottles = perfectDivs + remaining % 7 + 1;

   } else if (remaining > 5 && remaining < 7) {
    minBottles = perfectDivs + remaining % 5 + 1;

   } else if (remaining < 5) { // satisfied by 1 litre bottles
    minBottles = perfectDivs + remaining;

   }

   if (i == 0) {
    result = minBottles;
   }
   if (result > minBottles) {
    result = minBottles;
   }

  }

  return result;
 }
}

Please share : Hope it is a useful article :)

Wednesday, 10 June 2015

HOW TO GET NOTIFIED OF EVENTS ON A DIRECTORY - USING JAVA 7 WatchService - A NIO.2 Feature

Java 7 introduced New Input/Output 2 (NIO.2) API, which provides a new I/O API.
The features provided in NIO.2 are essential for working with a file system efficiently.

Out of any many NIO.2 API features, In this post - I am going to discuss a feature  known as a watch service, which watches for events on a directory such as creating, modifying, and deleting a file, etc. So using this watch service - a java program can receives a notification of such events.

The watch service uses a native file event notification facility of the file system. If a file system does not provide a file event notification facility, it may use other mechanisms such as polling.

How it works?

In a nutshell, first we need to create a watch service and register a directory path using Path object (a typical directory on file system) on that watch service. When an object is registered - it is given a watch key as an identity of registration. Initially, the watch key is in a ready state. When watch service detects any changes for the registered object - it then signals and queues the watch key. Then using the watch key methods - we can retrieve the pending events and process the events. Once a watch key is in this state, it always remains in this state until we invoke the reset() method of watch key to bring it to ready state again. Once after all events are processed you need to close the watch service.

Now lets discuss this in a more detail way.

Before diving into code specifics, it is worth knowing the core interfaces and classes.

Some of the important interfaces and classes used in watch service are listed below. All these interfaces & classes are from java.nio.file package.

Important Interfaces & Classes:

WatchService interface

A WatchService represents a service that watches registered objects for changes. Generally, we will register a directory path using Path object.

Syntax: Path <<var>> = Paths.get("<<PATH_STRING>>")

For instance, a directory path can be like this:

In Windows

Path directoryPath = Paths.get("c:\\dinesh\\watchme")

In Linux/UNIX

Path directoryPath = Paths.get("/home/dinesh/watchme")

Here, Path is an object that may be used to locate a file/directory in a file system. It typically represent a system dependent file path.

Paths class contains exclusively of static methods that return a Path by converting a path string or URI.

Watchable interface

A Watchable  object represents a file-system object (eg: directory) that can be watched for changes. A Watchable object can be registered with a watch service. A Path object is a watchable object.

In the above example, Path objects declared are considered as Watchable Objects.

WatchKey  interface

WatchKey identifies a registered object with a watch service. Whenever an object is registered with a watch service - WatchService returns a WatchKey that acts as a registration token.

WatchEvent<T> interface

Represent an event or repeated event for a file-system object that is registered with a WatchService.

Note: WatchEvent interface has a method count() returns the number of times an event occured. If the event count is greater than 1 then it is considered as a repeated event.

WatchEvent.Kind<T> interface ( An event kind )

WatchEvent.Kind<T> is an inner interface of WathEvent interface. Any event that occurs on a registered Path object must be of type WatchEvent.Kind<T>.

StandardWatchEventKinds class 

This class defines standard event kinds. It contains four constants to identify an event.

Constants:

ENTRY_CREATE

(Directory entry created)

If a directory is registered for this event then the WatchKey is queued when a directory entry is created or renamed into the directory. For instance, say a new file is created.

ENTRY_DELETE

(Directory entry deleted)

If a directory is registered for this event then the WatchKey is queued when a directory entry is deleted. For instance, say a file is deleted.

ENTRY_MODIFY

(Directory entry modified)

If a directory is registered for this event then the WatchKey is queued when a directory entry is modified. For instance, say a file content is changed in a registered directory.

OVERFLOW

A special event to indicate that events may have been lost or discarded.

File systems may reports faster than they can be retrieved and processed and an
implementation may impose an unspecified limit on number of events that it may accumulate. Where an implementation knowingly discards events then it arranges watch key's pollEvents() method to return an element with an event type of OVERFLOW. This event can be used by the consumer as a trigger to re-examine the state of the object.

All these are of type WatchEvent.Kind<T> .


STEPS FOR CONFIGURING WatchService

STEP 1:

Create a watch service for a file system in which you want a directory to be monitered


                FileSystem fs = FileSystems.getDefault();

                WatchService ws = fs.newWatchService();

                                                     (or)

 WatchService ws  = FileSystems.getDefault().newWatchService();

STEP 2:

Register a directory with watch service

// First get a watchable Path object - as aforementioned
Path watchingDir = Paths.get("/home/dinesh/tempdir");

//  Register the above Path object - returns a WatchKey
WatchKey wkey = watchingDir. register( ws, ENTRY_MODIFY, ENTRY_CREATE);

register() method signature is like this:

WatchKey register(WatchService watcher, WatchEvent.Kind<?> ... events)

In the above example, I want the watch service to monitor for only creation and modification events - but not deletion events.

STEP 3: 

Retrieve a watch key from the watch service queue

To retrieve a watch key we use either a poll() or take() methods of watch service.

A Watch key has a state. When initially created the watch key is said to be in ready state. When an event is detected the key is signalled and queued so that it can be retrieved by invoking WatchService's poll() or take() methods.

take() method waits until a WatchKey is available.

Eg:

// keep watching for events - an infinite loop
while(true){

 //to retrieve a watch key
WatchKey key = ws.take();

 }
                                                  (or)

poll() method lets you to specify the timeout for wait.

Eg:

WatchKey key = ws.poll(60, TimeUnit.SECONDS);

pollEvents() method - retrives and removes all pending events for this
watch key, returning a List of the events that were retrieved.


STEP 4:

Process events that occurred on the registered directory.

Once after getting a WatchKey - you can use a pollEvents() method to retrieve the events.


// retrieving events using pollEvents() method
for (WatchEvent<?> event : key.pollEvents()) {

         //process the events
}

Important method  of WatchEvent<?>: context()

Context() method returns a Path object that is relative path between the directory registered with the watch service, and the entry that is created, deleted, or modified.

For Example: registered path is /home/dinesh/tempdir

If I delete a file xyz.txt which is in the tempdir directory - then context() method returns the xyz as Path object, which is a relative path. useful to know which file is changed, created, or deleted.


STEP 5:

 Reset the watch key after processing the events.

To bring back the WatchKey to ready state again. Note: Whenever an event is detected - WatchKey is signalled and queued and it is in the same state unitl it reseted using reset() method.

reset() method returns true if the watch key is still valid. Otherwise, it returns false.

A WatchKey would be invalid if a watch service is closed or a watch key is cancelled using its cancel() method.

//Reset the watch key - bringing into ready state
boolean iskeyvalid = key.reset();

Based on the boolean value- we can know the watch service is still watching or not.

                if (!isKeyValid) {
                    System.out.println("No longer watching " + dirToWatch);
                    break;
                }

STEP 6:

Close the watch service.

WatchService is a AutoCloseable. So use java 7 try-with-resource statement for WatchService. By using this statement - you don't need to close the watch service explicitly. Otherwise, you can use close() method to close the watch service.

 Code Sample:

import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

public class Watcher {
 public static void main(String[] args) {

  // Step 1: Creating watch service
  try (WatchService ws = FileSystems.getDefault().newWatchService()) {

   /*
    * Step2: Get a Path object for /home/dinesh/tempdir directory to
    * watch
    */
   Path dirToWatch = Paths.get("/home/dinesh/tempdir");

   /*
    * Register the path with the watch service for modify and delete
    * events - doesn't show creating events
    */
   dirToWatch.register(ws, ENTRY_DELETE, ENTRY_MODIFY);

   System.out.println("Watching " + dirToWatch + " for events.");

   /*
    * Keep watching for events on the dirToWatch
    */
   while (true) {

    // Step 3: Retrieve and remove the next available WatchKey
                                // best step for a debug breakpoint
    WatchKey key = ws.take();

    // WatchKey key = ws.poll(60, TimeUnit.SECONDS);

    /*
     * Step 4: Retrieves & remove all pending events in this watch
     * key
     */
    for (WatchEvent event : key.pollEvents()) {

     /*
      * events are of type WatchEvent.Kind these are constants
      * declared in StandardWatchEventKinds ENTRY_DELETE
      * ENTRY_CREATE ENTRY_MODIFY OVERFLOW
      */

     Kind eventKind = event.kind();

     /*
      * Get the context of the event, which is the directory
      * entry on which the event occurred - may be on a file.
      */
     WatchEvent currEvent = (WatchEvent) event;
     Path dirEntry = currEvent.context();

     // Print the event details
     System.out.println(eventKind + " occurred on " + dirEntry);
    }

    /*
     * Step 5: Reset the key - bringing back to ready state so again
     * it ready to be queued for events
     */
    boolean isKeyValid = key.reset();
                                
    //checking whether the watch key is still valid 
    if (!isKeyValid) {
     System.out.println("No longer watching " + dirToWatch);
     break;
    }
   }
  } catch (IOException | InterruptedException e) {
   e.printStackTrace();
  }
 }
}


Source Code: Download

Tuesday, 14 April 2015

CREATING A DATASOURCE DEFINITION USING ANNOTATION @DataSourceDefinition : JAVA EE 7

In an enterprise application, the most important and a necessary task is to persist (save)
the data into the database.(Typically the data entered by the user in  the front end).
In order to persist the data, the developer needs to make a connection to the data source.

Earlier, even today most of the legacy code deals with JDBC boilerplate code- which was conventional way of doing the things.

We know that in order to connect to  database from the java classes is to use a datasource defintion created in an application server.

We generally use a jdbc connection resource which is pre-configured in the application server. But, In Java EE 7, you can create a Data Source using an annotation  @DataSourceDefinition, which takes some necessary parameters- like

  • a JNDI name for the connection, 
  • Database name, 
  • Database credentials: username & password
  • relative database driver
  • and a Database URL for the connection. 

Syntax:

@DataSourceDefinition(
        name="<<JNDI name  for Data Source>>",
        className="<<Database Driver Class Name>>",
        url="<<Database URL>>",
        user="<<Database User>>",
        password="<<Password>>") 

We place this annotation on any container managed bean like say on EJB.
First, the container will deploy the bean and then create the data source.

Generally, developers use the application server user interface to do this. But this way of doing is easy and time saving. Because you don't need to use the user interface by logging into it.

In this post, I have first created an EJB which registers this data source. And to test the data source created after the application deployment I would write a simple test to check the data source.

Instead of deploying the application into an application server, I would want to use an Embedded Glassfish EJB Container, this makes easy deployment and there is no need of any installation of any particular Application Server.

You can any other Embedded Container(Java EE 7 compliant) like WELD to test this.

Here, I have created a Maven project - these are some of the required artifacts.
Note: If your new to maven please read this post once More on Maven ....

Required maven artifacts:

1) Java(TM) EE 7 Specification APIs » 7.0

        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>

As we are writing some EJB code - we need a javaee-api artifact. Observer its scope: provided - because artifact is provided by Embedded Glassfish Server.

2) Embedded GlassFish All In One
        <dependency>
            <groupId>org.glassfish.main.extras</groupId>
            <artifactId>glassfish-embedded-all</artifactId>
            <version>4.1</version>
        </dependency>

Most important dependency to be added. Embedded Glassfish Server enables you run Glassfish Server inside of any virtual machine for Java Platform ( Java Virtual Machine or JVMmachine). No installation or configuration of embedded GlassFish Server is required. Just add this dependency to the POM.xml of your maven project.

3) MySQL java connector
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>

This dependency is used to connect the Mysql Database - contains required Driver class. you can use any other databases. I would recommend you to use the embedded databases like Derby, H2, HSQL.

4)  JUnit
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

In order to test the data source created - you need any testing framework.
you can use TestNG testing framework instead.

Example:

This Example contains only two classes -
DataSourceDefinitionConfig.java - EJB
TestDataSource.java - Test Class

This EJB acts as a marker - because it does not have any code in it. Just the declaration of the annotation. This class created under src/main/java in the maven project structure.

As we know there are 3 types of Session Beans: Stateful, Stateless, Singleton.
A Singleton session bean is shared between clients and supports concurrent access.
The container will make sure that only one instance exits for entire application. So by making this data source definition as a singleton we can ensure - it is been created only once and shared by all the users of the application.

@Singleton - indicates this session bean. @Startup indicates the container invokes this bean class during the application startup.

package com.config;

import javax.annotation.sql.DataSourceDefinition;
import javax.ejb.Singleton;
import javax.ejb.Startup;


@Singleton
@Startup
@DataSourceDefinition(
  name="java:global/jdbc/MyOwnDatasource",
  className="com.mysql.jdbc.Driver",
  url="jdbc:mysql://localhost:3306/mydatabase",
  databaseName="mydatabase",
  user="root",
  password="root")
public class DataSourceDefinitionConfig {
}

 JUnit Test Class: created under src/test/java

package com.test;

import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.ejb.embeddable.EJBContainer;
import javax.naming.Context;
import javax.naming.NamingException;

import org.junit.Assert;
import org.junit.Test;

import com.service.BlogService;

public class TestDataSource {

 @Test
 public void testDataSourceDefintion() {

  Map properties = new HashMap<>();
  properties.put(EJBContainer.MODULES, new File("target/classes"));

  try (EJBContainer ec = EJBContainer.createEJBContainer(properties)) {

   Context ctx = ec.getContext();

   // Check JNDI dependencies (Datasource)
   try {
    assertNotNull(ctx.lookup("java:global/classes/DataSourceDefinitionConfig"));
    assertNotNull(ctx.lookup("java:global/jdbc/MyOwnDatasource"));
       } catch (NamingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }

  }

 }
 }


Here, Embedded Container object is created in try-with-resource statement, so that you don't need to close the container.

Embedded Container instance requires some properties - Here, they are supplied as a Map.

EJBContainer.MODULES  as  target/classes

Container requires the path for the classes. when we run a maven goal : mvn package or in this case mvn test - this would generate a target folder in your project, which in turn contains classes folder. so provide the path for classes in target folder as a property.

In the @Test method - we are testing whether the session bean is loaded or not and also testing whether this session bean (EJB) created the data source or not.

We need to lookup the session beans and data source resource in Context. For this, first get the Context object from the instance of EJBContainer. 
                                     
                                             Context ctx = ec.getContext();

          assertNotNull(ctx.lookup("java:global/classes/DataSourceDefinitionConfig"));
          assertNotNull(ctx.lookup("java:global/jdbc/MyOwnDatasource"));

Note:

Whenever an EJB is deployed into an application server, the server would provide a JNDI name for all the beans deployed. If you could see the console while this test runs - you would observe this JNDI name- server provides a JNDI name for the session bean :

 DataSourceDefinitionConfig.java as
java:global/classes/DataSourceDefinitionConfig.

Actually every session bean does not get same form of JNDI names - but it depends on the interface views that session beans is using. I would recommend you to know more on portable JNDI names. More on Portable JNDI names

Generally JNDI names for EJBs start with either of these namespaces :

java:global/
java:app/
java:module/

Similarly, A Data Source is also a Server Resource - so It would also have a JNDI name :  java:global/jdbc/MyOwnDatasource

Note: This JNDI name is what we have provided in its declaration.
 Try to provide a prefix like this "java:global/jdbc/<<your own name>>"

SOME EXAMPLES ON VARIOUS DATABASES:

H2 Database

@DataSourceDefinition(
        name="java:app/MyDatasource",
        className="org.h2.jdbcx.JdbcDataSource",
        url="jdbc:h2:mem:test")

H2 Database - is an in memory database. Does not requires any installation of the database. But you must add a  dependency for h2 database in your maven POM.xml file. Know more on : H2 Database URL format...

Maven Dependency :

        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.186</version>
        </dependency>

DERBY DATABASE

@DataSourceDefinition(
className = "org.apache.derby.jdbc.EmbeddedDataSource",
name = "java:global/jdbc/NewDS",
user = "app",
password = "app",
databaseName = "NewDS",
properties = {"connectionAttributes=;create=true"}
)
DERBY database: creates a embedded database and also creates a data source.

Maven Dependency :

        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derby</artifactId>
            <version>10.10.1.1</version>
        </dependency>

This example is extended in the source code provided down.
In the source code an entity is persisted into the database by using this data source
created with @DataSourceDefinition.

Note: you must provide your JNDI name in the jta-data-source in persistence.xml file.

Once after running the test- check your MySQL database - A table named "BLOG" will be created.

Wednesday, 25 March 2015

EASILY GENERATE SETTERS/GETTERS / equals() /hashCode() METHODS -USING LOMBOK.JAR

These days POJO's  (Plain Old Java Objects) are used in all kinds of Java Projects.

A Typical POJO consists of fields, all related getters/setters, and sometimes equals() & hashCode() methods.

Sample POJO:

public class Product {   

    private Integer Id; 

    private String name;

    public Integer getId() {
        return Id;
    }
    public void setId(Integer id) {
        Id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        //equality logic
    }

    @Override
    public int hashCode() {
        //some logic
    }
    

}

By using lombok jar, we can simulate getters/setters methods, equals() method, hashCode() method and many other features. To simulate these methods just you need to use their respective annotations. Every feature has its own annotations.

For Example: To simulate  setter methods - just use @Setter on the required fields

    @Setter
    private Integer Id; 

    @Setter
    private String name;

First you need to download the lombok.jar  Lombok.jar 

Different IDE's has different way of configuring lombok jar - If you would want to use in eclipse IDE - need to install first.

Usage on other IDEs can be found at Download link page.

Installing lombok on Eclipse:

>> open commond prompt - > go to lombok jar directory
(If not downloaded lombok.jar - do it first)

 >> run the jar using the following command

<path to lombok jar>$ java -jar lombok.jar



>> This opens a lombok installer window


>> Now, Click the Specify location.. - select the eclipse IDE installation location.


>> In the above dialog, you must browse to Eclipse IDE installation directory and must choose eclipse.ini as labelled orange in the above pic.

>>Click Select


>> Given a correct installation directory - goes to the above screen. Click Install/Update.

You are done with installation of Lombok.
(If you observe IDE directory - a copy lombok.jar would be added to IDE installation directory.)

**Note:

Even though, you have installed lombok on eclipse IDE- you need lombok jar file on your classpath again.

So, In my example I using a lombok maven dependecny (so it automatically get my jar to the classpath)

Maven Dependency:

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.2</version>
        </dependency>


Sample POJO with lombok annoations:
package com.examples;

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;


@ToString
@EqualsAndHashCode
public class Product {

 @Setter
 @Getter
 private Integer Id;
 
 @Setter
 @Getter
 private String name;

}

@Setter - To Simulate Setter Methods

@Getter - To Simulate Getter Methods

@ToString - toString Method

@EqualsAndHashCode - To Simulate equals and hashcode Methods.

This POJO is equivalent to the Sample POJO above.

We can test this POJO by writing a simple TestNG test:

Also add a TestNG jar to run your tests successfully:

package com.test;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;

import org.testng.Assert;

import com.examples.Product;

public class LombokTest {

 Product product1 = new Product();

 Product product2 = new Product();

 @BeforeMethod
 public void setUp() {
  
  
  // accessing setters on POJO
  product1.setId(1);
  product1.setName("Washing Machine");

  product2.setId(2);
  product2.setName("Gas Stove");
 }

 @Test
 public void testProducts() {

  // accessing getters
  Assert.assertEquals("Washing Machine", product1.getName());

  Assert.assertEquals("Gas Stove", product2.getName());

 }

 @Test
 public void testObjectEquality() {
  // shows they are different objects
  Assert.assertNotEquals(product1, product2);

 }

}

Download Complete Example: Source Code

More Features: lombok features

Please Share - Hope you like it.

Wednesday, 18 March 2015

CONFIGURING JAVAMAIL SESSIONS IN GLASSFISH SERVER - THREE DIFFERENT WAYS

This post describes how we can configure  JavaMail Sessions in Glassfish Server.

It is very easy to construct a mailing logic If a JavaMail Session is pre-configured in Application server. In JavaEE 7, you can fetch a JavaMail Session configured in the Application Server using @Resource annotation.

@Resource

This annotation is available under javax.annotation package.

Note: In JavaEE, @EJB, @PersistenceContext, @PersistenceUnit, @Inject, @WebServiceRef, @Resource are some of the annotations used for dependecny injection.

@Resource

This annotation is mainly used to inject several resources such as JDBC data sources, JMS connection factories & destinations, JavaMail Sessions, Timer service, etc..

Here, we will see how to configure JavaMail Sessions in Glassfish Server and fetch the resource using @Resource annotation.

We can configure a JavaMail Session in Glassfish server in three ways:

1. Using Admin Console - a web page
   
      URL:   http://localhost:4848/common/index.jsf

2. Using Glassfish Server Command-Line Tool (CLI) : asadmin

3. Using a Glassfish Server XML Resource Configuration file
    ( glassfish-resources.xml )


First Way:

1. Using admin console:

>>> Start the Glassfish server.

   you can start using a command line tool: asadmin

   you can find asadmin (bat/sh file) -navigate to bin folder of your Glassfish Server location on file system.

eg:  /home/dinesh/glassfish/bin  (on Linux)

     C:\Softwares\Glassfish\bin (On Windows)

Command to start the Glassfish server using CLI:

>asadmin start-domain

Note: This is best way to start the server. But you can do this very easily if you are using any IDE.

>>>  Once the server is started properly - open a browser - go to 
http://localhost:4848/common/index.jsf

you should see admin console.

>>> On left-side Tree Pane - Select Resources -> JavaMail Sessions

You should see the web page like this: 


 >>> Click the New... button, then configure the JavaMail Session Details.

In the example, I have configured like this:

Important Details to be Entered:

JNDI Name: *  mail/myOwn

Note: Generally JNDI names have some default naming conventions like for JDBC starts with "jdbc/" .So here, this should be prefixed with "mail/".

Mail Host: * smtp.gmail.com

Mail host for gmail is smtp.gmail.com

Default User: * donthadineshkumar
(username for connecting to mail server - from mail id remove the @gmail.com )

Here, you can set your mail username

Default Sender Address: * donthadineshkumar@gmail.com

(from Email address - from this mail id the mail will be sent).

Here, you can set your email address.

Note: These are the mandatory fields needs to be filled. Some defaults are already provided by Glassfish Server Admin console.

Additional Properties:

At the bottom of the same page - you need to add some important properties.

property  :   value

mail-smtp-auth : true

mail-smtp-starttls-enable:true

mail-smtp-port:587

mail-smtp-password: <<your password>>

I have used gmail SMTP TLS configuration. That is the reason why the smtp-port is 587 & smtp-starttls-enable property is enabled. you can also use SMTP SSL configuration where your port is 465. I think an SSL configuration may be required.

Even ways I have used SMTP TLS configuration.

Your configuration should look like this:


Additional properties (on same page- bottom)


Here, In the pic, I have blurred the place where password should be entered for the default mail user entered in the previous fields.

Now, go to upper right-side corner(on the same page) to save the configuration.

If you are properly configured your details- then this should show a success message. This completes the JavaMail Session configuration using Admin Console.

Second Way:

2. Using Glassfish Server Command-Line Tool : asadmin

As aforementioned, you must to bin folder of Glassfish Server on your file system.

>>start the server

>asadmin start-domain

This will start the Glassfish Server.

Waiting for domain1 to start ......................
Successfully started the domain : domain1
domain  Location: /home/dinesh/Downloads/JavaDownloads/GlassFish_Server/glassfish/domains/domain1
Log File: /home/dinesh/Downloads/JavaDownloads/GlassFish_Server/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

 
asadmin>

you can configure JavaMail Session using a command

create-javamail-resource

Note: To get more on this type

asadmin>create-javamail-resource --help

From this help you can see lot of usage details.

Example:

     Usage: create-javamail-resource --mailhost=mailhost --mailus
     er=mailuser --fromaddress=fromaddress [--storeprotocol=imap]
      [--storeprotocolclass=com.sun.mail.imap.IMAPStore] [--trans
     protocol=smtp] [--transprotocolclass=com.sun.mail.smtp.SMTPT
     ransport] [--enabled=true] [--debug=false] [--property=prope
     rty] [--target=server] [--description=description] jndi_name



If you observe, there are properties which are specified in brackets [ ] - those are optional.

Configure like this:
(As we configured in Admin console - same details are given here)

--mailhost smtp.gmail.com

--mailuser donthadineshkumar

--fromaddress donthadineshkumar@gmail.com

Example:

create-javamail-resource  --mailhost smtp.gmail.com --mailuser donthadineshkumar --fromaddress donthadineshkumar@gmail.com  --property mail-smtp-auth=true:mail-smtp-starttls-enable=true:mail-smtp-port=587:mail-smtp-password=*****  mail/cmdMailSession 

>>>All additional properties must be separated by colon :

>>>Must be prefixed with --property  

>>>Must enter your password (replace **** with your password)

Note: For Windows Users, if the above does not work then try replacing the separator using semi-colon.

After all the properties, give you JNDI name for the JavaMail Session. Please provide a unique name. Otherwise It would fail to create the resource.

Using ADMIN CONSOLE : created mail/myOwn

Using asadmin : created mail/cmdMailSession 
(given a different JNDI name)

Once executed - you should see

Mail Resource mail/cmdMailSession created.
Command create-javamail-resource executed successfully.




Listing JavaMail Sessions: 

 You can list all the JavaMail Sessions created using a command
 list-javamail-resources

adamin>list-javamail-resources

Deleting JavaMail Sessions: 

you can delete JavaMail resources created earlier -using command
delete-javamail-resource
 
asadmin>delete-javamail-resource  <<JNDI-JAVAMAIL-SESSION-NAME>>

asadmin>delete-javamail-resource mail/cmdMailSession


Third Way:

3.Using Glassfish Resource XML Configuration file
( glassfish-resources.xml)

Same Details are to be configured:

Example: 
 glassfish-resources.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE resources PUBLIC
"-//GlassFish.org//DTD GlassFish Application Server 3.1 Resource Definitions//EN"
"http://glassfish.org/dtds/glassfish-resources_1_5.dtd">
<resources>
  <mail-resource debug="false"
                 enabled="true"
                 from="donthadineshkumar@gmail.com"
                 host="smtp.gmail.com"
                 jndi-name="mail/myXmlJavaMail"
                 object-type="user"
                 store-protocol="imap"
                 store-protocol-class="com.sun.mail.imap.IMAPStore"
                 transport-protocol="smtp"
                 transport-protocol-class="com.sun.mail.smtp.SMTPTransport"
                 user="donthadineshkumar">
    <description>Configuring JavaMail Session Using glassfish-server.xml    file</description>
    <property name="mail-smtp-auth" value="true"/>
    <property name="mail-smtp-password" value="***your password**"/>
    <property name="mail-smtp-port" value="587"/>
    <property name="mail-smtp-starttls-enable" value="true"/>
  </mail-resource>

</resources>

Note: you can change the details -according to your usage. Properties which are labelled -RED - just change those.

glassfish-resources.xml file location in your project must look like this:

Showing in Enterprise Application Level:

ear
      -> META-INF
                              -> application.xml
                              -> glassfish-resources.xml [Application scoped resources]
      -> web-module
                  -> WEB-INF
                                        -> web.xml
                                        -> glassfish-web.xml
                                        -> glassfish-resources.xml [Module scoped resources]
     -> ejb-module 
                 -> META-INF
                                         -> ejb-jar.xml
                                         -> glassfish-ejb-jar.xml
                                         -> glassfish-resources.xml [Module scoped resources]



Note:

Simple Java Project :  must be in META-INF folder.

Web Project: must be in WEB-INF folder.

EJB Module: must be in META-INF folder.

Even though, if there are no JavaMail Sessions in Glassfish Server, with XML configuration (
glassfish-resources.xml) file, you can create a Session during deployment of the project.

Place this proper location and use the JNDI name as specified in XML configuration file.

eg:   @Resource("mail/myXmlJavaMail")

Sample Example:

Here, I am using the configured JavaMail Session in a Servlet using @Resource annotation.

@Resource("mail/myOwn")

package com.mail.example;

import java.io.IOException;
import java.io.PrintWriter;
import javax.annotation.Resource;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author dinesh
 */
@WebServlet(name = "MailServlet", urlPatterns = {"/MailServlet"})
public class MailServlet extends HttpServlet {

    @Resource(name = "mail/myOwn")
    private Session mailSession;

    /**
     * Processes requests for both HTTP GET and POST
     * methods.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */

            Message message = new MimeMessage(mailSession);
            String toUser = request.getParameter("tomailid");
            String sub = request.getParameter("subject");
            String msg = request.getParameter("msg");
            out.println("");
            out.println("");
            out.println("");
            out.println("Servlet MailServlet");
            out.println("");
            out.println("");
            try {
                message.setSubject(sub);
                message.setRecipient(Message.RecipientType.TO, new InternetAddress(toUser));
                message.setText(msg);
               Transport.send(message);
                out.println("Message Sent SuccessFully..please check your mail");

            } catch (MessagingException ex) {
                out.println("Oops! Got an Exception");
                out.println(ex.toString());
            }
            out.println("");
            out.println("");
        }
    }

    /**
     * Handles the HTTP POST method.
     *
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Returns a short description of the servlet.
     *
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Servlet uses glassfish mail resources - preconfigured";
    }} 

Download Complete Example:  Source Code

Note: Can be imported into NETBEANS IDE.

Execution Steps:

>>Download Code - Open In Netbeans IDE
>> First create JavaMail Sessions - in any of three ways.
>> Just change the JavaMail Session name in @Resource("<<your JNDI name>>")

Useful Links:

Glassfish asadmin commands - Read more...
More on glassfish-resources.xml file placement Read More...

Hope you like it - Please Share ☺ 

Saturday, 28 February 2015

CREATE PDF FILES USING iTextPdf Jar LIBRARY - BASIC EXAMPLE

iText is an API for creating and manipulating PDF files in java.

Note: you must add itextpdf jar file to your build path in order to use itext pdf API.

Download Link:

itextpdf-5.5.5.jar

(or)

Using Maven:

If you are interested to use a maven dependency - add the following to your dependencies list:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.5</version>
</dependency>

Note: you can continue reading this post even if you don't no maven.

If you are new to maven - click here ---> What is Maven & how to use it?

This post explains the creation of PDF with a specifed format like this:

Example PDF :  CWCReport.pdf

Important Classes:

Mostly all the classes I am using here are from same package:
com.itextpdf.text package


>>Document - Objects of this classes resembles the real world PDF document.

//creating an instance of Document
Document document = new Document();

Document class has different overloaded constructors. I am using one which specifies the page size of A4.

//creating an instance of Document
Document document = new Document(PageSize.A4.rotate());

Here,
>>PageSize  - class having all standard page formats like A1-A10 , B1-B10

rotate() method - creates a landscape PDF.

>>PdfWriter

* After defining a Document object - define PdfWriter object

//creating PdfWriter instance using a static method getInstance

//You can specify the path for PDF file creating using FileOutputStream
 OutputStream file=new FileOutputStream(new File("/home/dinesh/CWCReport.pdf"));

For File pass you pdf path where you want to create on your file system.

Note: On windows, you may have you give \\ (double slashes) for file's path.
Like: c:\\home\\pdfs\\create.pdf

//Parameters document & FileOutStream file
PdfWriter.getInstance(document, file);

Defining Document Information using document object:

using document object - we can define the pdf author, subject, title, & creation date.

                 //defining an author
                document.addAuthor("Dinesh Dontha");

                 //defining a subject
                document.addSubject("CWC Matches List");
   
                // title on the document-window
                document.addTitle("CWC - Schedule");

                // creation date
                document.addCreationDate();

Opening a Document:

Note: Inorder to write content into the pdf document - you must open it first

//open a document
document.open();

Adding a Paragraph:

>> Paragraph

Objects of this classes resembles real-object Paragraphs - so to create a paragraph use an object of it.

Paragraph class extends a Phrase class.

Phrase is like a sentence.

Defining Paragraphs :

//create a paragraph - using a String argument
Paragraph para2 = new Paragraph("para1....");

//create a paragraph -using a Phrase

>>Phrase
 
Phrase is a series of chunks

Here, we also have Chunk class

Chunk is the smallest significant part of the text that can be added to
document.

//creating a phrase with no parameters
Phrase phrase = new Phrase();

//Phrase with a specified font
Phrase title =new Phrase("phrase1",new Font(FontFamily.HELVETICA, 32));

Note:

>>Font  class 

 FontFamily  is an ENUM defined inside Font class

//creating Paragraph by passing Phrase instance
Paragraph para2 = new Paragraph(phrase);

//creating Paragraph with specified Font
Paragraph para2 = new Paragraph("Paragraph Text", new Font(FontFamily.HELVETICA, 16));

 Adding New Blank Lines between Paragraphs:

Using Chunk class

>>Chunk

//adds a blank line
document.add(Chunk.NEWLINE);

Creating a table:

Use  PdfPTable class instance

>>PdfPTable

While creating the instance of PdfPTable - we can define the number of columns in that table

//create a table with 2 columns
PdfPTable table = new PdfPTable(2);

Using this instance, you can set some global properties for this table elements

//setting the table width in the document
table.setWidthPercentage(100);

Here, table extends complete width of page.

 //setting a padding for all cells
table.getDefaultCell().setPadding(10);

//setting an align of cell data      
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

Defining Table Cells:

we can add table cells using  addCell() method of PdfPTable class

//adding a basic cell using addCell() method

table.addCell("Match Date");
table.addCell("Between");

(or)

you can define table cells using PdfPCell class

>>PdfPCell
PdfPCell class has many overloaded constructors

//with no parameters
PdfPCell cell1 = new PdfPCell();

//with a Phrase paramter -defines the cell content with Phrase
Phrase p1 =new Phrase("Cell Content");

//defining cell with phrase as content
PdfPCell cell = new PdfPCell(p1);

Once defined a cell instance - we can override the properties that are
globally defined- defined on table i.e, PdfPTable object.

//overrides padding defined on table object
cellHeader2.setPadding(20);

**Note:
 //setting properties on PdfPTable object-"table" are not applicable for this particular cell defined using PdfPCell class

i.e,       table.getDefaultCell().setPadding(10);

Here, padding for all cells is 10. But, for this cell - it is 20.

//similarly this overrides - alignment property set on table(PdfPTable) object
cellHeader2.setHorizontalAlignment(Element.ALIGN_CENTER);

Example:

All the data in this example are stored in a Map object.

Note: finally close the document object and file stream object.

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/* GeneratePdf.java
 * Created on 26-Sep-2014
 */

public class CreatePdf {

 public static void main(String[] args) {

try {

 // creating a file stream object
 OutputStream file = new FileOutputStream(new File(
   "/home/dinesh/CWCReport.pdf"));

 // creating a document object - with A4 size
 // please see the effect of rotate() method -with and without it

 // rotate() method -creates a pdf in landscape format
 Document document = new Document(PageSize.A4.rotate());

 // must create a PdfWriter object -pass document and file output
 // stream
 PdfWriter.getInstance(document, file);

 // creating document info
 document.addAuthor("Dinesh Dontha");
 document.addSubject("CWC Matches List");
 document.addTitle("CWC - Schedule");
 document.addCreationDate();

 // must open a document -to put content
 document.open();

 // creating a Phrase
 Phrase title = new Phrase("Cricket World Cup-2015- Schedule",
   new Font(FontFamily.HELVETICA, 32));

 // creating a Paragrapgh with Phrase as parameter
 Paragraph para1 = new Paragraph(title);
 para1.setAlignment(Element.ALIGN_CENTER);

 // adding paragraph to document -this main heading for document.
 document.add(para1);

 // adding a blank line after - heading/title
 document.add(Chunk.NEWLINE);

 // creating a paragraph
 Paragraph para2 = new Paragraph(
   "Next upcoming league matches of Team India in the "
     + "giagantic Cricket World Cup-2015", new Font(
     FontFamily.HELVETICA, 16));
 para2.setAlignment(Element.ALIGN_LEFT);

 // adding a paragraph - this is infact the first paragraph in this
 // exxample
 document.add(para2);

 // adding a blank line after - first paragraph
 document.add(Chunk.NEWLINE);

 // adding all cell data to a Map object
 Map indiaMatches = new HashMap<>();

 indiaMatches.put("Sunday, March 6th 2015", "INDIA VS WEST INDIES");
 indiaMatches.put("Sunday, March 10th 2015", "INDIA VS IRELAND");
 indiaMatches.put("Sunday, March 14th 2015", "INDIA Vs ZIMBABWE");

 // Define a PDF table with 2 columns - Match Date & Between column
 // Names
 PdfPTable table = new PdfPTable(2);

 // Setting global table cell properties
 table.setWidthPercentage(100);
 table.getDefaultCell().setPadding(10);
 table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);

 // table header creation -using PdfPCell class

 // creating table header -cell -first column - Match Date
 Phrase matchDate = new Phrase("Match Date", new Font(
   FontFamily.HELVETICA, 14, Font.BOLD));
 // using PdfPCell class
 PdfPCell cellHeader1 = new PdfPCell(matchDate);
 cellHeader1.setBackgroundColor(BaseColor.ORANGE);
 cellHeader1.setPadding(10);
 cellHeader1.setHorizontalAlignment(Element.ALIGN_CENTER);
 table.addCell(cellHeader1);

 // creating table header -cell -second column - Between
 Phrase matchBetween = new Phrase("Match Between", new Font(
   FontFamily.HELVETICA, 14, Font.BOLD));
 // using PdfPCell class
 PdfPCell cellHeader2 = new PdfPCell(matchBetween);
 cellHeader2.setBackgroundColor(BaseColor.ORANGE);
 cellHeader2.setPadding(10);
 cellHeader2.setHorizontalAlignment(Element.ALIGN_CENTER);
 table.addCell(cellHeader2);

 // creating cell data -other than table column headers- using
 // addCell()
 // method of PdfPTable object
 for (Map.Entry entry : indiaMatches.entrySet()) {
  table.addCell(entry.getKey());
  table.addCell(entry.getValue());
 }

 // adding table to Pdf document
 document.add(table);

 // finally close - document & file stream
 document.close();
 file.close();

} catch (DocumentException | IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
}
}

}

Source Code: Download
Note: To run it successfully change the file path.