Thursday, March 10, 2011

Finding duplicates in an unsorted array

 

Q: You are given an array of elements. Some/all of them are duplicates. Find them in 0(n) time and 0(1) space. Property of inputs - Number are in the range of 1..n where n is the limit of the array.

Algorithm:

1. Read input from startPos
2. If input is within the maxRange or it's not in correct place then it's a candidate to be   replaced else incrementStartPos
3. finalPosition for input is input[i]
4. if finalPosition < maxRange then swap input with finalPosition and increment finalPosition with MaxRange
5. else no need to swap as previous instances of this element are recorded at finalPos so just increment finalPosition with MaxRange to record another instance
6. if input at startPos is in correct place or reached zero then increment startPos++ till you go through end of Array
7. Iterate through the array and divide each element with maxRange. The divisor indicates how many times a element was repeated and 0 indicates a missing element

Eg: if an array had
(2, 3, 4, 3, 2}
1. n=5 after step1 we'll get
{3, 7, 4, 3, 2}
2. now a[0] = 3 so again in loop we'll get
{4, 7, 8, 3, 2}
3. now a[0] = 4 so again in loop we'll get
{3, 7, 8, 9, 2}
4. a[0] = 3 so again in loop we'll get { , 7, 13, 9, 2}
5. since a[0] is empty move to a[1] and in loop we find it's at the right place so move to next, 8, 9 are also in place so we move to last element and have the final array as
{ , 12, 13, 9, }

Now to find how many are duplicates divide every element by 5 and take the mod => m = (a[i] mod n) -1 this gives you how many times an element is repeated.

 

public static void main(String[] args) {       

        int[] inputArr1 = {0, 2, 3, 4, 3, 2};
        findDuplicates(inputArr1, 5);
        printDuplicatesAndMissingElements(inputArr1);
    }

    private static void findDuplicates(int[] inputArr, int maxRange) {
        // for simplicity reasons we will assume nothing is there in 0 index of array
        // and start from 1
        int i = 1;
        int maxArrLength = inputArr.length;
       
        while(true) {
            if ( i > maxArrLength - 1)
                break;
           
            int finalPos = inputArr[i];
            System.out.println(" Read :: " + inputArr[i]);
           
            if (finalPos > maxRange) {
                //this element is already in final position skip and move further looking for elements within maxRange
                i++;
                continue;
            }
            int finalPosElement = inputArr[inputArr[i]];
            int startPos = i;
            int startPosElement = inputArr[i];
           
            // if startPos element isn't in place and it's within the maxRange..
            // then candidate for swap or reaching final pos...
            if (inputArr[startPos] != i ||
                    inputArr[startPos] <= maxRange) {

                if (finalPosElement > maxRange) {
                    // if finalposElement > maxRange then no swapping required
                    // just add maxRange to denote multiple entry
                    inputArr[finalPos] += maxRange;   
                    //make startPosElement as 0
                    inputArr[startPos] = 0;
                    System.out.println("No swapping required incemented " + inputArr[finalPos] );
                }
                else {
                    //swap
                    int temp = startPosElement;
                    inputArr[startPos] = finalPosElement;
                    inputArr[finalPos] = temp + maxRange;
                    System.out.println("Swapped : " + startPosElement + " with " +finalPosElement);
                }
            }
            printArray(inputArr);
            // if the element in current evaluated position isn't still correct repeat the above again
            if (inputArr[startPos] == i ||
                    
                    inputArr[startPos] > maxRange) {
                System.out.println(" Read :: "+ inputArr[startPos] + " it's already in place");
                inputArr[startPos] += maxRange;
                i++;
            }
            else if (inputArr[startPos] == 0){
                i++;
                continue;
            }
            else {
                continue;
            }
               
        }
       
    }
   
    private static void printArray(int[] inputArr) {
        for (int i=1; i < inputArr.length; i++) {
            System.out.print(inputArr[i] +",");
        }
        System.out.println("");
    }
    private static void printDuplicatesAndMissingElements(int[] inputArr) {
        int maxRange = inputArr.length;
        for (int i=1; i < inputArr.length; i++) {
            if (inputArr[i] == 0) {
                System.out.println(" Element [" + i + "] is missing");
            }
            int input = inputArr[i];
            int mod = input / maxRange;
            if ( mod > 1) {
                System.out.println (" Element [" + i + "] is repeated + [" + mod + "] times");
               
            }
        }
    }

}

Monday, February 7, 2011

Ternary Search Tree implementation

The ternary search tree contains three types of links. First, there are pointers that correspond to links in the corresponding trie, shown as dashed down-arrows. Traversing a down-link corresponds to “matching” the character from which the arrow starts. The left- and right- links are traversed when the current character does not match the desired character at the current position. We take the left-link if the character we are looking for is alphabetically before the character in the current node, and the right-link in the opposite case.

Ternary tree data structure solves the memory problem of tries which we discussed in the earlier post in a more clever way. To avoid the memory occupied by unnecessary pointers, each trie node is represented as a tree-within-a-tree rather than as an array. Each non-null pointer in the trie node gets its own node in a ternary search tree.

Each node in a Ternary search tree could be implemented like this in java:

class TNode
{
    char m_char;
    TNode left, center, right;
    boolean wordEnd;

    public TNode(char ch, boolean wordEnd)
    {
        m_char = ch;
        wordEnd = wordEnd;
    }
}

Here is a Ternary search tree that stores words AB, ABBA, ABCD, and BCD. Nodes that terminate words are marked yellow:

image_thumb[7]

Here is a simple Ternary search tree implementation in java:


public class TernarySearchTree {

    TNode root = null;
   
    public TernarySearchTree()
    {
        this.root = null;
    }

    private void insert(String key, int pos, TNode node)
    {
        char s[] = key.toCharArray();
        if (node == null) { node = new TNode(s[pos], false); }

        if (s[pos] < node.m_char) {
            insert(key, pos, node.left);
            }
        else if (s[pos] > node.m_char) {
            insert(key, pos, node.right);
            }
        else
        {
            if (pos + 1 == key.length()) { node.wordEnd = true; }
            else { insert(key, pos + 1, node.center); }
        }
    }

    public void insert(String s)
    {
        if (s == null || s == "") throw new IllegalArgumentException();

        insert(s, 0, this.root);
    }

    public boolean containsKey(String key)
    {
        if (key == null || key == "") throw new IllegalArgumentException();

        int pos = 0;
        TNode node = this.root;
        char s[] = key.toCharArray();
        while (node != null)
        {

            if (s[pos] < node.m_char) { node = node.left; }
            else if (s[pos] > node.m_char) { node = node.right; }
            else
            {
                if (++pos == key.length()) return node.wordEnd;
                node = node.center;
            }
        }

        return false;
    }
   
    public static void main(String[] args)
    {
        TernarySearchTree tree = new TernarySearchTree();
        tree.insert("AB");
        tree.insert("ABBA");
        tree.insert("ABCD");
        tree.insert("BCD");
       
        boolean found = tree.containsKey("AB");
       
        if(found)
            System.out.println("AB is found in the tree");
        else
            System.out.println("AB is not found");
       
        found = tree.containsKey("ABCD");
       
        if(found)
            System.out.println("ABCD is found in the tree");
        else
            System.out.println("ABCD is not found");

    }
}

class TNode
{
    char m_char;
    TNode left, center, right;
    boolean wordEnd;

    public TNode(char ch, boolean wordEnd)
    {
        m_char = ch;
        wordEnd = wordEnd;
    }
}

Trie implementation

A trie is a tree-like data structure in which each node contains an array of pointers, one pointer for each character in the alphabet. Starting at the root node, we can trace a word by following pointers corresponding to the letters in the target word.

Some of the uses of this Trie data structure is

1) Auto completion of the words or sentences like in Google Suggest.

2) Dictionary etc..

Each node in a trie could be implemented like this in java:

class Node {
    Node[] children;
    boolean isKey;

    public Node() {
        isKey = false;
        children = new Node[26];
    }

    public Node(boolean key) {
        isKey = key;
        children = new Node[26];
    }

}

 

Here is a trie that stores words AB, ABBA, ABCD, and BCD. Nodes that terminate words are marked yellow:

 

image

 

Here is a simple Trie search tree implementation in java:

public class Trie {

    Node root;

    public Trie() {
        this.root = new Node();
    }

    /**
     * Method to insert a string to Node and its children
     *
     * @param key
     *            the string to insert (the string is assumed to be uppercase)
     * @return true if the node or one of its children is changed, false
     *         otherwise
     */
    public boolean insert(String key) {
        return root.insert(key.toUpperCase());
    }

    /**
     * Returns whether key is a valid prefix for certain key in this trie. For
     * example: if key "hello" is in this trie, tests with all prefixes "hel",
     * "hell", "hello" return true
     *
     * @param prefix
     *            the prefix to check
     * @return true if the prefix is valid, false otherwise
     */
    public boolean containPrefix(String prefix) {
        return root.containPrefix(prefix.toUpperCase());
    }

    /**
     * Returns whether key is a valid key in this trie. For example: if key
     * "hello" is in this trie, tests with all prefixes "hel", "hell" return
     * false
     *
     * @param key
     *            the key to check
     * @return true if the key is valid, false otherwise
     */
    public boolean containKey(String key) {
        return root.containKey(key.toUpperCase());
    }
   
    public static void main(String[] args)
    {
       
        Trie trie = new Trie();
        trie.insert("AB");
        trie.insert("ABBA");
        trie.insert("ABCD");
        trie.insert("BCD");
       
        boolean found = trie.containKey("AB");
       
        if(found)
            System.out.println("AB is found in the trie");
        else
            System.out.println("AB is not found");
       
        found = trie.containPrefix("ABC");
       
        if(found)
            System.out.println("ABC prefix is found in the trie");
        else
            System.out.println("ABC prefix is not found");

    }
}

class Node {
    Node[] children;
    boolean isKey;

    public Node() {
        isKey = false;
        children = new Node[26];
    }

    public Node(boolean key) {
        isKey = key;
        children = new Node[26];
    }

    /**
     * Method to insert a string to Node and its children
     *
     * @param key
     *            the string to insert (the string is assumed to be uppercase)
     * @return true if the node or one of its children is changed, false
     *         otherwise
     */
    public boolean insert(String key) {
        // If the key is empty, this node is a key
        if (key.length() == 0) {
            if (isKey)
                return false;
            else {
                isKey = true;
                return true;
            }
        } else {// otherwise, insert in one of its child

            int childNodePosition = key.charAt(0) - 'A';
            if (children[childNodePosition] == null) {
                children[childNodePosition] = new Node();
                children[childNodePosition].insert(key.substring(1));
                return true;
            } else {
                return children[childNodePosition].insert(key.substring(1));
            }
        }
    }

    /**
     * Returns whether key is a valid prefix for certain key in this trie. For
     * example: if key "hello" is in this trie, tests with all prefixes "hel",
     * "hell", "hello" return true
     *
     * @param prefix
     *            the prefix to check
     * @return true if the prefix is valid, false otherwise
     */
    public boolean containPrefix(String prefix) {
        // If the prefix is empty, return true
        if (prefix.length() == 0) {
            return true;
        } else {// otherwise, check in one of its child
            int childNodePosition = prefix.charAt(0) - 'A';
            return children[childNodePosition] != null
                    && children[childNodePosition].containPrefix(prefix
                            .substring(1));
        }
    }

    /**
     * Returns whether key is a valid key in this trie. For example: if key
     * "hello" is in this trie, tests with all prefixes "hel", "hell" return
     * false
     *
     * @param key
     *            the key to check
     * @return true if the key is valid, false otherwise
     */
    public boolean containKey(String key) {
        // If the prefix is empty, return true
        if (key.length() == 0) {
            return isKey;
        } else {// otherwise, check in one of its child
            int childNodePosition = key.charAt(0) - 'A';
            return children[childNodePosition] != null
                    && children[childNodePosition].containKey(key.substring(1));
        }
    }

    public boolean isKey() {
        return isKey;
    }

    public void setKey(boolean key) {
        isKey = key;
    }
}

Wednesday, February 17, 2010

360 degree Viewer

Sample Application showing the 360 degree view of an image using paper vision 3d.

Demo here

360view

Source code

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
                xmlns:view="org.papervision3d.view.*" creationComplete="init();"
                width="622" height="504"
                backgroundGradientAlphas="[1.0, 1.0]" backgroundGradientColors="[#FFFFFF, #DEDEDE]">
    <mx:Script>
        <![CDATA[
            import mx.events.ItemClickEvent;
            import org.papervision3d.objects.primitives.Cylinder;
            import org.papervision3d.materials.BitmapFileMaterial;
            private var cylinder:Cylinder;
            //Initialization function
            private function init():void{
                // BasicView added to the Stage
                myUI.addChild( bv );
                bv.cameraAsCamera3D.x = 0;
                bv.cameraAsCamera3D.z = 0;
                bv.cameraAsCamera3D.y = 0;
                //Create object
                var mat:BitmapFileMaterial = new BitmapFileMaterial("DSC00020.jpg",true);
                mat.doubleSided = true;
                mat.precise = true;
                mat.smooth = true;
                cylinder = new Cylinder( mat , 80 , 100 , 100 , 100 , 80 , false , false );
                bv.scene.addChild( cylinder );
                //Rendering bv.startRendering();
                this.addEventListener(Event.ENTER_FRAME , onTimer );
            }
            //Rendering
            private function onTimer( e:Event ):void{
                bv.renderer.renderScene( bv.scene , bv.camera , bv.viewport );
                cylinder.rotationY += (myUI.width - myUI.mouseX )/ 100;
            }
            private function onClick(e:ItemClickEvent):void{
                cylinder.rotationY = e.item.angle;
            }
        ]]>
    </mx:Script>
    <view:BasicView id="bv"/>
    <mx:UIComponent id="myUI" width="300" height="300"/>
    <mx:LinkBar id="link" x="263.5" y="6" labelField="label" itemClick="onClick(event)">
        <mx:Object label="a" angle="0"/>
        <mx:Object label="b" angle="90"/>
        <mx:Object label="c" angle="180"/>
        <mx:Object label="d" angle="270"/>
    </mx:LinkBar>
    <mx:Label x="280.5" y="476" text="360 Video"/>
</mx:Application>

Monday, December 14, 2009

Crud Operations with Java Web Services, Flex and Flash Builder

 

Java SE 6 has built-in support for web services thanks to JAX-WS 2.0. Using the DCD features in Flash Builder 4, a web service can be easily accessed.  We will build an end-to-end simple CRUD application in Java and Flex 4, where the Java methods are exposed as web service operations. We will take an Employee Class as an example and try to do the crud operations on it, using the Flex UI and Flash Builder 4 for deploying the web services and using it.

Create an Employee table as shown below.

CREATE TABLE `employee` (
  `emp_id` int(11) NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(50) NOT NULL,
  `dept` varchar(50) NOT NULL,
  `emp_sal` int(11) NOT NULL,
  `manager` varchar(50) NOT NULL,
  PRIMARY KEY (`emp_id`)
)

The Employee POJO is shown below.

package com.adobe.objects;

public class SimpleEmployee {
   private int empId;
   private String empName;
   private String dept;
   private int empSal;
   private String manager;
   public SimpleEmployee(int id, String name, String dep, int sal,
        String mgr) {
        this.empId = id;
        this.empName = name;
        this.dept = dep;
        this.empSal = sal;
        this.manager = mgr;
    }
    public SimpleEmployee() {
    // TODO Auto-generated constructor stub
}
    public int getEmpId() {
        return empId;
    }
    public void setEmpId(int id) {
        this.empId = id;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String name) {
        this.empName = name;
    }
    public String getDept() {
        return dept;
    }
    public void setDept(String dep) {
        this.dept = dep;
    }
    public int getEmpSal() {
        return empSal;
    }
    public void setEmpSal(int sal) {
        this.empSal = sal;
    }
    public String getManager() {
        return manager;
    }
    public void setManager(String mgr) {
        this.manager = mgr;
    }

}

The Employee Service with all the operations exposed is as shown below. 

To expose your Java class as a web service, simply:

1) Annotate your Java class with @WebService, @WebMethod.

2) Use the Endpoint class in main()

EmployeeService.Java

package com.adobe.services;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Endpoint;

import com.adobe.objects.SimpleEmployee;
import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;

@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)

public class SimpleEmployeeService
{
    public SimpleEmployeeService()
    {
    }
     @WebMethod
    public int addEmployee(SimpleEmployee emp)
    {
        int createdEmpId= 0;
        Connection connection = null;

        if(emp == null)
        {
            throw new IllegalArgumentException("Employee object is invalid");
        }
        int empId = emp.getEmpId();
        String empName = emp.getEmpName();
        String dept = emp.getDept();
        int sal = emp.getEmpSal();
        String manager = emp.getManager();
        if(empName == null ||
                dept == null ||
                manager == null)
        {
            throw new IllegalArgumentException("employee object is invalid");
        }
        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("INSERT INTO employee (" +
                        "emp_id, emp_name, dept,emp_sal,manager) " +
                        "VALUES(?,?,?,?,?)");
            statement.setInt(1, empId);
            statement.setString(2, empName);
            statement.setString(3, dept);
            statement.setInt(4, sal);
            statement.setString(5,manager);
            int rowCount = statement.executeUpdate();

            if(rowCount == 1)
            {
                ResultSet rs = statement.getGeneratedKeys();
                if(rs.next())
                {
                    createdEmpId = rs.getInt(1);
                }
            }
        }
        catch(MySQLIntegrityConstraintViolationException multipleEntryException)
        {
            //duplicate entry found
            throw new RuntimeException("Employee entry already exists");
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }       
        return createdEmpId;
    }
     @WebMethod

    public void updateEmployee(SimpleEmployee emp)
    {
        Connection connection = null;

        if(emp == null)
        {
            throw new IllegalArgumentException("Employee object is invalid");
        }

        int empId = emp.getEmpId();
        String empName = emp.getEmpName();
        String dept = emp.getDept();
        int sal = emp.getEmpSal();
        String manager = emp.getManager();
        if(empName == null ||
                dept == null ||
                empId <= 0 ||
                manager == null)
        {
            throw new IllegalArgumentException("Employee object is invalid");
        }
        //update customer address
        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("UPDATE employee SET " +
                        "emp_name = ?," +
                        "dept = ?, " +
                        "manager = ?," +
                        "emp_sal = ? " +
                        "WHERE emp_id = ?");
            statement.setString(1, empName);
            statement.setString(2, dept);
            statement.setString(3, manager);
            statement.setInt(4, sal);
            statement.setInt(5, empId);
            statement.executeUpdate();

        }
        catch(MySQLIntegrityConstraintViolationException multipleEntryException)
        {
            //duplicate entry found
            throw new RuntimeException("Employee entry already exists");
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               
    }
     @WebMethod
    public boolean deleteEmployee(SimpleEmployee emp)
    {
        boolean result = false;
        Connection connection = null;
        if(emp == null)
        {
            throw new IllegalArgumentException("Employee instance  is invalid");
        }
        int empId = emp.getEmpId();

        if(empId <= 0)
        {
            throw new IllegalArgumentException("Employee id is invalid");
        }

        try
        {
            connection = getConnection();
            PreparedStatement employeeStatement;

            employeeStatement = connection.prepareStatement("DELETE FROM employee WHERE emp_id = ?");
            employeeStatement.setInt(1, empId);
            int rowCount = employeeStatement.executeUpdate();
            if(rowCount == 1)
            {
                result = true;
            }   
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }       
        return result;
    }
     @WebMethod
    public SimpleEmployee getEmployee(int empId)
    {
        SimpleEmployee result = null;
        Connection connection = null;

        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("SELECT * FROM employee WHERE emp_id = ?");
            statement.setInt(1, empId);
            ResultSet rs = statement.executeQuery();
            ArrayList<SimpleEmployee> emps = createEmployeesFromRS(rs);
            if(emps != null && emps.size() > 0 )
            {
                result = emps.get(0);
            }
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               

        return result;
    }
    public int getEmployeesCount()
    {
        int result = 0;
        SimpleEmployee[] emps = getAllEmployees();
        if(emps != null)
        {
            result = emps.length;
        }
        return result;
    }

    public ArrayList<SimpleEmployee> getEmployeePaged(int startIndex, int numberOfRows)
    {
        ArrayList<SimpleEmployee> employees = new ArrayList<SimpleEmployee>();
        Connection connection = null;

        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("SELECT * FROM employees LIMIT ?, ?");
            statement.setInt(1, startIndex);
            statement.setInt(2, numberOfRows);
            ResultSet rs = statement.executeQuery();
            employees = createEmployeesFromRS(rs);
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               
        return employees;
    }

    @WebMethod
    public SimpleEmployee[] getAllEmployees()
    {
        ArrayList<SimpleEmployee> employees = new ArrayList<SimpleEmployee>();
        Connection connection = null;

        try
        {
            connection = getConnection();
            PreparedStatement statement =
                connection.prepareStatement("SELECT * FROM employee");
            ResultSet rs = statement.executeQuery();
            employees = createEmployeesFromRS(rs);
        }
        catch(Exception e)
        {
            throw new RuntimeException(e);
        }       
        finally
        {
            try
            {
                if(connection != null)
                {
                    connection.close();   
                }
            }catch(SQLException sqe)
            {
                throw new RuntimeException(sqe);
            }           
        }               
        int len = employees.size();
        SimpleEmployee[] emps = new SimpleEmployee[len];
        employees.toArray(emps);
        return emps;
    }

    private ArrayList<SimpleEmployee> createEmployeesFromRS(ResultSet rs)throws Exception
    {
        ArrayList<SimpleEmployee> emps = new ArrayList<SimpleEmployee>();
        SimpleEmployee emp;
        while(rs.next())
        {
            emp = new SimpleEmployee();
            emp.setEmpId(rs.getInt("emp_id"));
            emp.setEmpName(rs.getString("emp_name"));
            emp.setDept(rs.getString("dept"));
            emp.setEmpSal(rs.getInt("emp_sal"));
            emp.setManager(rs.getString("manager"));
            emps.add(emp);
        }       
        return emps;
    }
    private Connection getConnection()throws Exception
    {
        Connection connection = null;
         try
            {
                Class.forName("org.gjt.mm.mysql.Driver").newInstance();
            }
            catch (Exception e)
            {
                throw e;
            }

            try
            {
                connection = DriverManager.getConnection(
                  "jdbc:mysql://localhost/" + "empdb", "root","");
            }
            catch (SQLException sqlException)
            {
                throw sqlException;
            }       
        return connection;       
    }
    public static void main(String[] args)
    {
        // create and publish an endpoint
        SimpleEmployeeService empService = new SimpleEmployeeService();
        Endpoint endpoint = Endpoint.publish("http://localhost:8080/employee", empService);
    }

}

Create a directory called generated and run apt (Annotation Processing Tool):

apt -cp .;mysql.jar -d generated com\adobe\services\EmployeeService.java
Run your class: java -cp generated;mysql.jar com.adobe.services.EmployeeService


That's it, you have a web server running on localhost:8080 and you can access the WSDL by navigating to http://localhost:8080/employee?wsdl



Now the FlashBuilder will do the rest.




  1. Create a new Flex Project, type in a project name and hit Finish.


  2. In the bottom part of Flash Builder, choose the Data/Services tab and click on "Connect to Data/Service".


  3. Pick Web Service, hit Next.


  4. Paste the WSDL URL http://localhost:8080/employee?wsdl as the "WSDL URI" and hit Finish.


  5. Flash Builder 4 will verify the WSDL and show you a list of operations you can select. Hit Finish.



The Flex code is as shown below. You can generate this with just few clicks in the Flash Builder.



<?xml version="1.0" encoding="utf-8"?>

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo"


    minWidth="1024" minHeight="768" xmlns:employee="services.employee.*" xmlns:valueObjects="valueObjects.*">


    <fx:Script>


     <![CDATA[


            import mx.events.FlexEvent;


            import mx.controls.Alert;


            import spark.events.IndexChangeEvent;


            protected function list_creationCompleteHandler(event:FlexEvent):void


            {


                getAllEmployeesResult.token = employee.getAllEmployees();


                getAllEmployeesResult2.token = employee.getAllEmployees();


            }


            protected function list_changeHandler(event:IndexChangeEvent):void


            {


                simpleEmployee = list.selectedItem as SimpleEmployee;


            }


            protected function button_clickHandler(event:MouseEvent):void


            { 
                addEmployeeResult.token = employee.addEmployee(simpleEmployee);


            }


            protected function button2_clickHandler(event:MouseEvent):void


            {


                updateEmployeeResult.token = employee.updateEmployee(simpleEmployee);


            }


            protected function button3_clickHandler(event:MouseEvent):void


            {


                deleteEmployeeResult.token = employee.deleteEmployee(simpleEmployee);


            }


            protected function button4_clickHandler(event:MouseEvent):void


            {


                list_creationCompleteHandler(null);


            }


        ]]>


    </fx:Script>


    <fx:Declarations>


        <s:CallResponder id="getAllEmployeesResult"/>


        <employee:Employee id="employee" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>


        <s:CallResponder id="getAllEmployeesResult2"/>


        <valueObjects:SimpleEmployee id="simpleEmployee" empId="{parseInt(empIdTextInput.text)}" empSal="{parseInt(empSalTextInput.text)}"/>


        <s:CallResponder id="addEmployeeResult" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="updateEmployeeResult" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="updateEmployeeResult2" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="deleteEmployeeResult" result="list_creationCompleteHandler(null)"/>


        <s:CallResponder id="getEmployeeResult"/>


    </fx:Declarations>


    <s:Panel title="Employees" x="61" y="78" width="124" height="387">


        <s:List id="list" x="0" y="10" width="100%" height="100%" borderVisible="false" creationComplete="list_creationCompleteHandler(event)" dataProvider="{getAllEmployeesResult2.lastResult}" labelField="empName" change="list_changeHandler(event)"></s:List>


    </s:Panel>


    <s:Panel title="Employee Info" x="193" y="78" width="379" height="387">


        <mx:Form x="0" y="10" width="377" height="300">


            <mx:FormItem label="Dept">


                <s:TextInput id="deptTextInput" text="@{simpleEmployee.dept}"/>


            </mx:FormItem>


            <mx:FormItem label="EmpId">


                <s:TextInput id="empIdTextInput" text="{simpleEmployee.empId}"/>


            </mx:FormItem>


            <mx:FormItem label="EmpName">


                <s:TextInput id="empNameTextInput" text="@{simpleEmployee.empName}"/>


            </mx:FormItem>


            <mx:FormItem label="EmpSal">


                <s:TextInput id="empSalTextInput" text="{simpleEmployee.empSal}"/>


            </mx:FormItem>


            <mx:FormItem label="Manager">


                <s:TextInput id="managerTextInput" text="@{simpleEmployee.manager}"/>


            </mx:FormItem>


        </mx:Form>


        <s:HGroup x="66" y="309" height="46" verticalAlign="middle" contentBackgroundColor="#938F8F">


            <s:Button label="Add" id="button"   click="button_clickHandler(event)"/>


            <s:Button label="Update" id="button2"  click="button2_clickHandler(event)"/>


            <s:Button label="Delete" id="button3"  click="button3_clickHandler(event)"/>


            <s:Button label="Get" id="button4"   click="button4_clickHandler(event)"/>


        </s:HGroup>


    </s:Panel>


</s:Application>

Data Centric Development with Flex, PHP and Flash Builder 4

Data Centric development is made simple with Flash Builder 4. If you have a PHP class, Flash Builder 4 allows you to create a Flex front end for it with just few clicks.


Create a table employee in your Mysql database as shown below


CREATE TABLE `employee` (
  `emp_id` int(11) NOT NULL AUTO_INCREMENT,
  `emp_name` varchar(50) NOT NULL,
  `dept` varchar(50) NOT NULL,
  `emp_sal` int(11) NOT NULL,
  `manager` varchar(50) NOT NULL,
  PRIMARY KEY (`emp_id`)
)

The Employee Pojo  and the Employee Service is as shown below.

Employee.php

<?php

class Employee
{
    public $empId;
    public $empName;
    public $dept;
    public $empSal;
    public $manager;
}

?>

EmployeeService.php

<?php
include_once 'Employee.php';
class EmployeeService {

    private $connection;

    private function connect()
        {
             $connection = mysql_connect("localhost:3306",  "root",  "") or die(mysql_error());
             mysql_select_db("empdb", $connection) or die(mysql_error());
    }

    public function getAllEmployees()
    {       
          $response = array();
          $this->connect();
          $sql = "SELECT * FROM employee";
          $result = mysql_query($sql) or die('Query failed: ' . mysql_error());
            $counter = 0;
            $resultObj = null;
            if($result)
            {
                while(($row = mysql_fetch_assoc($result)))
                {
                    $resultObj = $this->createEmployeeObject($row);
                    if($resultObj != null)
                    {
                        $response[$counter] = $resultObj;
                        $counter++;                   
                    }
                }
            }
          return $response;
    }
    private function createEmployeeObject($row)
    {
        $empObj = null;
        if($row)
        {
            $empObj = new Customer();
            $empObj->empId = intval($row["emp_id"]);
            $empObj->empName = $row["emp_name"];
            $empObj->dept = $row["dept"];
            $empObj->empSal = $row["emp_sal"];
            $empObj->manager = $row["manager"];
        }
        return $empObj;
    }
}

?>

Follow the following Steps for creating the Flex Project with the Flash Builder 4.

In this screen:

  1. Set the project name to “DCDFlex”

  2. Set the Application type to “web (run in Adobe Flash Player)”

  3. Set the Application server type to “PHP”

  4. Click next to continue.

  5. In the Next screen, set the Web root to the root folder of your PHP server. Its c:\wamp\www in this sample

  6. Set the Root URL to the root URL of your PHP server. Its http://localhost in this sample

  7. Leave the Output folder to default value

  8. Click the “Validate Configuration” to validate the server details entered

  9. Click on finish to continue.

  10. Once the project is created, to create a service, Select the Data/Services window. If this is not visible, select it from Window -> Data/Services

  11. Click on “Connect to Data/Service” in the Data/Services window

  12. Since we want to communicate with the PHP we created, select PHP and click on next button.

  13. Browse and select the PHP file to use. Make sure the PHP file is deployed in your web application

  14. Click on next button to continue.

You will see a window displayed, saying Zend AMF library will be installed. Just click on OK and continue will the set up. Flash Builder will deploy the Zend AMF on your PHP server.Once the installation completes, Flash Builder will display a message. Clicking OK will display the functions in the PHP class. PHP class functions are referred as “operation”.Click on finish to continue. Service created above can be seen in the services explorer. 

Configuring Return Type

In this step we will test the operation and configure the return type on the client i.e. we will specify what type of object to create with the response from the server. This will make it easy for us to develop, since it is easier to deal with strong typed objects.

Right click on the “getAllEmployees” operation in the services explorer and select “Configure return type” A window will be launched with options to configure the return type. You can chose an existing data type or let the Flash Builder generate VO classes based on the response from the server. Let’s leave it to the Flash Builder to generate required VO classes based on the server response. Click next to continue. You can see the response from the server in the window. Flash Builder introspected the Employee object returned from the server. Just click on finish. You can see the return type of the operation changed. When we invoke the “getAllEmployees” operation, response will be object of the type “Customer”, in our case ArrayCollection containing Employee objects.

Displaying or binding service results in UI controls

We usually write code to display the response from the service in a DataGrid or any other control. Flash Builder 4 has an awesome option which allows you to just bind a service response to a control.

  1. Switch to design view

  2. Change the Application layout to “vertical” using the properties panel

  3. Drag and drop a “DataGrid” from the “components” panel on to the design area

  4. Set the width and height properties of the “DataGrid” to 100%

Right click on the DataGrid and select “Bind to Data …”. A window will be opened.

  1. We select a “New service call” because there are no existing services in the current application.

  2. Select the “EmployeeService”

  3. Select “getAllEmployees():Employee[]” from the operations list

  4. Click OK

You can see the DataGrid in the design updated with properties of the Employee object. That’s all about it. We are done, and a DCD Flex application is ready with PHP as the backend in just a few minutes.

The Flex code is as below for your reference

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768" xmlns:employeeservice="services.employeeservice.*">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;
            import mx.controls.Alert;

            protected function dataGrid_creationCompleteHandler(event:FlexEvent):void
            {
                getAllEmployeesResult.token = employeeService.getAllEmployees();
            }

        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:CallResponder id="getAllEmployeesResult"/>
        <employeeservice:EmployeeService id="employeeService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <mx:DataGrid width="100%" height="100%" id="dataGrid" creationComplete="dataGrid_creationCompleteHandler(event)" dataProvider="{getAllEmployeesResult.lastResult}">
        <mx:columns>
            <mx:DataGridColumn headerText="empName" dataField="empName"/>
            <mx:DataGridColumn headerText="manager" dataField="manager"/>
            <mx:DataGridColumn headerText="empSal" dataField="empSal"/>
            <mx:DataGridColumn headerText="empId" dataField="empId"/>
            <mx:DataGridColumn headerText="dept" dataField="dept"/>
        </mx:columns>
    </mx:DataGrid>
</s:Application>