Thursday, June 7, 2012

Java Class code to test whether springframework's SimpleJdbcCall is Thread Safe or not


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

import javax.sql.DataSource;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

import com.sushant.verma.common.dto.UserDto;

public class MyThread implements Runnable{
 private static Logger log=LogManager.getLogger(MyThread.class);
 /**
  * creating Instance Variables
  */
 private UserDto userDto;
 private static SimpleJdbcCall procReaduserDto;
 /**
  * name and password VALUE set at instance level to be used
  */
 private String name="code";
 private String pwd="zila";


 public static void setDataSource(DataSource dataSource) {
  log.debug("Inside setDataSource ");
  /**
   * procReaduserDto Object to be created by the main thread in start to be used by multiple threads
   * as in the case of Spring IOC
   */
  procReaduserDto =new SimpleJdbcCall(dataSource);  
 } 

 public static void main(String [] args) throws Throwable  
 {
  /**
   * calling setDataSource with new dataSource object
   * in the start before starting thread as in Spring IOC
   */
  DataSource dataSource = new DriverManagerDataSource();
  ((DriverManagerDataSource) dataSource).setDriverClassName( "com.mysql.jdbc.Driver");
  ((AbstractDriverBasedDataSource) dataSource).setUrl( "jdbc:mysql://localhost:3306/test");
  ((AbstractDriverBasedDataSource) dataSource).setUsername( "root");
  ((AbstractDriverBasedDataSource) dataSource).setPassword( "admin"); 
  setDataSource(dataSource);

  log.debug("========Creating & Starting Threads===========");
  MyThread obj1 = new MyThread();
  MyThread obj2 = new MyThread();
  new Thread(obj1).start();
  new Thread(obj2).start();
  // main thread is ending here,
  // Thread-0 and Thread-1 continue to run.
 }

 public void run()
 {
  try {
   /**
    * Iterating for 3 times
    */
   for (int i=0; i<3; i++) {
    log.info("************************loop "+i+" begins************************");
    if(Thread.currentThread().getName().equals("Thread-1")){
     /**
      * changing Instance Variable name/pwd value for thread-1 
      */
     setName("wrong_userName");
     setPwd("wrong_password");
    }

    /**
     * calling the readUser method for both the threads with different name/pwd values
     */
    setUserDto(readUser(name, pwd));
    /**
     * Thread-1 should return __isUserValid=false & __getUserExists=0
     * Thread-0 should return __isUserValid=true & __getUserExists=1
     */
    log.info("~~~~~~~~~loop "+i+" ends~~~~~~~~~");
   }
  } catch (Throwable t) { }
 }


 public UserDto readUser(String userEmail,String password) {
  /**
   * procReaduserDto object value should be same as created before the thread starts as to be the case with Spring IOC
   */
  log.debug(" @ readUser with procReaduserDto="+procReaduserDto);
  MyThread.procReaduserDto.withProcedureName("sp_authenticateUser");  

  Map args=new HashMap();  
  args.put("in_userName", userEmail);  
  args.put("in_password", password);  
  @SuppressWarnings("unused")
  Map out = procReaduserDto.execute(args);  

  UserDto userDto = new UserDto();  
  userDto.setUserExists((String) out.get("out_userexists"));  
  String userValid=(String) out.get("out_isuservalid");  
  if(userValid.equals("1"))  
   userDto.setUserValid(true);  
  else  
   userDto.setUserValid(false);  

  return userDto;  
 }

 public String getName() {
  return name;
 }

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

 public String getPwd() {
  return pwd;
 }

 public void setPwd(String pwd) {
  this.pwd = pwd;
 }

 public void setUserDto(UserDto userDto) {
  this.userDto = userDto;
 }

 public UserDto getUserDto() {
  return userDto;
 }


}

Wednesday, April 25, 2012

How to generate a random alphanumeric word with special characters of variable length

Usually we need to create a random word of some 8+ character to use as a password or an encryption key.
I have recently created this one, though very simple but very effective.
I have tried to replicate the same sequence and run in a loop of 1000000 iteration but with length of 8 characters there were no repetition. Hope the readers would like it.

package in.codeZila.www.utility;

public class RandomWordGenerator {

 public static final String getRandomWord(int length) {
  String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*";
  String rw = "";
  for(int i = 0; i < length; i++) {
   int index = (int) Math.floor(Math.random() * 62);
   rw += chars.charAt(index);
  }

  return rw;
 }
 
 public static void main(String[] args) {
  for(int i=0;i<100;i++){
   String randomPwd=getRandomWord(8);
   System.out.println(randomPwd);
  }
 }
 
}


The Random words generated are :

Please feel free to ask any doubts or clarifications.

Saturday, April 14, 2012

How to get the XML String for a DTO (Data transfer object) using XStream

To get the XML for a DTO XStream (com.thoughtworks.xstream.XStream) is used, Download the "xstream-1.4.2.jar" jar : Click Here and add into your lib folder.

The Method which returns the XML for the passed DTO:
public static String getDTOasXML(Object dto){
 XStream xstream = new XStream();
        return xstream.toXML(dto);
}


The UserDto which needs to be converted to XML :

public class UserDto{

 
 private Long userId;

 private String userName;

 private String userEmail;

 public Long getUserId() {
  return userId;
 }

 public void setUserId(Long userId) {
  this.userId = userId;
 }

 public String getUserName() {
  return userName;
 }

 public void setUserName(String userName) {
  this.userName = userName;
 }

 public String getUserEmail() {
  return userEmail;
 }

 public void setUserEmail(String userEmail) {
  this.userEmail = userEmail;
 } 
}

Note: Notice that the fields are private. XStream doesn't care about the visibility of the fields. No getters or setters are needed. Also, XStream does not limit you to having a default constructor.

The Test Class to implement the XStream.toXML() method :

package in.codeZila.test;

import in.codeZila.test.dto.UserDto;
import com.thoughtworks.xstream.XStream;


public class Test{
 
 /**
  * Using XStream method toXML():String to generate the XML for the passed DTO object
  * @param dto
  * @return dto XML as String
  */
 public static String getDTOasXML(Object dto){
  XStream xstream = new XStream();
  /**
   * Now, to make the XML outputted by XStream more concise, 
   * you can create aliases for your custom class names to XML 
   * element names. This is the only type of mapping required to 
   * use XStream and even this is optional.
   * 
   * Note: This is an optional step. Without it XStream would work fine, 
   * but the XML element names would contain the fully qualified name of 
   * each class (including package) which would bulk up the XML a bit.
   */
  xstream.alias("UserDto", UserDto.class);
  return xstream.toXML(dto);
 }
 
 public static void main(String[] args) {
  /**
   * Instantiate the UserDto and set its variables
   */
  UserDto userDto=new UserDto();
  userDto.setUserId(new Long(1));
  userDto.setUserName("CodeZila");
  userDto.setUserEmail("codezila@codezila.in");
  /**
   * Pass the userDto Object created above as getDTOasXML() argument
   */
  String dtoXml=Test.getDTOasXML(userDto);
  System.out.println(dtoXml);
 }
}



The Output XML :

Thats all, how simple XStream is!

Summary:

  • Create element name to class name aliases for any custom classes using xstream.alias(String elementName, Class cls); 
  • Convert an object to XML using xstream.toXML(Object obj); 
  • Convert XML back to an object using xstream.fromXML(String xml);


Your valuable inputs and suggestions are welcomed!