Friday, April 27, 2012

How to get Width and Height in Android Density Pixel (DP)

Android recommends to use Density-independent Pixel (dp) instead of Pixels in order to scale views based on the current screen density. In order to get the width and height of the android in "dp" units, you can use the following code.

.
.
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
	
float density  = getResources().getDisplayMetrics().density;
float dpHeight = outMetrics.heightPixels / density;
float dpWidth  = outMetrics.widthPixels / density;
.
.


This code is independent of the container view and could be used to calculate screen size and draw custom user interface.

Tuesday, February 14, 2012

Deploy SQLite Database on Android

Android provides full support for SQLite databases. However, Android recommends that you create the database tables along with any pre-populated data when you first run your application. This method may not be very desirable because the developer has to write a huge number of SQL statements using Java strings, which is time consuming and prone to errors. To avoid this complexity, there are some solutions that ship a SQLite database file with application and then copy this file on Android data path. This solution is not very safe because there may be incompatibility issues between the packaged SQLite database and Android. Therefore there should be some easy way to ship complex tables along with data in Android applications. Or better yet, Android should be able to download and install the database, thereby reducing the application size drastically.

Welcome to SQLiteDBDeploy!!! SQLiteDBDeploy is an easy to use utility to deploy SQLite databases without any compatibility issues. The main idea is you design and develop your database and once you are done, you create a dump file of the database. This dump file is compressed to reduce its size and is either packaged with application or hosted on a website. This compressed dump file is then deployed on Android using SQLiteDBDeploy utility class.

For demonstration purposes, I will now deploy NorthWind database and use it in my Android application. Before you try this tutorial, please download SQLite shell from http://www.sqlite.org/download.html

Step 1
Create a SQLite database using SQLite database browser or sqlite3 command line shell. You can create complex tables and insert as much data as you wish. If you already have a database on Android and wish to use it, then pull this database using adb utility. For example, to pull database "northwind.db" in my package "com.ingeniouscamel.droid.mydbapp", I would issue the following command.
$ adb pull /data/data/com.ingeniouscamel.droid.mydbapp/databases/northwind.db 

Step 2
Once you have the database on your local file system, create a dump file using the sqlite3 command-line shell as follows:

sqlite3 <your sqlite database file that you wish to deploy> .dump > <dump file name>
$ sqlite3 northwind.dp .dump > northwind.dmp

Step 3
Compress the dump file using any zip utility. Do NOT password protect the file.
$ zip northwind.zip northwing.dmp
  adding: northwind.dmp (172 bytes security) (deflated 59%)

Step 4
If you wish to package this dump file in your application, then copy the file to assets folder under your Android project in eclipse and continue to step 5.
$ cp northwind.zip /projects/MyDBApp/assets/.  

Another packaging method is to directly access the dump file from a remote web server. There are several pros and cons for this method. First of all your application size is small, because you are not including the dump file in your application. Second, you can release upgrades or new versions of databases without reinstalling the application. However, the database is not safe because the dump file is not encrypted and anyone can access it over the internet. However, you can make this operation safer by employing encryption and authentication.

I have uploaded my sample northwind dump file to google source control server and could be accessed by using the following URL.

http://ingenious-camel.googlecode.com/svn/trunk/SQLiteDBDeployer/assets/northwind.zip

Don’t forget to grant Internet permission to your android application. In file AndroidManifest.xml, add the following line:
.
.

.
.

Step 5
Deploy the compressed dump file in your Android application using the SQLite deploy utility class. Download the Java source code for this utility class from here and copy it under src folder of your Android eclipse project. Depending on where you have the compressed dump file, call the deploy function on your database helper's OnCreate event as follows:

To deploy a packaged dump file in your application, call function deploy in class SQLiteDBDeploy using context, SQLiteDatabase and filename parameters.
.
.
 @Override
 public void onCreate(SQLiteDatabase sqlLiteDb) {
  SQLiteDBDeploy.deploy(this.context, sqlLiteDb, "northwind.zip");
 }
.
.

To deploy a dump file on a remote web server, call function deploy in class SQLiteDBDeploy using SQLiteDatabase and dump file URL parameters.
.
.
 @Override
 public void onCreate(SQLiteDatabase sqlLiteDb) {
  SQLiteDBDeploy.deploy(sqlLiteDb, "http://ingenious-camel.googlecode.com/svn/trunk/SQLiteDBDeployer/assets/northwind.zip");
 }
.
.

That is it. You are all set. Now, when you run the application for the first time, SQLiteDBDeploy utility will load the compressed dump file and run SQL statements to recreate the database. You can see the running SQL statements in eclipse's LogCat.

You can download my sample Android application that loads packaged dump file from here. This Android application displays shippers from northwind database.

Monday, January 9, 2012

How to use JBoss Transactions in Spring

JBoss transactions could used in a Spring application for various reasons. Here are some scenarios:

1. Your standalone Spring application uses multiple resources and you would like to make multiple phase transaction commits
2. Your are using Hibernate or some other DAO framework to access multiple databases in your Spring application and this application is being deployed in Tomcat or some other servlet/JSP container where you need a transaction manager
3. You just need a JTA transaction provider in Spring for some other framework or library such as JBoss's Infinispan

Step 1
Download JBossTM or add dependency to your maven project as follows.
.
.
<dependency>
  <groupId>org.jboss.jbossts</groupId>
  <artifactId>jbossjta</artifactId>
  <version>4.16.0.Final</version>
</dependency>
.
.

If this is a web application, you must remove servlet jar from the dependency as follows:
.
.
<dependency>
  <groupId>org.jboss.jbossts</groupId>
  <artifactId>jbossjta</artifactId>
  <version>4.16.0.Final</version>
   <exclusions>
     <exclusion>
       <artifactId>jboss-servlet-api_3.0_spec</artifactId>
       <groupId>org.jboss.spec.javax.servlet</groupId>
     </exclusion>
   </exclusions>
</dependency>
.
.

Step 2
JBossTM could be configured for timeout and transaction object store folders. These settings could be done via setting system variables in Java command.
.
.
java -Dcom.arjuna.ats.arjuna.coordinator.defaultTimeout=60 
-Dcom.arjuna.ats.arjuna.objectstore.objectStoreDir=/tmp/jbosstm/tx/a 
-DObjectStoreEnvironmentBean.objectStoreDir=/tmp/jbosstm/tx/a ...
.
.

Or through Spring's system properties in application context file.

.
.
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" id="systemPrereqs">
  
  
  
  
    60
    /tmp/jbosstm/tx/a
    /tmp/jbosstm/tx/a 
       
  

</bean>
.
.

Step 3
Configure JBoss's Transaction Manager and User Transaction beans in Spring's application context as follows.
.
.
  
  
.

After this step, JBoss TM is up and running. If you like, you can use the transaction manager using the usual JNDI lookup.

Step 4
Finally, use JBossTM beans to configure Spring JTA transaction manager bean as follows.
.
.

  
    
  
  
    
  

.

This JTA transaction manager could now be used in your session factories or simply enable annotated driver transaction for auto injection.
.
.
<tx:annotation-driven></tx:annotation-driven>
.

Download Project
You can download my project from google code. SVN URL is http://ingenious-camel.googlecode.com/svn/trunk/SpringJBossTx

Sunday, August 14, 2011

Rendering a Java Map using JSF DataTable

Recently, I had a requirement to render a java map using JSF datatable. Since the map was modified by several threads at the same time, I decided to use ConcurrentMap. When it came to rendering this map, I did a quick google to find out what kind of strategy developers were using to render a java map.

I found out that many developers were rendering a java map using two calls. First, they would return the map itself and then they would return a list of keys using a list. Here is a sample bean source code.

.
.
public Map<String,Employee> getManagers() {
   return managerService.getManagers();
}
public List<String> getRegions() {
   List<String> regions = new ArrayList<String>();
   regions.addAll(managerService.getManagers().keySet());
   return regions;
}
.
.

And the corresponding JSF script.
.
.
<rich:dataTable value="#{managerBean.regions}" var="region" >
   <rich:column>
      <h:outputText value="#{managerBean.managers[region].id}"/>
   </rich:column>
</rich:dataTable>
.
.
The problem with this strategy is that if the map changes after I read the keys (using getRegions()) then I may get an error because the key/value pair may not exist in the map.

Moreover, I wanted the bean to return all the map key/value pairs in a single call. After doing a little research on DataTable and good old java collections library, I came up with this strategy and it works great. The trick is to return a list consisting of map's entry objects that will hold the key/value pair. Here is the sample code:

.
.
public List<Map.Entry<String, Employee>> getManagers() {
   Set<Map.Entry<String, Employee>> managerSet = managerService.getAllManagers().entrySet();
   return new ArrayList<Map.Entry<String, Employee>>(managerSet);
  }
.
.

The corresponding JSF script uses this map entry object to get both the key as well as the value object. This value object can then be used to get the POJO member variables.

.
.
<h:dataTable value="#{managerBean.managers}" var="managerEntry">
  <h:column>
    <h:outputText value="#{managerEntry.key}" />
  </h:column>
 
  <h:column>
    <h:outputText value="#{managerEntry.value.id}" />
  </h:column>
.
.

Download Project
You can download my project from google code. SVN URL is http://ingenious-camel.googlecode.com/svn/trunk/JSFRenderMapDataTable

Tuesday, May 10, 2011

Spring web services using Apache CXF

This blog illustrates how to configure and develop a web service and client using Apache CXF.

Step 1
Download and Install JDK 1.6, Maven and your favorite web application container(tomcat,jboss,glassfish).

Step 2
Create a maven application with archetype "maven-archetype-webapp". Ask Google if you need help running this archetype.

Step 3
Add maven repository for JBoss and dependencies for junit and Apache CXF.

pom.xml
        .
        .
    <repositories>
        <repository>
            <id>jboss-public-repository-group</id>
            <name>JBoss Public Maven Repository Group</name>
            <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>
    </repositories>

    <properties>
        <cxf.version>2.4.0</cxf.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>
    </dependencies>
        .
        .

Step 4
Develop the webservice interface and class using JAX-WS annotations.

CalculatorService.java
@WebService
public interface CalculatorService {
    double addNumbers(double a, double b);

    double subtractNumbers(double a, double b);
}

CalculatorServiceImpl.java
@WebService(endpointInterface = "com.ingeniouscamel.springcxfws.service.CalculatorService", 
                        serviceName = "calculatorService")
public class CalculatorServiceImpl implements CalculatorService {
    public double addNumbers(double a, double b) {
        return a + b;
    }

    public double subtractNumbers(double a, double b) {
        return a - b;
    }
}

Step 5
Configure spring context loader and Apache's CXF Servlet in web.xml.

web.xml
       .
       .
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>cxfws-servlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cxfws-servlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>
       .
       .

Step 6
Configure calculator service endpoint in spring's context by specifying service class and URL.

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://cxf.apache.org/jaxws 
        http://cxf.apache.org/schemas/jaxws.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
    
    <jaxws:endpoint id="calculatorService"
        implementor="com.ingeniouscamel.springcxfws.service.CalculatorServiceImpl"
        address="/calculator"/>
</beans>

Step 7
Run the application in your webapp container and test it using the following URL

http://localhost:<Port>/<WebAppContext>/services/calculator?WSDL



Step 8
Configure Apache CXF's JaxWsProxyFactoryBean class to return a service interface to our webservice and call methods on the web service directly.

CalculatorWebServiceClientTest.java
public class CalculatorWebServiceClientTest {
    private CalculatorService calculatorWebService;

    @Before
    public void setUp() throws Exception {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(CalculatorService.class);
        factory.setAddress("http://localhost:8080/SpringCxfWSApp/services/calculator");
        calculatorWebService = (CalculatorService) factory.create();
    }

    @Test
    public void testAddNumbers() {
        Assert.isTrue(calculatorWebService.addNumbers(3, 5) == 8);
    }

    @Test
    public void testSubtractNumbers() {
        Assert.isTrue(calculatorWebService.subtractNumbers(7, 4) == 3);
    }
}

Download Project
You can download my project from google code. SVN URL is http://ingenious-camel.googlecode.com/svn/trunk/SpringCxfWSApp/

Wednesday, May 4, 2011

Spring web services using JAX-WS

This blog illustrates how to configure and develop a JAX-WS server and client using spring framework.

Step 1
Download and Install JDK 1.6, Maven and your favorite web application container(tomcat,jboss,glassfish).

Step 2
Create a maven application with archetype "maven-archetype-webapp". Ask Google if you need help running this archetype.

Step 3
Add maven repository for JBoss and dependencies for junit, spring, jaxb, and jvnet's jaxws-spring. Since spring is already configured exclude spring from jvnet.

pom.xml
    .
    .
    <repositories>
        <repository>
            <id>jboss</id>
            <name>JBoss Maven Repository</name>
            <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        </repository>
    </repositories>

    <properties>
        <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
           <groupId>com.sun.xml.bind</groupId>
           <artifactId>jaxb-impl</artifactId>
           <version>2.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.jvnet.jax-ws-commons.spring</groupId>
            <artifactId>jaxws-spring</artifactId>
            <version>1.8</version>
            <exclusions>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
    .
    .

Step 4
Develop the webservice class using JAX-WS annotations

CalculatorServiceImpl.java
@WebService
@SOAPBinding(style = Style.RPC, use = Use.LITERAL)
public class CalculatorServiceImpl implements CalculatorService {
    public double addNumbers(double a, double b) {
        return a + b;
    }

    public double subtractNumbers(double a, double b) {
        return a - b;
    }
}

Step 5
Configure spring context loader and jvnet's WSSpringServlet in web.xml.

web.xml
    .
    .
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
    <servlet-name>jaxws-servlet</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>jaxws-servlet</servlet-name>
    <url-pattern>/calculator</url-pattern>
</servlet-mapping>
    .
    .
Step 6   
Configure calculator service as a bean in spring's context. Next, add this service to the web URL that we configured earlier in web.xml.

applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:ws="http://jax-ws.dev.java.net/spring/core" xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://jax-ws.dev.java.net/spring/core  http://jax-ws.dev.java.net/spring/core.xsd
         http://jax-ws.dev.java.net/spring/servlet http://jax-ws.dev.java.net/spring/servlet.xsd">

    <bean id="calculatorService"
        class="com.ingeniouscamel.springjaxws.service.CalculatorServiceImpl" />

    <wss:binding url="/calculator">
        <wss:service>
            <ws:service bean="#calculatorService" />
        </wss:service>
    </wss:binding>
</beans>

Step 7
Run the application in your webapp container and test it using the following URL

http://localhost:<Port>/<WebAppContext>/calculator?WSDL



Step 8
In order to develop a client, first develop a webservice client interface. You can cheat this step by running wsimport command on the WSDL and using the generated source file.

CalculatorServiceImpl.java
@WebService(name = "CalculatorServiceImpl", targetNamespace = "http://service.springjaxws.ingeniouscamel.com/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface CalculatorServiceImpl {
    @WebMethod
    @WebResult(partName = "return")
    public double addNumbers(
            @WebParam(name = "arg0", partName = "arg0") double arg0,
            @WebParam(name = "arg1", partName = "arg1") double arg1);

    @WebMethod
    @WebResult(partName = "return")
    public double subtractNumbers(
            @WebParam(name = "arg0", partName = "arg0") double arg0,
            @WebParam(name = "arg1", partName = "arg1") double arg1);
}

Step 9
Configure client's spring context to bind the above interface to the web service using spring's JaxWsPortProxyFactoryBean bean (you will find this file in src/main/resources folder of my project).

applicationClientContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"    
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <bean id="calculatorWebService" class="org.springframework.remoting.jaxws.JaxWsPortProxyFactoryBean">
        <property name="serviceInterface" value="com.ingeniouscamel.springjaxws.client.CalculatorServiceImpl"/>
        <property name="wsdlDocumentUrl" value="http://localhost:8080/SpringJaxWSApp/calculator?WSDL"/>
        <property name="namespaceUri" value="http://service.springjaxws.ingeniouscamel.com/"/>
        <property name="serviceName" value="CalculatorServiceImplService"/>
        <property name="portName" value="CalculatorServiceImplPort"/>
    </bean>    
</beans>

Step 10
You can now load the above client's context (applicationClientContext.xml) and call methods on the web service client directly.

CalculatorWebServiceClientTest.java
public class CalculatorWebServiceClientTest {
    private CalculatorServiceImpl calculatorWebService;

    @Before
    public void setUp() throws Exception {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationClientContext.xml");
        calculatorWebService = (CalculatorServiceImpl)context.getBean("calculatorWebService");
    }

    @Test
    public void testAddNumbers() {
        Assert.isTrue(calculatorWebService.addNumbers(3, 5) == 8);
    }

    @Test
    public void testSubtractNumbers() {
        Assert.isTrue(calculatorWebService.subtractNumbers(7, 4) == 3);
    }
}

Download Project
You can download my project from google code. SVN URL is http://ingenious-camel.googlecode.com/svn/trunk/SpringJaxWSApp/

Monday, May 2, 2011

JSF Part 2: Navigation and Ajax

This blog illustrates how to develop page navigation including simple ajax functionality. We shall use the project from JSF Part 1 tutorial.

Step 1
Develop DeptService and DeptBean classes that return list of all departments

DeptService.java
public class DeptService {
    public List<String> getAllDepts() {
        ....
    }
}

DeptBean.java
@ManagedBean
public class DeptBean {
    private DeptService deptService = new DeptService();

    public List<String> getAllDepts() {
        return deptService.getAllDepts();
    }
}

Step 2
Develop EmployeeBean and set up selectedDept variable that will hold the value of selected department name

EmployeeBean.java
@ManagedBean
public class EmployeeBean {
    private String selectedDept;
  
    public String getSelectedDept() {
        return selectedDept;
    }

    public void setSelectedDept(String selectedDept) {
        this.selectedDept = selectedDept;
    }
}

Step 3
Develop index.xhtml that displays list of departments and allows user to select a department

index.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.prime.com.tr/ui">

<h:head>
    <title>Departments</title>
</h:head>
<h:body>
    <h:form prependId="false">
        <p:panel header="Search By Dept"> Select Dept :
            <h:selectOneMenu value="#{employeeBean.selectedDept}">
                <f:selectItems value="#{deptBean.allDepts}" />
            </h:selectOneMenu>          
        </p:panel>
    </h:form>
</h:body>
</html>

Step 4
Run the application in your webapp container and test it using the following URL

http://localhost:<Port>/<WebAppContext>/faces/index.xhtml



Step 5
Now that "selectedDept" variable is set, lets invoke a function on EmployeeBean.java to perform search. Add a commandButton after selectOneMenu in index.xhtml that will invoke function "performSearch"

index.html
                .
                .              
            </h:selectOneMenu>         
            <p:commandButton action="#{employeeBean.performSearch}" value="Search" ajax="false"/>         
        </p:panel>
             .
             .

Step 6
Add functionality to EmployeeBean.java and EmployeeService.java that will  search employees based on  selectedDept and cache results in searchResults variable 

EmployeeBean.java
public class EmployeeBean {
    .
    .
    private List<Employee> searchResults;

    public List<Employee> getSearchResults() {
        return searchResults;
    }

    public String performSearch() {
        if (selectedDept.equals("All")  ) {
            searchResults = employeeService.getAllEmployees();
        } else {
            searchResults = employeeService.getEmployeesByDept(selectedDept);
        }
        return "results";
    }
    .
    .
}

EmployeeService.java
public class EmployeeService {
    .
    .
    public List<Employee> getEmployeesByDept(String dept) {
        List<Employee> list = new ArrayList<Employee>();
        for (Employee e : employees) {
            if (e.getDept().equals(dept)) {
                list.add(e);
            }
        }
        return list;
    }
    .
    .
}

Step 7
Configure page navigation in /WEB-INF/faces-config.xml. The xml stanza says "from page index.xhtml, if function employeeBean.performSearch returns "results", then display view results.xhtml

faces-config.xml
<?xml version="1.0"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
    <navigation-rule>
        <from-view-id>/index.xhtml</from-view-id>
        <navigation-case>
            <from-action>#{employeeBean.performSearch}</from-action>
            <from-outcome>results</from-outcome>
            <to-view-id>/results.xhtml</to-view-id>
        </navigation-case>
    </navigation-rule>
</faces-config>

Step 8
Finally, render the list in dataTable

results.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.prime.com.tr/ui">

<h:head>
    <title>Employees</title>
</h:head>
<h:body>
    <h:form prependId="false">
        <p:dataTable value="#{employeeBean.searchResults}" var="emp">
            <f:facet name="header">
                <h:outputText value="Employees search results for " />
                <h:outputText value="#{employeeBean.selectedDept}" />
                <h:outputText value=" Dept" />
            </f:facet>
            <p:column>
                <f:facet name="header">
                    <h:outputText value="Id" />
                </f:facet>
                <h:outputText value="#{emp.id}" />
            </p:column>
            <p:column>
                <f:facet name="header">
                    <h:outputText value="Name" />
                </f:facet>
                <h:outputText value="#{emp.name}" />
            </p:column>
            <p:column>
                <f:facet name="header">
                    <h:outputText value="Dept" />
                </f:facet>
                <h:outputText value="#{emp.dept}" />
            </p:column>
        </p:dataTable>
    </h:form>
</h:body>
</html>

Step 9
Run the application in your webapp container and test it using the following URL

http://localhost:<Port>/<WebAppContext>/faces/index.xhtml


Select a department and hit "Search" button.


Step 10
Instead of two page navigation, all components could be placed in one page and the dataTable could be refreshed using Ajax. This is accomplished by adding update attribute to commandButton which will refresh "empTable" component after setting selectedDept in AjaxEmployeeBean.

ajax.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.prime.com.tr/ui">

<h:head>
    <title>Employees</title>
</h:head>
<h:body>
    <h:form prependId="false">
        <p:panel header="Search By Dept"> Select Country :
            <h:selectOneMenu value="#{ajaxEmployeeBean.selectedDept}">
                <f:selectItems value="#{deptBean.allDepts}" />
            </h:selectOneMenu>

            <p:commandButton action="#{ajaxEmployeeBean.performSearch}" value="Search" update="empTable" />

            <p:dataTable id="empTable" value="#{ajaxEmployeeBean.searchResults}" var="emp">
                <f:facet name="header">
                    <h:outputText value="Employees search results for " />
                    <h:outputText value="#{ajaxEmployeeBean.selectedDept}" />
                    <h:outputText value=" Dept" />
                </f:facet>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Id" />
                    </f:facet>
                    <h:outputText value="#{emp.id}" />
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Name" />
                    </f:facet>
                    <h:outputText value="#{emp.name}" />
                </p:column>
                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Dept" />
                    </f:facet>
                    <h:outputText value="#{emp.dept}" />
                </p:column>
            </p:dataTable>
        </p:panel>
    </h:form>
</h:body>
</html>

Step 11
Since this ajax page has no navigation, the performSearch method should return null. Class EmployeeBean could be rewritten as AjaxEmployeeBean, with function performSearch returning null.

AjaxEmployeeBean.java
@ManagedBean
public class AjaxEmployeeBean {
    private EmployeeService employeeService = new EmployeeService();

    private String selectedDept;
    private List<Employee> searchResults;

    public String getSelectedDept() {
        return selectedDept;
    }

    public void setSelectedDept(String selectedDept) {
        this.selectedDept = selectedDept;
    }

    public List<Employee> getSearchResults() {
        return searchResults;
    }    
    
    public String performSearch() {
        if (selectedDept.equals("All")  ) {
            searchResults = employeeService.getAllEmployees();
        } else {
            searchResults = employeeService.getEmployeesByDept(selectedDept);
        }
        return null;
    }
}

Step 12
Run the application in your webapp container and test it using the following URL

http://localhost:<Port>/<WebAppContext>/faces/ajax.xhtml


Download Project
You can download my project from google code. SVN URL is http://ingenious-camel.googlecode.com/svn/trunk/JSF2NavigationAjax/