Tuesday, 26 May 2015

Map internal details


New key:

1. Calculate hashcode for the key
2. Calculate position hash % (arrayLength-1)) where element should be placed(bucket number)
3. If you try to add a value with a key which has already been saved in HashMap, then value gets overwritten.
4. Otherwise element is added to the bucket. If bucket has already at least one element - a new one is gets added and placed in the first position in the bucket. Its next field refers to the old element.

Deletion:

1. Calculate hashcode for the given key
2. Calculate bucket number (hash % (arrayLength-1))
3. Get a reference to the first Entry object in the bucket and by means of equals method iterate over all entries in the given bucket. Eventually we will find correct Entry. If desired element is not found - return null


put:

Step1- First of all, key object is checked for null. If key is null, value is stored in table[0] position. Because hash code for null is always 0.
Step2- Then on next step, a hash value is calculated using key’s hash code by calling its hashCode() method. This hash value is used to calculate index in array for storing Entry object. JDK designers well assumed that there might be some poorly written hashCode() functions that can return very high or low hash code value. To solve this issue, they introduced another hash() function, and passed the object’s hash code to this hash() function to bring hash value in range of array index size.
Step3- Then on next step, a hash value is calculated using key’s hash code by calling its hashCode() method. This hash value is used to calculate index in array for storing Entry object. JDK designers well assumed that there might be some poorly written hashCode() functions that can return very high or low hash code value. To solve this issue, they introduced another hash() function, and passed the object’s hash code to this hash() function to bring hash value in range of array index size.
Step4- Here comes the main part. Now, as we know that two unequal objects can have same hash code value, answer is linked list

public V put(K key, V value) {
  if (key == null)  
   return putForNullKey(value);  
  int hash = hash(key.hashCode());  
  int i = indexFor(hash, table.length);  
  for (Entry<k , V> e = table[i]; e != null; e = e.next) {
   Object k;
   if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
    V oldValue = e.value;
    e.value = value;
    e.recordAccess(this);
    return oldValue;
   }
  }

  modCount++;
  addEntry(hash, key, value, i);  
  return null;
 }

get:

public V get(Object key) {  
  if (key == null)  
   return getForNullKey();  
  int hash = hash(key.hashCode());  
  for (Entry<k , V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {  
   Object k;  
   if (e.hash == hash && ((k = e.key) == key || key.equals(k)))  
    return e.value;  
  }  
  return null;  
 }  


Sunday, 10 May 2015

JAX-B

1      Jax-B(Java API for XML Binding)

Jax-B provides to convert java class to xml file(marshal) and xml to java objects (un-marshal).
Jax-B comes with JRE6 as a default. No need to install extra software’s to work with xml files.
We have provider and consumer programs consumer needs to interact with consumer and provider and consumer is written on java so he can send serializable object to provider but we are not sure which technology provider was. So here we have only one option to communicate with provider that is through xml files. To achieve this process we have jax-B API.
As part of xml we need to pass the security as well as application binding protocols.

2      Features of JAX-B 2.0

·         Annotations
·         Supports w3c xml schema features
·         Supports JAX-P validations

3      Creating schema

To generate java classes first we need to have the schema file. Schema is also xml file which contains the definitions of all data types as well as all related classes. Following are the normal java classes and we need to generate schemas for those
Employee(id, name, salary);
Address( street, city, state, pincode)
Phone(country code, number)
Account(id, number, name, balance, last 10 transactions)

3.1    Creating schema:

Mapping between schema and java
schema type
Java type
Simple type
Property
Attribute
Property
Complex type
Class

Following is the Employee normal java class and related Employee schema.
Public class Employee {
  Private Integer id;
  Private String name;
}
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
      xmlns:xs="http://www.w3.org/2001/XMLSchema"
      xmlns:product=http://www.ibm.com/schemas
      targetNamespace=http://www.ibm.com/schemas
      elementFormDefault="qualified"
      attributeFormDefault="unqualified">
               
              <xs:complexType name=”Employee”>
                 <xs:sequence>
                        <xs:element name=”id” type=”xs:integer”>
                       <xs:element name=”name” type=”xs:string”
                </xs:sequence>
              </xs:complexType>

</xs:schema>

4      Binding architecture

In general we have java class and object. Java class can be called as blue print of object and object fallows the structure of class and can be called as instance.
Similar we have schema and xml file. Xml will be created with the help of schema.
So java class is similar to schema and object is similar to xml file. Schema is equals to java class and object is equals to xml file. Following the details diagram for the mappings between java class, object and schema, xml file
Converting object to xml is called as marshal and xml to java class is called as un-marshal. In this process we can perform the schema validation that is called as in memory validation.
To deal with JAX-B we need following components.
·         Schema
·         Xml
·         JAX-B classes
·         Java object
JAX-B supports the two operations. Those are
·         One time operation
·         Run time operation

5      one time operation

This can be performed in two directions
1.       generating jax-b classes from schema
2.       generating schema from jax-b classes

5.1    Generating jax-b classes from schema

To generate jax-b classes we need schema first. Following is the schema file based on that file we need to generate jax-b classes
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
      targetNamespace="http://www.chandra.com/schemas" xmlns:employee="http://www.chandra.com/schemas"
      elementFormDefault="qualified" attributeFormDefault="unqualified">

      <xs:element name="employee" type="employee:employee" />

      <xs:complexType name="employee">
            <xs:sequence>
                  <xs:element name="employeeId" type="xs:integer" minOccurs="1"
                        maxOccurs="1" />
                  <xs:element name="employeeName" type="xs:string"
                        minOccurs="0" maxOccurs="1" />
                  <xs:element name="address" type="employee:address"
                        minOccurs="0" maxOccurs="unbounded" />
            </xs:sequence>
      </xs:complexType>
      <xs:complexType name="address">
            <xs:sequence>
                  <xs:element name="addressId" type="xs:int" minOccurs="1"
                        maxOccurs="1" />
                  <xs:element name="street" type="xs:string" minOccurs="0"
                        maxOccurs="1" />
                  <xs:element name="city" type="xs:string" minOccurs="0"
                        maxOccurs="1" />
                  <xs:element name="state" type="xs:string" minOccurs="0"
                        maxOccurs="1" />
                  <xs:element name="pin" type="xs:integer" minOccurs="0"
                        maxOccurs="1" />
            </xs:sequence>
      </xs:complexType>
</xs:schema>

With the help of above file we need to generate jax-b classes. This is possible multiple ways.
·         With xjc command
·         With eclipse

5.1.1      With xjc command

H:\xjc -d . EmployeeSchema.xsd

parsing a schema...
compiling a schema...
com\chandra\schemas\Address.java
com\chandra\schemas\Employee.java
com\chandra\schemas\ObjectFactory.java
com\chandra\schemas\package-info.java
Here dot represent where to save the generated jax-b classes

5.1.2    With eclipse

1.       To work with eclipse first we need to set the jdk path to eclipse instead of jre
2.       Create schema definition file
3.       Right click on schema definition file and select the generate java files
4.       It will open the popup screen and select the package when we need to save the java classes

5.1.3    Generated classes:

1
package com.chandra.jaxb;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "employee", propOrder = {
    "employeeId",
    "employeeName",
    "address"
})
public class Employee {

    @XmlElement(required = true)
    protected BigInteger employeeId;
    protected String employeeName;
    protected List<Address> address;

    //setter and getter methods
    public List<Address> getAddress() {
        if (address == null) {
            address = new ArrayList<Address>();
        }
        return this.address;
    }
}
2
package com.chandra.jaxb;

import java.math.BigInteger;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "address", propOrder = {
    "addressId",
    "street",
    "city",
    "state",
    "pin"
})
public class Address {

    protected int addressId;
    protected String street;
    protected String city;
    protected String state;
    protected BigInteger pin;
    /setter and getter methods
}
3
package com.chandra.jaxb;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
@XmlRegistry
public class ObjectFactory {

    private final static QName _Employee_QNAME = new    QName("http://www.chandra.com/jaxb", "employee");

   
    public ObjectFactory() {
    }
    public Employee createEmployee() {
        return new Employee();
    }

    public Address createAddress() {
        return new Address();
    }

    @XmlElementDecl(namespace = "http://www.chandra.com/jaxb", name = "employee")
    public JAXBElement<Employee> createEmployee(Employee value) {
        return new JAXBElement<Employee>(_Employee_QNAME, Employee.class, null, value);
    }

}
4
@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.chandra.com/jaxb", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.chandra.jaxb;

5.2    Generating schema from javax b classes:

Schema also can generate from eclipse as well as command prompt. To do this first we need to create jaxb classes

5.2.1    From command prompt:

H:\WebServices\JaxBToschema\src\com\chandra\jaxb>schemagen -cp . *.java

warning: The apt tool and its associated API are planned to be
removed in the next major JDK release.  These features have been
superseded by javac and the standardized annotation processing API,
javax.annotation.processing and javax.lang.model.  Users are
recommended to migrate to the annotation processing features of
javac; see the javac man page for more information.
Note: Writing H:\WebServices\JaxBToschema\src\com\chandra\jaxb\schema1.xsd

5.2.2    From eclipse:

·         Select File > New > Other > Schema from JAXB Classes
·         Click on next
·         Select the source folder or project to generate the schema and write the schema name on file name box
·         Click on next and select the project name on next popup
·         Click on finish button it will generate schema

5.2.3    Generated schema:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://www.chandra.com.schema"
      xmlns:tns="http://www.chandra.com.schema" xmlns:xs="http://www.w3.org/2001/XMLSchema">

      <xs:element name="employee" type="tns:employee" />

      <xs:complexType name="employee">
            <xs:sequence>
                  <xs:element name="id" type="xs:int" minOccurs="0" />
                  <xs:element name="name" type="xs:string" minOccurs="0" />
                  <xs:element name="address" type="tns:address" minOccurs="0" />
            </xs:sequence>
      </xs:complexType>

      <xs:complexType name="address">
            <xs:sequence>
                  <xs:element name="id" type="xs:int" minOccurs="0" />
                  <xs:element name="city" type="xs:string" minOccurs="0" />
                  <xs:element name="state" type="xs:string" minOccurs="0" />
            </xs:sequence>
      </xs:complexType>
</xs:schema>



6      Run time operation

Run time operations are converting from jaxb to xml file and xml file to jaxb classes

6.1    marshaller

Converting object to xml is called as marshal. To do this following are the steps
·         Create domain object
·         Create JAXBContext object
·         Get Marshaller class object
·         Set property to formatted out put
·         Call marshl on domain object
Product prod = new Product();
prod.setId(1);
prod.setName("Chadnra");
prod.setPrice(10.12D);
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
Marshaller mar = context.createMarshaller();
mar.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
mar.marshal(prod, System.out);

6.2    Un-marshaller

Converting xml to object is called as un-marshal
Procedure to create object from xml file:
·         Create xml file
·         Get JAXBContext object
·         Get Unmarshaller object
·         Get JAXBElement by calling the unmarshal method. which can have the object
·         Get domain object from jaxb element
·         Display data
<?xml version="1.0" encoding="UTF-8"?>
<prod:product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.ibm.com/schemas file:///H:/XML/Product.xsd"
      xmlns:prod="http://www.ibm.com/schemas">
      <prod:id>1</prod:id>
      <prod:name>Lux</prod:name>
      <prod:price>10.0</prod:price>
</prod:product>
JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
JAXBElement<Product> jp = (JAXBElement<Product>) unMarshaller.unmarshal(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/ProductSchema.xml"));
Product p = jp.getValue();
System.out.println(p);
System.out.println(p.getId());
System.out.println(p.getName());
System.out.println(p.getPrice());

6.3    schema validation on marshaller

public class InMemoryValidationMarshaller
{
    private static final String CLASS_PATH = System.getProperty("java.class.path");
    public static void main(String[] args) throws SAXException, JAXBException
    {
        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = factory.newSchema(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/Product.xsd"));
        JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setSchema(schema);
        Product prod = new Product();
        prod.setId(1);
        prod.setName("Chadnra");
        prod.setPrice(10.12D);
        marshaller.marshal(prod, System.out);
    }
}

6.4    schema validation on un-marshaller

public class InMemoryalidationUnMarshaller
{
    private static final String CLASS_PATH = System.getProperty("java.class.path");

    public static void main(String[] args) throws SAXException, JAXBException
    {
        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = factory.newSchema(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/Product.xsd"));
        JAXBContext context = JAXBContext.newInstance(ObjectFactory.class);
        Unmarshaller unMarshaller = context.createUnmarshaller();
        unMarshaller.setSchema(schema);
        JAXBElement<Product> jp = (JAXBElement<Product>) unMarshaller.unmarshal(new File(CLASS_PATH + "/com/ibm/pdc/ephs/jaxb/resources/ProductSchema.xml"));
        Product p = jp.getValue();
        System.out.println(p);
        System.out.println(p.getId());
        System.out.println(p.getName());
        System.out.println(p.getPrice());
    }
}