Wednesday 17 October 2012

Text File Parsing :Fixed Length data


package com.opensourzesupport.parsers;

import com.opensourzesupport.parsers.model.User;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.coury.jfilehelpers.engines.FileHelperEngine;

/**
 *
 * @author Prasobh.K
 */
public class TestJHelper {

    public static void main(String[] args) throws IOException {
        FileHelperEngine<User> engine = new FileHelperEngine<User>(User.class);
        List<User> users = new ArrayList<User>();    
        users = engine.readFile("src/data.txt");

        for (User user : users) {
            System.out.println("User "+user);
        }
    }
}


User.java

package com.opensourzesupport.parsers.model;


import org.coury.jfilehelpers.annotations.FieldFixedLength;

/**
 *
 * @author Prasobh.K
 */

public class User {

    @FieldFixedLength(11)
    private String name;
    @FieldFixedLength(2)
    private Integer age;
    @FieldFixedLength(16)
    private String address;
    @FieldFixedLength(16)
    private String areaOfProfession;
    @FieldFixedLength(15)
    private String designation;
    @FieldFixedLength(8)   
    private String salary;

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public String getAddress() {
        return address;
    }

    public String getAreaOfProfession() {
        return areaOfProfession;
    }

    public String getDesignation() {
        return designation;
    }

    public String getSalary() {
        return salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setAreaOfProfession(String areaOfProfession) {
        this.areaOfProfession = areaOfProfession;
    }

    public void setDesignation(String designation) {
        this.designation = designation;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User1{" + "name=" + name + ", age=" + age + ", address=" + address + ", areaOfProfession=" + areaOfProfession + ", designation=" + designation + ", salary=" + salary + '}';
    }
    
} 

data.txt 

Prasobh    26 kollattu       IT              Tech Lead      25000.02
Reena      18 veettil        IT              ProjectManager 25000.02
Ronald     25 kollattu       IT              ProjectLeader  25000.02
Vinu       22 kollattu       IT              ClarityAdmin   25000.02

Output :

User User{name=Prasobh    , age=26, address= kollattu       , areaOfProfession=IT              , designation=Tech Lead      , salary=25000.02}
User User{name=Reena      , age=18, address= veettil        , areaOfProfession=IT              , designation=ProjectManager , salary=25000.02}
User User{name=Ronald     , age=25, address= kollattu       , areaOfProfession=IT              , designation=ProjectLeader  , salary=25000.02}
User User{name=Vinu       , age=22, address= kollattu       , areaOfProfession=IT              , designation=ClarityAdmin   , salary=25000.02}

Library used:

jfilehelpers-0.2a-20080607.jar

Monday 15 October 2012

SPRING JPA and REST Together


Spring

The Spring Framework is an open source application framework and Inversion of Control container for the Java platform.

JPA

Java Persistence API (JPA) provides POJO (Plain Old Java Object) standard and object relational mapping (OR mapping) for data persistence among applications. Persistence, which deals with storing and retrieving of application data

REST 

As described in a dissertation by Roy Fielding, REST is an "architectural style" that basically exploits the existing technology and protocols of the Web, including HTTP (Hypertext Transfer Protocol) and XML. REST is simpler to use than the well-known SOAP (Simple Object Access Protocol) approach, which requires writing or using a provided server program (to serve data) and a client program (to request data). SOAP, however, offers potentially more capability. For example, a syndicator that wanted to include up-to-date stock prices to subscribing Web sites might need to use SOAP, which allows a greater amount of program interaction between client and server.

Incorporating these technologies together is a little bit of challenge.

JPA is a specification it has many implementation.Hibernate is one of the most widely used implementation.Here we are going to use hibernate(4.x.x) as JPA implementation.
REST too has many implementaion.
We will focus mainly on Oracle Jersey and JBOSS RESTEasy.

 Jersey will work only on Glassfish  but RESTEasy will work on any Application Server.
 But we need to do some changes accordingly.

Let's see how to make these stuffs work together for a GlassFish Application Server.

Here is our applicationContext.xml:-

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:flow="http://www.springframework.org/schema/webflow-config"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:osgi="http://www.springframework.org/schema/osgi"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
          http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
          http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
          http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-3.0.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd ">
              
     <!-- specifying the property file   -->
    <bean id="placeholderPropertiesuserdao" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:application.properties" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
    </bean>
    
  <bean class="com.opensourzesupport
.rest.network.ProductResource" p:platformTransactionManager-ref="transactionManager" />
  
    <!-- datasource information -->
    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"  >
        <property name="uRL" value="${db.jdbc.url}" />
        <property name="user" value="${db.jdbc.user}" />
        <property name="password" value="${db.jdbc.password}" />
    </bean>
    
    <context:component-scan base-package="com.opensourzesupport.model" />

    
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/>  
   
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >  
        <property name="persistenceUnitName" value="app_persist_unit"/>  
        <property name="dataSource" ref="dataSource"/>  
        <property name="persistenceXmlLocation" value="classpath:persistence.xml"/> 
        <property name="jpaVendorAdapter">  
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="${db.orm.showsql}" />              
                <property name="generateDdl" value="${db.orm.generateDdl}" />               
                <property name="database" value="${db.type}"/>  
                <property name="databasePlatform" value="${db.orm.dialect}" />
            </bean>
        </property>  
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>
    
   
</beans> 

We will use JAXB  and JPA annotation together in our POJO class.
All the annoted classes will be specified in persistence.xml and it should be in classpath

persistence.xml
 
 <?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="app_persist_unit" transaction-type="RESOURCE_LOCAL">
        <description>Oracle db Persistence Unit</description> 
         <class>com.opensourzesupport.rest.model.Product</class>
    </persistence-unit>
</persistence>


Web.xml(if using Jersey)

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  id="WebApp_ID" version="2.5">
  <display-name>spring-jpa-rest</display-name>
   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
<!--    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>-->
     <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.opensourzesupport.rest</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app> 
 
Web.xml(if using RESTEasy )

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">
    <display-name>spring-jpa-rest</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- Auto scan REST service -->
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>
        
        <!-- this need same with resteasy servlet url-pattern -->
    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>/rest</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
        </listener-class>
    </listener>
    
    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app> 

Product.java is our annoted POJO class.

Product.java
package com.opensourzesupport.rest.model;

import com.opensourzesupport.rest.util.Constants;
import javax.persistence.*;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author Prasobh.K
 */
@XmlRootElement
@Entity
@NamedQueries({
    @NamedQuery(name = Constants.GET_PRODUCT,
    query = "select T from Product T")})
@XmlAccessorType(XmlAccessType.FIELD)
public class Product {

    @Column
    @Id
    String name;
    @Column
    String description;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
 

ProductList.java
package com.opensourzesupport.rest.model;

import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;

/**
 *
 * @author Prasobh.K
 */
@XmlRootElement(name="root")
public class ProductList {
  
   public  List product ;

    public List getProducts() {
        return product;
    }

    public void setProducts(List products) {
        this.product = products;
    }
}

ProductResource.java is our service class, where we will do all rest based annotations.

ProductResource.java
package com.opensourzesupport.rest.network;

import com.opensourzesupport.rest.model.Product;
import com.opensourzesupport.rest.model.ProductList;
import com.opensourzesupport.rest.util.Constants;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 *
 * @author Prasobh.K
 */
@Path("/service")
public class ProductResource {

    @PersistenceContext
    private EntityManager em = null;
    private PlatformTransactionManager platformTransactionManager = null;
    private List list = new ArrayList();

    public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
        this.platformTransactionManager = platformTransactionManager;
    }

    @GET
    @Produces({MediaType.APPLICATION_XML})
    @Path("/product/xml")
    public ProductList getXML() {
        ProductList productList = new ProductList();
        productList.setProducts(getRoot());
        return productList;
    }

    @GET
    @Produces({MediaType.TEXT_PLAIN})
    @Path("/product/save")
    public String saveProduct() {
        TransactionStatus transactionStatus = platformTransactionManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
        Product product = new Product();
        product.setName("TestProduct");
        product.setDescription("testing Persistance");
        String status = "Failed";
        try {
            em.persist(product);
            platformTransactionManager.commit(transactionStatus);
            status = "Success";
        } catch (Exception e) {
            System.out.println("Error" + e);
            platformTransactionManager.rollback(transactionStatus);
        }
        return status;
    }

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    @Path("/product/get")
    public Product getProduct() {
        try {
            Query query = em.createNamedQuery(Constants.GET_PRODUCT);
            Product p = (Product) query.getSingleResult();
            return p;
        } catch (Exception e) {
            System.out.println("Error" + e);
        }
        return null;
    }

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    @Path("/product/json")
    public List getJSON() {
        return getRoot();
    }

    @GET
    @Produces({MediaType.TEXT_HTML})
    @Path("/html")
    public List getHTML() {

        return getRoot();
    }

    public List getRoot() {
        List root = new ArrayList();
        Product product1 = new Product();
        product1.setName("IOS");
        product1.setDescription("Mobile");
        root.add(product1);
        Product product2 = new Product();
        product2.setName("Android");
        product2.setDescription("Mobile");
        root.add(product2);
        Product product3 = new Product();
        product3.setName("BlacBerry");
        product3.setDescription("Mobile");
        root.add(product3);
        Product product4 = new Product();
        product4.setName("J2ME");
        product4.setDescription("Mobile");
        root.add(product4);
        return root;
    }
}

 Output :

http://localhost:8080/webservice/rest/service/products/xml


<root>
    <product>
        <name>IOS</name>
        <description>Mobile</description>
    </product>
    <product>
        <name>Android</name>
        <description>Mobile</description>
    </product>
    <product>
        <name>BlacBerry</name>
        <description>Mobile</description>
    </product>
    <product>
        <name>J2ME</name>
        <description>Mobile</description>
    </product>
    <products>
        <name>IOS</name>
        <description>Mobile</description>
    </products>
    <products>
        <name>Android</name>
        <description>Mobile</description>
    </products>
    <products>
        <name>BlacBerry</name>
        <description>Mobile</description>
    </products>
    <products>
        <name>J2ME</name>
        <description>Mobile</description>
    </products>
</root>

http://localhost:8080/webservice/rest/service/products/json



{"product":
[{"name":"IOS","description":"Mobile"},
{"name":"Android","description":"Mobile"},
{"name":"BlacBerry","description":"Mobile"},
{"name":"J2ME","description":"Mobile"}]
}

http://localhost:8080/webservice/rest/service/product/save

Success

http://localhost:8080/webservice/rest/service/product/get


{"name":"TestProduct","description":"testing Persistance"}

if(RESTEasy )
include :
scannotation-1.0.3.jar
resteasy-jaxb-provider-2.3.4.Final.jar
resteasy-jaxrs-2.3.4.Final.jar
if(Jersey)
include :
jersey-core-1.14.jar
jersey-server-1.14.jar
jersey-spring-1.9.jar

Jar Files Used for Jersey















To Make RESTEasy to work with JBOSS(jboss-5.1.0.GA), please use the following configuration :

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:flow="http://www.springframework.org/schema/webflow-config"
       xmlns:jms="http://www.springframework.org/schema/jms"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xmlns:lang="http://www.springframework.org/schema/lang"
       xmlns:osgi="http://www.springframework.org/schema/osgi"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.0.xsd
          http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
          http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
          http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-3.0.xsd
          http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-3.0.xsd
          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
          http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd ">
       
    <context:component-scan base-package="com.opensourzesupport.rest" />
<!--    <tx:annotation-driven   />-->
    <context:annotation-config/>
     <!-- specifying the property file   -->
    <bean id="placeholderPropertiesuserdao" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:application.properties" />
        <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
    </bean>
    
    <bean class="com.opensourzesupport.rest.network.ProductResource" p:platformTransactionManager-ref="transactionManager" />
  
    <!-- datasource information -->
    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"  >
        <property name="uRL" value="${db.jdbc.url}" />
        <property name="user" value="${db.jdbc.user}" />
        <property name="password" value="${db.jdbc.password}" />
    </bean>
<!--    <bean class="com.opensourzesupport.rest.core.SpringApplicationContext"></bean>-->
   
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" p:entityManagerFactory-ref="entityManagerFactory"/>  
   
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" >  
        <property name="persistenceUnitName" value="persistanceUnit"/>  
        <property name="dataSource" ref="dataSource"/>  
        <property name="persistenceXmlLocation" value="classpath:persistence.xml"/> 
        <property name="jpaVendorAdapter">  
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="${db.orm.showsql}" />              
                <property name="generateDdl" value="${db.orm.generateDdl}" />               
                <property name="database" value="${db.type}"/>  
                <property name="databasePlatform" value="${db.orm.dialect}" />
            </bean>
        </property>  
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>
    
   
</beans>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         id="WebApp_ID" version="2.5">
    <display-name>spring-jpa-rest</display-name>  
    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
        </listener-class>
    </listener>
    
    <listener>
        <listener-class>
            org.jboss.resteasy.plugins.spring.SpringContextLoaderListener
        </listener-class>
    </listener>
    <servlet>
        <servlet-name>resteasy-servlet</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
    </servlet>
 
    <servlet-mapping>
        <servlet-name>resteasy-servlet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <context-param>
        <param-name>resteasy.servlet.mapping.prefix</param-name>
        <param-value>rest</param-value>
    </context-param>
 
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>false</param-value>
    </context-param>
</web-app> 

ProductResource.java
package com.opensourzesupport.rest.network;

import com.opensourzesupport.rest.core.SpringApplicationContext;
import com.opensourzesupport.rest.model.Product;
import com.opensourzesupport.rest.model.ProductList;
import com.opensourzesupport.rest.util.Constants;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 *
 * @author Prasobh.K
 */
@Component
@Path("/service")
public class ProductResource {

    @PersistenceContext
    private EntityManager em = null;
    private PlatformTransactionManager platformTransactionManager = null;
    private List<ProductList> list = new ArrayList<ProductList>();

    public PlatformTransactionManager getPlatformTransactionManager() {
        if(platformTransactionManager == null){
            platformTransactionManager = (PlatformTransactionManager) SpringApplicationContext.getBean("transactionManager");
        }
        return platformTransactionManager;
    }


    
    public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
        System.out.println("setting ptm");
        this.platformTransactionManager = platformTransactionManager;
    }

    @GET
    @Produces({MediaType.APPLICATION_XML})
    @Path("/products/xml")
    public List<Product> getXML() {
      
         return getRoot();
    }

    @GET
    @Produces({MediaType.TEXT_PLAIN})
    @Path("/product/save")
    public String saveProduct() {
        System.out.println("platformTransactionManager "+platformTransactionManager);
        TransactionStatus transactionStatus =platformTransactionManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
        Product product = new Product();
        product.setName("TestProduct");
        product.setDescription("testing Persistance");
        String status = "Failed";
        try {
            em.persist(product);
           platformTransactionManager.commit(transactionStatus);
            status = "Success";
        } catch (Exception e) {
            System.out.println("Error" + e);
           platformTransactionManager.rollback(transactionStatus);
        }
        return status;
    }

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    @Path("/product/get")
    public Product getProduct() {
        try {
            Query query = em.createNamedQuery(Constants.GET_PRODUCT);
            Product p = (Product) query.getSingleResult();
            return p;
        } catch (Exception e) {
            System.out.println("Error" + e);
        }
        return null;
    }

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    @Path("/products/json")
    public List<Product> getJSON() {
        return getRoot();
    }

    @GET
    @Produces({MediaType.TEXT_HTML})
    @Path("/html")
    public List<Product> getHTML() {

        return getRoot();
    }

    public List<Product> getRoot() {
        List<Product> root = new ArrayList<Product>();
        Product product1 = new Product();
        product1.setName("IOS");
        product1.setDescription("Mobile");
        root.add(product1);
        Product product2 = new Product();
        product2.setName("Android");
        product2.setDescription("Mobile");
        root.add(product2);
        Product product3 = new Product();
        product3.setName("BlacBerry");
        product3.setDescription("Mobile");
        root.add(product3);
        Product product4 = new Product();
        product4.setName("J2ME");
        product4.setDescription("Mobile");
        root.add(product4);
        return root;
    }
}

Libraries Used :


Thursday 11 October 2012

Spring Batch 2.0

Many applications within the enterprise domain require bulk processing to perform business operations in mission critical environments. These business operations include automated, complex processing of large volumes of information that is most efficiently processed without user interaction. These operations typically include time based events (e.g. month-end calculations, notices or correspondence), periodic application of complex business rules processed repetitively across very large data sets (e.g. Insurance benefit determination or rate adjustments), or the integration of information that is received from internal and external systems that typically requires formatting, validation and processing in a transactional manner into the system of record. Batch processing is used to process billions of transactions every day for enterprises.

What's New in Spring Batch 2.0

The Spring Batch 2.0 release has six major themes:
  • Java 5
  • Non Sequential Step Execution
  • Chunk oriented processing
  • Meta Data enhancements
  • Scalability
  • Configuration

The Domain Language of Batch

 Job

A Job is an entity that encapsulates an entire batch process. As is common with other Spring projects, a Job will be wired together via an XML configuration file. This file may be referred to as the "job configuration". However, Job is just the top of an overall hierarchy:


JobInstance

 A JobInstance refers to the concept of a logical job run.

JobParameters

Having discussed JobInstance and how it differs from Job, the natural question to ask is: "how is one JobInstance distinguished from another?" The answer is: JobParameters. JobParameters is a set of parameters used to start a batch job.

JobExecution

A JobExecution refers to the technical concept of a single attempt to run a Job

Step

A Step is a domain object that encapsulates an independent, sequential phase of a batch job. Therefore, every Job is composed entirely of one or more steps. A Step contains all of the information necessary to define and control the actual batch processing.







StepExecution

 A StepExecution represents a single attempt to execute a Step.  

ExecutionContext

 An ExecutionContext represents a collection of key/value pairs that are persisted and controlled by the framework in order to allow developers a place to store persistent state that is scoped to a StepExecution or JobExecution.

ExecutionContext ecStep = stepExecution.getExecutionContext();
ExecutionContext ecJob = jobExecution.getExecutionContext();
//ecStep does not equal ecJob
 

JobRepository

JobRepository is the persistence mechanism for all of the Stereotypes mentioned above. It provides CRUD operations for JobLauncher, Job, and Step implementations. When a Job is first launched, a JobExecution is obtained from the repository, and during the course of execution StepExecution and JobExecution implementations are persisted by passing them to the repository:

 JobLauncher

 JobLauncher represents a simple interface for launching a Job with a given set of JobParameters:

Item Reader

ItemReader is an abstraction that represents the retrieval of input for a Step, one item at a time. When the ItemReader has exhausted the items it can provide, it will indicate this by returning null.

Item Writer

ItemWriter is an abstraction that represents the output of a Step, one batch or chunk of items at a time.

Item Processor

ItemProcessor is an abstraction that represents the business processing of an item. While the ItemReader reads one item, and the ItemWriter writes them, the ItemProcessor provides access to transform or apply other business processing. 

Configuring and Running a Job

Lets see  small application which uses batch technology pratically.

Here is our applicationContext.xml:

  
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/batch
       http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
        http://www.springframework.org/schema/aop
   http://www.springframework.org/schema/aop/spring-aop.xsd"
       xmlns:j="http://www.springframework.org/schema/batch">



 <bean id="jobListener" class="com.opensourzesupport.batch.job.listeners.JobListener" />
 <bean id="dataReader" class="com.opensourzesupport.batch.job.CustomReader" />
 <bean id="dataWriter" class="com.opensourzesupport.batch.job.CustomWriter" />
 <bean id="dataProcessor" class="com.opensourzesupport.batch.job.CustomProcessor" />

 <!-- Billing job flow -->
 <job id="job_dataproc" xmlns="http://www.springframework.org/schema/batch"
  restartable="true">
  <step id="step1">
   <tasklet task-executor="pooledTaskExecutor" throttle-limit="1">
    <chunk reader="dataReader" writer="dataWriter" processor="dataProcessor"
     commit-interval="2" />
   </tasklet>
  </step>
  <listeners>
   <listener ref="jobListener" />
  </listeners>
 </job>

 <!-- pooledTaskExecutor is using in chunk processing other wise sepearte 
  thread will spone on each chunk procesing -->
 <bean id="pooledTaskExecutor"
  class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
  <property name="corePoolSize" value="2" />
  <property name="maxPoolSize" value="10" />
  <property name="queueCapacity" value="25" />
 </bean>

 <j:job-repository id="jobRepository" data-source="applicationSettingsDBdataSource"
  transaction-manager="transactionManager" isolation-level-for-create="SERIALIZABLE"
  table-prefix="BATCH_" />
 <bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" lazy-init="true">
    </bean>
 <!-- Optional A JobRegistry (and its parent interface JobLocator) is not 
  mandatory, but it can be useful if you want to keep track of which jobs are 
  available in the context. It is also useful for collecting jobs centrally -->
 <bean id="jobRegistry"
  class="org.springframework.batch.core.configuration.support.MapJobRegistry" />

 <!-- Optional : Used only if JobRegistry is used This is a bean post-processor 
  that can register all jobs as they are created -->
 <bean id="jobRegistryBeanPostProcessor"
  class="org.springframework.batch.core.configuration.support.JobRegistryBeanPostProcessor">
  <property name="jobRegistry" ref="jobRegistry" />
 </bean>


 <!-- Following are related to asynchronized job lanching -->
 <bean id="asyncTaskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor">
 </bean>
 <bean id="asyncJobLauncher"
  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  <property name="jobRepository" ref="jobRepository" />
  <property name="taskExecutor" ref="asyncTaskExecutor" />
 </bean>
 <!-- orderdata mothly , adhoc and billing service are using asyncJobOperator -->
 <bean id="asyncJobOperator"
  class="org.springframework.batch.core.launch.support.SimpleJobOperator">
  <property name="jobExplorer">
   <bean
    class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
    <property name="dataSource" ref="applicationSettingsDBdataSource" />
   </bean>
  </property>
  <property name="jobRepository" ref="jobRepository" />
  <property name="jobRegistry" ref="jobRegistry" />
  <property name="jobLauncher" ref="asyncJobLauncher" />
 </bean>
 <!-- Ends asynchronized job lanching -->


 <!-- Following are related to synchronized job lanching , currently no job 
  using syncJobOperator -->
 <bean id="syncTaskExecutor" class="org.springframework.core.task.SyncTaskExecutor">
 </bean>
 <bean id="syncJobLauncher"
  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
  <property name="jobRepository" ref="jobRepository" />
  <property name="taskExecutor" ref="syncTaskExecutor" />
 </bean>
 <bean id="syncJobOperator"
  class="org.springframework.batch.core.launch.support.SimpleJobOperator">
  <property name="jobExplorer">
   <bean
    class="org.springframework.batch.core.explore.support.JobExplorerFactoryBean">
    <property name="dataSource" ref="applicationSettingsDBdataSource" />
   </bean>
  </property>
  <property name="jobRepository" ref="jobRepository" />
  <property name="jobRegistry" ref="jobRegistry" />
  <property name="jobLauncher" ref="syncJobLauncher" />
 </bean>
 <bean id="applicationSettingsDBdataSource" class="oracle.jdbc.pool.OracleDataSource"
  destroy-method="close">
  <property name="URL" value="oracle.url" />
  <property name="user" value="username" />
  <property name="password" value="password" />

 </bean>
 
 <bean class="com.opensourzesupport.batch.RunApp" init-method="init"   >
 <property name="jobOperator" ref="syncJobOperator" />
 </bean>
</beans>

  CustomReader.java

 
package com.opensourzesupport.batch.job;

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

import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;

import com.opensourzesupport.batch.job.model.DataWrapper;
/**
 * 
 * @author Prasobh.K
 *
 */
public class CustomReader implements ItemReader> {

    private int count = 0;
 @Override
 public List read() throws Exception, UnexpectedInputException,
   ParseException {
  count++;
  System.out.println("In CustomReader Count is : "+count);   
  List retList = null;
  if(count <3 data-blogger-escaped-arraylist="arraylist" data-blogger-escaped-atawrapper="atawrapper" data-blogger-escaped-retlist="new">();
   DataWrapper dataWrapper = new DataWrapper();
   dataWrapper.setCustId("" + System.currentTimeMillis());
   retList.add(dataWrapper);
   DataWrapper dataWrapper1 = new DataWrapper();
   dataWrapper1.setCustId("" + System.currentTimeMillis());
   retList.add(dataWrapper1);
  }
  //else will return null to end reading data 
  return retList;
 }

}

CustomProcessor.java

package com.opensourzesupport.batch.job;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.batch.item.ItemProcessor;
import com.opensourzesupport.batch.job.model.DataWrapper;

/**
 * 
 * @author Prasobh.K
 * 
 */
public class CustomProcessor implements
  ItemProcessor, Map> {

 @Override
 public Map process(List arg0) throws Exception {  

  Map map = new HashMap();
  
  int i = 0;
  for (DataWrapper dataWrapper : arg0) {
   System.out.println("In processor : " + dataWrapper.getCustId());
   map.put("custid" + i, dataWrapper.getCustId());
  }
  return map;
 }

}

CustomWriter.java

package com.opensourzesupport.batch.job;

import java.util.List;
import java.util.Map;

import org.springframework.batch.item.ItemWriter;

/**
 * 
 * @author Prasobh.K
 * 
 */
public class CustomWriter implements ItemWriter> {

 @Override
 public void write(List> arg0)
   throws Exception {
  System.out.println("In Customwriter : " + arg0);
 }

}

Main.java

package com.opensourzesupport.batch;

/**
 * 
 * @author Prasobh.K
 * 
 */
public class Main {

 public static void main(String[] a) {
  String[] ar = { "resources/applicationContext.xml" };
  try {
   org.springframework.batch.core.launch.support.JobRegistryBackgroundJobRunner
     .main(ar);

  } catch (Exception e) {
   e.printStackTrace();
  }

 }
}
 

RunApp.java

package com.opensourzesupport.batch;

import org.springframework.batch.core.launch.JobOperator;

/**
 * 
 * @author Prasobh.K
 * 
 */
public class RunApp {

 public JobOperator jobOperator;

 public void setJobOperator(JobOperator jobOperator) {
  this.jobOperator = jobOperator;
 }

 public void init() {
  String jobParameters = "01253 =" + System.currentTimeMillis();
  System.out.print("In RunApp init");

  try {
   jobOperator.start("job_dataproc", jobParameters);
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

 }
}

Output :

Before job 2950
In CustomReader Count is : 1
In CustomReader Count is : 2
In processor : 1350016945897
In processor : 1350016945897
In processor : 1350016945897
In processor : 1350016945897
In Customwriter : [{custid0=1350016945897}, {custid0=1350016945897}]
In CustomReader Count is : 3
In CustomReader Count is : 4
After job 2950

 

CommitInterval decides how many times item should be read.if reader return null, reading will stop.
Below is a code representation of the same concepts shown above:

List items = new Arraylist();
for(int i = 0; i < commitInterval; i++){
    Object item = itemReader.read()
    Object processedItem = itemProcessor.process(item);
    items.add(processedItem);
}
itemWriter.write(items);

  Jar Used


 






 

Tuesday 9 October 2012

Eclipse Shortcuts(Juno)

This post is basically focusing on Eclipse 4.2(Juno) shortcuts

Shortcuts help developers to be much more productive.Few of the shortcuts are listed below :-
Navigation :

Shortcut Description
Ctrl + Shift + R Open / Search for resources, e.g. files
Ctrl + Shift + T Open / Search for Types
Ctrl + E Allows to select an editor from the currently open editors
Ctrl + F8 Shortcut for switching perspectives
Alt + ← or Alt + → Go to previous/ next editor position in history
Ctrl-PageUp/PageDown Switch to previous/next editor
F3 Go to the declaration of this variable
Ctrl + Shift + P Go to the matching bracket

 Search:

Shortcut Description
Ctrl + . Go to the next problem / error
Ctrl + , Go to the previous problem / error
F4 on a variable Show type hierarchy
Ctrl + J , Ctrl + K Incremental search, find next
Ctrl + Shift + G

Run:

Shortcut Description
Ctrl + F11 Run last launched
Alt + Shift + X - J Run current selected class as Java application


Editing :

Shortcut Description
Ctrl + 1 Quickfix; result depending on cursor position
Ctrl + Space Content assist/ code completion
Ctrl + T Show the inheritance tree of the current Java class
Ctrl + O Show all methods of the current class, press Ctrl + O again to show the inherited methods.
F12 Focuses on the editor (especially helpful if you work with Fast Views).
Ctrl + M Maximize Java editor
Ctrl + Shift + F Format source code
Ctrl + Shift + O Organize the imports; will import the missing import statements.
Ctrl + Q Go to position the cursor at the last changed position in the editor.
Ctrl + Alt + Z Wrap the select block of code into a block, e.g. try/catch.


Arrow Shortcuts:


Shortcut Description
Ctrl + Left Move one element to the left
Ctrl + Right Move one element to the right
Ctrl + Alt + Up/Down Copy line
Alt + Up / Down Move line up / down
Alt + Shift Up / Down Select the previous / next syntactical element
Alt + Shift Up / Down / Left / Right Extending / Reducing the selection of the previous / next syntactical element
Ctrl + Up / Down Scroll up / down a line in the editor





 Delete:

Shortcut Description
Ctrl + D Deletes line
Ctrl + Shift + DEL Delete until end of line
Ctrl + DEL Delete next element
Ctrl + BACKSPACE Delete previous element

Coding :

Table 8. Coding
Shortcut Description
Shift + F2 Show the Javadoc for the selected type / class / method
Alt+Shift + N + Letter Type shortcut for the command, e.g. njc to create a new Java class or npip to create a new Plugin project
Alt + Shift + Z Surround block with try and catch

 Refractoring:

Shortcut Description
Alt + Shift + R Rename
Ctrl+2, R Rename locally (in file), faster then Alt + Shift + R
Alt + Shift + T Opens the quick refactoring menu