Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Thursday, June 6, 2013

Java Code Refactoring





I recently browsed again the excellent book Code Complete from Steve McConnell while in the middle of several Java code reviews. Although the book is nor specifically dedicated to Java code, I still found it quite useful and inspiring.

The chapter on refactoring in particular offers a very practical perspective that all programmer should have in mind when it comes to infuse a dose of evolution in the life cycle of their software.

What I found particularly valuable are the checklists that the author has put together: reasons to refactor, specific re-factorings (data level, statement level, routine-level, class-implementation, class-interface, system-level), refactoring safely, strategies, summary.

In this post, I would like to illustrate some of these refactoring techniques with java code snippets.

Since I do not have time to comment every item in these checklists, I decided to pick-up those that are not trivial or obvious and might bring the best return on your refactoring investment. These items are high-lighted in green and developed in sections at the end of this article.

If you think that missing items are worth explaining, please add a comment to this post and I will be glad to add a specific paragraph for those as well.







Checklist: Reasons to Refactor

  • Code is duplicate
  • A routine is too long
  • A loop is too long or too deeply nested
  • A class/interface/method has poor cohesion
  • A class interface does not provide a consistent level of abstraction
  • A parameter list has too many parameters
  • Changes within a class tend to be compartmentalized
  • Changes require parallel modifications to multiple classes
  • Inheritance hierarchies have to be modified in parallel
  • Related data items that are used together are not organized into classes
  • A routine uses more features of another class than of its own class
  • A primitive data type is overloaded
  • A class doesn't do very much
  • A chain of routines passes tramp data
  • A middle man object isn't doing anything
  • One class is overly intimate with another
  • A routine has a poor name
  • Data members are public
  • A subclass uses only a small percentage of its parents' routines
  • Comments are used to explain difficult code
  • Global variables are used
  • A routine uses setup code before a routine call or takedown code after a routine call
  • A program contains code that seems like it might be needed someday

 Checklist: Summary of Refactorings


Data Level Refactoring
  • Replace a magic number with a named constant
  • Rename a variable with a clearer or more informative name
  • Move an expression inline
  • Replace an expression with a routine
  • Introduce an intermediate variable
  • Convert a multi-use variable to a multiple single-use variables
  • Use a local variable for local purposes rather than a parameter
  • Convert a data primitive to a class
  • Convert a set of type codes to a class
  • Convert a set of type codes to a class with subclasses
  • Change an array to an object
  • Encapsulate a collection
  • Replace a traditional record with a data class
Statement Level Refactorings
  • Decompose a boolean expression
  • Move a complex boolean expression into a well-named boolean function
  • Consolidate fragments that are duplicated within different parts of a conditional
  • Use break or return instead of a loop control variable
  • Return as soon as you know the answer instead of assigning a return value within nested if-then-else statements
  • Replace conditionals with polymorphism (especially repeated case statements)
  • Create and use null objects instead of testing for null values
Routine Level Refactorings
  • Extract a routine
  • Move a routine's code inline
  • Convert a long routine to a class
  • Substitute a simple algorithm for a complex algorithm
  • Add a parameter
  • Remove a parameter
  • Separate query operations from modification operations
  • Combine similar routines by parameterizing them
  • Separate routines whose behavior depends on parameters passed in
  • Pass a whole object rather than specific fields
  • Pass specific fields rather than a whole object
  • Encapsulate downcasting ⇐ 

Class Implementation Refactorings
  • Change value objects to reference objects
  • Change reference objects to value objects
  • Replace virtual routines with data initialization
  • Change member routine or data placement
  • Extract specialized code into a subclass
  • Combine similar code into a superclass
Class Interface Refactorings
  • Move a routine to another class
  • Convert one class to two
  • Eliminate a class
  • Hide a delegate
  • Replace inheritance with delegation
  • Replace delegation with inheritance
  • Remove a middle man
  • Introduce a foreign routine
  • Introduce a class extension
  • Encapsulate an exposed member variable
  • Remove Set() routines for fields that cannot be changed
  • Hide routines that are not intended to be used outside the class
  • Encapsulate unused routines
  • Collapse a superclass and subclass if their implementations are very similar
System Level Refactorings
  • Duplicate data you can't control
  • Change unidirectional class association to bidirectional class association
  • Change bidirectional class association to unidirectional class association
  • Provide a factory routine rather than a simple constructor
  • Replace error codes with exceptions or vice versa

Selected items refactoring samples in java

  • A class/interface/method has poor cohesion
    • A class, interface or method should be only responsible for a precise and meaningful set of functionality and behavior. For example,the interface KitchenAppliance below lacks cohesion. A generic kitchen appliance should not allow to wash both clothes and dishes.
    •  
      public interface KitchenAppliance {
       public float waterConsumption = 0;
       public float energyConsumption = 0;
       void washClothes();
       void washDishes();
      }
      

              ⇒

      public interface WashingKitchenAppliance {
       public float waterConsumption = 0;
       public float energyConsumption = 0;
       void wash();
      } 
       
       
  • A class interface does not provide a consistent level of abstraction
    •  In Java, a consistent level of abstraction is usually obtained when the objects that represent abstract actors perform work, report on, change their state and communicate with other java objects in a a compatible and comparable way.
      The use of inheritance, encapsulation and polymorphism is usually the key to a consistent level of abstraction and is at the core of good design patterns. In the example below, an intermediary level of abstraction, e.g. DairyAnimal (cows, goats) and MeatAnimal (pigs, steers), could be created to avoid  specifying the type of food for each animal and focus on more specific features for the sub-classes.
    •  
      public class Animal extends LivingThing
      {
       private Location loc;
       private double energyReserves;
      
       public boolean isHungry() {
        return energyReserves < 2.5;
       }
       public void eat(Food food) {
        energyReserves += food.getCalories();
       }
       public void moveTo(Location location) {
        this.loc = location;
       }
      }
      
      thePig = new Animal();
      theCow = new Animal();
      if (thePig.isHungry()) {
          thePig.eat(tableScraps);
      }
      if (theCow.isHungry()) {
          theCow.eat(grass);
      }
      theCow.moveTo(theBarn);
       

       
      public class DairyAnimal extends Animal {
       private Double milkProduction;
      
       public Double getMilkProduction() {
        return milkProduction;
       }
              ...
      }
      
  • A parameter list has too many parameters
    • Methods with too many parameters is an indication that the code has either been badly designed initially (lack of abstraction) or has evolved over the months or years without proper refactoring. One elegant solution for creational methods/constructor requiring a large number of parameters is to use a builder pattern well define in Joshua Bloch's Effective Java and offers a way to use optional parameters:
    •  
      public NutritionFacts(int servingSize, int servings, int sodium, int iron, int fat, int carbs) {
           this.servingSize = servingSize;
           this.sodium = sodium;
           this.servingSize = servingSize;
           this.iron = iron;
           this.fat = fat;
           this.carbs = carbs;
      }
      
      NutritionFacts soda = new NutritionFacts(240, 8, 35, 13, 0, 27);
      

      public class NutritionFacts {
       private int servingSize = 0;
       private int servings  = 0;
       private int sodium  = 0;
       private int iron  = 0;
       private int fat  = 0;
       private int carbs  = 0;
      
       public static class Builder {
        private int servingSize;
        private int servings;
        private int sodium;
        private int iron;
        private int fat;
        private int carbs;
      
        public Builder(int servingSize, int servings) {
         this.servingSize = servingSize;
         this.servings = servings;
        }
        
        public Builder sodium(int val) {
         this.sodium = val;
         return this;
        }
        
        public Builder iron(int val) {
         this.iron = val;
         return this;
        }
      
        public Builder fat(int val) {
         this.fat = val;
         return this;
        }
      
        public Builder carbs(int val) {
         this.carbs = val;
         return this;
        }
        
        public NutritionFacts build() {
         return new NutritionFacts(this);
        }
       }
       
       private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        sodium = builder.sodium;
        iron = builder.iron;
        fat = builder.fat;
        carbs = builder.carbs;
       }
      }
      
      NutritionFacts soda = new NutritionFacts(240, 8).build();
      or
      NutritionFacts soda = new NutritionFacts(240, 8).sodium(35).iron(13).fat(0).carbs(27).build();
      or
      NutritionFacts soda = new NutritionFacts(240, 8).sodium(35).iron(13).carbs(27).build();
      
      
  • Changes require parallel modifications to multiple classes
    • If you regularly have to modify the same set of classes then try to refactor these classes with the correct level of abstraction and factorization so changes only affect one class.
  • Related data items that are used together are not organized into classes
    • Recurrent set of operations can be combined in its own class:
    • theCow = new DairyAnimal();
      theCow.brush();
      theCow.feed();
      theCow.milk();
      theCow.feed();
      

      public class DairyAnimalOperation {
       public void tend(DairyAnimal dairyAnimal) {
        dairyAnimal.brush();
        dairyAnimal.feed();
        dairyAnimal.milk();
        dairyAnimal.feed();
      };
      
      Even better, refactoring can include the use of a flexible strategy pattern, if the recurrent process needs to be dynamically.
  • A chain of routines passes tramp data
    • "Tramp data" refers to passing data to one method so it can be passed to another one (Page-Jones 1988). This can be solved by introducing a better level of abstraction in the interfaces in question
  • Replace a magic number with a named constant
    • The word magic refers to the use of numeric or string literal. Use constants or Enums instead.
    • public double areaOfCircle (double radius)  {  
          return Math.pow(radius * 3.14159, 2);  
      }  
      

      private static final double PI = 3.14159;
      
      public double areaOfCircle (double radius)  {  
          return Math.pow(radius * PI, 2);  
      } 
      
  • Convert a multi-use variable to a multiple single-use variables
    • Common offenders are variable names like i,j, temp. These need to be replaced by specific names (e.g. row, column).
    • for (int i=0;i&tl;N;i++) {
          for (int j=0;j&tl;M;j++) {
             matrix[i][j] = 0; 
          }
      }
      

      for (int row=0;row&tl;numRows;row++) {
          for (int colum=0;colum&tl;numColumns;colum++) {
              matrix[row][colum] = 0; 
          }
      }
      
  • Encapsulate a collection
    • Instead of returning the collection itself, encapsulate a read-only collection instance with specific methods to add or remove elements in the original collection. You can leverage unmodifiable view methods that are part of the collection class for this:
    • public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
      public static <T> Set<T> unmodifiableSet(Set<? extends T> s)
      public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
      public static <T> List<T> unmodifiableList(List<? extends T> list)
      public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
      public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
      
  • Replace conditionals with polymorphism
    • With polymorphism, subclasses of a class possesses their own specific behaviors and share also some of the functionality of their parent class. Refactor conditionals, especially complex case statements with polymorphism design:
    • Bike myBike = new Bike();
      String bikeType = "default";
      witch(myBike.getTireWidth()) {
       case 23 : 
        if (myBike.getSuspension().compareToIgnoreCase("Simple") == 0) {
         bikeType = "Road bike";
        }
       break;
       default : 
        if (myBike.getSuspension().compareToIgnoreCase("Dual") == 0) {
         bikeType = "Mountain bike";
        }
       break;
      }

             ⇒

      public class MountainBike extends Bicycle {
          private String suspension;
      
          public MountainBike(
                     int startCadence,
                     int startSpeed,
                     int startGear,
                     String suspensionType){
              super(startCadence,
                    startSpeed,
                    startGear);
              this.setSuspension(suspensionType);
          }
      
          public String getSuspension(){
            return this.suspension;
          }
      
          public void setSuspension(String suspensionType) {
              this.suspension = suspensionType;
          }
      } 
      
      public class RoadBike extends Bicycle{
          private int tireWidth;
      
          public RoadBike(int startCadence,
                          int startSpeed,
                          int startGear,
                          int newTireWidth){
              super(startCadence,
                    startSpeed,
                    startGear);
              this.setTireWidth(newTireWidth);
          }
      
          public int getTireWidth(){
            return this.tireWidth;
          }
      
          public void setTireWidth(int newTireWidth){
              this.tireWidth = newTireWidth;
          }
      }
      
  • Separate routines whose behavior depends on parameters passed in
    •  If you have a method which executes different statements based on a particular parameter value, figure out if you can break the method into separate ones without passing the parameter in question.
  • Encapsulate downcasting
    • Objects returned by a method should use the most specific type possible. 
    • public class A {
       public String doSomething() {
        return "Do something.";
       }
      }
      
      public class B extends A {
       public String doSomethingMoreSpecific() {
        return "Do something more specific.";
       }
      }
      
      public class DownCast {
      
       private List<A> list;
       
       public List<A> getList() {
        return list;
       }
      
       public List<B> getMostSpecificList() {
        return (List<B>) (List<?>) list;
       }
        
       public void setList(List<A> list) {
        this.list = list;
       }
      
       public DownCast() {
        list = new ArrayList<A>();
        for (int i=0;i<10;i++) {
         list.add(new B());
        }
       }
      
      }
      
      public static void main(String[] args) {
        
       DownCast obj = new DownCast();
       List<A> listOfA = obj.getList();
       System.out.println(listOfA.get(0).doSomething());
         
       List<B> listOfB = obj.getMostSpecificList();
       System.out.println(listOfB.get(0).doSomethingMoreSpecific());
          
      }
      
  •  Extract specialized code into a subclass
    • Refactor specialized code into specific own subclasses if the code in question is only used in a subset of initial classes.
  •  Hide a delegate
    •  If Class A calls B then C while A was supposed to only call B and B calls C, then dissociates C from A and have B calls C only.
  •  Remove a middle man
    • On the other hand, if you think that A should call C directly as long as the role of B is still clearly defines, does not have overlap with C and can be used independently of C.
  •  Encapsulate unused methods
    • Create new interfaces for the most common used set of methods
    • public class Bird {
       
       private String species;
       private String eggColor;
       private String food;
       private int flySpeed;
       private int flyHeight;
       private String dragType;
       private String wingType;
       
       public String getSpecies() {
        return species;
       }
       public void setSpecies(String species) {
        this.species = species;
       }
       public String getEggColor() {
        return eggColor;
       }
       public void setEggColor(String eggColor) {
        this.eggColor = eggColor;
       }
       public String getFood() {
        return food;
       }
       public void setFood(String food) {
        this.food = food;
       }
       public int getFlySpeed() {
        return flySpeed;
       }
       public void setFlySpeed(int flySpeed) {
        this.flySpeed = flySpeed;
       }
              ...
      }

             ⇒

       
      public interface BirdFlight {
       public int getFlySpeed();
       public void setFlySpeed(int flySpeed);
       public int getFlyHeight();
       public void setFlyHeight(int flyHeight);
       public String getDragType();
       public void setDragType(String dragType);
       public String getWingType() ;
       public void setWingType(String wingType);
      }
      
      public class Bird implements BirdFlight {
       
       private String species;
       private String eggColor;
       private String food;
       
       public String getSpecies() {
        return species;
       }
       public void setSpecies(String species) {
        this.species = species;
       }
       public String getEggColor() {
        return eggColor;
       }
       public void setEggColor(String eggColor) {
        this.eggColor = eggColor;
       }
       public String getFood() {
        return food;
       }
       public void setFood(String food) {
        this.food = food;
       }
       
       @Override
       public int getFlySpeed() {
        ...
       }
       @Override
       public void setFlySpeed(int flySpeed) {
        ...
       }
       @Override
       public int getFlyHeight() {
        ...
       }
       @Override
       public void setFlyHeight(int flyHeight) {
        ...
       }
       ...
        
      }
      
  •  Duplicate data you can't control
    • As long as layering principles are not violated, wrap or access data maintain by the system via a consistent way/interface/API. A typical examples is data shares in GUI control in the front-end layer. Try to find a way to copy/mirror the data in question and treat it as reference source of data.

Thursday, March 28, 2013

Richfaces Ajax CDI Push and JBoss



You may not know it, but when you go to a restaurant, you most likely to be served via a method called service à la russe (service in the Russian Style). This is in contradiction to the much older traditional service à la française (service in the French Style).

In the original French Style, all the food was brought from the kitchen into the dining room of the aristocrats or high clergy and served all at once. Then the cooks who lost their jobs during the French revolution, end-up opening places call restaurants to make a living when common people could come to eat and relax (from the verb se restaurer in French), meaning "to restore itself".

French serving style remains in some high class restaurants where small tables or guéridons are moved close to the guest's table where the food preparation is completed and served.



The buffet is a variation of the French Style where the guests help themselves from the table (in French it is traditionally a piece of furniture that looks like a table with drawers called in fact buffet).











On the other hand, the Russian Style that comes from Russia was introduced in the French restaurants during the 19th century where courses are brought to the table sequentially by the waiter. This is now the style in which most modern western restaurants serve food (with some significant modifications).

The place setting (called a cover) for each guest includes a service plate, all the necessary cutlery except those required for dessert, and stemmed glasses for water, wines and champagne

Guests immediately remove their napkins and place them in their laps.

The rule is as such: a filled plate is always replaced with an empty one, and no place goes without a plate until just before the dessert course.

Directly before dessert everything is removed from the place settings but the wine and water glasses. Crumbs are cleared and dessert is served.

As you can see, both styles have very precise rules and mechanisms that must be followed to ensure the best service.




Richfaces itself offers several Ajax server-side push mechanisms to bring data from the server to the client.

Interesting to point-out by the way, that a waiter in french is called "un serveur" (someone who serves) and that the same word is used to design a server in computer science.

These three Ajax Push methods are:
  • TopicsContext - accesses a RichFaces message queue directly
  • Push CDI - uses the CDI Event mechanism to fire messages
  • Push JMS - the RichFaces Push consumes messages from an enterprise messaging system and exposes them to the client (tightly coupled with the JMS runtime) 
In a previous article I was explaining how RichFaces Extended Data Tables can be enhanced.

In this article, I will describe how Richfaces Ajax Push CDI can be implemented and deployed specifically on a JBoss container (I am using JBoss application server 7.0)



The Richfaces showcase describes well as usual the java and JSF code needed to implements the CDI Ajax Push.  One thing though, the Push JMS mechanism in not explicated in the show case, but described in the chapter 3 of the documentation.

First what does CDI means?

If you look at your project  facets (I am using Eclipse IDE), you will see that CDI stands for Context and Dependency Injection.

Container/Context Dependency Injection in Java EE 6 decouples the processing threads of  event producers and event consumers by using the Observer pattern in the form of event broadcasting.

An event in CDI is just a regular POJO that can be fired by any class through the use of the Event implementation injected automatically by the container via the @Inject annotation.







 

import java.io.Serializable;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.event.Event;

import javax.inject.Inject;
import javax.inject.Named;

import org.richfaces.cdi.push.Push;

@Named
@RequestScoped
public class PushCdiBean implements Serializable {

 private static final long serialVersionUID = 6414191802542861042L;
 public static final String PUSH_CDI_TOPIC = "pushCdi";
 private String message = "";

 @Inject
 @Push(topic = PUSH_CDI_TOPIC)
 Event<string>pushEvent;
 
 
 public void sendMessage() throws Exception {
  if (pushEvent == null) {
  } else {
   pushEvent.fire(message);
  }
  message = "";
 }

 public String getMessage() {
  return message;
 }

 public void setMessage(String message) {
  this.message = message;
 }
}

If you download the source code of the Richfaces showcase (I am using richfaces-4.3.1.Final), you will see that the readme file located under .\richfaces-4.3.1.Final\examples\richfaces-showcase describes useful steps necessary to deploy the sample application on various containers, including JBoss.



First, you need your Maven pom file to have both the Java API CDI and the atmosphere dependencies:
<dependency>
 <groupId>javax.enterprise</groupId>
 <artifactId>cdi-api</artifactId>
 <version>1.1-20130222</version> 
</dependency>
<dependency>
 <groupId>org.atmosphere</groupId>
        <artifactId>atmosphere-runtime</artifactId>
        <version>1.0.10</version>
</dependency>

To be able to inject your CDI bean, your WEB-INF folder needs to contain a bean.xml file:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:weld="http://jboss.org/schema/weld/beans" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://docs.jboss.org/cdi/beans_1_0.xsd http://jboss.org/schema/weld/beans http://jboss.org/schema/weld/beans_1_1.xsd"> </beans>

On your deployment platform, you need JBoss standalone configuration located in .\standalone\configuration\standalone-full.xml to have a JMS topic that match your Push CDI topic:


<jms-destinations>
 <jms-queue name="testQueue">       
  <entry name="queue/test"/>  
  <entry name="java:jboss/exported/jms/queue/test"/>
        </jms-queue>  
 <jms-topic name="pushCdi">
         <entry name="topic/pushCdi"/>  
 </jms-topic>     
</jms-destinations>


You also need to start the JBoss server in full configuration:























Another necessary step is  to create the JMS user account/password:

























From there, you should be able to test your Ajax CDI push application. In my case, the consumer is a popup window that I launch by clicking a button (see code below):

Producer code:

<ui:define name="body">
 <h:form id ="from">
  <a4j:commandButton value="Message Consumer"
   oncomplete="#{rich:component('cdi_message_consumer_popup')}.show();" />
  <h:panelGrid columns="4">
   <h:outputLabel value="Message:" />
   <h:inputText id="messageInput" value="#{pushCdiBean.message}"/>
   <a4j:commandButton value="Send" 
    action="#{pushCdiBean.sendMessage}"
    execute="@form" 
    render="messageInput" 
    oncomplete="#{rich:element('messageInput')}.value=''"/>
  </h:panelGrid>
 </h:form>
 <ui:include src="rf_ajax_push_consumer_popup.xhtml" />
</ui:define>

Consumer code:

<rich:popupPanel 
 id="cdi_message_consumer_popup" 
 modal="false"
 resizeable="false" top="100" 
 left="300" 
 autosized="true"
 domElementAttachment="parent">
 <f:facet name="header">
  <h:outputText value="Ajax Push/CDI Message Consumer    " />
 </f:facet>
 <f:facet name="controls">
  <h:outputLink value="#"
   onclick="#{rich:component('cdi_message_consumer_popup')}.hide(); return false;">
   <h:outputText value="X" styleClass="textHeader" />
  </h:outputLink>
 </f:facet>
 <h:form>
  <h:panelGrid columns="3">
   <a4j:push address="pushCdi" 
    onerror="alert('error: ' + event.rf.data)"
    ondataavailable="jQuery('<li />').prependTo('#messages').text(event.rf.data)">
   </a4j:push>
   <ul id="messages" />
  </h:panelGrid>
 </h:form>
</rich:popupPanel>















The message (simple string) is send to the server and pushed back to the browser. The original message is then cleaned:
















A big thank to my colleague Asha Ambikavijayakumaran for figuring out all the tricky details for the JBoss deployment for this Richfaces showcase!


All ingredients and open source code related to this recipe can be found at YummyCode on the JSF Plate project.





Saturday, February 9, 2013

Advanced RichFaces Extended Data Tables

 
With Mardi Gras and Carnival around the corner, this is crêpe season!

This post is the first of a set of recipes that describe useful tips and reusable code and patterns related to Java, JSF 2.0 and RichFaces 4.0.  In this article I am describing practical integration code when using advanced Richfaces Extended Data Tables.

The RichFaces showcase describes well how to start creating your own extendedDataTable. However, here are some additional personal ingredients that can be very handy when preparing an appealing stack of JSF based web pages.





1) Setting your Table

The first time your try to put together a RichFaces extendedDataTable, you might encounter the following behavior: your table does not look like as you expected it: columns have a default size (the length of the label) and the whole size is the size of your whole window, so you end up with a large white space where they are no columns:


 One reason could be that no column or table size has been specified:


 <rich:extendedDataTable id="table" value="#{countries.countryItems} var="country" >
    <f:facet name="header">
        <h:outputText value="Countries" />
    </f:facet>
    <rich:column>
        <f:facet name="header">
            <h:outputText value="Name" />
        </f:facet>
        <h:outputText value="#{country.name}" />
    </rich:column>
    <rich:column>
        <f:facet name="header">
            <h:outputText value="Capital" />
        </f:facet>
        <h:outputText value="#{country.capital}" />
    </rich:column>
    <rich:column>
        <f:facet name="header">
            <h:outputText value="Language(s)" />
        </f:facet>
        <h:outputText value="#{country.languages}" />
    </rich:column>
</rich:extendedDataTable>


One way to quickly fix this is to assign specific sizes to your columns and headers (in my case these are absolute values in pixels and have adjusted the values to take into account the height of a row and the presence of a vertical scroller).  I have also added single selection mode so I can click on a row to retrieve more information about a certain item:

<rich:extendedDataTable id="table" value="#{countries.countryItems}"
    var="country" selection="#{countries.selection}" 
    style="height:190px; width:503px;"
    selectionMode="single">
    <a4j:ajax execute="@form" event="selectionchange" listener="#{countries.selectionListener}"/>
        <f:facet name="header">
            <h:outputText value="Countries" />
        </f:facet>
        <rich:column width="100px">
            <f:facet name="header">
                <h:outputText value="Name" />
            </f:facet>
            <h:outputText value="#{country.name}" />
        </rich:column>
        <rich:column width="100px">
            <f:facet name="header">
                 <h:outputText value="Capital" />
            </f:facet>
            <h:outputText value="#{country.capital}" />
        </rich:column>
        <rich:column width="300px">
            <f:facet name="header">
                <h:outputText value="Language(s)" />
            </f:facet>
            <h:outputText value="#{country.languages}" />
        </rich:column>
</rich:extendedDataTable>
















2) Interaction improvements

Let say now that you want to add a button to load or refresh the information in the table and that this takes some time because you are connected to a remote service. You may want to show to the end-user an indicator that some processing or data retrieval is happening (for this example, I added a waiting function in the iem list bean to simulate a few seconds wait).

I propose to use an animated GIF and take advantage of the RichFaces a4j:status (an indicator of an Ajax request. It has two states: start and stop. The start state indicates that an Ajax request is in progress. When an Ajax response is returned, the component switches to the stop state).

In this case, I refer to a4j:status every time I click on the refresh button to download the countries statistics. I have also added an animated GIF file called processing.gif in my webapp/img folder and top aligned both the button and the ajax indicator into a JSF panel grid:


<h:panelGroup>
    <h:panelGrid columns="2" columnClasses="alignTop, alignTop">
        <a4j:commandButton value="Refresh" status="refreshTable"
     oncomplete="#{countries.refresh()}" />
        <a4j:status name="someProcessing">
            <f:facet name="start">
         <h:graphicImage value="/img/processing.gif" />
     </f:facet>
        </a4j:status>
    </h:panelGrid>
</h:panelGroup>

As a result, the processing indicator appears next to the button when it is clicked and disappear after the table has been refreshed.


















In fact, you can use the same indicator when selecting a row to display detailed information about an item if the retrieval of the additional information takes too long for the user (e.g. more than a couple of seconds):


<a4j:ajax execute="@form" event="selectionchange" status="someProcessing" listener="#{countries.selectionListener}" />


3) Adding some coloring and flavor

If you don't have a predefine look and feel (e.g. a reusable template or UI toolkit), you can easily use the themes and skins that come with RichFaces.  A skin can be quickly added to the web.xml file as follow:


<context-param>
    <param-name>org.richfaces.skin</param-name>
    <param-value>wine</param-value>
</context-param>

Some of my favorites predefined skins are deepMarine and wine:

 
















4) The missing ingredients

Even though the RichFaces Extended Data Tables have a lot of features such as filtering, sorting, scrolling, frozen columns, here are always missing ingredients that you would like to use to offer a better experience to the end user. One that you will not find in the ExtendedDataTable is the wrapping of text in a column or a robust column horizontal scrolling. Hopefully this feature will be added in future release.


5) Always give a tip if you can

Offering tips is generally a good practice. It makes feel everybody happy: the person who provides it knowing that he/she has done a good job, and the end-user who enjoys it and saves time using them.

In this example, I have added a column to to indicate which countries have a GDP above one Trillion US Dollars. When the use hovers the mouse above the checkbox or the name of the country, a tooltip appears and shows the GDP number for the selected country.

















Tooltips can be easily added as follow:

<rich:column styleClass="#{msg.status}" width="35px">
    <f:facet name="header">
        <h:outputText value="GDP > $1T" />
    </f:facet>
    <rich:tooltip mode="client" target="largeGDPCountry">
        <h:outputText value="#{country.name} - 2011 GDP: #{country.gdp} > $1T" />
    </rich:tooltip>
    <h:graphicImage id="largeGDPCountry" value="/img/checkmark.png" rendered="#{country.largeGdp}" alt="GDP" />
</rich:column>
<rich:column width="100px">
    <f:facet name="header">
        <h:outputText value="Name" />
    </f:facet>
    <h:outputText id="countryName" value="#{country.name}" />
    <rich:tooltip mode="client" target="countryName">
        <h:outputText value="#{country.name} - 2011 GDP: #{country.gdp} $M" />
    </rich:tooltip>
</rich:column>


Ingredients and open source code related to this recipe can be found at YummyCode on the JSF Plate project.

Thursday, April 19, 2012

java XSLT processing with Saxon



Recently, I was looking for an efficient way to reduce the size of XML based clinical documents (CCD) that I am sending from a java REST API to mobile devices. These healthcare HL7 XML documents contain textual narrative blocks that are not used by the applications residing on the mobile devices.

On solution was to use Saxon, an open source XSLT processor in conjunction with a transformation style sheet to strip the Continuity of Care Documents of their narrative blocks.

In a CCD, each section under ClinicalDocument/component/structuredBody/component can have a text section that usually contains a narrative block similar to HTML content that can typically add 30% or more to the size of the CCD document:










































This has the advantage to avoid creating a full DOM representation, and is more robust and flexible than an event based sequential SAX processor.

The first step is to create a XSLT stylesheet that will transform (in my case strip the text sections) from the XML document.
In my case, since I wanted to remove all text sections, I was able to use an identity transform mechanism that I modified to strip the text sections (uses the hl7 namespace):

<xsl:stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform' version='2.0'
xmlns:hl7="urn:hl7-org:v3">

<xsl:output indent="no"/>
<xsl:strip-space elements="*"/>

<!-- identity template -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<!--  remove descriptive sections -->
<xsl:template match="hl7:text"/>  

</xsl:stylesheet>


Then I placed this file (I named it ccd_no_text_sections.xsl)  under the /src/main/resources folder.

To use this XSLT stylesheet with Saxon, you need to use one of the Saxon Java libaries.
If you using maven, for example, just add the dependencies to your pom file based on the version you want to use:
<dependency>
 <groupId>net.sf.saxon</groupId>
 <artifactId>saxon</artifactId>
 <version>9.0</version>
</dependency>

<dependency>
 <groupId>net.sf.saxon</groupId>
 <artifactId>saxon-dom</artifactId>
 <version>9.0</version>
</dependency>

or for the latest free version:

<dependency>
 <groupId>net.sf.saxon</groupId>
 <artifactId>Saxon-HE</artifactId>
 <version>9.4</version>
</dependency>

Then you need to create a transformer and call your style sheet for the transformation.
In my case, since I was planning other transformations, I decided to cash the XSLT transformer into a HashTable as follow:

import java.io.InputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class XSLTProcessor {

 private static final HashMap<String,Transformer> TRANSFORMER_CACHE = new HashMap<String,Transformer>();

 final static String CCD_NO_TEXT_SECTIONS = "/ccd_no_text_sections.xsl";
  
 private XSLTProcessor() {
   // no instantiation
 }

 private static Transformer getCCDTransformer() throws TransformerConfigurationException {

  Transformer transformer = TRANSFORMER_CACHE.get(CCD_NO_TEXT_SECTIONS);
  if (transformer == null) { 
   TransformerFactory tsf = TransformerFactory.newInstance();
         InputStream is = XSLTProcessor.class.getResourceAsStream(CCD_NO_TEXT_SECTIONS);
   transformer = tsf.newTransformer(new StreamSource(is));
   return transformer;
  }
  return transformer;
 }
 
 public static String stripTextSections(final String xmlString) throws TransformerConfigurationException,
        TransformerException, 
        TransformerFactoryConfigurationError {

        final StringReader xmlReader = new StringReader(xmlString);
        final StringWriter xmlWriter = new StringWriter();
        final Transformer ccdTransformer = getCCDTransformer();
        ccdTransformer.transform(new StreamSource(xmlReader),
            new StreamResult(xmlWriter));
        
        return xmlWriter.toString();
 }
}


In this way, you can easily add new transformers if needed and refer to them by their stylesheet name located under the resource folder.
In addition to this, the transformer is created only once and always available for a transformation.

The transformation can be called directly on the document as follow:

try {
    String new_ccd = XSLTProcessor.stripTextSections(ccd);
}
catch (TransformerConfigurationException e) {
    log.error("TransformerConfigurationException"+e);
}
catch (TransformerException e) {
    log.error("TransformerException"+e);
}
catch (TransformerFactoryConfigurationError e) {
    log.error("TransformerFactoryConfigurationError"+e);
}

Friday, December 30, 2011

How to extract HTTP header fields in a REST API



To be able to extract HTTP headers fields from incoming requests accessing a REST API is particularly useful when trying to log the transactions that are coming through the REST based service.

In this example, I use Java based JBoss RESTEasy together with @Context java annotation to extract the header information.

One of the REST API operation is /version that returns the current version of the API in a JSON format.The interface operation is defined as follow:

     import javax.ws.rs.core.HttpHeaders;

     /**
     * Get the current version of the REST API.
     */
     @GET
     @Path("/version")
     @Produces("application/json")
     @GZIP
     public Response getVersion(@Context HttpHeaders headers);

The @Context annotation allows you to map request HTTP headers to the method invocation.

One way to safely extract all available header parameters is to loop through the headers.The method getRequestHeaders from javax.ws.rs.core.HttpHeaders returns the values of HTTP request headers. The returned map is case-insensitive and is read-only.

   if (headers != null) {
       for (String header : headers.getRequestHeaders().keySet()) {
          System.out.println("Header:"+header+
                             "Value:"+headers.getRequestHeader(header));
       }
   }

When querying the REST API via a browser:

  http://www.acme.com/api/version

you obtain a minimum set of headers fields:

   Header:cache-control Value:[max-age=0]
   Header:connection Value:[keep-alive]
   Header:accept-language Value:[en-us,en;q=0.5]
   Header:host Value:[www.acme.com]
   Header:accept Value:[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8]
   Header:user-agent Value:[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0)    
   Gecko/20100101 Firefox/8.0]
   Header:accept-encoding Value:[gzip, deflate]
   Header:session-id Value:[d636369c]
   Header:accept-charset Value:[ISO-8859-1,utf-8;q=0.7,*;q=0.7]

To be able to extract a specific header field (e.g. Host), you can use the getRequestHeader function:

 public Response getVersion(@Context HttpHeaders headers) {
     if (headers != null) {
        List<String> hostHeader = headers.getRequestHeader("host");
        if (hostHeader != null) {
           for (String host : hostHeader) {
              LOG.debug("Host:"+host);
           }
        }
     } 
  
     // Get the version
     final Version current_version = new Version();
     final ObjectMapper mapper = new ObjectMapper();
     final JsonNode rootNode = mapper.createObjectNode();
     ((ObjectNode) rootNode).putPOJO(Version.XML_ROOT_ELEMENT, current_version);
     
     final ResponseBuilder builder = Response.ok(rootNode);
     return builder.build();
   }

If you are using a test harness tools like cURL, you can also easily add additional HTTP header fields
(e.g. the email address of the user making the request or the referer) and test the logging functionality of your REST API:
curl -H "From: user@example.com" http://www.acme.com/api/version
curl -H "Referer: http://consumer.service.acme.com" http://www.acme.com/api/version

The headers can also be obtained through the HttpServletRequest object.
This can be done using the @Context HttpServletRequest annotation and can provide additional information about the incoming request:

public Response getVersion(@Context HttpServletRequest request) {
   LOG.debug("Host:"+request.getHeader("host"));
   LOG.debug("Request-URL:"+request.getRequestURL());
   ...
} 

Since HttpServletRequest extends ServletRequest you also getting useful methods providing information on the Internet Protocol (IP) address, host and port of the client or last proxy that initiated the request.

public Response getVersion(@Context HttpServletRequest request) {
   LOG.debug("Remote-IP:"+request.getRemoteAddr());
   LOG.debug("Remote-Host:"+request.getRemoteHost());
   LOG.debug("Remote-Port:"+request.getRemotePort());
   ...
} 
 

Tuesday, September 30, 2008

The ABCs of Google Health Data API

Recently, I have been involved in a small project to aggregate medications from various Personal Health Records (PHR), including Google Health.

The documentation for the Google Data APIs Client Library and the Health Data API is quite complete and extensive. But it can be also be quite complex for someone who want to develop quickly a prototype or just test a proof of concept using these APIs.

Since I was going to develop my project in Java, I first downloaded he most recent GData Java Client Library (version 1.22 with samples - 6.8 MB).

The sample code can be used out of the box for a simple stand-alone java testing program.

I did import the sample code and the library in my IDE (eclipse) and just changed the credentials (sample.credentials.username and sample.credentials.password) in gdata/java/build-samples/build.properties using my google health account login and password.

To run the Google Health sample program, at the prompt under ./gdata/java just run: ant -f build-samples.xml sample.health.run
The next step for me was to reuse the sample code to develop a web application (I am creating small Liferay JSP based portlets).

Google offers two platforms for the developers to test their applications:
For my small web project I initially tested my code against H9, as recommended by Google.
The main reason is because the authentication with H9 is more simple than with Google Health production.

The application I wanted to build is supposed to connect to various PHRs (ICW LifeSensor, Microsoft Health Vault and Google Health/H9) and retrieve the medication lists. For Google I don't need to enter a login and password in my web application since I am going to use Google AuthSub mechanism:



By clicking on the Google 'connect' button, I am redirected to the Google AuthSub web site:

     <input id="btn_connect_google" name="Disconnect" type="submit"
         value="Connect" onClick="connectToGoogle();return false;"/>

Here is the Javascript function I use for URL redirection:

     function connectToGoogle() { 
       if (btn_connect_google.value == "Connect") {
          window.location.href = googleAuthSubURL.value;
       }
       else {
          btn_connect_google.value = "Connect"; 
       }
     }
I construct the AuthSub URL in advance in my JSP java code:
public String getGoogleAuthSubURL(HttpServletRequest request) {
     
       gh9s = new H9Service("ICW-H9Medications-1.0");

       String nextUrl = "http://localhost:8080/sample/hello.jsp";
       String scope = "https://www.google.com/h9/feeds/";
     
       boolean secure = false;
       boolean session = true;
    
       String authSubLink = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);
       authSubLink += "&permission=1";
       authSubLink = authSubLink.replaceFirst("/accounts/AuthSubRequest", "/h9/authsub");
     
      return authSubLink;
   }
I store the URL in an hidden field:

   <input type=hidden id="googleAuthSubURL" value="<%= getGoogleAuthSubURL(request) %>" >

You can refer to the Google Data API and Google Health API, including security settings for AuthSub Request and application identification (for logging purpose).

I am redirected to the Google AuthSub WebSite where I can choose which H9 account I want to use.




Then I am redirected back to my original application, with a single use token associated to the request. I can then parse the request and extract the token that I exchange for the token session:
  http://localhost:8080/sample/hello.jsp?token=1%2FBtOEh.....lsYenOFQ&permission=1
  if (gh9s != null)  {        
      try {
        
         // Extract Single Use Token for the session
         String queryString = request.getQueryString();
                  if (queryString != null) {
           
                      String singleUseToken = AuthSubUtil.getTokenFromReply(queryString);
                 
                      if (singleUseToken != null) {
                        String sessionToken = AuthSubUtil.exchangeForSessionToken(URLDecoder.decode(singleUseToken, "UTF-8"), null);
                        gh9s.setAuthSubToken(sessionToken);
                        System.out.println("Google SetAuthSubToken");
                          
                        URL profile_url = new URL(PROFILE_DEFAULT_PATH);
                        System.out.println("Google ProfileURL:"+profile_url);
                        gh_feed = gh9s.getFeed(profile_url, ProfileFeed.class);
               
                        createReferences(gh_feed.getEntries());
                      }
                  }
            } catch (AuthenticationException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (ServiceException e) {
                throw new RuntimeException(e);
            }
        }

For my portlet version (Liferay), I just had to replace the definition of the current URL:
   String singleUseToken = AuthSubUtil.getTokenFromReply(getCurrentURL(request).getQuery());

   private URL getCurrentURL(HttpServletRequest request) {
    try {
       return(new URL(request.getScheme(), request.getServerName(), request.getServerPort(), request.getAttribute("CURRENT_URL").toString())); 
    } catch (MalformedURLException e) {
    throw new RuntimeException(e);
    }
   }
The next step is to obtain medication entries by parsing the Google CCR data feed:

  private void createReferences(List entries) { 
     if (entries != null) {
        for (ProfileEntry entry : entries) {
           System.out.println("Google CCR:"+entry.getContinuityOfCareRecord().getXmlBlob().getBlob());
                 GoogleCCRWrapper ccrWrapper = getDomRepresentation(entry);
                 if (ccrWrapper.containsMedications()) 
                    medication_list.add(ccrWrapper.getMedication());
                    source_list.add(SRC_GOOGLE_HEALTH);
         }
      }
   }

The GoogleCCRWrapper java class parses the CCRg XML data feed:

    public GoogleCCRWrapper(String xml) {
        DocumentBuilder builder = null;
        try {
            builder = documentBuilderFactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            throw new RuntimeException("Error creating DocumentBuilder.", e);
        }
        
        try {
            document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
        } catch (SAXException e) {
            throw new RuntimeException("Error parsing XML.", e);
        } catch (IOException e) {
            throw new RuntimeException("Error parsing XML.", e);
        }
    }
public boolean containsMedications() {
        return document.getElementsByTagName("Medications").getLength() > 0;
    }

    public String getMedication() {   
     Element e = getElementFromDocument("Medications");
     e = getElement(e, "Medication");
     e = getElement(e, "Product"); 
     e = getElement(e, "ProductName");
     e = getElement(e, "Text"); 
     return getText(e);
    }

Here is the resulting portlet (Google Health and Lifesensor Medications):