Sunday, May 13, 2012

Implementation of ArrayList ... (add(.),get(..),set(..))


What is the default capacity of ArrayList and what is the growth algorithm of array list?
Ø  Default capacity of array list is 10.
 /**
      * Constructs an empty list with an initial capacity of ten.
      */
       public ArrayList()
       {
         this(10);
       }
     However we can also specify initial capacity of an array list.
   /**
     * Constructs an empty list with the specified initial capacity.
     * @param   initialCapacity   the initial capacity of the list
     * @exception IllegalArgumentException if the specified initial capacity
     *            is negative    
     */
    public ArrayList(int initialCapacity) {
       super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
       this.elementData = new Object[initialCapacity];
    }
Where ‘elementData’ is an object array to which size is initialized.
    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer.
     */
    private transient Object[] elementData;

Growth algorithm of ArrayList is:

int newCapacity = (oldCapacity * 3)/2 + 1;
e.g.: LET oldCapacity =10
      THEN (10*3)/2+1 = 16
SO newCapacity is 16.

Working of ArrayList:

public class WorkingOfArrayList {
       public static void main(String[] args) {
              ArrayList<String> aList= new ArrayList<String>();
              aList.add("a");
              aList.add("b");
              aList.add("c");
              aList.add("d");
              aList.add("e");
              aList.add("f");
              aList.add("g");
              aList.add("h");
              aList.add("i");
              aList.add("j");
              aList.add("k");
              //when 11th element is going to be added in list the capacity of list is resized.
              //Growth algo is: (OLDCAPACITY*3)/2+1 i.e., if oldCapacity is 10 then new capacity is 16.
              System.out.println("ArrayList: "+aList);
              System.out.println("Get value at 1st: "+aList.get(1));
              aList.set(4,"abhinav");
              System.out.println("ArrayList: "+aList);
              System.out.println("Get value at 4th: "+aList.get(4));
       }
}

Output>

Flow:
Element ‘a’ is added in list using add() method which implementation is given in such a way that it always ensures the capacity of list and then add the element into it, if capacity is full then it will automatically add all the elements in the current array to a  new array of increased size. This is done by using System.arrayCopy(..) method.

Implementation of add() method:
private int size; // initial  size of an array.
private int modCount;
private transient Object[] elementData;// object array buffer

public boolean add(E e) {
       ensureCapacity(size + 1);  // Increments modCount(how many times list is structurally modified.)!!
       elementData[size++] = e;
      //object array of some size in which elements are added.
       return true;
}


  /**
     * Increases the capacity of this <tt>ArrayList</tt> instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param   minCapacity   the desired minimum capacity
     */
    public void ensureCapacity(int minCapacity) {
       modCount++;// flag to maintain the log of list’s structure modification.
       int oldCapacity = elementData.length;

      //This below block is used when list size met the total capacity of list.
       if (minCapacity > oldCapacity) {
           Object oldData[] = elementData;
           int newCapacity = (oldCapacity * 3)/2 + 1;
           if (newCapacity < minCapacity)
              newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);

           //Internally System.arrayCopy() is used to copy all elements from old array to new size array after growth of list is performed.
       }
    }

From above example elements (a - j) in the list are added normally till the size is reached to 10, because default initialization of list gives size as 10.
When ‘k’ is going to be added in the list it is computed that its size is full.
(minCapacity > oldCapacity ) i.e., (11> 10), then list is resized.
Ø  A new array of capacity 16 is created.
Ø  All the elements in the old array are copied into the new array using System.arrayCopy(..).
Ø  New array of size 16 is calculated by growth algo (oldCapactity(10)*3)/2+1=16;

Implementation of get (int index) method:

   /**
     * Returns the element at the specified position in this list.
     *
     * @param index index of the element to return
     * @return the element at the specified position in this list
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E get(int index) {
       RangeCheck(index); //check whether entered range is valid or not
       return (E) elementData[index];
    }

   /**
     * Checks if the given index is in range.  If not, throws an appropriate
     * runtime exception.  This method does *not* check if the index is
     * negative: It is always used immediately prior to an array access,
     * which throws an ArrayIndexOutOfBoundsException if index is negative.
     */
    private void RangeCheck(int index) {
       if (index >= size)
           throw new IndexOutOfBoundsException(
              "Index: "+index+", Size: "+size);
    }   
Implementation of set (int index, Element e) method:

           /**
     * Replaces the element at the specified position in this list with
     * the specified element.
     *
     * @param index index of the element to replace
     * @param element element to be stored at the specified position
     * @return the element previously at the specified position
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public E set(int index, E element) {
       RangeCheck(index);//check whether entered range is valid or not

       E oldValue = (E) elementData[index];
       elementData[index] = element;
       return oldValue;
    }

Saturday, May 12, 2012

Creating ANT BUILD Configuration.....

"build.properties" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>



lib.dir=WebContent/WEB-INF/lib
src.dir=src
conf.dir=WebContent/WEB-INF
web.content=WebContent
project.name=Struts2SpringDemo
build.dir=build
dist.dir=dist
javadoc.dir = JavaDocs
*********************************************************************************
"build.xml" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

<?xml version="1.0" encoding="UTF-8"?>
<project name="Struts2SpringDemo" default="war" basedir=".">
    
    <property file="build.properties"/>
    <!--<property file="version.properties"/>-->
    <!--
        Tasks to be done!
        1. clean
        2. init
        3. compile
        4. copy
        5. war
        6. clean-javadoc
        7. javadoc
    -->
    <!-- setting the classpath for compiling java files -->
    <path id="classpath">
        <fileset dir="${lib.dir}" includes="**/*.jar"/>
    </path>  
    
    <!-- deleting the existing dist and build directories -->
    <target name="clean">
        <echo>******Cleaning the ${build.dir} and ${dist.dir}******</echo>
        <delete dir="${build.dir}"/>
        <delete dir="${dist.dir}"/>
    </target>
    
    <!-- deleting the existing docs directories -->
    <target name="clean-javadoc">
        <echo>******Cleaning the ${javadoc.dir}******</echo>        
        <delete dir="${javadoc.dir}"/>
    </target>
    
    <!-- creating the dist and build directories -->
    <target name="init" depends="clean">
        <echo>******Creating the required directories******</echo>
        <mkdir dir="${dist.dir}"/>
        <mkdir dir="${build.dir}/WEB-INF/classes"/>
        <mkdir dir="${build.dir}/WEB-INF/lib"/>
    </target>
    
    <!-- compile the source code -->
    <target name="compile" depends="init">
        <echo>******Compile the source files******</echo>
        <javac debug="on" srcdir="${src.dir}" destdir="${build.dir}/WEB-INF/classes" includes="**/*">
            <classpath refid="classpath"/>            
        </javac>
    </target>
    
    <!-- copy the all relative files and creating a package for war file -->
    <target name="copy" depends="compile">
        <echo>******Copying the source files into ******${build.dir}**</echo>
        <copy todir="${build.dir}/WEB-INF">
            <fileset dir="${conf.dir}"/>
        </copy>
        <copy todir="${build.dir}">
            <fileset dir="${web.content}"/>
        </copy>      
        <copy todir="${build.dir}/WEB-INF/lib">
            <fileset dir="${lib.dir}"/>
        </copy>
        <copy todir="${build.dir}/WEB-INF/classes">
            <fileset dir="${src.dir}" includes="**/*.properties"/>
        </copy>
        <copy todir="${build.dir}/WEB-INF/classes">
            <fileset dir="${src.dir}" includes="**/*.xml"/>
        </copy>
<copy todir="${build.dir}/WEB-INF/classes">
            <fileset dir="${src.dir}" includes="**/*.xsl"/>
        </copy>
    </target>
    
    <!-- the ant war task. with all resources in place, create the war file -->
    <target name="war" depends="copy">
        <echo>******Building the war file******${project.name}.war**</echo>
        <war destfile="${dist.dir}/${project.name}.war" webxml="${build.dir}/WEB-INF/web.xml">
            <fileset dir="${build.dir}"/>
        </war>
    </target>
    
    <!-- the ant javadoc task. Generates JavaDocs for the Browser App code -->
    <target name="javadoc" description="Generates JavaDocs for the Browser App code" depends="clean-javadoc">
        <echo>*****Generating docs for Struts2SpringDemo app*****</echo>
        <mkdir dir="${javadoc.dir}"/>        
        <javadoc
            destdir="${javadoc.dir}"
            author="false"
            version="false"
            access="private"
            use="true"
            source="1.6+"
            windowtitle="Struts2SpringDemo App API">
            <classpath refid="classpath"/>
            <fileset dir="${src.dir}" defaultexcludes="yes">
                <include name="com/**"/> 
                <exclude name="com/**/*.properties"/>
                <exclude name="com/**/*.xml"/>
            </fileset>            
            <doctitle><![CDATA[<h1>Struts2SpringDemo application Api</h1>]]></doctitle>
            <bottom><![CDATA[<i>Copyright &#169; 2012 Abhinav Mishra. All Rights Reserved.</i>]]></bottom>
        </javadoc>
    </target>
</project>
********************************************************************
"build-all.xml" >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

<?xml version="1.0" encoding="UTF-8"?>
<project name="struts2spring-build-all" default="all">   
    <!-- no need to run target "clean" as individual build files are calling clean target -->
    <!-- THIS BUILD FILE IS FOR RUNNING ALL THE BUILD FILES TO CREATE RESPECTIVE JARS/WARS -->
    <target name="all">
       
        <echo>******STARTED RUNNING THE STRUTS2SPRING APPLICATION BUILD******</echo>
<ant antfile="./code/Struts2SpringDemo/build.xml" useNativeBasedir="true" />
    </target>

    <target name="clean">
<echo>******STARTED RUNNING THE STRUTS2SPRING APPLICATION CLEAN******        </echo>
        <ant antfile="./code/Struts2SpringDemo/build.xml" useNativeBasedir="true" />
    </target>
</project>

Sending Stream To HttpResponse in struts2 instead of Writing response using getWriter().write(response).

Action Class which generates response:::


package com.action;

import java.io.InputStream;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;

import com.bean.AuthBean;
import com.serviceImpl.ServiceAware;
import com.utility.Utilities;


/**
 * The Class HomeAction.
 */
public class HomeAction extends Utilities{

/**
* Instantiates a new home action.
*/
public HomeAction(){
super();
logger.info("HomeAction instantiated...");
String users = "abhinav@gmail.com|" +
"bhawna@gmail.com|" +
"chikku@gmail.com|" +
"rashmi@gmail.com|" +
"vinay@gmail.com|" +
"kunal@gmail.com|" +
"rahul@gmail.com|" +
"abhishek@gmail.com|" +
"raju@gmail.com|" +
"mamu@gmail.com|" +
"dadu@gmail.com|" +
"baby@gmail.com|" +
"shikhu@gmail.com|" +
"pinku@gmail.com|" +
"sonu@gmail.com";
userList = new ArrayList<String>();
StringTokenizer st = new StringTokenizer(users, "|");

while (st.hasMoreTokens()) {
userList.add(st.nextToken().trim());
}
Collections.sort(userList);
userMap.put("a",1);
userMap.put("c",2);
userMap.put("b",4);
userMap.put("d",3);
}

/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;

/** The user. */
private AuthBean authBean;

/** The service aware. */
private ServiceAware service;

/** The input stream. */
private InputStream inputStream;

/** The list. */
private List<String> userList;


/**
* Gets the user list.
*
* @return the user list
*/
public List<String> getUserList() {
return userList;
}

/**
* Sets the user list.
*
* @param userList the new user list
*/
public void setUserList(List<String> userList) {
this.userList = userList;
}

/**
* Gets the input stream.
*
* @return the input stream
*/
public InputStream getInputStream() {
return inputStream;
}

/**
* Sets the input stream.
*
* @param inputStream the new input stream
*/
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}

/**
* Gets the service.
*
* @return the service
*/
public ServiceAware getService() {
return service;
}

/**
* Sets the service.
*
* @param service the new service
*/
public void setService(ServiceAware service) {
this.service = service;
}

/**
* Gets the auth bean.
*
* @return the auth bean
*/
public AuthBean getAuthBean() {
return authBean;
}

/**
* Sets the auth bean.
*
* @param authBean the new auth bean
*/
public void setAuthBean(AuthBean authBean) {
this.authBean = authBean;
}

/** The user map. */
private Map<Object, Object> userMap=new HashMap<Object, Object>();

/** The m. */
private TreeMap<Object, Object> m;

/**
* Gets the m.
*
* @return the m
*/
public TreeMap<Object, Object> getM() {
return m;
}

/**
* Sets the m.
*
* @param m the m
*/
public void setM(TreeMap<Object, Object> m) {
this.m = m;
}

/**
* Gets the user map.
*
* @return the user map
*/
public Map<Object, Object> getUserMap() {
return userMap;
}

/**
* Sets the user map.
*
* @param userMap the user map
*/
public void  setUserMap(Map<Object, Object> userMap) {
this.userMap = userMap;
}

/**
* Home page.
*
* @return the string
*/
public String homePage(){
return SUCCESS;
}

/**
* Gets the user profile .
*
* @return the user profile action
* @throws Exception the exception
*/
public String getUserProfileAction()throws Exception{
Map<String, Object> response=null;
String responseStr="";
String userName=getSession().get("username").toString();
response = getService().getUserMgmtService().getUserProfile(userName);
responseStr=response.get("username").toString()+"|"+response.get("firstname").toString()+"|"+response.get("lastname").toString()+"|"+response.get("emailid")+"|"+response.get("role");
getAuthBean().setResponse(responseStr);
getSession().putAll(response);
inputStream = new StringBufferInputStream(responseStr);
inputStream.close();
return SUCCESS;
}

/**
* Update user profile action.
*
* @return the string
* @throws Exception the exception
*/
public String updateUserProfileAction()throws Exception{
String response="";
response = getService().getUserMgmtService().updateUser(getAuthBean().getUserName(),
getAuthBean().getFirstName(),
getAuthBean().getLastName(),
getAuthBean().getEmailId(),
getAuthBean().getRole()
);
getAuthBean().setResponse(response);
inputStream = new StringBufferInputStream(response);
inputStream.close();
return SUCCESS;
}

/**
* Change password action.
*
* @return the string
* @throws Exception the exception
*/
public String changePasswordAction()throws Exception{
String response="";
response = getService().getUserMgmtService().changePasword(getAuthBean().getUserName(),Utilities.getPassword(getAuthBean().getNewPassword()),
Utilities.getPassword(getAuthBean().getOldPassword()));
getAuthBean().setResponse(response);
inputStream = new StringBufferInputStream(response);
inputStream.close();
return SUCCESS;
}

/**
* Creates the user action.
*
* @return the string
* @throws Exception the exception
*/
public String createUserAction()throws Exception{
String response="";
response=getService().getUserMgmtService().createNewUser(
getAuthBean().getUserName(),
getAuthBean().getFirstName(),
getAuthBean().getLastName(),
getAuthBean().getEmailId(),
getAuthBean().getRole()
);
getAuthBean().setResponse(response);
inputStream = new StringBufferInputStream(response);
inputStream.close();
return SUCCESS;
}

/**
* Sort on key.
*
* @return the string
* @throws Exception the exception
*/
public String sortOnKey()throws Exception{
m= new TreeMap<Object, Object>();
m.putAll(userMap);
return SUCCESS;
}

/**
* Sort on value.
*
* @return the string
* @throws Exception the exception
*/
public String sortOnValue()throws Exception{
m= new TreeMap<Object, Object>(new HashMapValueComparator(userMap));
m.putAll(userMap);
return SUCCESS;
}
}


/**
 * The Class HashMapValueComparator.
 */
class HashMapValueComparator implements Comparator<Object>{

/** The map. */
Map<Object, Object> map;

/**
* Instantiates a new hash map value comparator.
*
* @param m the m
*/
public HashMapValueComparator(Map<Object, Object> m){
super();
this.map = m;
}

/**
* Instantiates a new hash map value comparator.
*/
public HashMapValueComparator() {
super();
}

/* (non-Javadoc)
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(Object o1, Object o2) {
int retType;
Object v1=map.get(o1);
Object v2=map.get(o2);
if(v1.hashCode()>v2.hashCode()){
retType=1;
}else if(v1.hashCode()<v2.hashCode()){
retType=-1;
}else{
retType=0;
}
return retType;
}
}


###############################################################################
Struts.xml CONFIGURATION:::::::


<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<package name="userMgmt" extends="strutsSpringDemo">
<!-- USER MGMT ACTIONS AND MAPPINGS START-->
<action name="homeAction" class="com.action.HomeAction" method="homePage">
<result name="success" type="tiles">/homePage.tiles</result>
</action>
           

  <!-- getUserProfileAction sending >>>> Input stream -->

<action name="userProfile" class="com.action.HomeAction"
method="getUserProfileAction">
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
</action>


<action name="changePassword" class="com.action.HomeAction"
method="changePasswordAction">
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
</action>
<action name="updateProfile" class="com.action.HomeAction"
method="updateUserProfileAction">
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
</action>
<action name="createUser" class="com.action.HomeAction" method="createUserAction">
<result name="success" type="stream">
<param name="contentType">text/html</param>
<param name="inputName">inputStream</param>
</result>
</action>
<action name="sortOnKey" class="com.action.HomeAction" method="sortOnKey">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="execAndWait">
<param name="delay">50</param>
<param name="delaySleepInterval">150</param>
</interceptor-ref>
<result name="wait">jsp/waitProcess.jsp</result>
<result name="success" type="tiles">/homePage.tiles</result>
</action>
<action name="sortOnVal" class="com.action.HomeAction" method="sortOnValue">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="execAndWait">
<param name="delay">50</param>
<param name="delaySleepInterval">150</param>
</interceptor-ref>
<result name="wait">jsp/waitProcess.jsp</result>
<result name="success" type="tiles">/homePage.tiles</result>
</action>
<!-- USER MGMT ACTIONS AND MAPPINGS END-->
</package>
</struts>