Saturday, June 23, 2012

Producer Consumer Problem - Java solution

Shared Stack and Signaling variables
final Stack stack = new Stack();
final int maxLimit = 5;
final Object obj1 = new Object();
final Object obj2 = new Object();
Producer code
Thread producer = new Thread() {

 @Override
 public void run() {

 while (true) {
  synchronized (obj1) {
   if (stack.size() == maxLimit) {
    try {
     obj1.wait();
    }

    catch (InterruptedException e) {
     e.printStackTrace();
    }
   }
  }
  synchronized (obj2) {
   stack.push("producing items....");
   obj2.notify();
  }
 }

 }
};

Consumer code
Thread consumer = new Thread() {

 @Override
 public void run() {

  while (true) {
   synchronized (obj2) {
    if (stack.size() == 0) {
     try {
      obj2.wait();
     }
     catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   }
   
   synchronized (obj1) {
    stack.pop();
    obj1.notify();
   }
  }
 }
};
Then start producer thread and consumer thread as follow.
producer.start();
consumer.start();
If this code is a buggy one please feel free to correct me.

Monday, June 18, 2012

Executing a Shell Script From a java Class

In this post I am going to explain the way of executing a shell script through a java class. But this kind of implementations are discourage by java programming language since this will remove the great power of java which is portability. (compile one one machine and can run on anywhere we have JRE). For this purpose we can use java ProcessBuilder and execute shell script file with the help of it.

private static void executeProcess(Operation command, String database) throws IOException,
            InterruptedException {

        final File executorDirectory = new File("src/main/resources/");

      
private final static String shellScript = "./sample.sh";
     
           ProcessBuilder processBuilder = new ProcessBuilder(shellScript, command.getOperation(), "argument-one");
      

        processBuilder.directory(executorDirectory);

        Process process = processBuilder.start();

        try {
            int shellExitStatus = process.waitFor();
            if (shellExitStatus != 0) {
                logger.info("Successfully executed the shell script");
            }
        } catch (InterruptedException ex) {
            logger.error("Shell Script preocess is interrupted");
        }

    }

In this case my shell script is reside in resources folder. You can see I have set the process builder directory to that, so the commands are executing from that directory.And also we can pass any number of arguments to shell script via process builder.In this case we have pass a single parameter to the shell script and from the shell script it can be accessed by $1. Following is the sample shell script we have invoked through the java class.
   echo "Sample script is executing"
   echo "parameter is :" $1 
Same way you can invoke a windows batch file as well.

Friday, June 15, 2012

Unmarshalling XML files with jaxb

In this post I am going to explain how to create a schema definition from a sample xml file and use that schema definition file to marshalling and un-marshalling by using jaxb2.

Following is the sample xml formal I want to handle. (Suppose we have a web service and it can accept this kind of requests)

    
        Eshan
        test@gmail.com
    
    
        
            SE-12
            web camera
        
        
            SE-75
            mobile phone
        
    

You can create the schema definition file (xsd) of a given  sample by using modern IDE's. For this purpose I used Intelij xml to xsd converter which makes life easier. But we need to edit the generated xsd file for our simplicity. So following is the schema definition for the above xml file.

    

    
        

            
                
                    
                
            

            
                
                    
                    
                
            

        
    

    
        
            
            
        
    

    
        
            
        
    

    
        
            
            
        
    


Now we have finished the work with schema related stuff. Then we need to generate generate java classes from this xsd file. So its time to deal with jaxb2. In this case I had a problem which is the generated java classes are not in a proper naming convention. (All tha classes has "Type" postfix). To fix that we can use a bindings xml which can be pass as a parameter to jaxb.

    
        
            
        

        
            
        
        
            
        
        
            
        
        
            
        
        

So now we are almost done. Its time to generate java classes from these two xml files (xsd file and binding xml). For this purpose instead of calling jaxb xjc directly, I used maven jaxb plugin which is more flexible. following is the jaxb plugin confutation which comes in your pom file.
 
        
            
                generated-sources/xjc/com/demo/xsd
            
        
        
            
                org.jvnet.jaxb2.maven2
                maven-jaxb2-plugin
                
                    
                        
                            generate
                        
                    
                
                
                    src/main/resources
                    true
                    true
                    false
                    true
                    
                        bindings.xml
                    
                
            
        
    
Once you invoke the maven target it will create the java classes of the complex types in our schema definition file. SO now its time to write a client program which uses those java classes to unmarshall a sample xml file.
package com.demo.xsd;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;
import java.io.File;

public class Unmarshalling {
    public static void main(String[] args) {

        try {                 
            //sample xml file to be unmarshall
            File file = new File("path/to/sample.xml");
            javax.xml.bind.JAXBContext jc = javax.xml.bind.JAXBContext
                    .newInstance(Order.class);
            javax.xml.bind.Unmarshaller u = jc.createUnmarshaller();
            JAXBElement orderJAXBElement = u.unmarshal(new StreamSource(file),
            Order.class);
            Order order1 = orderJAXBElement.getValue();
            String itemName =order1.getItems().item.get(0).getName();
            System.out.println("Item name " + itemName );

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

So we are done. One important thing to mention is with the jaxb 2 xml validation part is being lost(for ans example lets say we need to restrict a particular element to have only specific string values, then the unmarshalling process should throw and parsing exception)

 But in case of you need to validate xml you can do it by setting the schema file to the unmarshaller object as follows.
SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI);  

     jaxbUnmarshaller.setSchema(sf.newSchema(new File("/path/sample.xsd")));

Saturday, June 2, 2012

Print Diamond Problem with TDD approach

Problem given at the event :
Given a letter print a diamond starting with 'A' with the supplied letter at the widest point.
Development Approach we need to practice : "Test Driven Development"

During the coderetreat event conducted by  Johannes Brodwall  we practiced the same problem over and over with different devs with different approaches. In this post what I am trying to summarize the things I got through out this valuable event. 
The way I looked at the the problem is more biased in to a geometrical view. My observation is that we can put our elements in a 2D Cartesian space as follows. Following is the example for Letter C.
red dot - Letter A
green dot - Letter B
blue dot - Letter C

So if we can find the equation of the line XY then we can find the points by substituting Y=0,1,2 (We can write a simple logic to get the Y's range)

Equation for line XY :  Y = -X +2
by substituting y values we can get following points.
(0,2),( 1,1) and (2,0)

Similarly you can obtain the equation for line LM.
Equation for line LM :  Y = -X -2
by substituting y values we can get following points.(y=0,-1,-2)
(0,-2), (-1,-1) and (-2,0)

Equation for line XM :  Y = X -2
by substituting y values we can get following points.(y=0,-1,-2)
(0,-2),(1,-1) and (2,0)

Equation for line LY :  Y = X +2
by substituting y values we can get following points.(y=0,-1,-2)
(0,-2),(1,-1) and (2,0) 

If you are familiar with the absolute value function you can write above functions with a single function as follows.

| X | + | Y | = 2

so our task has reduced to find a simple liner equation for a given charactor.
So the general form of the equation is |X| + |Y| = c
When it comes to TDD approach first thing we need to do is write a simple test against our business logic which gives an assertion failure. Test should be smaller enough to fail.  
Following are the test cases I wanted to cover :
1).  Find the interceptor of the equation for a given input character :
@Test
 public void test_the_intercept_of_the_line() {
  Diamond diamond = new Diamond();
  Assert.assertEquals(0, diamond.getInterceptor('A'));
  Assert.assertEquals(1, diamond.getInterceptor('B'));
  Assert.assertEquals(2, diamond.getInterceptor('C'));
 } 
Source for this test case is simple as follows.
public class Diamond {

 public int getInterceptor(char c) {  
  return c-65;
 }
}
In this case what you need to make sure is just write enough code which is capable of passing you test case.

2) As for my second test scenario I used Input character 'B' and test the points list where I need to print characters. 
@Test
 public void test_output_diamond_for_input_charactor_B() {
  Diamond diamond = new Diamond();
  Set pointSet = diamond.getPointSet('B');
  Assert.assertEquals(true, pointSet.contains(new Point(0, 1)));
  Assert.assertEquals(true, pointSet.contains(new Point(0, -1)));
  Assert.assertEquals(true, pointSet.contains(new Point(1, 0)));
  Assert.assertEquals(true, pointSet.contains(new Point(-1, 0)));
  Assert.assertEquals(false, pointSet.contains(new Point(-1, -1)));
 }
In order to pass the test case I used following algorithm which i was planing to apply in above explanation.(Implementation of absolute value function with +/- notations)
public class Diamond {

 public int getInterceptor(char c) {
  return c - 65;
 }

 public Set getPointSet(char c) {
  Set pointsSet = new HashSet();
  int interceptor = getInterceptor(c);

  for (int yIndex = interceptor; yIndex >= 0; yIndex--) {
   int xIndex = interceptor - yIndex;
   pointsSet.add(new Point(xIndex, yIndex));
   pointsSet.add(new Point(xIndex, -yIndex));
   pointsSet.add(new Point(-xIndex, yIndex));
   pointsSet.add(new Point(-xIndex, -yIndex));
  }
  return pointsSet;
 }
}
Since I wanted to apply some OOP concepts I created Point class and implement the constructor which we can pass X,Y coordinates. And also I implement the hash code , toString and equals methods in the Point class.(This can be generated by using eclipse IDE). In addition to that I am going to store relevant character with that point object as follows.
 
public Point(int i, int j) {
  this.setX(i);
  this.setY(j);
  this.setCharacter((char)(Math.abs(j)+65));
 }

3) During the workshop I heard that some guys  were taking about write test cases to figure out whether the points are located with in the boundary. But in this approach we don't need such kind of a test since we are substituting the correct range of Y values. That range is indirectly tested by test_interceptor_of_the_line method. I found that it is not compulsory to write a test for figure out the boundary of the grid.
At this point I know my algorithm is working properly. And then I need to print the character pattern in to the console output. In order to do so I just had to write following simple logic.

public void printDiamond(char c) {
  int interceptor = getInterceptor(c);
  int gridArea = 2 * interceptor + 1;
  // Create an array with all 'X' values
  char[][] diamond = new char[gridArea][gridArea];
  for (char[] ds : diamond) {
   for (int i = 0; i < ds.length; i++) {
    ds[i] = 'X';
   }
  }
  Set pointSet = getPointSet(c);

  for (Point point : pointSet) {
   diamond[point.getX() + interceptor][point.getY() + interceptor] = point
     .getCharacter();
  }

  for (int row = 0; row < gridArea; row++) {
   for (int column = 0; column < gridArea; column++) {
    System.out.print(String.valueOf(diamond[row][column]));
   }
   System.out.println();
  }

 }
It will gives the expected diamond for a given input character.

Since my tests are passing I thought of having some refactoring to Dimond class. for and example I do not need to expose getInterceptor method to public. So i can make it private.

Another self finding of this workshop is that we should think the test case as a opposition party  and always write the test cases which will give the maximum pain for the source code end. (Class under Test). At the same time you need to make sure to write a simple test which gives enough potential to fail.

So its about how to treat our code. Overall it was a wonderful event and  I could deal with the people who has different kind of mind sets. At the end of the day what I had is a green color sticky note which says that you should practice some code kata with TDD until you will get the right skill. Kudos for Johannes.

Note : In the case where you need to have a closer look in to the code you can get it from here.