Marrying JSF and Scala Part 3 - Custom Components in Scala

 Marrying JSF and Scala part 3: Custom Components in Scala

Introduction

While JSF2.0 has simplified the component building a lot thanks to the
composite components, there are still usecases when the classical component
building tasks have to be performed.

We showed in part 1 and part 2 how to build the basic JSF artifacts in Scala we now are going to dive deeper into JSF by showing how to leverage Scala to build your own jsf custom component.

In this article we combine various techniques of Scala for programming custom components.
The case we are going to investigate is a simple hello world component.

A custom component in Scala

First we have a look at the component itself:
 

Code a) Custom component

We have a simple component which exposes one additional attribute sayHello2. The component itself is a composite component with an xml template for rendering an performs some listener tasks.

So far so good, however we use several things here which are of interest:
 

Code b) Singleton

  • A singleton object for static replacements and struct replacements

Code c) Listeners Array

  • A listeners array for combining multiple listeners 

Code d) trait 

  • a trait instead of a utils class to combine common functionality of components 

Code e) Type matches

  • matches for types to avoid instanceof cascades

Lets dissect the code parts one by one:


1) Object HelloWorld

Scala does have neither static variables nor structs, instead of that it provides singletons as language construct.
Static variables simply can be simulated by a singleton and a simple in class import:
 

Code b) Singleton 

 and then
 

 Code f) import

Allows you to import the instance variables and methods as semi native members.
 

 Code g) import usage

2) Annotation Arrays
 

 Code h) annotation array Scala

is simply what would be in Java

 Code i) annotation array Java

Since this code transition is not quite obvious even within the Scala documentation, it is worth to be noted in this blog.

3) Traits

The most interesting part is the traits part.
First of all, what is a trait? To sum it up, a trait is an abstract class which can be multiply inherited sort of an interface with code. Now this opens quite a few possibilities:

  • Common constraints can be isolated and shared among object instances without having to revert to singletons.
  • Traits can access "this" and can call methods provided by the class as abstract members.


We reuse traits in this case to isolate common component behavior without having to introduce yet another helper class or an abstract base class.

In fact we finally can share this referencing code among components with different base classes without having to introduce our own inheritance hierarchy.

The trait looks like following:
 

 Code j) Trait

We use only a subset of this functionality namely getAttr and setAttr.

 

 Code k) getAttr

Here we can see clearly the this reference to the underlying component getAttributes with

 
def getAttributes(): java.util.Map[String, AnyRef]
 

being defined only as interface, which has to be implemented by the component or one of its parents.

4) Match patterns

Now an interesting language part in Scala is the extended matches. Not only you can match in Scala for values, also matches for types and patterns are allowed.
We use the type matches to avoid instanceof if cascades:
 

 Code l) match patterns

The cases basically replace if instanceof constructs here


 A renderer in Scala

Now what if we want to write the renderer in Scala.
Scala there can support us as well, it has XML support in the language baked in.
Now lets have a look at the renderer (if not done in an xhtml template like it should be)

 

 Code m) renderer

Now the interesting part of this renderer is following code:

 Code m) render part

As we can see, we simply write the html directly constructs like     id={id} and {text} allow for inline templating.

There are constraints to this approach

  • We cannot write out partial xml. The xml written always must be complete, hence we cannot simply write an open tag first, call a subclass and then close the tag
  • We do not use the startElement, endElement. The plus side is readability. 
  • In the end a composite component and its direct xhtml rendering should always be the first choice. Xhtml simply is the target platform in most cases why not use xhtml also for the component renderer part.


References

  1. Marrying JSF and Scala Part1
  2. Marrying JSF and Scala Part2
  3. Custom Components in JSF (German)
  4. Scala Documentation

JSF Ajax and Multiple Forms

This blog post is about a problem which about 80% of all user problems regarding JSF Ajax in the MyFaces mailinglist revolve around. Namely how do I handle the JSF Ajax in a multiple form scenario.

JSF Ajax and multiple forms, a standard case, which should be easy right?

Let's have a small look at an example:

As we see here, two forms each updating a component in itself via Ajax.

 

Now what happens if we submit the forms alternating. After a while we run into a ViewRoot cannot be found Exception on the server side.

We did everything right, why do we face this issue?

The answer lies in a bug in the JSF Ajax protocol, more precisely the way the ViewState is processed. Lets have a look at an Ajax response:

Here we see the root cause of the problem. There is a parameter defining the ViewState with the identifier javax.faces.ViewState, however it is not clear where it belongs to.

 

Practically a ViewState must be attached to a form. So the issuing form definitely must receive it. However what about the other forms? And here is the root cause of the error. Only the issuing form is updated and the ViewState which is dependend on the viewroot not the form in the second form is not updated. This image shows exactly what happens:

As you can see only one form is update the second form now has a ViewState which is not the current one and at one point is dropped from the ViewState history, a classical concurrency issue.

So the solution would be to update all forms in the html document, right?

Theoretically yes, but there is one API which prevents this simple solution: Portlets, in a portlet environment you have multiple ViewRoots all belonging to different JSF session instances on the server. The next logic solution would be to update all JSF elements under ViewRoot.

Again, a good idea, but the protocol prevents it. On the pure client side we do not have any marker or indicator, which tells the Ajax code where the current ViewRoot begins. To ease this protocol problem an extension to the JSF spec was added under 2.1 which eases this problem. According to the spec you have to add the second form manually as render target. Something which both implementations follow.

Here is a snippet which shows the solution:

 

Here we can see, we have added the second form as render target. Now both forms will be updated and the ViewState always will be up to date. This solution while being spec compliant is not satisfactory.

Sometimes, you dont know if a certain form is still present after the Ajax case. Is there still a way to update all forms in the page or at least to take the form id out of the equation? Unfortunately not within the bounds of the specification.

However, being aware of this issue, I have added in Apache MyFaces additionally to the spec behavior two other ways to resolve the issue. First, you don't have to define the form as render target, but you can define any element within a form as render target and the form will be updated.

Secondly, the probably best solution.

 

A configuration parameter which forces MyFaces to update all forms in a page. With following code snippet you can enable this mechanism:

 

Once you have added this snippet of Javascript, MyFaces will be in no portlet mode and will enforce an update all forms with the ViewStates policy.

 

Note: While this method wont break the code if you switch to Mojarra, you will not get the benefits, because Mojarra does not yet have a similar solution to the issue.

JSF Ajax and Encoding

The entire story started when we got the request to encode everything in ISO-8859-1, including the Ajax cycle. Well first I thought it was easy just change the encoding on the Javascript side, let the server handle the rest.

The encoding was easily detectable on the Javascript side simply by checking the xhtmls encoding (the meta tag head encoding itself would have been another option, but since we are nailed down to xhtml anyway due to facelets we have an easier way)

Easy, I thought, but then I ran into browser hell. The problem normally would be easily resolvable.

The XHR object has the option of adding

xhr header content type:

xhr.setRequestHeader("ContentType", "application/x-www-form-urlencoded; charset=ISO-8859-15");

The problem now are the browsers themselves. By testing the dynamic encoding on various browsers following came out:

Browser Actual Encoding
Mozilla 7 UTF-8
Chrome UTF-8
IE ISO-8859-15
Opera ISO-8859-15

So what does this mean, only Opera and IE got it right.

Which means the path of allowing non UTF-8 submits is blocked for now. However JSF automatically deals with the problem properly. While I implemented the most of the Ajax part of MyFaces, I have to admit the actual encoding part was provided by another project, namely j4fry and its implementors worked on that part, so I never gave a second thought.

However both implementations deal the same way with the issue. First Ajax submits are UTF-8 encoded, this at the first look could pose problems with non UTF pages.

It turns out there are none. The solution both implementations follow is to encode the actual key value pair parameters into a utf url encoded representation. Both implementations seem to apply the encodeURIComponent function of Javascript, no matter what content type the page has, always a proper utf-8 representation of the original content will be passed down.

Given the response type also then is UTF-8 what happens with the response. After all the page needs to handle the response properly in its own encoding.

Well there MyFaces and Mojarra differ slightly. Both in compliance with the specification, encode the response in a XML CDATA block. However MyFaces does additional escaping of non ascii chars with their unicode representation, while Mojarra simply pushes the content byte per byte into the CDATA block.

Here is an example:

Mojarra:

 

Here it is clearly visible that the cdata block has a different encoding than the outer UTF-8 encoded xml. In the final page representation all the special chars are visible again as they should be. However MyFaces goes one step further and escapes the content additionally to get rid of the non utf-8 representation of the characters.

However this comes from the fact that MyFaces basically also does an escape of special chars at a full page refresh, so the core behavior regarding the partial response is the same. So what happens for instance if you just tamper with the UTF header.

 

You automatically will run into problems due to the uri encoded UTF-8 representation of the parameters. In the worst case you will trigger a server error because of non decodable parameters, in the best case if you pass down ascii only chars you will get it through, in the normal case you will get junk in which is wrongly decoded.

See here an example on IE9 and Mojarra:


The question remains, are both save from a client point of view?

Theoretically it should be since everything is embedded in a CDATA block. However I cannot say if the browsers swallow really everything within their browser engines which is embedded in a CDATA block (aka every byte combination outside of their encoding).

It comes down again to the golden rule #1 in web programming, use UFT-8 and never bother with other encodings, if you can.

Slides and examples for W-JAX 2011

The slides (in german) and examples for both Irian W-JAX 2011 sessions are available.

Irian@W-JAX 2011

Irian will be at the W-JAX 2011 in Munich. Michael Kurz will do two sessions: Go Fullstack: Webanwendungen mit Java EE 6 bauen on 8th November 2011 and JSF and JPA effizient kombinieren on 9th November 2011.

1 2 3 4 5 6 7 8 9