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>

Sunday, December 13, 2009

URL Shortening Service : Flex Client & Google App Engine

I Tried this simple URL shortening Service Using Flex, Java and Google App Engine. This turned out to be very simple. I will post the client and the Server Code. Write in comments if you have any questions.


TinyUrl.mxml.

<?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">
    <s:layout>
        <s:TileLayout/>
    </s:layout>
    <fx:Script>
        <![CDATA[
            protected function button1_clickHandler(event:MouseEvent):void
            {
                sm.url = "http://localhost:8888/s/"+srcUrl.text;
                sm.send();
            }
        ]]>
    </fx:Script>
    <fx:Declarations>
        <mx:HTTPService id="sm"  useProxy="false"
                        method="GET" result="{shortUrl.text = sm.lastResult.toString()}">
        </mx:HTTPService>
    </fx:Declarations>
    <mx:VBox verticalAlign="middle" paddingLeft="20">
        <mx:Label text="URL Shortening Service"  fontStyle="normal" fontWeight="bold" fontSize="24"/>
        <mx:Label text="Enter Your URL Here" />
        <s:TextArea id="srcUrl" width="588" height="81">
        </s:TextArea>
        <s:Button label="Shorten" click="button1_clickHandler(event)"/>
        <s:Label text="Shortened URL" />
        <s:TextArea id="shortUrl"  width="588" height="73"/>
    </mx:VBox>
</s:Application>

Next the server part. First, persistence is a breeze in Googe AppEngine and hence I used their JDO approach to store it. The class (with the annotation) is as follows:
Mapping.java

package com.apps.tiny;
import javax.jdo.annotations.*;
@PersistenceCapable(identityType = IdentityType.DATASTORE)
public class Mapping {
        @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
        public Long id;
        @Persistent
        public String url;
}

Then comes the MappingManager, the piece that performs the I/O with the Datastore:
MappingManager.java

package com.apps.tiny;
import java.util.*;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
public class MappingManager {
    private static PersistenceManager pm = JDOHelper.getPersistenceManagerFactory("transactions-optional").getPersistenceManager();
    public static Long storeMapping(Mapping mapping) {
    long existingMapping = getMappingByUrl(mapping.url);
    return (existingMapping == -1)?pm.makePersistent(mapping).id:existingMapping;
    }
    public static Long getMappingByUrl(String url) {
    Iterator<Mapping> map = ((List)(pm.newQuery("select from " + Mapping.class.getName() + " where url == '" + url + "'").execute())).iterator();
    return (map == null || !map.hasNext())?-1:map.next().id;
    }
    public static String getLink(String urlId) {
    Iterator<Mapping> map = ((List)(pm.newQuery("select from " + Mapping.class.getName() + " where id == " + Long.valueOf(urlId, 36)).execute())).iterator();
    return (map == null || !map.hasNext())?null:map.next().url;
    }
}

The first method stores the mapping, the second gets a url id based on the url (so that we don't keep bloating our DB with repeated URLs) and the third gets a URL based on the Id. The expression "Long.valueOf(urlId, 36)" converts the url id from Base 36 String to a long.
Then comes the servlet code which converts a URL into a short URL and print it to the user:
TinyUrlServlet.java

package com.apps.tiny;
import java.io.IOException;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class TinyurlServlet extends HttpServlet {
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        Mapping mapping = new Mapping();
        mapping.url = req.getPathInfo().substring(1);
        String response = req.getRequestURL().toString().replaceAll(req.getPathInfo(), "/").replace("/s/", "/r/") + Long.toString(MappingManager.storeMapping(mapping), 36);
        resp.setContentType("text/plain");
        resp.getWriter().println(response);
    }
}

The business logic, or storing the url to db, getting the id, converting to Base 36, constructing the URL and printing it.

Now, the last class which does the real work or taking a short URL and redirecting it to the correct URL stored in the DB:
Redirect.java

package com.apps.tiny;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
@SuppressWarnings("serial")
public class Redirect extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect(MappingManager.getLink(req.getPathInfo().substring(1)));
}
}

The only thing left is the Web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
    <servlet>
        <servlet-name>Tinyurl</servlet-name>
        <servlet-class>com.apps.tiny.TinyurlServlet</servlet-class>
    </servlet>
    <servlet>
        <servlet-name>Redirect</servlet-name>
        <servlet-class>com.apps.tiny.Redirect</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Tinyurl</servlet-name>
        <url-pattern>/s/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>Redirect</servlet-name>
        <url-pattern>/r/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>


Alright, We are all set to go.  You can check the demo here.

Tuesday, December 1, 2009

Using Mock Objects in a Flex Application

The usage of mock objects in a Flex application may represent a very powerful way to improve development speed and increase the quality of the tests you will prepare. A mock object can simulate the  behavior of complex, real (non-mock) objects and are therefore useful when a real object is not yet available (server side development is late!) or when a real object is impractical or impossible to incorporate into a unit test, the Mocker class we¹ll discuss during this session is an easy way to create tons of mock objects with few line of codes and with a predictable behavior. It may be useful to use a mock object in its place:
  • Supplies non-deterministic results (e.g. the current time or the current temperature)
  • Has states that are difficult to create or reproduce (e.g. a network error)
  • Is slow (e.g. a complete database, which would have to be initialized before the test)
  • Does not yet exist or may change behavior;
  • Would have to include information and methods exclusively for testing purposes (and not for its actual task)
Learn how to generate mock objects with the open source solution inspired by mockito! 
 
 
 

Calendar to choose only one week

We can give color to specific dates of the calender. There is a simple way to specify a range of selected dates on the calendar.

You Can specify the range like this.



disabledRanges = "([
  { rangeEnd   : new Date( 2009,10,4 ) }, (RangeEnd: new Date (2009,10,4)), 
  { rangeStart : new Date( 2009,10,10 ) } (RangeStart: new Date (2009,10,10))
]}" ]) " 
 



We can get the today date and calculate the difference using the following formula..
 



 disabledRanges="{[ disabledRanges = "([
  { rangeEnd   : new Date( new Date().getTime() - 1 * 1000 * 60 * 60 * 24 ) }, (RangeEnd: new Date (new Date (). GetTime () - 1 * 1000 * 60 * 60 * 24)),
  { rangeStart : new Date( new Date().getTime() + 7 * 1000 * 60 * 60 * 24 ) } (RangeStart: new Date (new Date (). GetTime () + 7 * 1000 * 60 * 60 * 24))
 ]}" ]) "
/> 

You can use such methods to color holidays in Action Script

View the demo


Simple Animation In Flex, with Flash Player 10

Simple 3d Animation in Flex 4



Perspective Projection

The PerspectiveProjection class provides an easy way to assign or modify the perspective transformations of a display object and all of its children. Once you create a PerspectiveProjection in Flex, you can set the projection to the canvas using the following code. 



/ / Change the perspective 
var pp: PerspectiveProjection = new PerspectiveProjection ();
pp.projectionCenter = new Point( this.width/2 , this.height/2); 
/ / Set the center pp.projectionCenter = new Point (this.width / 2, this.height / 2);
pp.fieldOfView = 1; pp.fieldOfView = 1;
myScene.transform.perspectiveProjection = pp; myScene.transform.perspectiveProjection = pp;
 
More References are here...

Perspective Projection 


Working in 3D with Flash Player 10 / Action Script 3

View the demo