Sunday, September 29, 2013

shopping list mobile application

weekly groceries tracking app

- one person in the family prepares a grocery list
- he/she prepares the list by browsing through different categories
- recently bought/frequently bought items bubbles to top
- available items shows up left had side/picked items on right hand side
- users drags items from left to right
- user can see last bought date, qty, price, store etc.
- user presses done
- other family members can share the list


Saturday, September 28, 2013

SecureSocial Database persistence service for users and tokens

/**

 * Copyright 2012 Jorge Aliss (jaliss at gmail dot com) - twitter: @jaliss
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package service;

import play.Application;
import play.Logger;
import scala.Option;
import scala.Some;
import securesocial.core.AuthenticationMethod;
import securesocial.core.Identity;
import securesocial.core.IdentityId;
import securesocial.core.PasswordInfo;
import securesocial.core.SocialUser;
import securesocial.core.java.BaseUserService;

import securesocial.core.java.Token;

import java.net.UnknownHostException;

import org.joda.time.DateTime;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;

/**
 * A Sample In Memory user service in Java
 *
 * Note: This is NOT suitable for a production environment and is provided only as a guide.
 * A real implementation would persist things in a database
 */
public class CopyOfInMemoryUserService extends BaseUserService {

    private static final String IS_SIGN_UP = "isSignUp";
    private static final String BCRYPT = "bcrypt";
    private static final String PASSWORD = "password";
    private static final String AUTH_METHOD = "authMethod";
    private static final String LAST_NAME = "lastName";
    private static final String FIRST_NAME = "firstName";
    private static final String USER_ID = "userId";
    private static final String PROVIDER_ID = "providerId";
    private static final String USERS = "users";
    private static final String EXPIRATION_TIME = "expirationTime";
    private static final String CREATION_TIME = "creationTime";
    private static final String EMAIL = "email";
    private static final String UUID = "uuid";
    private static final String USER_TOKENS = "userTokens";
 
 
    public CopyOfInMemoryUserService(Application application) {
        super(application);
    }

    @Override
    public Identity doSave(Identity user) {
        Logger.debug("doSave(user)***"+user);
        // this sample returns the same user object, but you could return an instance of your own class
        // here as long as it implements the Identity interface. This will allow you to use your own class in the
        // protected actions and event callbacks. The same goes for the doFind(UserId userId) method.
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USERS);
        BasicDBObject doc = new BasicDBObject(USER_ID, user.identityId().userId())
                            .append("userId:providerId", user.identityId().userId() + ":" + user.identityId().providerId())
                            .append(PROVIDER_ID, user.identityId().providerId())
                            .append(AUTH_METHOD,user.authMethod().method())
                            //.append("avatarUrl",user.avatarUrl().get())
                            .append(EMAIL,user.email().get())
                            .append(FIRST_NAME,user.firstName())
                            .append(LAST_NAME,user.lastName())
                            .append("fullName",user.fullName())
                            .append(PASSWORD,user.passwordInfo().get().password());

        Logger.debug("saving user:"+doc);
        userCollection.insert(doc);
     
        return user;
    }

    @Override
    public void doSave(Token token) {
        Logger.debug("***doSave(token):"+token);
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
     
        BasicDBObject doc = new BasicDBObject(UUID, token.getUuid())
                            .append(EMAIL, token.getEmail())
                            .append(IS_SIGN_UP, token.getIsSignUp())
                            .append(CREATION_TIME, Long.toString(token.getCreationTime().toDate().getTime()))
                            .append(EXPIRATION_TIME, Long.toString(token.getExpirationTime().toDate().getTime()));
        Logger.debug("Saving token:" + doc);
        userCollection.insert(doc);
    }

    @Override
    public Identity doFind(IdentityId identityId) {
        Logger.debug("****doFind(identityId):"+identityId);
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USERS);
        BasicDBObject query = new BasicDBObject("userId:providerId", identityId.userId() + ":" + identityId.providerId());
        DBCursor cursor = userCollection.find(query);
     
        Identity identity = null;
        if( cursor.hasNext() ) {
            DBObject dbUser = cursor.next();
            Logger.debug("Found user (with identityId):"+dbUser);
            identity = new SocialUser(identityId,        
                    dbUser.get(FIRST_NAME).toString(),
                    dbUser.get(LAST_NAME).toString(),
                    dbUser.get(FIRST_NAME).toString() + " " + dbUser.get(LAST_NAME).toString(),
                    Option.apply(dbUser.get(EMAIL).toString()),
                    null,
                    new AuthenticationMethod( dbUser.get(AUTH_METHOD).toString() ),
                    null,
                    null,
                    Some.apply(new PasswordInfo(BCRYPT, dbUser.get(PASSWORD).toString(), null))
                );
         
        }
        return identity;
    }

    @Override
    public Token doFindToken(String tokenId) {
        Logger.debug("doFindToken(tokenId):"+tokenId);
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
        BasicDBObject query = new BasicDBObject(UUID, tokenId);
        DBCursor cursor = userCollection.find(query);
     
        Token token = null;
        if( cursor.hasNext() ) {
            token = new Token();
            DBObject dbToken = cursor.next();
            Logger.debug("Found token with tokenId:"+dbToken);
         
            token.setUuid(dbToken.get(UUID).toString());
            token.setEmail(dbToken.get(EMAIL).toString());
            token.setIsSignUp( new Boolean( dbToken.get(IS_SIGN_UP).toString() ) );      
            token.setCreationTime( new DateTime(new Long( dbToken.get(CREATION_TIME).toString() ) ));    
            token.setExpirationTime( new DateTime( new Long( dbToken.get(EXPIRATION_TIME).toString()) ));
            token.setIsSignUp( new Boolean(dbToken.get(IS_SIGN_UP).toString()));
        }      
        return token;
    }

    @Override
    public Identity doFindByEmailAndProvider(String email, String providerId) {
        Logger.debug("finding user with email:"+email + " and providerId:"+providerId);
     
        Identity result = null;
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USERS);
        BasicDBObject query = new BasicDBObject(EMAIL, email).append(PROVIDER_ID, providerId);
        DBCursor cursor = userCollection.find(query);
     
        if( cursor.hasNext() ) {
            DBObject dbUser = cursor.next();
            Logger.debug("found user(with email and providerId:"+dbUser);
            if( dbUser != null ) {
                IdentityId userId = new IdentityId(dbUser.get(USER_ID).toString(), providerId);
                result = new SocialUser(userId ,        
                        dbUser.get(FIRST_NAME).toString(),
                        dbUser.get(LAST_NAME).toString(),
                        dbUser.get(FIRST_NAME).toString() + " " + dbUser.get(LAST_NAME).toString(),
                        Option.apply(dbUser.get(EMAIL).toString()),
                        null,
                        new AuthenticationMethod( dbUser.get(AUTH_METHOD).toString() ),
                        null,
                        null,
                        Some.apply(new PasswordInfo(BCRYPT, dbUser.get(PASSWORD).toString(), null))
                    );
            }
        }
        Logger.debug("found user with email and provider:"+result);
        return result;
    }

    @Override
    public void doDeleteToken(String uuid) {
        Logger.debug("********* doDeleteToken() called ****");
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
        BasicDBObject query = new BasicDBObject(UUID, uuid);
        DBCursor cursor = userCollection.find(query);
     
        if( cursor.hasNext() ) {
            DBObject dbToken = cursor.next();
            Logger.debug("Deleting token with uuid:"+uuid);
            userCollection.remove(dbToken);
        }      
    }

    @Override
    public void doDeleteExpiredTokens() {
        Logger.debug("***deleteExpiredTokens()");
        DB db = getMongoClient();          
        DBCollection userCollection = db.getCollection(USER_TOKENS);
        DBCursor cursor = userCollection.find();
     
        Token token = null;
        if( cursor.hasNext() ) {
            token = new Token();
            DBObject dbToken = cursor.next();

            Logger.debug("Got token:" + dbToken);
            token.setUuid(dbToken.get(UUID).toString());
            token.setEmail(dbToken.get(EMAIL).toString());

            DateTime d1 = new DateTime( new Long(dbToken.get(CREATION_TIME).toString()) );
            token.setCreationTime(d1);
         
            DateTime d2 = new DateTime( new Long(dbToken.get(EXPIRATION_TIME).toString()) );
            token.setExpirationTime(d2);        
            if( token.isExpired() ) {
                Logger.debug("Expired, deleting token:"+dbToken);
                userCollection.remove(dbToken);
            }
        }
    }
 
    private static DB getMongoClient() {
        MongoClient client = null;
        DB db = null;
        try {
            client = new MongoClient("localhost", 27017);

            db = client.getDB("UserDB");
        } catch(UnknownHostException e) {
            e.printStackTrace();
        }
     
        return db;
    }
}

Monday, July 01, 2013

JAX-RS Spring JPA Hibernate Maven web application

1. Workspace directory structure
C:\workspace\FFWD_NO_EJB>tree
Folder PATH listing
Volume serial number is 1C03-D338
C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───persistent
│       │           ├───entity
│       │           │   └───util
│       │           ├───rest
│       │           └───service
│       ├───resources
│       │   └───META-INF
│       └───webapp
│           └───WEB-INF
└───target

2. Entity java class
package com.persistent.entity;


import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlRootElement;


@Entity
@XmlRootElement
@Table(name="AUTH_STAT")
public class Status implements Serializable {

    @Id
    @Column(name="AUTH_STAT_CD")
    private String statusCode;

    @Column(name = "AUTH_STAT_DSC")
    private String statusDescr;

    @Column(name = "AUTH_SEREVITY_ID")
    private Integer severity;

    @Column(name = "CREATE_TS")
    private Date createTimestamp;

    @Column(name = "CREATE_USER_ID")
    private String createUserId;

    @Column(name = "UPD_USER_ID")
    private String updUserId;

    @Column(name = "UPD_TS")
    private Date updTimestamp;


3. REST service Impl (create a service interface too)

ackage com.persistent.rest;


import java.util.List;
import java.util.StringTokenizer;

import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.persistent.entity.Status;
import com.persistent.service.StatusService;

// The Java class will be hosted at the URI path "/persons"

@Component
@Path("/status")
public class StatusResourceWs implements StatusResource {
    @Autowired
    StatusService statusService;
    private Logger log = Logger.getLogger(this.getClass());
    // The Java method will process HTTP GET requests

    @GET
    @Path("{code}")
    @Produces("application/xml")
    public Status getStatus(@PathParam("code") String code) {
        log.info("Hit getStatus");
        Status status = statusService.getByCode(code);
        log.info("Sending: \n\n" + status + "\n\n");
        return status;
    }


4. JPA impl class (Crete a interface too)
package com.persistent.service;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.persistent.entity.Status;
import com.persistent.service.StatusService;


@Service("statusService")
public class StatusServiceJpa implements StatusService {
    private Logger log = Logger.getLogger(this.getClass());
    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    /* (non-Javadoc)
     * @see com.persistent.service.jpa.StatusService#getById(int)
     */
    @Transactional(readOnly = true)
    public Status getByCode(String code) {
        return entityManager.find(Status.class, code);
    }
}



5. Persistence.xml definition in META-INF directory of war file
<persistence 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"
        version="1.0">

    <persistence-unit name="status_persistence" transaction-type="RESOURCE_LOCAL">
        <class>com.persistent.entity.Status</class>
    </persistence-unit>

</persistence>


6. Spring application context file contents - goes into WEB-INF/classes

<?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:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
            ">
    <!--  Scan for both Jersey Rest Annotations a -->
    <context:component-scan
        base-package="com.persistent.rest,com.persistent.service,com.persistence.entity" />
    <context:annotation-config />
   
    <tx:annotation-driven />
   
    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/BPPSDataSource" expected-type="javax.sql.DataSource"/>
   
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
        <property name="persistenceUnitName" value="status_persistence" />
        <property name="jpaProperties">
            <value>
                  hibernate.query.factory_class=org.hibernate.hql.classic.ClassicQueryTranslatorFactory
                hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect
                hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
                  hibernate.show_sql=true
                hibernate.default_schema=BFPS
            </value>
        </property>
    </bean>
   
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
        p:entityManagerFactory-ref="entityManagerFactory" />
   
    <bean id="jpaAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
        p:database="ORACLE" p:showSql="true" />
</beans>



7. web.xml definition
<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>



8. Maven pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.persistent</groupId>
    <artifactId>FFWD_NO_EJB</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>FFWD_NO_EJB</name>
    <repositories>
        <repository>
            <id>maven2-repository.dev.java.net</id>
            <name>Java.net Maven 2 Repository</name>
            <url>http://download.java.net/maven/2/</url>
            <!-- <layout>default</layout> -->
        </repository>
        <repository>
            <id>maven-repository.dev.java.net</id>
            <name>Java.net Maven 1 Repository (legacy)</name>
            <url>http://download.java.net/maven/1</url>
            <layout>legacy</layout>
        </repository>
    </repositories>
    <build>
        <finalName>FFWD_NO_EJB</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <inherited>true</inherited>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.10</version>
            </plugin>
        </plugins>
    </build>
    <properties>
        <spring.version>2.5.5</spring.version>
        <hibernate.version>3.3.2.GA</hibernate.version>
        <commons-dbcp.version>1.2.2</commons-dbcp.version>
        <commons-logging.version>1.0.4</commons-logging.version>
        <jersey-version>1.0.2</jersey-version>
        <log4j.version>1.2.13</log4j.version>
    </properties>
    <dependencies>
        <!-- Adding in JPA With It's Requirements -->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>${commons-logging.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>javax.persistence</groupId>
            <artifactId>persistence-api</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>${commons-dbcp.version}</version>
            <scope>runtime</scope>
        </dependency>
        <!--Explicitly add -->
        <!-- change cglib-nodep Farrukh Najmi From net.java.dev.jersey.users Dec.
            10, 2007 -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>2.1_3</version>
        </dependency>
        <dependency>
            <groupId>geronimo-spec</groupId>
            <artifactId>geronimo-spec-jta</artifactId>
            <version>1.0.1B-rc4</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
           
            <!-- <artifactId>hibernate</artifactId> <version>3.2.5.ga</version> Explicitly
                remove: See: http://blog.interface21.com/main/2007/06/11/asm-version-incompatibilities-using-spring-autowired-with-hibernate/ -->
            <exclusions>
           
                <exclusion>
                    <groupId>javax.transaction</groupId>
                    <artifactId>jta</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>asm</groupId>
                    <artifactId>asm-attrs</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>cglib</groupId>
                    <artifactId>cglib</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- JPA Additions end. -->
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-spring</artifactId>
            <version>${jersey-version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
        </dependency>
    </dependencies>
</project>



9. Access REST url at http://localhost:7001/FFWD/rest/status/S

Simple JAX-RS Restful WebService example

1. Create service implementation
@Path("/pojo")
public class PojoRestfulService {

@GET
@Path("/person")
@Produces(MediaType.APPLICATION_JSON)
public Person getPerson() {
Person p = new Person("xyz");
return p;
}
}


2. Update web.xml
<servlet>
  <servlet-name>Jersey Web Application</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <!--You need to change this line to match your package name -->
      <param-value>foo.rest</param-value>
    </init-param>
    <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  <servlet-name>Jersey Web Application</servlet-name>
  <url-pattern>/*</url-pattern>
  </servlet-mapping>


3. Create client
public static void main(String[] args) {

ClientConfig clientConfig = new DefaultClientConfig();
clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING,
Boolean.TRUE);
Client client = Client.create(clientConfig);

WebResource resource = client.resource("http://localhost:7001/MavenWebProject/pojo/person");
ClientResponse response = resource.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class);

String output = response.getEntity(String.class);
System.out.println(output);
}

4. Client output
{"name":"xyz"}

Spring WS JAXB Web Sevice Client

1. See the WSDL and schema in my previous post here
2. Define beans in applicationContext.xml

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

<bean id="messageFactory" class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory">
<property name="soapVersion">
<util:constant static-field="org.springframework.ws.soap.SoapVersion.SOAP_11" />
</property>
</bean>

<bean id="XYZOrderServiceMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.abc.XYZ.integration.test.jaxb" />
</bean>

<bean id="XYZOrderServiceTemplate" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="XYZOrderServiceMarshaller"></property>
<property name="unmarshaller" ref="XYZOrderServiceMarshaller"></property>
<property name="messageSender">
<bean
class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
</bean>
</property>
<property name="defaultUri"
value="http://localhost:7001/XYZService/ws/XYZWebService.wsdl" />
</bean>

<bean id="XYZOrderServiceClient" class="com.abc.XYZ.integration.test.XYZOrderServiceClient">
<constructor-arg ref="XYZOrderServiceTemplate"></constructor-arg>
</bean>
</beans>

3. JUnit test case to invoke web service client

package com.abc.XYZ.integration.test;

import static org.junit.Assert.assertNotNull;

import org.junit.BeforeClass;
import org.junit.Test;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XYZServiceClientTest {

private static ClassPathXmlApplicationContext context = null;

@BeforeClass
public static void setUpBeforeClass() throws Exception {
context = new ClassPathXmlApplicationContext("/applicationContext.xml");
}

@Test
public void testPlaceOrder() {
XYZOrderServiceClient client = (XYZOrderServiceClient) context
.getBean("XYZOrderServiceClient");
String orderRef = client.placeOrder("offerId1");

assertNotNull(orderRef);
}
}

4. Service Client

package com.abc.XYZ.integration.test;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.ws.client.core.WebServiceTemplate;

import com.abc.XYZ.integration.test.jaxb.ObjectFactory;
import com.abc.XYZ.integration.test.jaxb.SendOrderRequest;
import com.abc.XYZ.integration.test.jaxb.SendOrderResponse;

public class XYZOrderServiceClient {

private static final Log logger = LogFactory.getLog(XYZOrderServiceClient.class);
private static final ObjectFactory WS_CLIENT_FACTORY = new ObjectFactory();

private WebServiceTemplate webServiceTemplate;

public XYZOrderServiceClient(WebServiceTemplate webServiceTemplate) {
this.webServiceTemplate = webServiceTemplate;
}

public String placeOrder(String offerId) {
logger.debug("Preparing PlaceOrderRequest.....");
SendOrderRequest request = WS_CLIENT_FACTORY.createSendOrderRequest();
request.setHHId(offerId);

logger.debug("Invoking Web service Operation[PlaceOrder]....");
SendOrderResponse response = (SendOrderResponse) webServiceTemplate
.marshalSendAndReceive(request);
logger.debug("Order reference:" + response.getField1());
return response.getField1();
}
}

5. maven POM.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.abc.XYZ.integration</groupId>
<artifactId>XYZtest</artifactId>
<version>0.0.1-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<scope>compile</scope>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
</dependencies>

<build>
<finalName>XYZServiceTest</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<generatePackage>com.abc.XYZ.integration.test.jaxb</generatePackage>
<schemaDirectory>src\main\resources</schemaDirectory>
<generateDirectory>src\main\java</generateDirectory>
<removeOldOutput>true</removeOldOutput>
<includeSchemas>
<includeSchema>*.xsd</includeSchema>
</includeSchemas>
<includeBindings>
<includeBinding>*.xjb</includeBinding>
</includeBindings>
<strict>false</strict>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>



Simple JAX-WS webservice in WebLogic using Java

1. Build jax-ws webservice using annotations
package foo;

import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;

@WebService(name = "ConversionService", serviceName="ConversionService", targetNamespace = "http://tempuri.org/")
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
public class ConversionServiceImpl implements ConversionService {


/* (non-Javadoc)
* @see foo.ConversionService#convert(double)
*/
@WebMethod(operationName = "convert")
public double convert(double i)
{
double answer = 1.0;
return answer;
}
}

2. sun-jaxws.xml
<?xml version="1.0" encoding="UTF-8"?>
<endpoints
  xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime"
  version="2.0">
  <endpoint
    name="ConversionService"
    implementation="foo.ConversionServiceImpl"
    url-pattern="/ConversionService"/>
</endpoints>

3. web.xml
<listener>
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
</listener>

<servlet>
<servlet-name>jaxws</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>jaxws</servlet-name>
<url-pattern>/ConversionService</url-pattern>
</servlet-mapping>

4. WebLogic's web service test client
http://localhost:7001/wls_utc/

5. Access webserice wsdl
http://localhost:7001/WARContextRoot/ConversionService?wsdl

Wednesday, March 13, 2013

Spring Hibernate Java Maven war example

1. Project structure

C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───xyz
│       │           └───persistence
│       ├───resources --> where Status.hbm.xml and web-application-config.xml are
│       └───webapp
│           ├───META-INF
│           └───WEB-INF
└───target

2.Status.java POJO code - This represents a row in the mapped table
public class Status implements Serializable {

    private static final long serialVersionUID = 1L;

    public Status() {
        super();
    }

    private String statusCode;

    private String statusDescr;

    private Integer severity;

    private Date createTimestamp;

    private String createUserId;

    private String updUserId;

    private Date updTimestamp;

3. StatusDAO.java interface code
public interface StatusDAO {
    void save(Status status);
    void update(Status status);
    void delete(Status status);
    Status findByStatusCode(String statusCode);
}

4. StatusDAOImpl.java code

import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class StatusDAOImpl extends HibernateDaoSupport implements StatusDAO {

    public void save(Status status) {
        getHibernateTemplate().save( status );
    }

    public void update(Status status) {
        getHibernateTemplate().update(status);
        
    }

    public void delete(Status status) {
        getHibernateTemplate().delete(status);        
    }

    public Status findByStatusCode(String statusCode) {
        List list = getHibernateTemplate().find(
                "from Status where statusCode=?",statusCode
          );
    return (Status)list.get(0);
    }

}


5. TestDriver.java code for running CRUD test cases

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class TestDriver {
    
    private StatusDAO statusDAO;
    
    public static void main(String[] args) {
        TestDriver driver = new TestDriver();
        try {
            driver.create();
            driver.retrieve();
            driver.update();
            driver.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public TestDriver() {
        super();        
        ApplicationContext appContext = 
            new ClassPathXmlApplicationContext("/web-application-config.xml");
        statusDAO = (StatusDAO)appContext.getBean("statusDAO");
    }

    public void create() throws Exception {    
        
        Status status = createStatus();
        
        // create a new status in db
        createStatus(status);

        // retrieve a status from db
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // delete a status
        deleteStatus(retrievedStatus);
    }

    public void retrieve() throws Exception {        
        create();
    }

    public void update() throws Exception {    
        Status status = createStatus();

        // create a new status in db
        createStatus(status);

        // retrieve a status
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // update a status
        updateStatus();    

        // delete a status
        deleteStatus(retrievedStatus);
    }

    public void delete() throws Exception {        
        Status status = createStatus();

        createStatus(status);

        // retrieve a status
        Status retrievedStatus = statusDAO.findByStatusCode("RR");

        // update a status
        updateStatus();

        // delete a status
        deleteStatus(retrievedStatus);
    }

    private Status createStatus() {
        Status status = new Status();

        status.setStatusCode("RR");
        status.setCreateTimestamp(new Date());
        status.setCreateUserId("sssss");
        status.setSeverity(new Integer(22));
        status.setStatusDescr("testing-sss");
        status.setUpdTimestamp(new Date());
        status.setUpdUserId("sssss");
        return status;
    }

    private void createStatus(Status status) {
        statusDAO.save(status);
    }

    private void updateStatus() {
        Status retrievedStatus = statusDAO.findByStatusCode("RR");
        retrievedStatus.setStatusDescr("updated description");
        statusDAO.update(retrievedStatus);
    }

    private void deleteStatus(Status retrievedStatus) {
        statusDAO.delete(retrievedStatus);
    }

6. Status.hbm.xml file
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xyz.persistence">
    <class name="Status" table="AUTH_STAT" mutable="false">
        <id name="statusCode" column="AUTH_STAT_CD" type="string"/>

        <property name="statusDescr" column="AUTH_STAT_DSC" type="string"/>
        <property name="severity" column="AUTH_SEREVITY_ID" type="integer"/>
        <property name="createTimestamp" column="CREATE_TS" type="timestamp"/>
        <property name="createUserId" column="CREATE_USER_ID" type="string"/>
        <property name="updUserId" column="UPD_USER_ID" type="string"/>
        <property name="updTimestamp" column="UPD_TS" type="timestamp"/>
    </class>
</hibernate-mapping>

7. Spring bean configuration file - web-application-config.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:context="http://www.springframework.org/schema/context"
    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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
        <property name="url"
            value="jdbc:oracle:thin:@dbhost:20009:sid" />
        <property name="username" value="ddd" />
        <property name="password" value="ddd" />
    </bean>

    <!-- Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">
            <ref bean="dataSource" />
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.default_schema">SchemaName</prop>
            </props>
        </property>

        <property name="mappingResources">
            <list>
                <value>/Status.hbm.xml</value>
            </list>
        </property>

    </bean>

    <!-- Status Data Access Object -->
    <bean id="statusDAO" class="com.xyz.persistence.StatusDAOImpl">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>
</beans>


8. index.jsp code to call test driver
<?xml version="1.0" encoding="UTF-8" ?>

<%@ page import="com.xyz.persistence.TestDriver"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hibernate + Oracle 11g DB CRUD test page</title>
</head>

<body>
    <%
        try {                
            TestDriver driver = new TestDriver();
            driver.create();
            out.println("Create Status succeeded");
            out.println("<br>");
            
            driver.retrieve();
            out.println("Retrieve Status succeeded");
            out.println("<br>");
            
            driver.update();
            out.println("Update Status succeeded");
            out.println("<br>");
            
            driver.delete();
            out.println("Delete Status succeeded");
            out.println("<br>");
            
            out.println("All CRUD operations succeeded");
        } catch (Exception e) {
            out.println("An exception occurred: " + e.getMessage());
        }
    %>
</body>

</html>


9. maven po.xml dependencies
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.0</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.6.1</version>
        </dependency>

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>3.3.2.GA</version>
        </dependency>

        <dependency>
            <groupId>javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.12.1.GA</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.1.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.0</version>
            <scope>test</scope>
        </dependency>

Tuesday, March 12, 2013

Hibernate Java Maven war example

1. Project structure
C:\workspace\testWebApp>tree
Folder PATH listing
Volume serial number is BED9-803F
C:.
├───.settings
├───src
│   └───main
│       ├───java
│       │   └───com
│       │       └───xyz
│       │           └───persistence
│       ├───resources --copy *.hbm.xml and hibernate.cfg.xml here
│       └───webapp
│           ├───META-INF
│           └───WEB-INF
└───target

2. Create Status Java POJO class - omitted getters and setters
import java.io.Serializable;
import java.util.Date;

public class Status implements Serializable {

 public Status() {
  super();
 }

 private String statusCode;

 private String statusDescr;

 private Integer severity;

 private Date createTimestamp;

 private String createUserId;

 private String updUserId;

 private Date updTimestamp;

3. Create status.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.xyz.persistence">
 <class name="Status" table="AUTH_STAT" mutable="false">
  <id name="statusCode" column="AUTH_STAT_CD" type="string"/>

  <property name="statusDescr" column="AUTH_STAT_DSC" type="string"/>
  <property name="severity" column="AUTH_SEREVITY_ID" type="integer"/>
  <property name="createTimestamp" column="CREATE_TS" type="timestamp"/>
  <property name="createUserId" column="CREATE_USER_ID" type="string"/>
  <property name="updUserId" column="UPD_USER_ID" type="string"/>
  <property name="updTimestamp" column="UPD_TS" type="timestamp"/>
 </class>
</hibernate-mapping>

4. Create hibernate.cfg.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
        <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="hibernate.connection.url">jdbc:oracle:thin:@dbhost.company.com:20009:sid</property>
        <property name="hibernate.connection.username">userName</property>
        <property name="hibernate.connection.password">password</property>
        <property name="show_sql">true</property>
        <property name="hibernate.default_schema">SID</property>
        <mapping resource="Status.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

5. Create a test driver class (DAO)
public class TestDriver {
 
 public static void main(String[] args) {
  TestDriver driver = new TestDriver();
  try {
   driver.create();
   driver.retrieve();
   driver.update();
   driver.delete();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 public TestDriver() {
  super();
 }

 public void create() throws Exception { 
  Status status = createStatus();
  
  // create a new status in db
  Session session = createStatus(status);

  // retrieve a status from db
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }

 public void retrieve() throws Exception {  
  create();
 }

 public void update() throws Exception { 
  Status status = createStatus();

  // create a new status in db
  Session session = createStatus(status);

  // retrieve a status
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // update a status
  updateStatus(session); 

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }

 public void delete() throws Exception {  
  Status status = createStatus();

  Session session = createStatus(status);

  // retrieve a status
  Status retrievedStatus = (Status) session.get(Status.class, "RR");

  // update a status
  updateStatus(session);

  // delete a status
  deleteStatus(session, retrievedStatus);
  
  HibernateUtil.shutdown();
 }
 
 public void runCRUDTestCases() throws Exception {
 }

 private Status createStatus() {
  Status status = new Status();

  status.setStatusCode("RR");
  status.setCreateTimestamp(new Date());
  status.setCreateUserId("sss");
  status.setSeverity(new Integer(22));
  status.setStatusDescr("testing-ssss");
  status.setUpdTimestamp(new Date());
  status.setUpdUserId("ssss");
  return status;
 }

 private Session createStatus(Status status) {
  Session session = HibernateUtil.getSessionFactory().openSession();
  session.beginTransaction();
  session.save(status);
  session.getTransaction().commit();
  return session;
 }

 private void updateStatus(Session session) {
  Status retrievedStatus;
  retrievedStatus = (Status) session.get(Status.class, "RR");
  retrievedStatus.setStatusDescr("updated description");
  session.beginTransaction();
  session.update(retrievedStatus);
  session.getTransaction().commit();
 }

 private void deleteStatus(Session session, Status retrievedStatus) {
  session.beginTransaction();
  session.delete(retrievedStatus);
  session.getTransaction().commit();
 }

6. HibernateUtil to create/close sessions
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {

 private static final SessionFactory sessionFactory = buildSessionFactory();

 private static SessionFactory buildSessionFactory() {
  try {
   // Create the SessionFactory from hibernate.cfg.xml
   return new Configuration().configure().buildSessionFactory();
  } catch (Throwable ex) {
   // Make sure you log the exception, as it might be swallowed
   System.err.println("Initial SessionFactory creation failed." + ex);
   throw new ExceptionInInitializerError(ex);
  }
 }

 public static SessionFactory getSessionFactory() {
  return sessionFactory;
 }

 public static void shutdown() {
  // Close caches and connection pools
  getSessionFactory().close();
 }
}

7. Create index.jsp that calls test driver
<?xml version="1.0" encoding="UTF-8" ?>

<%@ page import="com.xyz.persistence.TestDriver"%>

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Hibernate + Oracle 11g DB CRUD test page</title>
</head>

<body>
 <%
  try {
   TestDriver driver = new TestDriver();
   driver.runCRUDTestCases();
   driver.create();
   out.println("Create Status succeeded");
   out.println("<br>");
   
   driver.retrieve();
   out.println("Retrieve Status succeeded");
   out.println("<br>");
   
   driver.update();
   out.println("Update Status succeeded");
   out.println("<br>");
   
   driver.delete();
   out.println("Delete Status succeeded");
   out.println("<br>");
   
   out.println("All CRUD operations succeeded");
  } catch (Exception e) {
   out.println("An exception occurred: " + e.getMessage());
  }
 %>
</body>

</html>

8. Copy Oracle DB driver class to application server or package it within war file for this work

9. pom.xml
<artifactId>testWebApp</artifactId>
 <packaging>war</packaging>
 <version>0.0.1-SNAPSHOT</version>
 <name>testWebApp Maven Webapp</name>
 <url>http://maven.apache.org</url>

 <build>
  <finalName>testWebApp</finalName>
  <pluginManagement>
   <plugins>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-compiler-plugin</artifactId>
     <configuration>
      <encoding>UTF-8</encoding>
      <source>1.4</source>
      <target>1.4</target>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-resources-plugin</artifactId>
     <version>2.5</version>
     <configuration>
      <encoding>UTF-8</encoding>
     </configuration>
    </plugin>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-eclipse-plugin</artifactId>
     <version>2.8</version>
    </plugin>
   </plugins>
  </pluginManagement>
 </build>

 <!-- Project dependencies -->
 <dependencies>

  <dependency>
   <groupId>jstl</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
  </dependency>
  
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jsp-api</artifactId>
   <version>2.0</version>
  </dependency>
  
        <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.6.1</version>
  </dependency>
  
     <dependency>
       <groupId>org.hibernate</groupId>
       <artifactId>hibernate-core</artifactId>
       <version>3.3.2.GA</version>
     </dependency>

  <dependency>
   <groupId>javassist</groupId>
   <artifactId>javassist</artifactId>
   <version>3.12.1.GA</version>
  </dependency>

  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.0</version>
   <scope>test</scope>
  </dependency>

 </dependencies>

Thursday, March 07, 2013

Spec for small business class management mobile application

I got an idea to build a mobile application that can keep of track of classes, students and their payments for my daughter's music teacher. Here are some major usecases I can think of:

Manage classes:
- add new class for a specific time of day, set its recurring properties. Ex: Every Thursday at 7PM
- change an existing class
- delete an existing class
- set max students in a class
- track progress of the student
- show progress of things student can do vs things need to learn/master

Manage fee payment:
- mark student as paid
- browse a list of unpaid students

Manage enrollment into classes
- add/remove/find a student in a class

Generate reports
- who did not pay this month?

Nice to have:
- automatically adds public holidays
- preference to send reminder to students email if schedule changes
- change schedule for a particular occurrence of a recurrent class
- show picture of the student and his/her contact information

Integration patterns/technologies

I was talking with a friend of mine about different options available for integrating one system with another. Following came up in my mind:
  1. File based - In this type of integration, one system send a file of transactions or records every predefined period of time. The protocol could be FTP/SFTP. The other system picks up the file and processes those records. Optionally it could respond by sending a file of its own that contain error transactions/records. The advantage of this approach is that it is simple and straitforward. However, it is not real time. Also, there is no inherent persistence other than file based.
  2. Database sharing - in this approach both systems read/write from a shared database. The disadvantage is that the database becomes owner of data. It is not real time inherently but could be implemented for real time by polling database
  3. Message based such as JMS/MQ - request/respond pattern can be implemented for real time integration
  4. WebServices/SOAP/Rest - real time.

Monday, March 04, 2013

Simple shell script to invoke a java program with arguments

#!/bin/bash

#arguments, constants etc.
PROVIDER_URL="t3://abc37.abc.com:7002,abc38.abc.com:7002"
CONN_FACTORY="jms/emjoXAJMSConnectionFactory"
QUEUE="jms/ShopListINQueue"
MSG_COUNT=100

WL_HOME="/appl/wl/wlserver_10.3/server/lib"
JAVA_HOME=/usr/lib/jvm/jdk1.6.0_02
CLASSPATH=$WL_HOME/api.jar:$WL_HOME/weblogic.jar:./JmsClient.jar

#invoke java program
$JAVA_HOME/bin/java -cp $CLASSPATH com.abc.test.JmsClient $PROVIDER_URL $CONN_FACTORY $QUEUE $MSG_COUNT

Rewards API - for retail customer loyalty

Below is a spec for Rewards API for customer loyalty programs I came up with. The idea is to keep track of customer purchases by providing them with a store specific card and offer them a financial reward (such as 10$ for every 100$ spent in a month) in return of their spending at the store.

This API can be exposed as a SOAP or other remoting technology and integrated into POS systems.

Key usecases:
1. Customer enrolls in to loyalty program
2. Customer purchases are recorded and points get accumulated
3. Customer redeems rewards points accumulated in his account
4. System clears points accumulated that were not used at the end of every month

Data Model:
Customer_Card
Cardid--firstName--lastName--address--enrollDate

Card_Points
cardId--points--expirationDate
123 80 3/31/2013

Card_Purchases
cardId--purchaseDate--grossAmount
123 3/5/2013 45.0$

Points_Multiplier
pointsMultiplier
0.25

Rewards_Points
points--rewardAmount
100 10$

Application Programming Interface (API) Specification
Integer enrollCustomer(Customer)
void deleteCustomer(int cardId)
void updateCustomer(int cardId, Customer customer)
Customer getCustomer(int cardId)

Double getPointsBalance(int cardId)
Double getPointsMultiplier()

Double addPoints(cardId, purchaseAmount)
Double redeemPoints(cardId)

Business Rules:
- Points expire at the end of every month
- Points_Multiplier specifies how many points there are for 1$
- Rewards_Points specifies how many dollars are rewarded for points