Wednesday, November 10, 2010

Property File Reader

Property File Reader: This is an util class which can be used to convert the properties file with key and value pairs to HashMap. The passed key to getMapForPropertiesFileKey must de already defined as system variable in operating system. This is having only one static method and returns HashMap of key value pairs.

To define a system variable in WINDOWS go to My Computer - Properties - Advanced - Environment Variable - System Variables then click on New and define variable name as key which will be passed to the getMapForPropertiesFileKey method and value as the absolute path of the properties file.

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class PropertyReader {
 public static Map<String, String> getMapForPropertiesFileKey(
   String propertyFileKey) throws Exception {
  if (propertyFileKey == null || "".equals(propertyFileKey.trim())) {
   throw new IllegalArgumentException("Invalid property file key name");
  }
  Map<String, String> envMap = System.getenv();
  Map<String, String> proMap = null;
  File file = null;
  String proFileName = envMap.get(propertyFileKey);
  if (proFileName == null || "".equals(proFileName)) {
   throw new IllegalArgumentException(
     "Property key not set in environment variable");
  }
  file = new File(proFileName);
  if (!file.exists()) {
   throw new IllegalArgumentException("Properties File not found "
     + file.getAbsolutePath());
  }
  Properties pro = new Properties();
  InputStream is = new FileInputStream(proFileName);
  pro.load(is);
  is.close();
  if (pro.size() > 0) {
   proMap = new HashMap<String, String>(pro.size());
   Set<String> keys = pro.stringPropertyNames();
   for (String key : keys) {
    if (null != pro.getProperty(key)
      && !"".equals(pro.getProperty(key).trim())) {
     proMap.put(key, pro.getProperty(key));
    }
   }
  }
  return proMap;
 }
}

Friday, November 5, 2010

Prototype Design Pattern

Prototype Design Pattern: Whenever in JAVA we are making a clone of a Java Object means we are using Prototype Design Pattern.

Any Java object can be cloned only if it implements java.lang.Cloneable interface wihc is just a marker interface means you are allowing JVM to make the clone of this object and the class should override the clone method of Object class, this method of Object class is protected so you will have to make it public by overriding it.

Shallow and Deep Cloning: If the Object1 is having any reference to Object2 and you are making clone of Object1 only then in this case the new clone of Object1 will have the reference to same Object2 which is shallow cloning. If new clone of Object1 is also refering the clone of Object2 menas it is a Deep cloning. So in deep cloning no object should point out to original object reference.

Uses: It is used mainly in the situation when object creation is costly or time time consuming like creating an object using constrctor taks a lot of time. If you are planning to make a pool reusable objects then make only one object and then make copies of this new object by cloning and put them in pool.

Example: Below example shows the difference between creating an object by calling constructor and clone. We can see that clong is taking very less time in comparision to creating a new object by calling constructor.

package org.paandav.prototype;
public class Prototype implements Cloneable {
 public Prototype() {
  for (int i = 0; i < 10000000; i++) {
   // pass some time.
  }
 }

 @Override
 public Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
}


package org.paandav.prototype;
public class PrototypeTest {
 public static void main(String[] args) throws Exception {
  long start = System.nanoTime();
  Prototype pt = new Prototype();
  long stop = System.nanoTime();
  System.out.println("Time taken to create a new object="
    + (stop - start));
  start = System.nanoTime();
  Prototype ptClone = (Prototype) pt.clone();
  stop = System.nanoTime();
  System.out.println("Time taken to create clone object="
    + (stop - start));

 }
}

Shallow and Deep Cloning example:

package org.paandav.prototype;
public class Prototype2 {
}

package org.paandav.prototype;
public class Prototype2 implements Cloneable{
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
}

package org.paandav.prototype;
public class Prototype implements Cloneable {
 Prototype2 pt2 = null;

 public Prototype() {
  pt2 = new Prototype2();
 }

 @Override
 public Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
}

Both above classes shows an example of Shallow Cloning because when you will make a clone of Prototype object it will refer to same Prototype2 object.

To do the Deep cloning use the below Prototype classes

package org.paandav.prototype;
public class Prototype2 implements Cloneable{
 @Override
 protected Object clone() throws CloneNotSupportedException {
  return super.clone();
 }
}


package org.paandav.prototype;
public class Prototype implements Cloneable {
 Prototype2 pt2 = null;

 public Prototype() {
  pt2 = new Prototype2();
 }

 public void setPt2(Prototype2 pt2) {
  this.pt2 = pt2;
 }

 public Prototype2 getPt2() {
  return pt2;
 }

 @Override
 public Object clone() throws CloneNotSupportedException {
  Prototype pt = (Prototype) super.clone();
  pt.setPt2((Prototype2) pt.getPt2().clone());
  return pt;
 }
}

Thursday, November 4, 2010

Singleton Design Pattern

Singleton Pattern Flavors: Check out some Singleton Design Pattern flavors.

1: Simplest: Early Initialization

public class SimpleSingleton {
 private static final SimpleSingleton instance = new SimpleSingleton();

 private SimpleSingleton() {
 }
 public static SimpleSingleton getInstance() {
  return instance;
 }
}


2: Lazy Initialization with improved performance but does not guarantee for single object per JVM.

Reason: Think about a multithreaded environment where two threads try to call getInstance method first time. Thread one check that instace is equal to null and before creating an object in next line it suspends and second thread get a chance to run this method. Second thread comes and see that instance is null and creates an object and returns object. Now first suspended thread starts again and since it has already checked that instance was null it again create a new object and returns. So it does not guarantee for one object per jvm.

 public class SimpleSingleton {
 private static SimpleSingleton instance = null;

 private SimpleSingleton() {
 }
 public static SimpleSingleton getInstance() {
  if (instance == null) {
   instance = new SimpleSingleton();
  }
  return instance;
 }
}


3: Lazy Initialization at cost of poor performance:

public class SimpleSingleton {
 private static SimpleSingleton instance = null;

 private SimpleSingleton() {
 }
 public static synchronized SimpleSingleton getInstance() {
  if (instance == null) {
   instance = new SimpleSingleton();
  }
  return instance;
 }
}


4: Singleton with improved performence and guarantees single object per JVM with double checking mechanism.  

public class SimpleSingleton {
 private static SimpleSingleton instance = null;

 private SimpleSingleton() {
 }
 public SimpleSingleton getInstance() {
  if (instance == null) {
   synchronized (SimpleSingleton.class) {
    if (instance == null) {
     instance = new SimpleSingleton();
    }
   }
  }
  return instance;
 }
}

Tempalate Design Pattern

Template Pattern: Whenever we are using abstract classes in Java means we are implementing Template Pattern. Check out the below implementation.


package org.paandav.template;
import java.math.BigDecimal;
public abstract class TaxTemplate {
 public BigDecimal getTotalTax() {
  BigDecimal totalTax = new BigDecimal(0.0);
  totalTax = getFedTax().add(getStateTax());
  return totalTax;
 }

 public abstract BigDecimal getFedTax();
 public abstract BigDecimal getStateTax();
}


package org.paandav.template;
import java.math.BigDecimal;
public class StateOneTax extends TaxTemplate{
 @Override
 public BigDecimal getFedTax() {
  //Tax Calculation Logic
  return new BigDecimal(10.11);
 }

 @Override
 public BigDecimal getStateTax() {
  //Tax Calculation Logic
  return new BigDecimal(12.11);
 }

}

package org.paandav.template;
import java.math.BigDecimal;
public class StateTwoTax extends TaxTemplate{
 @Override
 public BigDecimal getFedTax() {
  //Tax Calculation Logic
  return new BigDecimal(13.00);
 }

 @Override
 public BigDecimal getStateTax() {
  //Tax Calculation Logic
  return new BigDecimal(19.66);
 }

}

package org.paandav.template;
import java.math.BigDecimal;
public class TemplatePatternTest {
 public static void main(String[] args) {
  TaxTemplate stateOneTax = new StateOneTax();
  TaxTemplate stateTwoTax = new StateTwoTax();
  BigDecimal txAmtOne = stateOneTax.getTotalTax();
  BigDecimal txAmtTwo = stateTwoTax.getTotalTax();
  System.out.println("State One Tax = " + txAmtOne);
  System.out.println("State Two Tax = " + txAmtTwo);
 }

}

Wednesday, November 3, 2010

Command Design Pattern

Command Design Pattern: Check the Configurable Command Pattern Implementation. You can pass parameters to command objects and get values after executing command.
Uses: Make a command.properties file and put command and implementer class like
 TESTCOMMAND=org.paandav.command.TestCommand

package org.paandav.command;
public interface Command {
 public Object execute(Object params);
}


package org.paandav.command;
public class CommandException extends Exception {
 private static final long serialVersionUID = 1L;
 public CommandException() {
  super();
 }
 public CommandException(String msg) {
  super(msg);
 }
}


package org.paandav.command;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class CommandExecutor {
 private static final String COMMAND_FILE = "command.properties";
 private static CommandExecutor cmdex = null;
 private static Map<String, String> commandMap = null;
 private CommandExecutor() throws CommandException {
  loadCommondMap();
 }
 public static CommandExecutor getInstance() throws CommandException {
  try {
   if (cmdex == null) {
    synchronized (CommandExecutor.class) {
     if (cmdex == null) {
      cmdex = new CommandExecutor();
     }
    }
   }
  } catch (Exception ex) {
   throw new CommandException(ex.getMessage());
  }
  return cmdex;
 }
 public Object executeCommand(String commondKey, Object params)
   throws CommandException {
  Object retObject = null;
  String cmdClsName = null;
  Command cmdObject = null;
  Class<?> cls = null;
  try {
   cmdClsName = commandMap.get(commondKey);
   if (cmdClsName == null || "".equals(cmdClsName.trim())) {
    throw new CommandException("Command class nor found");
   }
   cls = Class.forName(cmdClsName);
   cmdObject = (Command) cls.newInstance();
   retObject = cmdObject.execute(params);
  } catch (Exception ex) {
   throw new CommandException(ex.getMessage());
  }
  return retObject;
 }
 private static void loadCommondMap() throws CommandException {
  File pfile = new File(COMMAND_FILE);
  Properties pro = null;
  InputStream is = null;
  try {
   if (pfile.exists()) {
    pro = new Properties();
    is = new FileInputStream(pfile);
    pro.load(is);
    if (pro.size() > 0) {
     commandMap = new HashMap<String, String>();
     Set<String> keys = pro.stringPropertyNames();
     for (String key : keys) {
      if (null != pro.getProperty(key)
        && !"".equals(pro.getProperty(key).trim())) {
       commandMap.put(key, pro.getProperty(key));
      }
     }
    }
   } else {
    throw new CommandException("Could not find " + COMMAND_FILE);
   }
  } catch (Exception ex) {
   throw new CommandException(ex.getMessage());
  }
 }
}

package org.paandav.command;
public class TestCommand implements Command {
 @Override
 public Object execute(Object params) {
  if (params != null) {
   System.out.println("Params received" + params.toString());
  }
  return "TestCommand executed";
 }
}

package org.paandav.command;
public class CommandTest {
 public static void main(String[] args) throws Exception {
  CommandExecutor ex = CommandExecutor.getInstance();
  String[] arr = new String[] { "One", "Two" };
  Object retValue = ex.executeCommand("TESTCOMMAND", arr);
  System.out.println(retValue);

 }
}

Observer Design Pattern

Observer Design Pattern: Read about Observer Design patterns from various sources and check the below implementation

package org.paandav.observer;
public interface Observer {
 public void observableStateChanged(Observable obser);
}
package org.paandav.observer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Observable {
 private List<Observer> observers = null;
 Lock rlock = new ReentrantLock();
 public Observable() {
  observers = new ArrayList<Observer>();
 }
 public void addObserver(Observer observer) {
  try {
   rlock.lock();
   if (observer != null && !observers.contains(observer)) {
    observers.add(observer);
   }
  } finally {
   rlock.unlock();
  }
 }
 public void removeObserver(Observer observer) {
  try {
   rlock.lock();
   if (observer != null && observers.contains(observer)) {
    observers.remove(observer);
   }
  } finally {
   rlock.unlock();
  }
 }
 public void removeAllObservers() {
  try {
   rlock.lock();
   if (observers != null && observers.size() > 0) {
    observers = new ArrayList<Observer>();
   }
  } finally {
   rlock.unlock();
  }
 }
 protected void stateChanged() {
  try {
   rlock.lock();
   if (observers != null && observers.size() > 0) {
    for (Observer ob : observers) {
     ob.observableStateChanged(this);
    }
   }
  } finally {
   rlock.unlock();
  }
 }
}

package org.paandav.observer;
public class IamObservable extends Observable {
 private String data = "INIT";
 public String getData() {
  return data;
 }
 public void setData(String data) {
  this.data = data;
  stateChanged();
 }
}

package org.paandav.observer;
public class IamObserver implements Observer {
 @Override
 public void observableStateChanged(Observable obser) {
  if (obser instanceof IamObservable) {
   IamObservable io = (IamObservable) obser;
   System.out.println("New data in Observer is = " + io.getData());
  }
 }
}

package org.paandav.observer;
public class ObserverTest {
 public static void main(String[] args) {
  IamObservable observale = new IamObservable();
  IamObserver observer = new IamObserver();
  observale.addObserver(observer);
  observale.setData("This is new data");
 }
}

Factory Pattern Java Code

Factory Pattern: You can learn definition of Factory Pattern from various sources like books, java websites etc. Please look the code below for a working Dyanmic configurable factory java code.

How to use: Make a factory.properties file and put your key and class names as key value pair in this file and you are ready to use this factory.

package org.paandav.factory;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class DynamicFactory {
 private static final String FACTORY_FILE_NAME = "factory.properties";
 private static final DynamicFactory factory = new DynamicFactory();
 private static Map<String, String> keyClassMap = null;

 public static DynamicFactory getInstance() throws DynamicFactoryException {
  if (keyClassMap == null) {
   synchronized (DynamicFactory.class) {
    if (keyClassMap == null) {
     initialize();
    }
   }
  }
  return factory;
 }

 @SuppressWarnings("unchecked")
 public Object getObject(String key) throws DynamicFactoryException {
  String clsName = keyClassMap.get(key);
  Object obj = null;
  if (null == clsName || "".equals(clsName.trim())) {
   throw new DynamicFactoryException("Class for key " + key
     + " not found");
  }
  try {
   Class cls = Class.forName(clsName);
   obj = cls.newInstance();
  } catch (Exception cnf) {
   throw new DynamicFactoryException(clsName + " can not instatitate.");
  }

  return obj;
 }
 private static void initialize() throws DynamicFactoryException {
  try {
   File pfile = new File(FACTORY_FILE_NAME);
   Properties pro = null;
   InputStream is = null;

   if (pfile.exists()) {
    pro = new Properties();
    is = new FileInputStream(pfile);
    pro.load(is);
    if (pro.size() > 0) {
     keyClassMap = new HashMap<String, String>();
     Set<String> keys = pro.stringPropertyNames();
     for (String key : keys) {
      if (null != pro.getProperty(key)
        && !"".equals(pro.getProperty(key).trim())) {
       keyClassMap.put(key, pro.getProperty(key));
      }
     }
    }
   }
  } catch (Throwable th) {
   keyClassMap = null;
   throw new DynamicFactoryException(th.getMessage());
  }
 }
}



package org.paandav.factory;
public class DynamicFactoryException extends Exception {
 private static final long serialVersionUID = 1L;
 public DynamicFactoryException() {
  super();
 }

 public DynamicFactoryException(String msg) {
  super(msg);
 }

}