Showing posts with label Java EE 7. Show all posts
Showing posts with label Java EE 7. Show all posts

Monday, 4 May 2015

Introducing Jerry and Valerie

Or the JSF renderer interceptor and the (bean) validation extension.

A major new version is available under the Atbash umbrella: http://www.atbash.be/2018/02/26/a-renderer-interceptor-concept-for-java-serverfaces/

Introduction

The first opensource project where I ever posted a change to, was Apache MyFaces Extension Validation, ExtVal in short. It is a framework for having a validation platform with many great features.

But the last few years, I only used a few specific parts of the platform with some of my own extensions.
Since ExtVal was designed for JSF 1.x and later extended to JSF 2.x, I decided to recreate it.  CDI the cornerstone in every aspect of the version and geared towards JSF 2.x and Bean Validation.
But if you like, you can still create all the features from ExtVal in the new version.

Jerry

One of the features of ExtVal that I use a lot, is the JSF Renderer interceptor around which the complete platform is built. The idea is very simple, during registration of the renderers at startup, they are wrapped with a custom class.
This allows to have a before and after of all the important steps of a rendering; decode phase, encode begin, encode children, encode end and converted value.

This very simple concept has many possibilities. For example, you want to indicate every required input field with a special background colour.  These are the step that you need to do

1- Add Jerry to your maven project
<dependency>
   <groupId>be.rubus.web</groupId>
   <artifactId>jerry</artifactId>
   <version>${jerry.version}</version>
</dependency>

2- Define a ComponentInitializer, this is a specific renderer interceptor which can perform some actions in the before encode begin step.

@ApplicationScoped
public class RequiredInitializer implements ComponentInitializer {
   @Override
   public void configureComponent(FacesContext facesContext, UIComponent uiComponent, Map<String, Object> metaData) {
      InputText inputText = (InputText) uiComponent;

      if (inputText.isRequired()) {
         String style = inputText.getStyle();
         if (style == null) {
            style = "";
         }
         inputText.setStyle(style + " background-color: #B04A4A;");

      }
   }

   @Override
   public boolean isSupportedComponent(UIComponent uiComponent) {
      return uiComponent instanceof InputText;
   }
}

The above code adds the background colour to every PrimeFaces input text field.  This class is found using CDI mechanisms, and that is the reason why we have to annotate it with ApplicationScoped.  But it gives us also the possibility to inject any other CDI bean into this initialiser method.

Jerry is used in the Java EE declarative permission security framework Octopus to handle the security on the JSF component level.

Valerie

Another thing which I always find a bit annoying is that you should redefine the maximum length of a field at the JSF component level, although you have defined a Bean validation constraint on the java property.

For example, suppose you have a property for the name of a person

@Size(max = 50)
private String name;

When you have a JSF input field component pointing to to this property

<h:inputText value="#{personBean.name}"/>

then, the size restriction is checked during the validation phase. But why do you let the user input a longer then allowed value? So you have to use the size attribute on the h:inputText but it should go automatically, no.

That is where Valerie comes into the scene, another extraction from the ExtVal framework. 

side note; How the names are chosen. Jerry was chosen as it sounds phonetic like JRI (JSF Renderer Interceptor) So, I needed a female name to go alone with it and it should be related to validation.

So how can we have in the above example the size restriction from the bean validation property size on the screen?

The only thing you need to do is add the Valerie dependency to your project.  

<dependency>
   <groupId>be.rubus.web</groupId>
   <artifactId>valerie</artifactId>
   <version>${valerie.version}</version>
</dependency>

One renderer interceptor is responsible for retrieving and interpretation of the annotation information. A component initialiser then modifies the JSF component by specifying the size attribute from that info.

Conclusion

Jerry and Valerie are 2 small libraries extracted from the ExtVal framework.  They are centered around the JSF renderer interceptor and the extraction of bean validation information and gives you some handy features which makes your application easier to maintain.

The current version is 0.2, but since they have a firm solid history within ExtVal and are already used in a few projects, they are ready to use.  In the near future there will be some small features added and some more testing will be done before a first final version will be released.

They can be used in any Java EE 6 or Java EE 7 server (or servlet container if JSF, CDI and bean validation are present) and compiled with Java SE 6.

The basic documentation of the project can be found here and feedback, issues, feature request are welcome at the issue tracker on gitHub.

Maven artefacts are available in the C4J OpenSource Nexus 
<url>http://nexus-osc4j.rhcloud.com/content/groups/public/</url>
Have fun with it.

Wednesday, 25 September 2013

Generic JPA 2.1 converter for enum

Introduction

Until now, an enum value could be stored in the database by its ordinal number or his name in JPA. When you have a ‘legacy’ database or when you are doing refactorings you could be in trouble.  The only option then was to rely on the implementation to allow a custom value as the representation of the numeration in the database.
In the latest release of JPA, 2.1, there is support for custom converters so you can solve these kind of issues.

JPA 2 Converter

What do you need to do to have a custom converter? The enumeration class doesn’t need any change. In the entity were you use the enum, you need to specify the converter you like to use, like this:
@Entity
public class Person {
...

  @Column
  @Convert(converter = GenderEnumConverter.class)
  private Gender gender;
...
}

The converter class can look as this
@Converter
public class GenderEnumConverter implements AttributeConverter< Gender, String> {

  @Override
  public String convertToDatabaseColumn(Gender attribute) {
    String result = "";
    switch (attribute) {

      case MALE:
        result = "M";
        break;
      case FEMALE:
        result = "F";
        break;
      default:
    }
    return result;
  }

  @Override
  public Gender convertToEntityAttribute(String dbData) {
    Gender result = null;
    switch (dbData) {
      case "M":
        result = Gender.MALE;
        break;
      case "F":
        result = Gender.FEMALE;
        break;
      default:
    }
    return result;
  }
}

And the last thing you need to do is to ‘register’ the converter with JPA as no scanning is performed of the available classes.  You can specify the class name, just as you specify the entity classes in the persistence.xml file.
<persistence-unit name="converter-unit" >
  <description>Forge Persistence Unit</description>

  <class>be.rubus.web.ee7.jpa.converter.model.Person</class>
  <class>be.rubus.web.ee7.jpa.converter.jpa.GenderEnumConverter</class>
</persistence-unit>

Not OO


The above code is not ideal in several ways. If you have an enum class with a lot of values, you have to write a large if-then-else structure which is not very OO like. And you also need to write a lot of similar code which wants me to search for a more generic solution.

If we could define the database value together with the enum value, it would be a great improvement. It makes the code also much more logic as you can define the database value together with the enum value.

Since we need such functionality for each numeration that we use in the persistent objects, we can create an interface like DatabaseEnum.
public interface DatabaseEnum {

  Serializable getDatabaseValue();

}

And change the enum to implement this interface.
public enum Gender implements DatabaseEnum  {
  MALE("M"), FEMALE("F");

  private Serializable databaseValue;

  Gender(Serializable databaseValue) {
    this.databaseValue = databaseValue;
  }

  public Serializable getDatabaseValue() {
    return databaseValue;
  }

}

This should allow us to create a generic converter for the enums, except that the Java compiler removes the information regarding the generic types, know as type erasure. Otherwise a converter like this could be possible.
@Converter
public class EnumConverter<T extends DatabaseEnum> implements AttributeConverter< T, Serializable> {

  @Override
  public Serializable convertToDatabaseColumn(T attribute) {
    return attribute.getDatabaseValue();
  }

  @Override
  public T convertToEntityAttribute(Serializable dbData) {
    // There is no way we can create such a method
    return determineEnum(T, dbData);
  }

}

If we would be able to define that a custom constructor needs to be called, where we supply as parameter the class T, we would get away with it.  But this is not the case.
public EnumConverter(Class<T> enumType) {..}

Almost generic converter


Based on the optimal code above, we are able to create a converter that uses a generic utility method.  It means that we still need to create a converter for each enum class we like to use, but the code is much cleaner then the first example we show in the text.
@Converter
public class GenderEnumConverter implements AttributeConverter<DatabaseEnum, Serializable> {

  @Override
  public Serializable convertToDatabaseColumn(DatabaseEnum attribute) {
    return attribute.getDatabaseValue();
  }

  @Override
  public Gender convertToEntityAttribute(Serializable dbData) {
    return DatabaseEnumUtil.getEnumValue(Gender.class, dbData);
  }
}

And the utility method can be small and generic thanks to the not very known method getEnumConstants() of the JVM core classes.
  public static <T extends DatabaseEnum> T getEnumValue(Class<T> enumClass, Serializable dbValue) {
    T result = null;
    if (dbValue != null) {

      for (DatabaseEnum enumInstance : enumClass.getEnumConstants()) {
        if (dbValue.equals(enumInstance.getDatabaseValue())) {
          result = (T) enumInstance;
          break;
        }
      }
    }
    return result;
  }

Conclusion


In the latest version of JPA, a custom converter can be defined which can be very handy in a lot of situations.  You can use it to create a converter for Joda-time classes or for specifying the database value of an enum value.

The only thing that keeps us from creating a generic converter for enums is the type erasure thing of Java. Otherwise we could create a beautiful converter for all our enums.