Archive

Archive for the ‘jee-light’ Category

How to end JBoss Seam conversation in menu links?

November 17th, 2009 Shrihari No comments

Not all the times, we may be interested in using JBoss Seam’s link tag s:link to end conversation scope propagation. This holds good specifically for menu links and random hotkey navigations. One quick tip could be to specify the redirection url link with the parameter conversationPropagation=end.

Categories: jee-light Tags:

How to change authentication success/failure message in JBoss Seam?

November 16th, 2009 Shrihari No comments

If we rely on JBoss Seam’s Security Identity Management for user authentication on a web application, we certainly think of changing the default ‘Welcome <username>’ to something different and catchy. This particular tip explores such a possibility successfully in 2-3 steps:

1)  Assuming that you have defined the security identity and core resource loader components have been defined in WEB-INF/components.xml as below, we have to modify the properties myapplication_en.properties (_en is the default locale)

<security:identity authenticate-method="#{authenticator.authenticate}" remember-me="true"/>
<core:resource-loader bundle-names="myapplication"/>

define your custom message like this, where #0 is a parameter placeholder.

welcome.message=Good to see you, #0
loginfailed.message=Unable to login mate, please check your credentials!

2) Modify your authenticator component to add custom message if login/authentication is successful.

public boolean authenticate()
{  User loggedInUser = authenticationservice.autheticate(credentials.getUsername(), credentials.getPassword());
   FacesMessages messages = FacesMessages.instance();
    if(loggedInUser==null)
    {    messages.addFromResourceBundle("loginfailed.message", null);
         return false;
    }
    messages.addFromResourceBundle("welcome.message", loggedInUser.getFullname());
    return true;
}

Are we done? wait… We need to reset the earlier messages (the default ones)

3) Add two more entries to myapplication_en.properties and set these properties as blank. This would reset the existing default ones.

org.jboss.seam.loginSuccessful=
org.jboss.seam.loginFailed=

Aint it easy and cool!

Categories: jee-light Tags:

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.

Context specific Outjection modes in JBoss Seam

November 13th, 2009 Shrihari No comments

There are 7 types of contexts available in JBoss Seam. In order to outject (make an instantiated/ populated object available to other components participating in the same context) for a particular scope, say CONVERSATION, there are at least 2 ways of outjecting an instance as follows:

1) Declaratively : This could be used when there are component boundaries clearly demarcated and the instance needs to available for a longer running conversation. An example snippet is given below:

@Name("producer")
public class Producer
{   @Out(scope=ScopeType.CONVERSATION)
      private QueueFeed feed;

      //methods to produce and populate the feed
      @Begin public void doStart(){}
      @End public void close(){}
}
@Name("consumer")
public class Consumer
{   @In  private QueueFeed feed;
       //methods to consume and cleanup the feed
}

2) Programmaticaly : This approach is used when one would want place the instance in the already established context, and other seam components just reference the instance and used as given below:

@Name("producer")
public class Producer
{   public void produceIntermediate()
    {   QueueFeed queueFeed;
         //populate queueFeed
        Contexts.getConversationContext().set("queueFeed", queueFeed);
     }
}
@Name("consumer")
public class Consumer
{  public void consumeIntermediate()
    {   QueueFeed queueFeed = (QueueFeed) ( Contexts.getConversationContext().get("queueFeed",));
     }
}

This way one can manage scopes effectively with regard to instance usage across participating components

Categories: jee-light Tags:

Tip: Cached Associations in Hibernate Caching

November 10th, 2009 Shrihari No comments

In cases of deep rooted (entity objects with association chaining with other entity objects), there are N+1 select problem, where the chain of associated entity objects are queried and loaded into Hibernate Session from the database, everytime the master entity is loaded. To solve this problem, one should follow these practices:

1) Define the caching strategy on both the associated entity objects along the association chain.
2) Deactivate the lazy-loading on the association link. One has to be selective in choosing association links for deactivating lazy loading.
3) Define the caching strategy on the association link.

Categories: jee-light Tags: ,

Forking navigations based on user roles in JBoss Seam using Seam-Security

October 14th, 2009 Shrihari No comments

This particular tip on loading different homepages for the role associated for a specific logged in user for a JSF web application written using JBoss Seam and identity management using Seam-Security. This tip assumes that a single user will be associated with a single role.

Assume we need to develop a course management JSF application which supports users of 2 different roles : teacher and student. This means if a user with teacher role logs in teacher specific homepage should come  and student logging in should display student homepage. The following are steps to achieve this requirement.

1) Change WEB-INF/components.xml to include the seam-security authentication patterns

  <components xmlns="http://jboss.com/products/seam/components"
          ....
          xmlns:security="http://jboss.com/products/seam/security"
          xsi:schemaLocation="http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd
                ....
          ">
 ...
 <security:identity authenticate-method="#{authenticator.authenticate}"/>
</components>

2) Define an Authenticator action class with JBoss Seam component name “authenticator” and define an authenticate method inside

@Name("authenticator")
public class AuthenticatorAction
{   @In
    private Identity identity;
    @In(create=true)
    private AuthService service;

    ...
    @SuppressWarnings("deprecated")
    public boolean authenticate()
    {   String username = identity.getUsername();
        String password = identity.getPassword();
        if(username==null || password==null)
           return false;
        //authenticate the user from database
        User user = service.authenticate(username,password);
        // check user validity.
        identity.addRole(user.getRole());
        return true;
    }
}

3) Define the login portal widget in the login-page (say login.xhtml)

<ui:composition xmlns="http://www.w3.org/1999/xhtml">
 .....
   <h:panelGrid columns="2" style="width:27px">
      <h:outputText value="Username: "/>
      <h:inputText id="username" value="#{identity.username}" rows="1" cols="12">
         <f:validateLength minimum="8"  />
      </h:inputText>
      <h:outputText value="Password:" rows="1" cols="12"/>
      <h:inputSecret id="password" value="#{identity.password}" />
   </h:panelGrid>
   <h:commandButton id="login" action="#{identity.login}" value="Login"/>
    ...
 </ui:composition>

4) Wire the action outcomes to set up the navigation paths in WEB-INF/pages.xml

<pages xmlns="http://jboss.com/products/seam/pages"
       ....
       no-conversation-view-id="/index.html">

     <page view-id="/login.xhtml">
        <navigation from-action="#{authenticator.checkLogin}">
           <rule if="#{identity.loggedIn and identity.role=='Teacher'}">
               <redirect view-id="/teacher/homepage.xhtml" />
          </rule>
       </navigation>
       <navigation from-action="#{identity.login}">
           <rule if="#{identity.loggedIn and identity.hasRole('Teacher')}">
              <redirect view-id="/teacher/homepage.xhtml" />
          </rule>
       </navigation>
       <navigation from-action="#{authenticator.checkLogin}">
          <rule if="#{identity.loggedIn and identity.role=='Student'}">
               <redirect view-id="/student/homepage.xhtml" />
          </rule>
       </navigation>
       <navigation from-action="#{identity.login}">
           <rule if="#{identity.loggedIn and identity.hasRole('Student')}">
              <redirect view-id="/student/homepage.xhtml" />
          </rule>
       </navigation>
    </page>
    ....
   <exception>
        <redirect view-id="/index.xhtml">
           <message>Please log in first</message>
        </redirect>
   </exception>
</pages>

You can extend this tip to come out of different other user-role combinations.

Categories: jee-light Tags: ,

Unit testing CXF webservice endpoints using Spring-Test and TestNG

October 9th, 2009 Shrihari No comments

The Spring IOC feature of configurational wiring of POJOs to control and achieve network of business logic frees developers of writing any boilerplate code and eventually of bugs. I would like to explain one such facility with regard to establishing an unit testing infrastructure for writing unit test cases for JAXWS specific web service endpoints (CXF) using Spring-test module and TestNG unit testing framework.

Lets take a simple example of a web service endpoint exposing a functionality to query a book price, given the ISBN number, given a maven project. This write-up just concentrates on establishing a web service unit testing framework. Following are sequence of steps one could follow to achieve the required infrastructure setup.

1) Change ${basedir}/pom.xml include adding spring-test dependency, and TestNG dependency, with maven-surefire-plugin configuration (assuming CXF dependencies are already present)

<dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-test</artifactId>
 <version>2.5.6</version>
 </dependency>
<dependency>
 <groupId>org.testng</groupId>
 <artifactId>testng</artifactId>
 <version>5.9</version>
 <classfier>jdk15</classifier>
 <scope>test</scope>
</dependency>

2) Add a Spring configuration file (service-test.xml) under ${basedir}/src/test/resources. The CXF’s JaxWSProxyFactoryBean can be wired to to create a service proxy. Below is the snippet of the configuration file.

<?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:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"></span></pre>
    <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-extension-http.xml" />

     <!-- Required to load the service endpoint uris -->
     <bean id="propConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
         <property name="locations">
            <list>
               <value>classpath:service-test.properties</value>
             </list>
         </property>
     </bean>

     <bean id="proxyFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
         <property name="serviceClass" value="com.schtech.service.endpoint.store.BookPriceService"/>
         <property name="address" value="${bookstore.service.endpoint.url}"/>
         <property name="bus" ref="cxf" />
    </bean>

     <bean id="serviceClient" class="com.schtech.service.endpoint.store.BookPriceService" factory-bean="proxyFactory"
        factory-method="create"/>
</beans>

3) Implement the TestNG test case to test web service. Here three things have to be noted: (1) ContextConfiguration annotation helps us load
the configuration file. (2) The test case extends AbstractTestNGSpringContextTests to load the context configuration and autowire the service
bean. (3) Autowire annotation on the service endpoint interface initializes with proxy factory created service proxy instance.

@ContextConfiguration(locations = {"classpath:service-context.xml"})
public class BookCatalogTest extends AbstractTestNGSpringContextTests
 { @Autowired
   private BookPriceService serviceClient;

   @Test
   public void testBookPrice()
   { String isbn = "978-3-16-148410-0,";
     Double price  = serviceClient.findBookPrice(isbn);
     assertNotNull(price);
   }
}

The infrastructure is ready to be used to test other service endpoints hosted elsewhere. Running mvn test at the ${basedir} prompt would unit test the service endpoints.

Categories: jee-light Tags: , ,

Creating asynchronous service using Spring JMS (ServiceExporter) and ActiveMQ

October 2nd, 2009 Shrihari No comments

Spring MDPs (Message-Driven-Pojos) provide excellent alternatives to MDBs (EJB specification), as we can enable asynchronous request handling capabilities to any tested business logic without defining container constraints or dependency hooks. There are three ways we could implement a Spring MDP:

(1) implementing javax.jms.MessageListener
(2) implementing org.springframework.jms.listener.SessionAwareMessageListener (which is a wrapper around javax.jms.MessageListener with javax.jms.Session) or
(3) any interface with implementation logic which accepts a string argument containing message data

This particular post tries to explore the third option of converting a tested business entity to handle asynchronous requests using Spring JMS (ServiceExporter bean) with ActiveMQ embedded broke, using a JMS Queuer.

1) Let us assume that our business entity interface and implementation are defined as below:

public interface MyBusinessEntity
{      public void doBusinessLogic(String logicParameters) throws MyBusinessException;
}
public class MyBusinessEntityImpl implements MyBusinessEntity
{      public void doBusinessLogic(String logicParameters) throws MyBusinessException
       {       //using logicParameters, perform the business logic
       }
}

2) The Spring application context should be defined to wire the embedded ActiveMQ broker with Spring JMS Service Exporter bean and the business entities as below:

<beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:amq="http://activemq.apache.org/schema/core"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                                  http://activemq.apache.org/schema/core  http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd">

     <!-- Defines the ActiveMQ embedded  broker -->
    <amq:broker useJmx="false" persistent="false">
        <amq:transportConnectors>
                 <amq:transportConnector uri="tcp://localhost:0" />
        </amq:transportConnectors>
      </amq:broker>

     <amq:queue id="qDestination" physicalName="embedded" />

    <amq:connectionFactory id="connectionFactory" brokerURL="vm://localhost" />

   <bean id="mybusinessService" class="org.springframework.jms.remoting.JmsInvokerServiceExporter">
     <property name="serviceInterface" value="mypackage.MyBusinessEntity"/>
     <property name="service">
            <bean class="mypackage.MyBusinessEntityImpl"/>
     </property>
   </bean>

   <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">
       <property name="connectionFactory" ref="connectionFactory"/>
       <property name="destination" ref="qDestination"/>
       <property name="messageListener" ref="placeBidService"/>
   </bean>

</beans>

3) If the application is a web-archive (war), add the Spring ContextLoader Listener to load the spring Context to your WEB-INF/web.xml.

<listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
   <context-param>
          <param-name>contextConfigLocation</param-name>
         <param-value>classpath:jms-context.xml</param-value>
   </context-param>

4) In order to asynchronously place a request, from the client, you need to define another client Spring context configuration mapping containing the reference to MyBusinessEntrity interface as given below, which could be used directly to place a request.

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:amq="http://activemq.apache.org/schema/core"
      xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                       http://activemq.apache.org/schema/core  http://activemq.apache.org/schema/core/activemq-core-5.2.0.xsd">

 <bean id="mybusinessService" class="org.springframework.jms.remoting.JmsInvokerProxyFactoryBean">
      <property name="serviceInterface" value="mypackage.MyBusinessEntity"/>
      <property name="connectionFactory" ref="connectionFactory"/>
      <property name="queue" ref="qDestination"/>
 </bean>

 <amq:queue id="qDestination" physicalName="embedded" />
 <amq:connectionFactory id="connectionFactory" brokerURL="vm://localhost" />
</beans>

Having setup the server and client logics, the client can asynchronously lodge a request on server for the specific business logic.

Categories: jee-light Tags: ,

Loading Spring Context from Google Guice

September 15th, 2009 Shrihari No comments

Using Spring framework in any application opens a plethora of opportunities with regard to resolving complex requirement needs in lieu of the number of extensible components available based on the Spring framework. Some of the most preferred specification based stacks (such as Apache CXF)  are coupled with Spring Framework, and it would call for a need to figure out options of getting the best of breed application stacks.

This particular entry looks at loading Spring Framework from Google Guice container. There are two approaches I have across till now, which I will try covering in breif:

1) Using Guice’s SpringIntegration

In this approach you need to download guice-spring.jar (version 1.0) or if your project is maven based, add the following dependency.

<dependency>
     <groupId>com.google.inject.integration</groupId>
     <artifactId>guice-spring</artifactId>
     <version>1.0</version>
</dependency>

You need to generalize an AbstractModule and use the com.google.inject.spring.SpringIntegration to load the Spring context into the Guice’s container.

import com.google.inject.spring.SpringIntegration;
import com.google.inject.AbstractModule;
//other imports...
public class SpringContextModule extends AbstractModule
{ @Override
   protected void configure()
   { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("appcontext-config.xml");
     SpringIntegration.bindAll(binder(), applicationContext);
    }
}

2) Using GuiceyFruit’s SpringModule

In this approach,  the dependency injection is based on JSR-250 common annotations specification and is resolved using the Spring annotation @Autowired (i.e.) all the beans have to be modified, introducing the annotation wherever the injection is required. This approach is suitable for all the beans for which we have control on the source code, and may not be a viable option for integration proven Spring modular components. In case if you have maven project, you need to include the below dependency:

 <dependency>
      <groupId>org.guiceyfruit</groupId>
      <artifactId>guiceyfruit-spring</artifactId>
      <version>2.0-beta-6</version>
    </dependency>

and create a Guice injector using

Injector injector = Guice.createInjector(new SpringModule());

More details can be looked at Guicey-Spring integration wiki page.

Approach 1 is prefered for integration of various most commonly used module component common both between Guice and Spring, as the configuration context can be reused, while the other approach is good enough for custom modules in Spring to be injected in Google Guice.

Adding Code Syntaxhiglighter plugin to Richfaces text editor

September 12th, 2009 Shrihari No comments

Exadel’s Richfaces Rich text editor integrates with TinyMCE javascript plugin to provide the rich text editor functions present in any document processing application. However often would be a need where we have to embed source code from a particular programming  language. In order to support embedding code in the richtext editor, the code should be surrounded wuth appropriate “pre” tags with options for the selected programming language. This particular tip explores integrating a SyntaxHighlighter plugin with Richfaces rich text editor, enabling the editor support for source code editing:

1) Download the sources from site.

2) Create a folder under ${contextroot}/js/tinymceplugins/syntaxhighlight and extract all the contents of the downloaded zip/sources here. Remember that the folder name should be ‘tinymceplugin’ as the TinyMCE javascript plugin looks for this folder for additional plugins if configured. Also note that ${contextroot} is your web application context root.

3) The different languages you need to support are present under ${contextroot}/js/tinymceplugins/syntaxhighlight/dialog.htm, where you retain only the relevant ones. For XML/XHTML support, you may need to add 2 additional lines, which would convert the XML tags to respective character equivalents in ${contextroot}/js/tinymceplugins/syntaxhighlight/js/dialog.js

content_text = f.syntaxhl_code.value.replace(/</g,"&lt;");
 content_text = content_text.replace(/>/g,"&gt;");
 textarea_output +=  content_text;

4) Create a properties file rteplugins.properties (name with custom plugins are resolved) with a property containing full path (relative with regard to ${contextroot}) of the editor_plugin.js from the downloaded sources as given below. Remember that property name used here (syntaxhl) is the plugin name used in the richtext editor configuration

syntaxhl=/js/tinymceplugins/syntaxhighlight/editor_plugin.js

5) The richfaces text editor configuration should be modified as below:

<rich:editor id="description" width="750" height="250" value="#{mybackingbean.description}"
 theme="advanced" viewMode="visual"  customPlugins="rteplugins" plugins="media,fullscreen,syntaxhl">
          <f:param name="theme_advanced_buttons1"  value="code,bold,italic,underline,fullscreen,justifyleft,justifycenter,justifyright,
                                    fontselect,fontsizeselect,styleprops,tablecontrols,syntaxhl,
                                    search,replace,selectall,media,forecolor,backcolor,cut,copy,paste"/>
          <f:param name="theme_advanced_toolbar_location" value="top" />
          <f:param name="theme_advanced_toolbar_align" value="left" />
          <f:param name="extended_valid_elements" value="pre[name|class]"/>
 </rich:editor>

Note: parameter ‘extended_valid_elements’ identifies valid tags that can be present in the text in raw HTML form.

Well now you are ready to use the rich text editor to contain code snippets. Lets also try to look at how to view code in highlighted format in the next tip.