Sunday, July 29, 2012

N th level category using Tree Like Implementation in JAVA

Recently while working on one project I had scenario where we has to load N level category and maintain them into memory.Basically I needed something like Tree. So that from any given node I can start traversing down. So this is what I used It is bit customized to my needs but can easily be made generic
Since In my case Category ID was supposed be unique I used that to recognize each element uniquely
So this is my simple CategoyBean.java(Customized to my needs)
package com.dataStructure;

import java.util.List;

public class CategoryBean {
 private String parentID;
 private String catID;
 private List childIDs;
 private String catName;

 public String getCatID() {
  return catID;
 }

 public void setCatID(String catID) {
  this.catID = catID;
 }

 public List getChildIDs() {
  return childIDs;
 }

 public void setChildIDs(List childIDs) {
  this.childIDs = childIDs;
 }

 public String getCatName() {
  return catName;
 }

 public void setCatName(String catName) {
  this.catName = catName;
 }

 public String getParentID() {
  return parentID;
 }

 public void setParentID(String parentID) {
  this.parentID = parentID;
 }
}
I am using Hash Map to store the data. But put method is customized to achieve tree like functionality
package com.dataStructure;

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

public class TreeImpl extends HashMap {
 public static String ROOT_PARENT = "-1";

 public boolean put(CategoryBean catBean) {
  boolean insertStatus = false;
  String parentID = catBean.getParentID();
  if (this.containsKey(parentID)) {
   CategoryBean parent = (CategoryBean) this.get(parentID);
   List children = parent.getChildIDs();
   if(null==children){
    children = new ArrayList();
   }
   children.add(catBean.getCatID());
   parent.setChildIDs(children);
   this.put(parent.getCatID(), parent);
   this.put(catBean.getCatID(), catBean);
   insertStatus = true;
  } else if (ROOT_PARENT.equals(parentID)) {
   System.out.println("Root Node added");
   this.put(catBean.getCatID(), catBean);
  } else {
   System.out.println("No such parent exist");
  }
  return insertStatus;
 }

 public Object get(String key){
  return super.get(key);
 }
}
Now finally lets say I want to have Category implementation as below
Root - Movies
1st level - BollyWood and HollyWood
2nd Level in BollyWood -Aamir Khan Movies,SRk Movies,Govinda
2nd level in HollyWood - Tom Cruise,Brad Pitt

So this is the way We approach t initialize and parse the data structure
package com.dataStructure;

import java.util.List;

public class CallTrees {
 public static int LEFT_INDENT = 0;
 public static void main(String[] args) {
  TreeImpl t = new TreeImpl();
  populateTree(t);  
  parseTree(t, "1");

 }

 private static void parseTree(TreeImpl t, String location) {
  CategoryBean cat = (CategoryBean) t.get(location);
  if (null != cat) {
   System.out.print(cat.getCatName()+"=>");
   List l = cat.getChildIDs();
   if (null != l) {
    int length = l.size();
    System.out.println();
    for (int i = 0; i < length; i++) {
     parseTree(t, l.get(i));
    }
    System.out.println();
   }
  }

 }

 private static void populateTree(TreeImpl t) {
  CategoryBean root = new CategoryBean();
  root.setParentID(TreeImpl.ROOT_PARENT);
  root.setCatID("1");
  root.setCatName("Movies");
  t.put(root);
  CategoryBean firstLevel = new CategoryBean();
  firstLevel.setParentID("1");
  firstLevel.setCatID("2");
  firstLevel.setCatName("BollyWood");
  t.put(firstLevel);
  firstLevel = new CategoryBean();
  firstLevel.setParentID("1");
  firstLevel.setCatID("3");
  firstLevel.setCatName("HollyWood");
  t.put(firstLevel);
  CategoryBean secondLevel = new CategoryBean();
  secondLevel.setParentID("2");
  secondLevel.setCatID("4");
  secondLevel.setCatName("Aamir Khan");
  t.put(secondLevel);
  secondLevel = new CategoryBean();
  secondLevel.setParentID("2");
  secondLevel.setCatID("5");
  secondLevel.setCatName("Sharukh Khan Movies");
  t.put(secondLevel);
  secondLevel = new CategoryBean();
  secondLevel.setParentID("2");
  secondLevel.setCatID("6");
  secondLevel.setCatName("Govinda Movies");
  t.put(secondLevel);
  secondLevel = new CategoryBean();
  secondLevel.setParentID("3");
  secondLevel.setCatID("7");
  secondLevel.setCatName("Tom Cruise Movies");
  t.put(secondLevel);
  secondLevel = new CategoryBean();
  secondLevel.setParentID("3");
  secondLevel.setCatID("8");
  secondLevel.setCatName("Brad Pitt Movies");
  t.put(secondLevel);
 }
}
So final out output when we navigate from ROOT node would be
Root Node added
Movies=>
BollyWood=>
Aamir Khan=>Sharukh Khan Movies=>Govinda Movies=>
HollyWood=>
Tom Cruise Movies=>Brad Pitt Movies=>
This is not a sophisticated implementation but very simple implementation to get Tree like functionality. Additional methods can be added depending on requirements
Any Suggestions are welcome!!

Thursday, March 29, 2012

HashMap stores value by reference. Rare Programming Error

HashMap is one of most widely used collection classes in java. Inserting objects into hashmap is very common task every java developer do.However we do forget to get into depth way in which hashmap stores the values. This might led to serious issues with our code. Below is simple piece of code. Try guessing its output

  StringBuffer sb = new StringBuffer("AA");
  Map m = new HashMap();
  m.put("A", sb);
  sb.append("AAA");
  m.put("B", sb);
  Iterator it = m.entrySet().iterator();
  while (it.hasNext()) 
                {
   Map.Entry pairs = (Map.Entry) it.next();
   System.out.println(pairs.getKey() + " = " + pairs.getValue());
  }
  sb.append("CCCCC");
  System.out.println("HashMap entry after String buffer is modified further");
  it = m.entrySet().iterator();
  while (it.hasNext())
                {
   Map.Entry pairs = (Map.Entry) it.next();
   System.out.println(pairs.getKey() + " = " + pairs.getValue());
  }

 
many of you might predict output to be
A = AA
B = AAAAA
HashMap entry after String buffer is modified further
A = AA
B = AAAAA
But to your surprise if you run above piece of code output would be
A = AAAAA
B = AAAAA
HashMap entry after String buffer is modified further
A = AAAAACCCCC
B = AAAAACCCCC

Actually what happens is Hash map stores object by reference and dosent make copy of object when you say m.put(Object o). So if the reference o gets modified then Entry inside hashmap also would get modified
So whenever you are inserting some data into Hashmap ensure that either object is mutable ie it will create fresh instance if it undergoes modification else you need to ensure that same reference is not modified anywhere else in program effecting the data in hashmap.

Monday, February 20, 2012

Detecting presence of CDATA in XML node using Java

many times while performing compare 2 XML or parsing XML we encounter scenario in which node value is enclosed in CDATA tag and we need to determine if node value is enclosed in CDATA tag.Unfortunately have dosent have any inbuilt method as hasCDATA() or something on similar lines.


What is CDATA?

The term CDATA is used about text data that should not be parsed by the XML parser.
Characters like "<" and "&" are illegal in XML elements.
"<" will generate an error because the parser interprets it as the start of a new element.
"&" will generate an error because the parser interprets it as the start of an character entity.

Now consider a XML as below

 
  select * from t_employees
  
 


When we try to read node value of both sql using getNodeValue()  method we get same output as

select * from t_employees
However in normal circumstances is fine but in certain scenarios we need to know if node value is enclosed in CDATA or not.Consider below code in which you can decide whether the code has CDATA section or not
public static void main(String[] args) {
  try {

   DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
     .newInstance();
   docBuilderFactory.setNamespaceAware(true);
   docBuilderFactory.setIgnoringElementContentWhitespace(true);
   docBuilderFactory.setIgnoringComments(true);
   DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
   Document doc = docBuilder.parse(new File("book.xml"));
   NodeList nd = doc.getElementsByTagName("sql");
   for (int i = 0; i < nd.getLength(); i++) {
    Element e = (Element) nd.item(i);
    if (e.getFirstChild().getNodeType() == Node.CDATA_SECTION_NODE) {
     System.out.println("Node with value "
          + e.getFirstChild().getNodeValue().trim()
       + " is enclosed in CDATA tag");
    }
    else{
     System.out.println("Node with value "
       + e.getFirstChild().getNodeValue()
       + " is not in CDATA tag");
     
    }
   }

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

 }

Above code when run would give output as 
Node with value select * from t_employees is not in CDATA tag
Node with value select * from t_employees is enclosed in CDATA tag
In above code we use Node type to determine if the given node is a text node alone or text node with CDATA section.getNodeType() would return value as 4 od datatype short if it is enclosed in CDATA section or else will return value as 3 from formal text node..

Sunday, January 22, 2012

Own Custom Task in Ant

Many times when developing complicated Ant scripts we feel the need of custom Ant tags or need to develop our own task in Ant. Here is a step by step guide to achieve the same
Prerequisites:
Download and set up the Apache ant.
 1.Create a new Java Project in eclipse.Right click on Project->Properties->Java Build Path->Add external Jar. Browse to Ant.jar file in ANT_HOME/lib folder.



2.Make a new class say Hello which has to extend class org.apache.tools.ant.Task;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;

public class HelloWorld extends Task {
 private String retproperty = null;
 private String msg;

 public String getRetProperty() {
  return retproperty;
 }

 public void setRetProperty(String property) {
  this.retproperty = property;
 }

 public void setMsg(String msg) {
  this.msg = msg;
 }

 public void execute() throws BuildException {
  System.out.println(msg);
  Project project = getProject();
  project.setProperty(retproperty,
    "This is Value Returned By Custom task to Ant script");
 }
}

In this program we will learn how to pass a value to java class from ant and how to get the value as return value from Java Custom task.
3.Once you have the java code ready in eclipse click on File=>Export=>Choose Jar and expost to any suitable location on your system. as shown in below screenshot

4. Now its time to write Ant script which will call this custom task pass a value and also read the value returned by the task.So write a similar Ant script.Here classpath should be location where jar in Step 3 was exported.

  
  
   
   
  


5.Now we can run the Ant script through command prompt or eclipse as per convenience. We will get output as below
In developing Ant custom task whatever Java variables we want to be accessed through ant we should make them private with public getter and setter methods.Now when through Ant below line is executed



This executes method of the HelloWorld class is invoked and msg variable is initialised with value passed. Similarly 
project.setProperty(retproperty,
    "This is Value Returned By Custom task to Ant script");

The above line sets the value into property val  which is again defined in retproperty. So that in Ant script variable val will hold the value returned or set inside the class so we can use it for further processing.

Please comment me if you face any issue implementing it.


Tuesday, January 17, 2012

Understanding Call By Reference And Call By Value In JAVA


In java we usually pass parameters to the function but sometimes it works out to be call by value and sometimes call by reference. This behavior is dependent on what parameters are getting passed to the function.Unlike C where we choose its call by reference or value.So below are set of rules you can keep in mind to decide whether the code will implement call by value or call by reference.

Simplified Rule:
Whenever we pass any variable belonging to primitive it is always passed as pass by value. Whenever we pass object of the class it mostly happens as pass by reference except certain circumstances.Below example 
public class Example {
 public class Try {
 public static void main(String[] args) {
  int i = 0;
  String s = "In Main:String";
  StringBuffer sb = new StringBuffer("In Main:StringBuffer");
  System.out.println("**********************************************");
  System.out.println("Value of i in main before calling function i=" + i);
  primitve(i);
  System.out.println("Value of i in main after calling function i=" + i);
  System.out.println("**********************************************");
  System.out.println("Value of StringBuffer sb in main before function ="+sb);
  stringBufferProcess(sb);
  System.out.println("Value of StringBuffer sb in main before function ="+sb);
  System.out.println("**********************************************");
  System.out.println("Value of s in main before calling function s=" + s);
  stringProcess(s);
  System.out.println("Value of s in main after calling function s=" + s);
 }

 public static void stringBufferProcess(StringBuffer c) {
  System.out.println("Value of StringBuffer inside function before processing="+c);
          c.append(":::stringBufferProcess Func:::");
          System.out.println("Value of StringBuffer inside function ="+c);
 }

 public static void primitve(int i) {
  System.out.println("Value of i in function before processsing i=" + i);
  i = i + 5;
  System.out.println("Value of i in function after processsing i=" + i);
 }

 public static void stringProcess(String s) {
  System.out.println("Value of s in function before processsing s=" + s);
  s = s + "In StringProcess:";
  System.out.println("Value of s in function after processsing s=" + s);
 }

}

The above program would generate some output like this:
**********************************************
Value of i in main before calling function i=0
Value of i in function before processsing i=0
Value of i in function after processsing i=5
Value of i in main after calling function i=0
**********************************************
Value of StringBuffer sb in main before function =In Main:StringBuffer
Value of StringBuffer inside function before processing=In Main:StringBuffer
Value of StringBuffer inside function =In Main:StringBuffer:::stringBufferProcess Func:::
Value of StringBuffer sb in main before function =In Main:StringBuffer:::stringBufferProcess Func:::
**********************************************
Value of s in main before calling function s=In Main:String
Value of s in function before processsing s=In Main:String
Value of s in function after processsing s=In Main:StringIn StringProcess:
Value of s in main after calling function s=In Main:String 
Explanation:

When we pass a primitive it will be pass by value so change in value of i is not reflected in main. When we pass object reference to the function  object get modified.However this is only true till the object passed is mutable.If the object passed in immutable it becomes pass by value. In above example behave objects of 2 classes String Buffer and String but both behave differently.
This is mainly due to the fact that object of String class is immutable whereas object of StringBuffer class is mutable ie. Immutable objects are the objects whose state can not be changed once constructed. whereas object of StringBuffer class is mutable.

Conclusion:
1)When we pass a primitive to a function it is call by value
2) When we pass object as parameter to the function and if object is immutable then it is pass by value.
3) When we pass object as parameter to the function and if object is mutable then it is pass by reference.


Clarification:
Java dosent have separate call by reference or call by value. I agree with it. The post just tries to draw lines with C. and tries to explain when you pass object as parameter to function when the value is reflected back in calling function and when it is not.


I think this explaination is clear