Archive

Posts Tagged ‘primefaces’

Integrating Hibernate Search on PrimeFaces using Google Guice and JBoss Seam

November 14th, 2009 Shrihari No comments

Recently I have been working on an application involving PrimeFaces and required search capabilities directly on the persisted data. Though I can use Hibernate search for implementing search services, the Google Guice, the underlying IoC framework, which PrimeFaces provide does not provide me the out-of-the-box integration. I am extending from my previous blog post which talked about using Google Guice to inject JPA EntityManager. This post builds on the previous post and explores the option of search. Here are the following sequence of steps I followed to ensure PrimeFaces widgets are Hibernate Search compliant:

1)  Follow the steps mentioned to get an EntityManager instance fro m JBoss Seam’s component xml and register in the Google Guice injector using a Provider  implementation. Make a little change where the Provider’s getter method is made static.  Following is the EntityManagerProvider code snippet to do that:

class EntityManagerProvider implements Provider
{       static EntityManagerFactory entityManagerFactory = null;
        public static EntityManager get()
        {   return entityManagerFactory.createEntityManager();
        }
}

2) Implement Guice injection Provider for constructing a FullTextEntityManager from EntityManager

public class FullTextEntityManagerProvider implements Provider
{    static FullTextEntityManager fullTextManager = null;
     private static EntityManager entityManager;

     public static void setEntityManager(EntityManager em)
     {   entityManager = em;
     }

      public FullTextEntityManager get()
      {   if(fullTextManager==null)
             fullTextManager = Search.getFullTextEntityManager(entityManager);
           return fullTextManager;
      }
}

3) Modify the custom module (now refactored as MySearchEntityManagerModule) to construct the FullTextEntityManager using EntityManager instance as shown below.

public class MySearchEntityManagerModule extends AbstractModule
{      public void configure()
       {   Expressions expressions = Expressions.instance();
           ValueExpression emfVE = expressions.createValueExpression("#{my_persistence_unit}");
           EntityManagerFactory emf = (EntityManagerFactory)emfVE.getValue();
           EntityManagerProvider.setEntityManagerFactory(emf);
           FullTextEntityManagerProvider.setEntityManager(provider.get());

            //bind EntityManager and FullTextEntityManager for both pure database and search specific integration
            bind(EntityManager.class).toProvider(EntityManagerProvider.class).in(Scopes.SINGLETON);
            bind(FullTextEntityManager.class).toProvider(FullTextEntityManagerProvider.class).in(Scopes.SINGLETON);
     }
}

3) Inject the FullTextEntityManager in the dataservice (DAO) for searching for text tokens using Hibernate Search.

@Name("hybrid")
@Guice
public class HybridDAO
{  @Inject FullTextEntityManager searchManager;
    //other DAO methods to perform search using Hibernate Search and Lucene
}

This quick tip provides us a capability of enhancing Primefaces widgets to use the power of Hibernate Search for search and much more extensible features.

Playing with Yahoo Maps on PrimeFaces

August 4th, 2009 Shrihari No comments

Yahoo Map services expose REST web-services API which aid the consumer to retreive maps given a locations based on address (street, city, state or zip) or coordinates (longitude, latitude). This cool tip explores an option to render a Yahoo hosted map for a PrimeFaces driven application.

1) Login to Yahoo Developer Network and generate an Yahoo Developer Application ID.

2) Define and implement a PrimeFaces Controller which defines a MapMetadata POJO (containing address based attributes or coordinate based attributes) and defines a method to render the map accordingly.

@Controller(name = "mapController", scope = REQUEST)
public class YahooMapController
{   private String mapURL = new String();
    private boolean showMap = false;
    private MapMetadata map = new MapMetadata();
    //setters and accessors
    public void renderMapByAddress()
    {   StringBuilder query = new StringBuilder();
        String details = map.getStreet();
        query.append((details!=null)?"street=" + details + "&":"");
        details = map.getCity();

        query.append((details!=null)?"city=" + details + "&":"");
        details = map.getState();

        query.append((details!=null)?"state=" + details + "&":"");
        details = map.getZip();

        query.append((details!=null)?"zip=" + details + "&":"");
        details = map.getLatitude();

        query.append((details1!=null)?"latitude=" + details1 + "&":"");
        details = map.getLongitude();

        query.append((details!=null)?"longitude=" + details + "&":"");
       renderMap(query.toString());
    }

    private void renderMap(String query)
    {   if (query.length() > 0)
        {   try {
                query = query.replace(" ", "+");
                String requestquery = "http://local.yahooapis.com/MapsService/V1/mapImage?appid=[my-app-id]" + query;
                HttpClient client = new HttpClient();
                GetMethod method = new GetMethod(requestquery);
                int statusCode = client.executeMethod(method);
                if (statusCode != HttpStatus.SC_OK)
                {   FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERTY_ERROR, "Unable to find map based on details!", "Unable to find map based on details!"));
                    showMap = false;
                    return;
                }
                InputStream rstream = method.getResponseBodyAsStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(rstream));
		String line;
		int i = 0;
		while ((line = br.readLine()) != null)
                {   if (i == 1 && line.contains("Result"))
                    {   mapURL = line.substring(62, line.length() - 9);
                        showMap = true;
                    }
                    i++;
		}
            } catch (IOException ex)
            {   ex.printStackTrace();
            }
        }
    }
}

The REST Get request is being placed using the Apache Commons HTTPClient library. The response from REST Get call is striped to fetch only the URL which displays the actual image of the Map.

3) Define and implement a XHTML page which defines a the view for accepting the location details and a rendering panel which is displayed if the map is successfully retrieved.

<ui:define name="content">
    <h:form>
        <h:messages/>
        <p:panel header="View Map">
          <h:panelGrid columns="2">
             <h:outputLabel value="Street :" for="street"></h:outputLabel>
             <h:inputText id="street" value="#{mapController.map.street}"/>

             <!-- Other input fields with labels accordingly -->

            <h:panelGroup>
             <h:commandButton action="#{mapController.renderMapByAddress}" value="Show Map" />
            </h:panelGroup>
          </h:panelGrid>
        </p:panel>
        <p:panel header="Map" rendered="#{mapController.showMap}">
           <h:panelGrid columns="1">
              <h:graphicImage value="#{mapController.mapURL}"/>
           </h:panelGrid>
        </p:panel>
     </h:form>
 </ui:define>

The graphicImage from JSF HTML taglib displays the URL generated image. One can also use the PrimeFaces dynamicImage Streaming (with StreamedContent)

Categories: jee-light Tags: ,