tag:blogger.com,1999:blog-72364653845825221832024-03-19T08:31:29.397+01:00JSF CornerRudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.comBlogger48125tag:blogger.com,1999:blog-7236465384582522183.post-74058758377326444052016-01-12T21:39:00.001+01:002016-01-12T21:45:06.674+01:00Lambda expression as JSF actionListener<h3>
Introduction</h3>
<div class="p1">
Although there is no official version of JSF which supports Java 8, there are various application servers that run on it today. And thus can we use some Java 8 features today.</div>
<div class="p2">
<br /></div>
<div class="p1">
I'll show you in this blog post an example of using a lambda expression as an action listener. And more specific where we have a custom composite component with multiple actions sources.</div>
<div class="p2">
<br /></div>
<div class="p1">
And although I'm not a fan of the <i>binding</i> property, probably due to the issues I had with it during the early days of JSF 1.x, it is a nice use case for Lambda expressions.</div>
<h3>
Custom composite component</h3>
<div class="p1">
Short recap of what a custom composite component is.</div>
<div class="p1">
If you have on multiple screens a set of components used in the same manner, you can create a custom component for it. The markup doesn't need to be exactly the same on all those pages or linked to the same managed bean, because you can specify parameters.</div>
<div class="p1">
<br /></div>
<div class="p1">
That way you can also 'build' your screens using different reusable blocks and you have a very modular approach comparable with using Java methods to increase readability.</div>
<div class="p2">
<br /></div>
<div class="p1">
And creating those custom composite components is very easy in JSF 2.x. Create JSF file with the definition of your component (interface and implementation parts) in a special specific folder and you are ready to use it due to the convention principles in place.</div>
<div class="p1">
Have a search on the internet on this topic and you find various examples how you can do it.</div>
<div class="p2">
<br /></div>
<div class="p1">
Assigning an action listener to a button within your custom composite components seems for some people a bit more difficult but using the <i>actionSource</i> attribute of the composite component namespace makes it very easy.</div>
<div class="p2">
<br />
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #e8bf6a;"><</span><span style="color: #9876aa;">ui</span><span style="color: #e8bf6a;">:component </span><span style="color: #bababa;">xmlns</span><span style="color: #6a8759;">="http://www.w3.org/1999/xhtml"
</span><span style="color: #6a8759;"> </span><span style="color: #bababa;">xmlns:</span><span style="color: #9876aa;">ui</span><span style="color: #6a8759;">="http://xmlns.jcp.org/jsf/facelets"
</span><span style="color: #6a8759;"> </span><span style="color: #bababa;">xmlns:</span><span style="color: #9876aa;">cc</span><span style="color: #6a8759;">="http://xmlns.jcp.org/jsf/composite"
</span><span style="color: #6a8759;"> </span><span style="color: #bababa;">xmlns:</span><span style="color: #9876aa;">p</span><span style="color: #6a8759;">="http://primefaces.org/ui"</span><span style="color: #e8bf6a;">>
</span><span style="color: #e8bf6a;">
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">cc:interface>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">cc:actionSource </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">name</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="submitListener" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">targets</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="submitBtn"</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">cc:actionSource </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">name</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="cancelListener" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">targets</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="cancelBtn"</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/cc:interface>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">cc:implementation>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">div>
</span><span style="color: #e8bf6a;"> </span>Some multiple button component <span style="color: #e8bf6a;">
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">p:commandButton </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">id</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="submitBtn" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">value</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="Submit"</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">p:commandButton </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">id</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="cancelBtn" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">value</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="Cancel" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">immediate</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="true"</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/div>
</span><span style="color: #e8bf6a;"> </span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/cc:implementation>
</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a;">/</span><span style="color: #9876aa;">ui</span><span style="color: #e8bf6a;">:component></span></pre>
</div>
<div class="p2">
<br /></div>
<div class="p2">
<br /></div>
<div class="p1">
The above example defines a custom composite component where we have 2 buttons and each of them, we can assign a different <i>actionListener</i>.</div>
<div class="p1">
<h3>
ActionListener</h3>
</div>
<div class="p1">
<i>ActionListener</i> is a JSF interface defined for those implementations which want to respond on the click on a button (for example there are other components which also generate the same event) on the screen.</div>
<div class="p2">
<br /></div>
<div class="p1">
The interface has just one method, as you can see;</div>
<div class="p2">
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #629755; font-style: italic;">/**
</span><span style="color: #629755; font-style: italic;"> * Invoked when an action occurs.
</span><span style="color: #629755; font-style: italic;"> * </span><span style="color: #629755; font-style: italic; font-weight: bold;">@param </span><span style="color: #8a653b; font-style: italic;">e </span><span style="color: #629755; font-style: italic;">the event to be processed
</span><span style="color: #629755; font-style: italic;"> */
</span><span style="color: #cc7832;">public void </span><span style="color: #ffc66d;">actionPerformed</span>(ActionEvent e)<span style="color: #cc7832;">;</span></pre>
</div>
<div class="p2">
<br /></div>
<div class="p1">
This makes it an ideal candidate to use it in combination with Lambda expressions since we have a <i>functional interface</i>.</div>
<div class="p2">
<br /></div>
<div class="p1">
So the following lambda expression</div>
<div class="p2">
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;">e -> System.<span style="color: #9876aa; font-style: italic;">out</span>.println(<span style="color: #6a8759;">"Save clicked"</span>)<span style="color: #cc7832;">;</span></pre>
<br /></div>
<div class="p1">
is valid implementation for the actionListener interface and thus we can assign such methods to the button(s).</div>
<div class="p1">
<h3>
Binding the actionListener implementation</h3>
</div>
<div class="p1">
As a said in the introduction, with the binding attribute, it is very easy to 'bind' an implementation of the <i>ActionListener</i> interface to the button. </div>
<div class="p2">
<br />
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="background-color: #232525; color: #e8bf6a;"><adv:multiple>
</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;"> <</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">f:actionListener </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">for</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="submitListener" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">binding</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="</span><span style="background-color: #232525; color: #cc7832; font-size: 9pt; font-weight: bold;">#{</span><span style="background-color: #232525; font-size: 9pt;">cityBean.save</span><span style="background-color: #232525; color: #cc7832; font-size: 9pt; font-weight: bold;">}</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">"</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/>
</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;"> <</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">f:actionListener </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">for</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="cancelListener" </span><span style="background-color: #232525; color: #bababa; font-size: 9pt;">binding</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">="</span><span style="background-color: #232525; color: #cc7832; font-size: 9pt; font-weight: bold;">#{</span><span style="background-color: #232525; font-size: 9pt;">cityBean.cancel</span><span style="background-color: #232525; color: #cc7832; font-size: 9pt; font-weight: bold;">}</span><span style="background-color: #232525; color: #6a8759; font-size: 9pt;">"</span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">/></span><span style="background-color: #232525; color: #e8bf6a; font-size: 9pt;">
<</span><span style="background-color: #232525; color: #e8bf6a;">/adv:multiple></span></pre>
</div>
<div class="p1">
In the above example we retrieve the instance to which the listener is bound to, with a method result. The java code can be as follows.</div>
<div class="p2">
<br /></div>
<div class="p2">
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #bbb529;">@Model</span><span style="color: #cc7832;">public class </span>CityBean {
<span style="color: #cc7832;">
private </span>ActionListener <span style="color: #9876aa;">save</span><span style="color: #cc7832;">;
</span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832;">private </span>ActionListener <span style="color: #9876aa;">cancel</span><span style="color: #cc7832;">;</span><span style="color: #bbb529;">
</span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #bbb529;">@PostConstruct
</span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832;">public void </span><span style="color: #ffc66d;">init</span>() {
<span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #9876aa; font-size: 9pt;">save </span><span style="font-size: 9pt;">= e -> System.</span><span style="color: #9876aa; font-size: 9pt; font-style: italic;">out</span><span style="font-size: 9pt;">.println(</span><span style="color: #6a8759; font-size: 9pt;">"Save clicked"</span><span style="font-size: 9pt;">)</span><span style="color: #cc7832; font-size: 9pt;">;
</span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #9876aa; font-size: 9pt;">cancel </span><span style="font-size: 9pt;">= e -> System.</span><span style="color: #9876aa; font-size: 9pt; font-style: italic;">out</span><span style="font-size: 9pt;">.println(</span><span style="color: #6a8759; font-size: 9pt;">"Cancel clicked"</span><span style="font-size: 9pt;">)</span><span style="color: #cc7832; font-size: 9pt;">;</span></pre>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #cc7832; font-size: 9pt;"> </span>}
<span style="color: #cc7832;">
</span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832;">public void </span><span style="color: #ffc66d;">performSearch</span>() {
<span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="font-size: 9pt;">System.</span><span style="color: #9876aa; font-size: 9pt; font-style: italic;">out</span><span style="font-size: 9pt;">.println(</span><span style="color: #6a8759; font-size: 9pt;">"Searching "</span><span style="font-size: 9pt;">)</span><span style="color: #cc7832; font-size: 9pt;">;</span></pre>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #cc7832; font-size: 9pt;"> </span>}
<span style="color: #cc7832;">
</span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832;">public </span>ActionListener <span style="color: #ffc66d;">getSave</span>() {
<span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;">return </span><span style="color: #9876aa; font-size: 9pt;">save</span><span style="color: #cc7832; font-size: 9pt;">;</span></pre>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #cc7832; font-size: 9pt;"> </span>}
<span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832;">public </span>ActionListener <span style="color: #ffc66d;">getCancel</span>() {
<span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;"> </span><span style="color: #cc7832; font-size: 9pt;">return </span><span style="color: #9876aa; font-size: 9pt;">cancel</span><span style="color: #cc7832; font-size: 9pt;">;</span></pre>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #cc7832; font-size: 9pt;"> </span>}
}</pre>
</div>
<div class="p1">
As you can see, this is a nice,clean usage of lambda expressions where we have multiple actionListener targets in the custom composite component.</div>
<div class="p1">
<h3>
Conclusion</h3>
</div>
<div class="p1">
Using a <i>lambda</i> expression for an <i>ActionListener</i> implementation make your code much more readable and reduces the boilerplate in those cases where you need multiple <i>actionSources</i> for a custom composite component.</div>
<div class="p2">
<br /></div>
<div class="p1">
Enjoy Java 8 and Java EE!</div>
<div class="p2">
<br /></div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-63916474321338813042015-11-05T21:44:00.001+01:002015-11-05T21:47:19.344+01:00Show application version on your JSF screens<h3>
Introduction</h3>
<div class="p1">
Sometimes it can be handy to show the application version on the screen of your application. </div>
<div class="p1">
Users get used to have access to this information and it can also ease the communication in a lot of situations. Especially when you are releasing very often.</div>
<div class="p1">
</div>
<ul>
<li>Users can see when a new version is available</li>
<li>When issues are reported, it is easier to indicate in which version it occurred</li>
<li>Refer to the version where a certain feature appeared in the application in the documentation.</li>
</ul>
<br />
<div class="p1">
In this text, I'll show you how you can create this version automatically with <i>Maven</i> and read and show it on a <i>JSF</i> screen.</div>
<h3>
Create version</h3>
<div class="p1">
<i>Maven</i> has support to put a timestamp and the project version in the manifest file. This file is specifically designed to contain this kind of information (among other things).</div>
<div class="p1">
You can configure the <i>maven-war-plugin</i> (this functionality is also available in the <i>maven-jar-plugin</i>) to put additional info in the <i><b>manifest.mf</b></i> file which is created by default.</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #e8bf6a;"><plugin>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">artifactId></span><span style="font-size: 9pt;">maven-war-plugin</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/artifactId>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">version></span><span style="font-size: 9pt;">2.4</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/version>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">configuration>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">failOnMissingWebXml></span><span style="font-size: 9pt;">false</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/failOnMissingWebXml>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">archive>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">manifestEntries>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">version></span><span style="font-size: 9pt;">${project.version}</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/version>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">buildTime></span><span style="font-size: 9pt;">${maven.build.timestamp}</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/buildTime>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">/manifestEntries>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">/archive>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">/configuration>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">goals>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">goal></span><span style="font-size: 9pt;">manifest</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/goal>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">/goals>
</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/plugin></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
The format in which the timestamp is placed in the file can be environment specific, like local settings of your computer.</div>
<div class="p1">
Therefor you should always define the timestamp format in the <i>pom.xml</i> file so that you have repeatable packaging between different environments.</div>
<div class="p2">
<br /></div>
<div class="p1">
The format can be specified by using a property like this.</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a;">properties>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">project.build.sourceEncoding></span><span style="font-size: 9pt;">UTF-8</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/project.build.sourceEncoding>
</span><span style="color: #e8bf6a; font-size: 9pt;"> <</span><span style="color: #e8bf6a; font-size: 9pt;">maven.build.timestamp.format></span><span style="font-size: 9pt;">yyyyMMdd-HHmm</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/maven.build.timestamp.format>
</span><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a; font-size: 9pt;">/properties></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
The result is that we have 2 entries in the manifest file, for example</div>
<div class="p1">
<span style="font-family: "courier new" , "courier" , monospace;">buildTime: 20151104-1123</span></div>
<div class="p1">
<span style="font-family: "courier new" , "courier" , monospace;">version: 1.0.2</span></div>
<h3>
Read the info</h3>
<div class="p1">
Reading the information is nothing specific for Java EE of JSF. We will use the <i>Properties</i> file functionality to read the file.</div>
<div class="p1">
A lot of people use the '=' sign as delimiter between the key and value pair in the file, but the semicolon (:) is also a default delimiter as you can read from this <a href="http://docs.oracle.com/javase/8/docs/api/java/util/Properties.html#load-java.io.Reader-" target="_blank">javadoc</a>.</div>
<div class="p2">
<br /></div>
<div class="p1">
So if we have a reference to the manifest file, we can feed it in the load method of the properties class and we have the version and build time (as a string).</div>
<div class="p1">
For this info, we can use the ServletContext and the resource loading which is available.</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #cc7832;">private </span>Properties <span style="color: #ffc66d;">loadManifestFile</span>() {
ServletContext servletContext = (ServletContext) FacesContext
.<span style="font-style: italic;">getCurrentInstance</span>().getExternalContext().getContext()<span style="color: #cc7832;">;</span><span style="color: #cc7832;">
</span>Properties prop = <span style="color: #cc7832;">new </span>Properties()<span style="color: #cc7832;">;
</span><span style="color: #cc7832;"> try </span>{
InputStream resourceAsStream = servletContext.getResourceAsStream(<span style="color: #6a8759;">"/META-INF/MANIFEST.MF"</span>)<span style="color: #cc7832;">;</span><span style="color: #cc7832;">
if </span>(resourceAsStream != <span style="color: #cc7832;">null</span>) {
prop.load(resourceAsStream)<span style="color: #cc7832;">;</span><span style="color: #cc7832;"> </span>}
} <span style="color: #cc7832;">catch </span>(IOException e) {
<span style="color: #9876aa;">unexpectedTechnicalExceptionController</span>.handleUnexpectedException(e)<span style="color: #cc7832;">;</span><span style="color: #cc7832;">
</span>}
<span style="color: #cc7832;">return </span>prop<span style="color: #cc7832;">;
</span>}</pre>
<div class="p2">
<br /></div>
<div class="p1">
As you can see in the above code, we need a reference to the FacesContext, so we need this code to be executed in the JSF context, like a <i>@PostConstruct</i> method of <i>@ApplicationScoped</i> CDI bean which keeps the version and build time, ready to shown it on a JSF screen.</div>
<h3>
Show the info</h3>
<div class="p1">
Showing the information is of course very specific for each application. And you would probably show it differently in each version.</div>
<div class="p1">
In my last application, I showed the information in a floating div in the bottom left area of the screen. That way, it was always visible.</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Menlo'; font-size: 9.0pt;"><span style="color: #e8bf6a; font-size: 9pt;"><</span><span style="color: #e8bf6a;">div </span><span style="color: #bababa;">style</span><span style="color: #6a8759;">="</span><span style="color: #bababa;">position</span>: <span style="color: #a5c261;">fixed</span><span style="color: #cc7832;">; </span><span style="color: #bababa;">bottom</span>: <span style="color: #6897bb;">0</span><span style="color: #cc7832;">; </span><span style="color: #bababa;">right</span>: <span style="color: #6897bb;">0</span><span style="color: #cc7832;">;</span><span style="color: #6a8759;">"</span><span style="color: #e8bf6a;">>
</span><span style="background-color: #232525; color: #cc7832; font-weight: bold;"> #{</span><span style="background-color: #232525;">infoBean.version</span><span style="background-color: #232525; color: #cc7832; font-weight: bold;">}</span><span style="color: #cc7832; font-weight: bold;"> </span>(<span style="background-color: #232525; color: #cc7832; font-weight: bold;">#{</span><span style="background-color: #232525;">infoBean.buildTime</span><span style="background-color: #232525; color: #cc7832; font-weight: bold;">}</span>)
<span style="color: #e8bf6a;"></div></span></pre>
<h3>
Conclusion</h3>
<div class="p1">
With some easy configuration of maven, a simple read from the manifest file with the Properties class, we are able to show the version and built time of your application on screen. </div>
<div class="p1">
This can help in the good communication with your end users.</div>
<div class="p1">
And of course, other information can be stored and used in a similar way.</div>
<div class="p1">
Enjoy.</div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-71020929523889952072015-07-27T21:28:00.000+02:002015-07-27T21:28:04.346+02:00Temporarily disable or conditional executing of PrimeFaces AJAX calls<h3>
Introduction</h3>
<div class="p2">
In JSF 2.0, the AJAX functionality is standardised in the specification and can be used in a consistent way between JSF implementations and component libraries like <b><i>PrimeFaces</i></b>.</div>
<div class="p1">
With the addition of new functionality, new usage patterns become a habit. But new usages also brings more advanced scenarios with their own issues.</div>
<div class="p2">
<br /></div>
<div class="p1">
The situation I want to discuss today, is where you have the need for some partial screen update with AJAX but which you don't want in all situations. The conditional aspect which I referred to in the title of the text.</div>
<h3>
Problem description</h3>
<div class="p2">
<br /></div>
<div class="p1">
Suppose you have the following screen area:</div>
<div class="p2">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnGEOKl8gzWu3ymespYqUgk4bnr2FNN3zI-AupR7Aj9poDWEYQPsw_hr0975kGIT7YFaum7zjkZeV6WTMzcwDnU_xY0egy_9Erd6z3DTc0oFpMmI0civV-cUb_KRIdAXuBBeoDTsuKjhoX/s1600/Screen+Shot+2015-07-27+at+21.01.45.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnGEOKl8gzWu3ymespYqUgk4bnr2FNN3zI-AupR7Aj9poDWEYQPsw_hr0975kGIT7YFaum7zjkZeV6WTMzcwDnU_xY0egy_9Erd6z3DTc0oFpMmI0civV-cUb_KRIdAXuBBeoDTsuKjhoX/s320/Screen+Shot+2015-07-27+at+21.01.45.png" width="320" /></a></div>
<div class="p2">
<br /></div>
<div class="p1">
It contains the following elements from left to right</div>
<div class="p1">
* A field to enter an existing code. When the end user leaves the field, the code is looked up.</div>
<div class="p1">
* A second, read only field or label, where the description of the code is placed when it is an existing one.</div>
<div class="p1">
* A button, which is only available when the first field doesn't contain an existing code and lets you add a new one.</div>
<div class="p2">
<br /></div>
Within the JSF page, the structure looks something like this.<br /><br /><pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="background-color: #303232; color: #e8bf6a;"><h:panelGroup </span><span style="background-color: #303232; color: #bababa;">id</span><span style="background-color: #303232; color: #a5c261;">="codeArea"</span><span style="background-color: #303232; color: #e8bf6a;">></span><span style="color: #e8bf6a;">
</span><span style="color: #e8bf6a;"> </span>Code :
</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;"><</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">p:inputText </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">value</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">#{</span><span style="background-color: #303232; font-size: x-small;">codeBean.code</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">}</span><span style="font-size: x-small;"><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232; color: #bababa;">id</span><span style="background-color: #303232; color: #a5c261;">="code"</span><span style="background-color: #303232; color: #e8bf6a;">>
</span></span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;"> <</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">p:ajax </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">event</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="blur" </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">listener</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">#{</span><span style="background-color: #303232; font-size: x-small;">codeBean.onBlurCode</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">" </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">update</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="codeArea"</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">/>
</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;"> <</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">/p:inputText></span></pre>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;"> <</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">p:inputText </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">value</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">#{</span><span style="background-color: #303232; font-size: x-small;">codeBean.codeDescription</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">" </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">disabled</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="true" </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">placeholder</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="description"</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">/>
</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;"> <</span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;">p:commandButton </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">icon</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="fa fa-plus-circle" </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">actionListener</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">#{</span><span style="background-color: #303232; font-size: x-small;">codeBean.addCode</span><span style="background-color: #303232; color: #cc7832; font-size: x-small; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">" </span><span style="background-color: #303232; color: #bababa; font-size: x-small;">update</span><span style="background-color: #303232; color: #a5c261; font-size: x-small;">="codeArea" </span><span style="font-size: x-small;"><span style="background-color: #303232; color: #bababa;">disabled</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">#{empty </span><span style="background-color: #303232;">codeBean.description</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232; color: #e8bf6a;">/>
</span></span><span style="background-color: #303232; color: #e8bf6a; font-size: x-small;"><</span><span style="font-size: x-small;"><span style="background-color: #303232; color: #e8bf6a;">/h:panelGroup></span></span></pre>
<br />With the ajax tag within the input field, we can perform the partial screen update when we leave the input field. We need to update the complete group as the button needs to become disabled as we enter an existing code.<h3>
Conditional executing</h3>
<div class="p1">
This construct works perfectly when you tab out of the input field. The blur event triggers the AJAX execution and the server side code checks if the code exists. Due to the partial screen update the button becomes disabled when the code doesn't exists or enabled when the code isn't found.</div>
<div class="p2">
<br /></div>
<div class="p1">
But there is a scenario which fails; when the focus is in the input field and we click on the command button. You will found out that the click on the button is ignored. </div>
<div class="p2">
<br /></div>
<div class="p1">
If we inspect what is happening in the network console of the browser; we see that there is an AJAX request to the server which corresponds to the blur event of the field. But there is no request which corresponds to the click on the button.</div>
<div class="p1">
This is because the blur event replaced the DOM element in the browser with another, for the end user identical component. So the click is on an element which no longer exist on the screen after the AJAX completes.</div>
<div class="p2">
<br /></div>
<div class="p1">
So how can we solve this? Luckily <b><i>PrimeFaces</i></b> uses <b><i>JQuery</i></b> on the client side. So when we could disable the <i>onblur</i> event execution in the case when we click on the button, we have a solution. And the good thing is that we can achieve this, quite easily.</div>
<div class="p2">
<br /></div>
<div class="p1">
The <i>mousedown</i> event is executed before the blur event. This is can bee seen by the following <a href="http://codepen.io/mudassir0909/pen/eIHqB" target="_blank">testing code</a>. (thanks to <a href="http://codepen.io/mudassir0909/" target="_blank">mudassir</a>)</div>
<div class="p1">
<br /></div>
<div class="p1">
So by adding the following code:</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: 'Courier New'; font-size: small;"><span style="background-color: #303232;">onmousedown</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">$(PrimeFaces.<wbr></wbr>escapeClientId('frm:<wbr></wbr>code')).off();</span><span style="background-color: #303232; color: #a5c261;"><wbr></wbr>"</span></pre>
<div class="p1">
<br /></div>
<div class="p1">
We can remove all event handlers from the input field, and thus the click is executed.</div>
<h3>
Conclusion</h3>
<div class="p2">
Making the AJAX functionality can be easily achieved within PrimeFaces with the help of <i>JQuery</i> which is already available in the browser? In this text I showed you how you can disable the <i>blur</i> event in the case when you click a specific button but it will be active in other scenarios.</div>
<div class="p2">
<br /></div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-44607057825660800012015-06-08T20:34:00.002+02:002015-06-08T20:34:54.945+02:00Focus HTML element after AJAX call with PrimeFaces<div class="p1">
<br /></div>
<h3>
Introduction</h3>
<div class="p1">
The combination of AJAX updates to the screen and the focus of a field is more then once an issue for the developer. And this is not an issue of PrimeFaces, but comes with the fact of using AJAX.</div>
<div class="p1">
<br /></div>
<div class="p2">
This blog explains what you can due in the 2 most important scenarios what you normally encounter.</div>
<h3>
Problem description</h3>
<div class="p1">
Image you have on the screen 2 input fields, field A en field B. There is an onBlur handler attached to field A which does a partial update of the screen, containing field B, with an AJAX call.</div>
<div class="p1">
<br /></div>
<div class="p2">
So what happens when the user is in field A en tabs out of the field? Leaving the field, results in the trigger of the <i>onBlur</i> handler. During the time that the AJAX calls is performed asynchronously, the browser performs the standard behaviour, and thus the focus is placed in the field B.</div>
<div class="p1">
<br /></div>
<div class="p2">
But then the AJAX call returns and results in updating the screen, and there are use cases where the developer decided to replace the field B. And since it is a replacement of the element in the DOM tree, the focus which was original in the field B is now lost because the field is replaced by another element.</div>
<h3>
Fixing focus issue</h3>
<div class="p2">
The first scenario describes the situation where the focus must be placed in a certain field which is updated by the AJAX call. But it is always the same field regardless of the result of the server side code.</div>
<div class="p1">
<br /></div>
<div class="p2">
This can easily achieved by using the <i>oncomplete</i> attribute of the PrimeFaces widget who initiated the AJAX call.</div>
<div class="p2">
This is JavaScript code which is performed when the AJAX call was successful (and thus there was no error) and the replacement of the DOM elements in the browser is completed.</div>
<div class="p2">
So at this point the DOM tree is stable again and we can give a field the focus.</div>
<div class="p1">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="background-color: #303232; color: #bababa;">oncomplete</span><span style="background-color: #303232; color: #a5c261;">="PrimeFaces.focus('frm:newProjectName');"</span></span></pre>
<div class="p1">
<br /></div>
<div class="p2">
The above snippet places the focus in the newProjectName field when the AJAX is finished.</div>
<h3>
Conditionally define the focus</h3>
<div class="p1">
Another scenario is where the fields that needs to get the focus needs to be defined conditionally. Lets examen this use case better with some screen example.</div>
<div class="p1">
<br /></div>
<div class="p1">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAM7UPnndvDgB0IpbpbPP0NGflJHUL-Bi9fTHMJ_uwmYtbAKk4m9fboBQ1lY5NykKCR3RDH0EW_O_ywsirp9BZZkYgRTl5bEqqhejX278doflkNgYL7-c0rYLdLkhqggSvCjyGmzj85i2g/s1600/FocusScreen.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAM7UPnndvDgB0IpbpbPP0NGflJHUL-Bi9fTHMJ_uwmYtbAKk4m9fboBQ1lY5NykKCR3RDH0EW_O_ywsirp9BZZkYgRTl5bEqqhejX278doflkNgYL7-c0rYLdLkhqggSvCjyGmzj85i2g/s320/FocusScreen.png" width="320" /></a></div>
<br /></div>
<div class="p1">
<br /></div>
<div class="p2">
In the above case, we have a field to enter some kind of code. And depending on the code, we sometimes needs additional information from the user.</div>
<div class="p2">
So, there will be an AJAX handler (p:ajax) which call some java listener method to perform the server side functionality which defines if there is additional information needed. </div>
<div class="p1">
<br /></div>
<div class="p2">
Initially the '<i>additional</i>' field is disabled, so the focus is not placed in this field by the browser. And since the field is replaced by the AJAX call in the DOM tree, the focus would be lost anyway.</div>
<div class="p1">
<br /></div>
<div class="p2">
But from within the Java listener method, we can execute some JavaScript when the AJAX call is finished. This is one of the great features of PrimeFaces.</div>
<div class="p1">
<br /></div>
<div class="p2">
So, by adding the following code in the Java method, we can place the focus in the additional field. And within Java it is easy when this focus must be placed there (the conditional aspect of this usecase)</div>
<div class="p1">
<br />
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;">RequestContext.<span style="font-style: italic;">getCurrentInstance</span>().execute(<span style="color: #6a8759;">"PrimeFaces.focus('frm:additionalInfo');"</span>)<span style="color: #cc7832;">;</span></span></pre>
<br /></div>
<div class="p2">
<h3>
Conclusion</h3>
</div>
<div class="p1">
The focus and AJAX combination has some conflicts. In the Expert group for JSF 2.3, they are considering some additional tags to handle those situations.</div>
<div class="p2">
Within PrimeFaces, we saw with 2 usecases that you can manage the problem with the usage of the excellent integration of JavaScript within PrimeFaces. This from within the view (JSF pages) as from within Java.</div>
<div class="p1">
<br /></div>
<div class="p2">
Have fun.</div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com2tag:blogger.com,1999:blog-7236465384582522183.post-85841751191332741752015-05-04T21:37:00.000+02:002018-02-26T09:11:07.134+01:00Introducing Jerry and Valerie<div class="p1">
Or the JSF renderer interceptor and the (bean) validation extension.</div>
<div class="p2">
<br />
A major new version is available under the Atbash umbrella: <a href="http://www.atbash.be/2018/02/26/a-renderer-interceptor-concept-for-java-serverfaces/">http://www.atbash.be/2018/02/26/a-renderer-interceptor-concept-for-java-serverfaces/</a></div>
<h3>
Introduction</h3>
<div class="p1">
The first opensource project where I ever posted a change to, was <b>Apache MyFaces Extension Validation</b>, <a href="http://wiki.apache.org/myfaces/Extensions/Validator" target="_blank">ExtVal</a> in short. It is a framework for having a validation platform with many great features.</div>
<div class="p2">
<br /></div>
<div class="p1">
But the last few years, I only used a few specific parts of the platform with some of my own extensions.</div>
<div class="p1">
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.</div>
<div class="p1">
But if you like, you can still create all the features from ExtVal in the new version.</div>
<div class="p2">
<br /></div>
<h3>
Jerry</h3>
<div class="p1">
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.</div>
<div class="p1">
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.</div>
<div class="p2">
<br /></div>
<div class="p1">
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</div>
<div class="p2">
<br /></div>
<div class="p1">
1- Add Jerry to your maven project</div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #e8bf6a;"><dependency>
</span></span><span style="color: #e8bf6a; font-size: x-small;"> <</span><span style="color: #e8bf6a; font-size: x-small;">groupId></span><span style="font-size: x-small;">be.rubus.web</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a; font-size: x-small;">/groupId>
</span><span style="color: #e8bf6a; font-size: x-small;"> <</span><span style="color: #e8bf6a; font-size: x-small;">artifactId></span><span style="font-size: x-small;">jerry</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a; font-size: x-small;">/artifactId>
</span><span style="color: #e8bf6a; font-size: x-small;"> <</span><span style="color: #e8bf6a; font-size: x-small;">version></span><span style="font-size: x-small;">${jerry.version}</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a; font-size: x-small;">/version>
</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="font-size: x-small;"><span style="color: #e8bf6a;">/dependency></span></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
2- Define a <i>ComponentInitializer</i>, this is a specific renderer interceptor which can perform some actions in the before encode begin step.</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #bbb529;">@ApplicationScoped
</span><span style="color: #cc7832;">public class </span>RequiredInitializer <span style="color: #cc7832;">implements </span>ComponentInitializer {
<span style="color: #bbb529;"> @Override
</span><span style="color: #cc7832;"> public void </span><span style="color: #ffc66d;">configureComponent</span>(FacesContext facesContext<span style="color: #cc7832;">, </span>UIComponent uiComponent<span style="color: #cc7832;">, </span>Map<String<span style="color: #cc7832;">, </span>Object> metaData) {
InputText inputText = (InputText) uiComponent<span style="color: #cc7832;">;
</span><span style="color: #cc7832;">
if </span>(inputText.isRequired()) {
String style = inputText.getStyle()<span style="color: #cc7832;">;
</span><span style="color: #cc7832;"> if </span>(style == <span style="color: #cc7832;">null</span>) {
style = <span style="color: #6a8759;">""</span><span style="color: #cc7832;">;
</span> }
inputText.setStyle(style + <span style="color: #6a8759;">" background-color: #B04A4A;"</span>)<span style="color: #cc7832;">;
</span>
}
}
<span style="color: #bbb529;">
@Override
</span><span style="color: #cc7832;"> public boolean </span><span style="color: #ffc66d;">isSupportedComponent</span>(UIComponent uiComponent) {
<span style="color: #cc7832;"> return </span>uiComponent <span style="color: #cc7832;">instanceof </span>InputText<span style="color: #cc7832;">;
</span> }
}</span><span style="font-size: 12pt;">
</span></pre>
<div class="p2">
<br /></div>
<div class="p1">
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 <i>ApplicationScoped</i>. But it gives us also the possibility to inject any other CDI bean into this initialiser method.</div>
<div class="p2">
<br /></div>
<div class="p1">
Jerry is used in the Java EE declarative permission security framework <b><a href="https://bitbucket.org/contribute-bitbucket/javaeesecurityfirst/wiki/UserManual%20v0.9.5" target="_blank">Octopus</a></b> to handle the security on the JSF component level.</div>
<h3>
Valerie</h3>
<div class="p1">
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.</div>
<div class="p2">
<br /></div>
<div class="p1">
For example, suppose you have a property for the name of a person</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #bbb529;">@Size</span>(<span style="color: #d0d0ff;">max </span>= <span style="color: #6897bb;">50</span>)
<span style="color: #cc7832;">private </span>String <span style="color: #9876aa;">name</span></span><span style="color: #cc7832;"><span style="font-size: x-small;">;</span><span style="font-size: 12pt;">
</span></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
When you have a JSF input field component pointing to to this property</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="font-size: x-small;"><span style="background-color: #303232; color: #e8bf6a;">h:inputText </span><span style="background-color: #303232; color: #bababa;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">#{</span><span style="background-color: #303232;">personBean.name</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232; color: #e8bf6a;">/></span></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
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 <i>h:inputText</i> but it should go automatically, no.</div>
<div class="p2">
<br /></div>
<div class="p1">
That is where Valerie comes into the scene, another extraction from the <b>ExtVal</b> framework. </div>
<div class="p2">
<br /></div>
<div class="p1">
<u>side note;</u> 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.</div>
<div class="p2">
<br /></div>
<div class="p1">
So how can we have in the above example the size restriction from the bean validation property size on the screen?</div>
<div class="p1">
<br /></div>
<div class="p1">
The only thing you need to do is add the Valerie dependency to your project. </div>
<div class="p1">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="font-size: x-small;"><span style="color: #e8bf6a;">dependency>
</span></span><span style="color: #e8bf6a; font-size: x-small;"> <</span><span style="color: #e8bf6a; font-size: x-small;">groupId></span><span style="font-size: x-small;">be.rubus.web</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a; font-size: x-small;">/groupId>
</span><span style="color: #e8bf6a; font-size: x-small;"> <</span><span style="color: #e8bf6a; font-size: x-small;">artifactId></span><span style="font-size: x-small;">valerie</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a; font-size: x-small;">/artifactId>
</span><span style="color: #e8bf6a; font-size: x-small;"> <</span><span style="color: #e8bf6a; font-size: x-small;">version></span><span style="font-size: x-small;">${valerie.version}</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a; font-size: x-small;">/version>
</span><span style="color: #e8bf6a; font-size: x-small;"><</span><span style="color: #e8bf6a;"><span style="font-size: x-small;">/dependency></span></span></pre>
<div class="p1">
<br /></div>
<div class="p1">
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.</div>
<h3>
Conclusion</h3>
<div class="p1">
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.</div>
<div class="p2">
<br /></div>
<div class="p1">
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.</div>
<div class="p2">
<br /></div>
<div class="p2">
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.</div>
<div class="p2">
<br /></div>
<div class="p1">
The basic documentation of the project can be found <a href="https://github.com/rdebusscher/jsf-renderer-extensions/wiki" target="_blank">here</a> and feedback, issues, feature request are welcome at the issue tracker on gitHub.</div>
<div class="p1">
<br /></div>
<div class="p1">
Maven artefacts are available in the C4J OpenSource Nexus </div>
<div class="p1">
<span style="font-size: x-small;"><span style="color: #e8bf6a; font-family: "menlo";"><url></span><span style="background-color: #2b2b2b; color: #a9b7c6; font-family: "menlo";">http://nexus-osc4j.rhcloud.com/content/groups/public/</span><span style="color: #e8bf6a; font-family: "menlo";"></url></span></span></div>
<div class="p1">
Have fun with it.</div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-30236531065418777362015-04-13T18:29:00.001+02:002015-04-13T18:45:53.143+02:00Native GridLayout component in PrimeFaces 5.2 (panelGrid)<h3>
Introduction</h3>
<div class="p1">
A while ago, I blogged here about the GridLayout component for JSF 2.X which allow you to have the responsive layout using DIV structure with CSS classes from Bootstrap or PrimeFaces. </div>
<div class="p2">
<br /></div>
<div class="p1">
<a href="http://jsfcorner.blogspot.be/2015/01/gridlayout-component-for-jsf-2x.html">http://jsfcorner.blogspot.be/2015/01/gridlayout-component-for-jsf-2x.html</a></div>
<div class="p2">
<br /></div>
<div class="p1">
In the recent PrimeFaces 5.2, the panelGrid component is improved so that you can have the same functionality. </div>
<h3>
Improvements</h3>
<div class="p1">
With the new version, you can specify the CSS column class yourself, which allows you to have columns of different width.</div>
<div class="p2">
<br /></div>
<br />
<div class="p1">
So now it is possible to write something like this </div>
<div class="p1">
<br />
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:panelGrid </span><span style="background-color: #303232;">columns</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">2</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">columnClasses</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">ui-grid-col-8, ui-grid-col-4</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">style</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">width: 100%</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">layout</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">grid</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">></span>
<span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">h:outputLabel </span><span style="background-color: #303232;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">First Column</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">/></span>
<span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">h:outputLabel </span><span style="background-color: #303232;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">Second Column</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">/></span>
<span style="background-color: #303232;"></</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:panelGrid</span><span style="background-color: #303232;">></span></span><span style="font-size: 12pt;">
</span></pre>
</div>
<div class="p1">
And have 2 columns, the first twice as wide as the second one.</div>
<div class="p2">
<br /></div>
<div class="p1">
The old functionality is still available, so if you don't specify any columnClasses in the above example, both columns have the same width.</div>
<div class="p2">
<br /></div>
<div class="p1">
So if you are using PrimeFaces, there is no need anymore for my GridLayout component, unless you want to use twitter bootstrap CSS classes.</div>
<div class="p2">
<br /></div>
<div class="p1">
</div>
<div class="p1">
That is all for now about the new primeFaces 5.2. Enjoy it.</div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-17561167129133952152015-03-29T20:53:00.000+02:002015-03-29T20:53:25.456+02:00Advanced File download with PrimeFaces<h3>
Introduction</h3>
<div class="p2">
<br /></div>
<div class="p1">
When your Web application needs to send a file to the browser, the classic approach is using a web servlet to serve the contents.</div>
<div class="p1">
<i>PrimeFaces</i> has a specific tag for downloading a file, so that you don't need a servlet. And with a small trick, you can even update the screen in the same action.</div>
<div class="p2">
<br /></div>
<h3>
FileDownload component</h3>
<div class="p1">
The example with the servlet can be skipped, I guess. Everyone created already a servlet which is able to send content to the browser.</div>
<div class="p1">
When you are working with JSF, and <i>PrimeFaces</i>, there is an alternative for the servlet approach.</div>
<div class="p1">
PrimeFaces has the <b>FileDownload</b> component. It is an <i>ActionListener</i>, so you can use it on a commandButton to perform the download.</div>
<div class="p2">
<br /></div>
<div class="p1">
Let's have an example.</div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:commandButton </span><span style="background-color: #303232;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">Download</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">ajax</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">false</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">></span>
<span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:fileDownload </span><span style="background-color: #303232;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">#{</span><span style="background-color: #303232;">fileBean.file</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">/></span>
<span style="background-color: #303232;"></</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:commandButton</span><span style="background-color: #303232;">></span></span></pre>
<div class="p1">
<br /></div>
<pre style="background-color: #2b2b2b; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #bbb529;">@ManagedBean</span><span style="color: #a9b7c6;">(</span><span style="color: #d0d0ff;">name </span><span style="color: #a9b7c6;">= </span><span style="color: #6a8759;">"fileBean"</span><span style="color: #a9b7c6;">)
</span><span style="color: #bbb529;">@RequestScoped
</span><span style="color: #cc7832;">public class </span><span style="color: #a9b7c6;">FileDownloadController {
</span><span style="color: #cc7832;">public </span><span style="color: #a9b7c6;">StreamedContent </span><span style="color: #ffc66d;">getFile</span><span style="color: #a9b7c6;">() {
InputStream stream = </span><span style="color: #cc7832;">this</span><span style="color: #a9b7c6;">.getClass().getResourceAsStream(</span><span style="color: #6a8759;">"/yourfile.txt"</span><span style="color: #a9b7c6;">)</span><span style="color: #cc7832;">;</span><span style="color: #cc7832;"> return new </span><span style="color: #a9b7c6;">DefaultStreamedContent(stream</span><span style="color: #cc7832;">, </span><span style="color: #6a8759;">"text/plain"</span><span style="color: #cc7832;">, </span><span style="color: #6a8759;">"downloaded_file.txt"</span><span style="color: #a9b7c6;">)</span><span style="color: #cc7832;">;</span><span style="color: #cc7832;"> </span><span style="color: #a9b7c6;">}
}</span></span></pre>
<div class="p1">
<br /></div>
<div class="p1">
The StreamedContent, already used by the graphicImage component, contains the data which is send to the browser. You can supply the constructor with an InputStream which has the actual contents.</div>
<div class="p2">
<br /></div>
<div class="p1">
This can be static file or a dynamically generated one. The PrimeFaces code is then responsible for reading from the InputStream and send it to the browser. Together with the required housekeeping like setting the mime type, http status and setting the JSF response as completed.</div>
<div class="p2">
<br /></div>
<h3>
Advanced use case</h3>
<div class="p1">
Together with file download, there are use cases where you also need to update the screen which initiated the download.</div>
<div class="p1">
Recently we had the use case where the end user can specify some options of the file he wants to download. The options are presented in a dialog which should be preferably closed when the download is performed. Also the screen should be indicate the file download occurred.</div>
<div class="p2">
<br /></div>
<div class="p1">
Here the <b>RemoteCommand</b> is the solution to these cases. The <b>RemoteCommand</b> allows to call some JSF bean methods and JSF lifecycle methods from JavaScript.</div>
<div class="p2">
<br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:commandButton </span><span style="background-color: #303232;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">Download2</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">ajax</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">false</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">onclick</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">pageRefresh();</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">></span>
<span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:fileDownload </span><span style="background-color: #303232;">value</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">#{</span><span style="background-color: #303232;">fileBean.file</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">}</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">/></span>
<span style="background-color: #303232;"></</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:commandButton</span><span style="background-color: #303232;">></span>
<span style="background-color: #303232;"><</span><span style="background-color: #303232; color: #cc7832; font-weight: bold;">p:remoteCommand </span><span style="background-color: #303232;">update</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">@all</span><span style="background-color: #303232; color: #a5c261;">" </span><span style="background-color: #303232;">name</span><span style="background-color: #303232; color: #a5c261;">="</span><span style="background-color: #303232; color: #6a8759;">pageRefresh</span><span style="background-color: #303232; color: #a5c261;">"</span><span style="background-color: #303232;">/></span></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
When we click on the button, the <i>onClick</i> activates the javaScript version of the RemoteCommand and initiates a AJAX partial page refresh of the screen. On the other hand, the click on the button also initiates the <i>ActionListener</i> of the <i>FileDownload</i> component to perform the file download.</div>
<div class="p2">
<br /></div>
<div class="p1">
Since we where able to initiate 2 calls, we can perform 2 actions, the download and the screen update.</div>
<div class="p2">
<br /></div>
<h3>
Conclusion</h3>
<div class="p1">
With the help of the FileDownload component it becomes easier to program the download of a static or dynamic file in JSF. You no longer need a servlet to perform these kind of actions.</div>
<div class="p1">
With the help of the very broad useable RemoteCommand component, we can even initiate 2 actions. The file download and some screen updates.</div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-80736382490057291512015-03-15T21:46:00.001+01:002015-03-15T21:46:32.838+01:00Override Java settings on OpenShift<h3>
Introduction</h3>
<div class="p2">
<br /></div>
<div class="p1">
With OpenShift, your server instance in the cloud is prepared with a few mouse clicks or with a single command with the rhc tool.</div>
<div class="p1">
In most of the cases, this is all you need and you can start right away with your freshly created server instance (named <i>gear</i> in OpenShift terminology).</div>
<div class="p1">
But in other situations, you want to make some changes to the Java environment, like setting system properties or changing the security settings.</div>
<div class="p2">
<br /></div>
<div class="p1">
In the case of the security settings, in a normal environment, you can update the <b>java.security</b> file in the <b>JRE_HOME/lib/security</b> folder. But on the OpenShift environment there are some constraints which makes this task a bit more difficult. This text shows you an easy way to accomplish your goal.</div>
<div class="p1">
<br /></div>
<h3>
History</h3>
<div class="p1">
We have developed a JSF application which uses OAuth2 as authentication means. So we are using an SSL connection to the OAuth2 provider to verify the tokens which are presented to the applications.</div>
<div class="p1">
It was working fine on OpenShift with the latest WildFly 8.2 cartridge. And last week, we created a new gear and our application throw an exception</div>
<div class="p2">
<br /></div>
<div class="p1">
<span style="font-family: Courier New, Courier, monospace;"><i>java.security.NoSuchAlgorithmException: EC AlgorithmParameters not available</i></span></div>
<div class="p2">
<br /></div>
<div class="p1">
When we compared this new instance with the instance we had already running, we found out that the java version was different. The newest one, is using <b>OpenJDK 8u31</b>. And searching on the web for the combination of this version and the exception we received, revealed that there is an issue with this version related to <b>Elliptic curve algorithm</b>.</div>
<div class="p2">
<br /></div>
<div class="p1">
So, the next step was to edit the <i>java.security</i> file to exclude the algorithm which causes problems in our cases. </div>
<div class="p1">
The key <b>jdk.tls.disabledAlgorithms</b> in the file, needs to contain the codes of the algorithms we don't want, in our situation <i>EC,ECDHE,ECDH.</i></div>
<div class="p2">
<br /></div>
<div class="p1">
But when I opened the java.security file and wanted to change the content, I received the warning that the film is <b>read-only</b>. And you can't change it and you can't become a super user to overrule it.</div>
<div class="p2">
<br /></div>
<div class="p1">
And I can understand that you want to secure some parts of the server. But it is no option for us to rewrite the Web application with Java 7 due to a, hopefully, temporarily issue with the Java which is running on the gear.</div>
<div class="p1">
<br /></div>
<h3>
Solution</h3>
<div class="p1">
The solution was found when I found the blog of <a href="http://blog.eyallupu.com/2012/11/how-to-overriding-java-security.html" target="_blank">Eyal Lupu</a> which gives a nice example of how you can override the contents of the <i>java.security</i> file (the documentation in the file itself indicate already this possibility but with the example it became clear for me) and the <a href="https://www.openshift.com/sites/default/files/documents/OpenShift_Online-2.0-User_Guide-en-US_7.pdf" target="_blank">OpenShift user guide</a>.</div>
<div class="p1">
<br /></div>
<div class="p1">
So we created a file on the gear to override the key <i>jdk.tls.disabledAlgorithms</i> from the <i>java.security</i> file. And by setting a system property using the <b>JAVA_OPTS_EXT</b> environment variable of the gear, we are able to make the application run again without throwing the exception.</div>
<div class="p2">
<br /></div>
<div class="p1">
<b><u>Create the file</u></b></div>
<div class="p2">
<br /></div>
<div class="p1">
</div>
<ul>
<li> rhc ssc <span style="font-family: Courier New, Courier, monospace;">gearName</span></li>
<li> cd $OPENSHIFT_DATA_DIR</li>
<li> vi <span style="font-family: Courier New, Courier, monospace;">override_security.properties</span></li>
<li> content is <span style="font-family: Courier New, Courier, monospace;">jdk.tls.disabledAlgorithms=EC,ECDHE,ECDH</span></li>
<li> pwd -> and note down (copy) the full path location of the just created file.</li>
<li> exit</li>
</ul>
<br />
<div class="p1">
<u><b>Set the environment variable</b></u></div>
<div class="p2">
<br /></div>
<div class="p1">
</div>
<ul>
<li> rhc env set JAVA_OPTS_EXT=-Djava.security.properties=file:<span style="font-family: Courier New, Courier, monospace;"><<filelocation>></filelocation></span> -a <span style="font-family: Courier New, Courier, monospace;">gearName</span></li>
</ul>
<div class="p1">
<b><u>Restart your gear/app</u></b></div>
<div class="p2">
<br /></div>
<div class="p1">
</div>
<ul>
<li> rhc app restart -a <span style="font-family: Courier New, Courier, monospace;">gearName</span></li>
</ul>
<br />
<div class="p2">
<br /></div>
<div class="p1">
The OPENSHIFT_DATA_DIR isn't chosen at random. It is the only directory which isn't cleared when you push some code to the git repository. So our file is save there and will not be touched by any of the system processes.</div>
<div class="p2">
<br /></div>
<h3>
Conclusion</h3>
<div class="p1">
The JAVA_OPTS_EXT environment variable is important if you want to change some settings of the Java Environment. You can add some system properties to configure your application (like setting the JSF project stage) or to override the <i>java.security</i> configuration for instance as explained in this text.</div>
<div class="p2">
<br /></div>
<br />
<div class="p1">
Hope this help you if you have a similar 'issue' with OpenShift.</div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-72400560216209649062015-01-19T09:16:00.000+01:002015-04-13T18:31:50.707+02:00GridLayout component for JSF 2.X<h3>
Introduction</h3>
<div class="p1">
It is common practice to use a CSS Grid to define the layout of your web application page. We shouldn’t use tables for that purpose.</div>
<div class="p1">
Also in JSF we can use this CSS Grid but it requires quit a lot of DIV elements and thus boilerplate in your page. The good thing is that we can create a custom component which reduce the amount of html we need to put in dramatically. The component got the name <b>gridLayout</b>.</div>
<div class="p2">
<br /></div>
<div class="p1">
PrimeFaces recently introduced in his version 5.1, also CSS Grid classes. The following example comes from the user guide.</div>
<div class="p3">
</div>
<div class="page" title="Page 235">
<div class="section" style="background-color: rgb(100.000000%, 83.137000%, 47.450000%);">
<div class="layoutArea">
<div class="column">
<pre><span style="font-family: 'Monaco'; font-size: 9.000000pt;"><div class="ui-grid">
</span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">div class="ui-grid-row"></span></pre>
<pre><span style="font-family: 'Monaco'; font-size: 9.000000pt;"> </span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">div class="ui-grid-col-4">Col1</span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">/div></span></pre>
<pre><span style="font-family: 'Monaco'; font-size: 9.000000pt;"> </span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">div class="ui-grid-col-4">Col2</span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">/div></span></pre>
<pre><span style="font-family: 'Monaco'; font-size: 9.000000pt;"> </span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">div class="ui-grid-col-4">Col2</span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">/div></span></pre>
<pre><span style="font-family: 'Monaco'; font-size: 9.000000pt;"> </span><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: Monaco; font-size: 9pt;">/div></span></pre>
<pre><span style="font-family: Monaco; font-size: 9pt;"><</span><span style="font-family: 'Monaco'; font-size: 9.000000pt;">/div>
</span></pre>
</div>
</div>
</div>
</div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">But also other CSS Grid systems can be used with the gridLayout custom component. The component was first used in an application that used the Bootstrap CSS grid. And in fact, all CSS grids can be used as you specify which CSS class will be used on the row DIV and which will be used on the column DIVs.</span></div>
<h3>
<span class="s1">gridLayout</span></h3>
<div class="p2">
The gridLayout component has 3 attributes, which are<span class="s1"></span></div>
<div class="p1">
<span class="s1"><b>columns</b>: This determines the number of columns which should be created.</span></div>
<div class="p1">
<span class="s1"><b>rowClass</b>: Determines the CSS class which will be used on the row DIV, in above example it is ui-grid-row.</span></div>
<div class="p1">
<span class="s1"><b>columnClasses</b>: A comma separated list of CSS classes which will be used on the column DIVs.</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<div class="p1">
<span class="s1">The needed steps to integrate the component are described further on in this text, I already give you an example usage:</span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #e8bf6a;"><</span><span style="color: #9876aa;">c4j</span><span style="color: #e8bf6a;">:gridLayout </span><span style="color: #bababa;">columns=</span><span style="color: #a5c261;">"2" </span><span style="color: #bababa;">rowClass=</span><span style="color: #a5c261;">"ui-grid-row" </span><span style="color: #bababa;">columnClasses=</span><span style="color: #a5c261;">"ui-grid-col-2, ui-grid-col-4"</span><span style="color: #e8bf6a;">>
</span><span style="color: #e8bf6a;"> <</span><span style="color: #9876aa;">p</span><span style="color: #e8bf6a;">:outputLabel </span><span style="color: #bababa;">for=</span><span style="color: #a5c261;">"firstName" </span><span style="color: #bababa;">value=</span><span style="color: #a5c261;">"First name"</span><span style="color: #e8bf6a;">/>
</span><span style="color: #e8bf6a;"> <</span><span style="color: #9876aa;">p</span><span style="color: #e8bf6a;">:inputText </span><span style="color: #bababa;">id=</span><span style="color: #a5c261;">"firstName"</span><span style="color: #e8bf6a;">/></span><span style="color: #e8bf6a;">
</span><span style="color: #e8bf6a;"> <</span><span style="color: #9876aa;">p</span><span style="color: #e8bf6a;">:outputLabel </span><span style="color: #bababa;">for=</span><span style="color: #a5c261;">"lastName" </span><span style="color: #bababa;">value=</span><span style="color: #a5c261;">"Last name"</span><span style="color: #e8bf6a;">/>
</span><span style="color: #e8bf6a;"> <</span><span style="color: #9876aa;">p</span><span style="color: #e8bf6a;">:inputText </span><span style="color: #bababa;">id=</span><span style="color: #a5c261;">"lastName"</span><span style="color: #e8bf6a;">/></span><span style="color: #e8bf6a;">
</span><span style="color: #e8bf6a;"> <</span><span style="color: #9876aa;">h</span><span style="color: #e8bf6a;">:panelGroup/>
</span><span style="color: #e8bf6a;"> <</span><span style="color: #9876aa;">p</span><span style="color: #e8bf6a;">:commandButton </span><span style="color: #bababa;">value=</span><span style="color: #a5c261;">"save"</span><span style="color: #e8bf6a;">/>
</span><span style="color: #e8bf6a;"></</span><span style="color: #9876aa;">c4j</span><span style="color: #e8bf6a;">:gridLayout></span></span></pre>
<div class="p1">
<span class="s1">The above example creates a layout with 2 columns. The first column, with the labels, spans 2 ‘<i>columns</i>’, the other column takes 4 ‘<i>columns</i>’ of the CSS grid. As you can see, we don’t need to take up the complete with available. In this example, we are just using half of the screen.</span></div>
<div class="p1">
<span class="s1">On the last row, the button is aligned with the fields due to the <h:panelgroup>.</h:panelgroup></span></div>
<div class="p2">
<span class="s1"></span><br /></div>
<h3>
<span class="s1">Configure the project and usage of the component.</span></h3>
<div class="p1">
</div>
<ul>
<li>Download the code from <a href="https://github.com/rdebusscher/gridLayout" target="_blank">GitHub</a>. It is a maven project but I didn’t deploy it to Maven Central.</li>
<li>Build it locally and add it to the dependencies of your project</li>
</ul>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo; font-size: x-small;"><span style="color: #e8bf6a;"><dependency></span>
<span style="color: #e8bf6a;"><groupId></span>be.rubus.web<span style="color: #e8bf6a;"></groupId></span>
<span style="color: #e8bf6a;"><artifactId></span>gridLayout<span style="color: #e8bf6a;"></artifactId></span>
<span style="color: #e8bf6a;"><version></span>1.0<span style="color: #e8bf6a;"></version></span>
<span style="color: #e8bf6a;"></dependency></span></pre>
<div class="p1">
</div>
<ul>
<li>Define the namespace on top of your xhtml page, like </li>
</ul>
<pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #bababa;">xmlns:</span><span style="color: #9876aa;">c4j</span><span style="color: #bababa;">=</span><span style="color: #a5c261;">"http://www.rubus.be/component"</span></span></pre>
<div class="p1">
</div>
<ul>
<li>Start using it, according to the info you saw already here.</li>
</ul>
<h3>
<span class="s1">Things to know</span></h3>
<div class="p1">
<ul>
<li>It is released under the Apache V2 License.</li>
<li>It is compiled against Java 1.5</li>
<li>It is only dependent on JSF 2.0 (Java EE 6).</li>
<li>It is NOT dependent on any component library.</li>
<li>If you define less CSS classes in the <i>columnClasses</i> attribute, as you have defined in the <i>columns</i> attribute, columnClasses are reused from the beginning of the attribute value.<br />So the example from the PrimeFaces user guide can be achieved by the following coding</li>
</ul>
</div>
<div class="p1">
<ul><pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #e8bf6a;"><</span><span style="color: #9876aa;">c4j</span><span style="color: #e8bf6a;">:gridLayout </span><span style="color: #bababa;">columns=</span><span style="color: #a5c261;">"3" </span><span style="color: #bababa;">rowClass=</span><span style="color: #a5c261;">"ui-grid-row" </span><span style="color: #bababa;">columnClasses=</span><span style="color: #a5c261;">"ui-grid-col-4"</span><span style="color: #e8bf6a;">></span></span></pre>
<li>The correct assignment of each JSF component to a certain column and row is only guaranteed if you use JSF components as children. If you use html elements or plain text/EL expressions, the layout can be very surprising and not want you had in mind.</li>
<li>You can also put your custom CSS classes in the <i>columnClasses</i> attribute and even combine them. So if you want to right align the label column, you can write something like this.<br /><pre style="background-color: #2b2b2b; color: #a9b7c6; font-family: Menlo;"><span style="font-size: x-small;"><span style="color: #e8bf6a;"><</span><span style="color: #9876aa;">c4j</span><span style="color: #e8bf6a;">:gridLayout </span><span style="color: #bababa;">columns=</span><span style="color: #a5c261;">"2" </span><span style="color: #bababa;">rowClass=</span><span style="color: #a5c261;">"ui-grid-row" </span><span style="color: #bababa;">columnClasses=</span><span style="color: #a5c261;">"ui-grid-col-2 alignRight, ui-grid-col-4"</span><span style="color: #e8bf6a;">></span></span></pre>
</li>
</ul>
</div>
<div class="p2">
<span class="s1"></span></div>
<h3>
<span class="s1">Conclusion</span></h3>
<div class="p1">
<span class="s1">The gridLayout component is a very small one but makes it easy to use the CSS Grid of your choice in your JSF Web pages.</span></div>
<div class="p1">
<span class="s1">Have fun coding.</span></div>
<div class="p2">
<span class="s1"></span><br />
<h3>
Update</h3>
13/4/2015<br />
<br /></div>
<div class="p2">
<span class="s1"></span>With the new PrimeFaces 5.2 release, the panelGrid component is updated to have similar functionality as the GridLayout (but only for PrimeFaces CSS classes)<br />
<br />
See <a href="http://jsfcorner.blogspot.co.at/2015/04/native-gridlayout-component-in.html">http://jsfcorner.blogspot.co.at/2015/04/native-gridlayout-component-in.html</a>.<br />
<br /></div>
<div class="p2">
<span class="s1"></span><br /></div>
<br />
<div class="p2">
<span class="s1"></span><br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-84935943734938736462014-12-23T07:47:00.001+01:002014-12-23T07:49:18.102+01:00My 3 Christmas wishes for Java EE Security<h3>
Introduction</h3>
<div class="p1">
Recently, there was the start up of the new Java EE Security JSR, JSR 375. For me, it is one of the areas, together with Integration testing, where the Java EE specs can be improved greatly.</div>
<div class="p1">
Over the years, I did a few large scale enterprise applications and those applications could benefit a lot if some of the following things would be standardised or available out of the box.</div>
<div class="p2">
<br /></div>
<div class="p1">
This blog post describes my needs and/or proposals that I have for Security from the JavaSever Faces view technology angle. And I know, there is much more that is vital for a good security implementation.</div>
<div class="p2">
<br /></div>
<h3>
LoginModule</h3>
<div class="p1">
<i>LoginModule</i> is an interface, part of the Java Authentication and Authorization Service (JAAS), some of the security basics of Java SE.</div>
<div class="p2">
<br /></div>
<div class="p1">
The <i>LoginModule</i> is responsible for taking the credentials (most of the time, they are the username and the password of the user) and verify it against some kind of store (database, LDAP, file, etc …)</div>
<div class="p2">
<br /></div>
<div class="p1">
The issue is that JAAS is only standardised within Java SE, so there is nothing specified how the Application servers should integrate it.</div>
<div class="p2">
<br /></div>
<div class="p1">
Glassfish for instance requires that you extend a custom class (which implements LoginModule of course) and WebSphere has his own extension of the Subject (the class which represents the end user) class.</div>
<div class="p1">
And all the application servers have heir own way of defining the <i>LoginModule</i> within the configuration.</div>
<div class="p2">
<br /></div>
<div class="p1">
So why not standardise this, by introducing a new annotation like <b>@Realm</b>, which defines the name of the realm and the LoginModule to use for it.</div>
<div class="p2">
<br /></div>
<div class="p1">
This name can then be defined in the <i>web.xml</i> file and that is basically all the things you need to do.</div>
<div class="p2">
<br /></div>
<h3>
Permission Based security</h3>
<div class="p1">
In almost all the cases, you only hear about role based access models as security means. I have done several, quit large enterprise projects and I never used the role based model.</div>
<div class="p1">
Simply because it is not flexibel enough. Because any change in what the user role is allowed to do, results in recompilation of the code. And I’m not even talking about the nightmare it is to properly test the role based security model over and over.</div>
<div class="p2">
<br /></div>
<div class="p1">
<b>Permission</b> based security on the other hand is much simpler. Every action the end user can perform or any data piece which needs to be displayed conditionally, gets a permission assigned. And the end user needs this permission to be able to perform the action or view the data.</div>
<div class="p1">
The main task is now the configuration which permissions are assigned to a user. But this is done outside the application, no recompilation is need as this info can be stored in a database for instance. There can be many permissions, I once had a set of almost 1000 permissions, so you can group them before you assign the groups to users.</div>
<div class="p2">
<br /></div>
<div class="p1">
The main difference between permissions and roles is that a permission is undividable and guards a single piece of the application. A role is linked to the end user and what the end user is allowed to do can change over time.</div>
<div class="p2">
<br /></div>
<div class="p1">
So I would like to see the term Permission appear in the specifications and how they are linked or mapped to users and roles.</div>
<div class="p1">
And the classic role base model also fits in this model. Just replace the term Permission with Role and assign the Permission/Role to multiple areas of application.</div>
<div class="p2">
<br /></div>
<h3>
Declarative security for JSF Components</h3>
<div class="p1">
This is specific for JavaServer Faces, which is the view technology I use most of the time. When data or a button shouldn’t be shown to the end user, the rendered attribute is used in most cases</div>
<div class="p2">
<i><br /></i></div>
<div class="p1">
<i><span style="font-family: Courier New, Courier, monospace;"><h:commandbutton rendered="{userBean.hasPermission('X')}"></h:commandbutton></span></i></div>
<div class="p2">
<br /></div>
<div class="p1">
But rendered attribute can contain also business logic rules that determine the visibility of the button.</div>
<div class="p1">
But security is a cross cutting concern and should thus be separated from the other logic. So the ideal situation is that you use tags to indicate which permission is needed to render the button.</div>
<div class="p2">
<br /></div>
<div class="p1">
Some years ago, I prototyped already such functionality. You can read more on that topic in this <a href="http://jsfcorner.blogspot.be/2011/03/jsf-security.html" target="_blank">blog text</a>.</div>
<div class="p2">
<br /></div>
<div class="p1">
<i><span style="font-family: Courier New, Courier, monospace;"><h:commandbutton></h:commandbutton></span></i></div>
<div class="p3">
<i><span style="font-family: Courier New, Courier, monospace;"><span class="s1"> </span><span class="s2"><sec:securedcomponent voter="loggedIn"></sec:securedcomponent></span></span></i></div>
<div class="p4">
<i><span style="font-family: Courier New, Courier, monospace;"></span></i></div>
<div class="p5">
<br /></div>
<div class="p4">
The framework allows you to define some voters that determine if a certain user is allowed to see the button based on a permission.</div>
<div class="p5">
<br /></div>
<div class="p4">
Beginning of this year, I integrated this feature in a larger security framework called <b>Octopus</b>. There it is combined with <i>Apache Shiro</i> to have <b>declarative security for JSF components</b>, URL protection and secured methods of EJB and CDI beans. See <a href="http://javaeesquad.blogspot.be/2014/03/octopus-framework.html" target="_blank">this text</a> for some more info.</div>
<div class="p5">
<br /></div>
<div class="p4">
But enough promotion for my work, the JSF tags for security are very handy and very readable. But it needs something like a Renderer interceptor and although possible today, it should be described in the specs and promoted as the preferred way for security.</div>
<div class="p5">
<br /></div>
<h3>
OAuth2</h3>
<div class="p4">
Oke, I had already my 3 wishes, but what about other authentication ways which doesn’t fit into the LoginModule concept like <b>OAuth2</b>. Social media is everywhere and thus also OAuth2 security providers which we can and should use.</div>
<div class="p4">
<br /></div>
<h3>
JSR 375</h3>
<div class="p4">
This JSR is a good start to modernise the security specification of Java EE. But I’m also sceptic. As said, security is a cross cutting concern and therefor can be seen separately from the rest.</div>
<div class="p4">
But many aspects are specific for the view technology, like the JSF security tags of Octopus. And will those kind of interaction be tackled by this JSR?</div>
<div class="p5">
<br /></div>
<div class="p4">
But since the JSR process is much more open nowadays, lets provide them with usecases we need. This was my contribution to that process.</div>
<div class="p5">
<br /></div>
<br />
<div class="p5">
<span class="Apple-tab-span"> </span></div>
<br />
<div class="p5">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-23542695427363054052014-10-31T16:57:00.000+01:002014-11-02T11:37:18.645+01:00Overriding defaults of PrimeFaces component properties<h2>
Introduction</h2>
<div class="p1">
The prime faces components can be customised with many options. They can be specified by using the properties on the components. For all these customisation possibilities, there are defaults active so that you don’t need to specify each option.</div>
<div class="p2">
<br /></div>
<div class="p1">
But what if that default value doesn’t fit for your project. What are your options? I’ll show you how you can override the default in the case of the datable component. but other components can be modified in the same way.</div>
<div class="p2">
<br /></div>
<h2>
Paginator for dataTable.</h2>
<div class="p2">
<br /></div>
<div class="p1">
The dataTable component can show the paginator bar to do navigation in a table with a lot of records. By default, this bar is shown on top and at the bottom of the table.</div>
<div class="p2">
<br /></div>
<div class="p1">
But what can you do when you only want to show it at the bottom of the table?</div>
<div class="p2">
<br /></div>
<h2>
Use the property</h2>
<div class="p2">
<br /></div>
<div class="p1">
Of course, everywhere you place the table on a screen, you can specify the <i>paginatorPosition</i> property and set it to <b>bottom</b>.<br />
<br /></div>
<div class="p2">
<pre><span class="s0" style="color: #a9b7c6;"> <</span><span class="s1" style="color: #e8bf6a;">p:dataTable </span><span class="s2" style="color: #bababa;">value</span><span class="s3" style="color: #a5c261;">="</span><span class="s4" style="color: #cc7832; font-weight: bold;">#{</span><span class="s0" style="color: #a9b7c6;">personBean.persons</span><span class="s4" style="color: #cc7832; font-weight: bold;">}</span><span class="s3" style="color: #a5c261;">" </span><span class="s2" style="color: #bababa;">var</span><span class="s3" style="color: #a5c261;">="person" </span><span class="s2" style="color: #bababa;">paginator</span><span class="s3" style="color: #a5c261;">="true"</span><span class="s3"><span style="color: #e8bf6a;"> </span></span><span class="s2" style="color: #bababa;">rows</span><span class="s3" style="color: #a5c261;">="3" </span><span class="s2" style="color: #bababa;">paginatorPosition</span><span class="s3" style="color: #a5c261;">="bottom"</span><span class="s1" style="color: #e8bf6a;">></span><span class="s0" style="color: #a9b7c6;">
</span><span style="color: #a9b7c6;"><</span><span class="s1" style="color: #e8bf6a;">p:column </span><span class="s2" style="color: #bababa;">headerText</span><span class="s3" style="color: #a5c261;">="name"</span><span class="s1" style="color: #e8bf6a;">> </span><span class="s4" style="color: #cc7832; font-weight: bold;">#{</span><span class="s0" style="color: #a9b7c6;">person.name</span><span class="s4" style="color: #cc7832; font-weight: bold;">}</span><span class="s1" style="color: #e8bf6a;"></span></pre>
</div>
<span class="s0" style="color: #a9b7c6;"> </span><br />
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #a9b7c6;"><</span><span style="color: #e8bf6a;">/p:dataTable></span></pre>
<div class="p1">
<br /></div>
<div class="p1">
This will work of course but is more work and it can be forgotten by the developers. especially in larger scale applications.</div>
<div class="p2">
<br /></div>
<div class="p1">
And what happens if they decide that after all, they want to show it as it ways, on top and at the bottom? Change everything again?</div>
<div class="p2">
<br /></div>
<h2>
CSS is everywhere</h2>
<div class="p1">
Since PrimeFaces relies heavily on CSS, a solution can be found in specifying some CSS style which hide the top paginator bar.</div>
<div class="p2">
<br /></div>
<div class="p1">
If you inspect the HTML in the browser, you can easily see that the top paginator has a style class with the name ui-paginator-top.</div>
<div class="p2">
<br /></div>
<div class="p1">
So the following CSS is able to hide the top paginator bar.</div>
<div class="p2">
<br /></div>
<div class="p2">
<pre><span class="s0" style="color: #a9b7c6;"> </span><span class="s1" style="color: #e8bf6a;"><style </span><span class="s2" style="color: #bababa;">type</span><span class="s3" style="color: #a5c261;">="text/css"</span><span class="s1" style="color: #e8bf6a;">></span><span class="s0" style="color: #a9b7c6;">
.</span><span class="s4" style="color: #ffc66d;">ui-paginator-top </span><span class="s0" style="color: #a9b7c6;">{
</span><span class="s5" style="color: #9876aa;">display</span><span class="s0" style="color: #a9b7c6;">: none</span><span class="s6" style="color: #cc7832;">;</span><span class="s0" style="color: #a9b7c6;">
}
</span><span style="color: #e8bf6a;"><</span><span style="color: #e8bf6a;">/style></span></pre>
<pre><span class="s1" style="color: #e8bf6a;">
</span></pre>
</div>
<div class="p1">
But this solution is not ideal. The paginator is suppressed in a general way, so we don’t need to change the xhtml files individually. But the server sends this information to the browser. So the size of the response is too large because some parts aren’t shown anyway.</div>
<h2>
Change the defaults</h2>
<div class="p2">
<br /></div>
<div class="p1">
There exists another way to achieve our goal. You can alter the defaults of PrimeFaces quite easily since PrimeFaces is designed with extensibility in mind. </div>
<div class="p1">
The default values are coded in the class org.primefaces.component.datatable.DataTable.</div>
<div class="p2">
<br /></div>
<div class="p1">
There exists for example a method <i>getPaginatorPosition()</i> which retrieves the values specified in the xhtml file or, when not specified, returns the value “both” which is the default for this property.</div>
<div class="p2">
<br /></div>
<div class="p1">
So when you extend this class, you can overwrite this method and return, for instance always the value “bottom” and we now have override the default (well we basically ignore the property and always return the same value)</div>
<div class="p2">
<br /></div>
<div class="p2">
<pre><span class="s0" style="color: #cc7832;">public class </span><span class="s1" style="color: #a9b7c6;">MyDataTable </span><span class="s0" style="color: #cc7832;">extends </span><span class="s1" style="color: #a9b7c6;">DataTable {
@Override
</span><span class="s0" style="color: #cc7832;">public </span><span class="s1" style="color: #a9b7c6;">String getPaginatorPosition() {
</span><span class="s0" style="color: #cc7832;">return </span><span class="s2" style="color: #6a8759;">"bottom"</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
}
}</span></pre>
<pre><span class="s1" style="color: #a9b7c6;">
</span></pre>
</div>
<div class="p1">
Just overriding the method in the extended class is not enough. You need to inform JSF that your version must be used as component class.</div>
<div class="p2">
<br /></div>
<div class="p1">
This can be done by specifying the following snippet in the faces-config.xml file.</div>
<div class="p2">
<br />
<pre><span class="s0" style="color: #a9b7c6;"> </span><span class="s1" style="color: #e8bf6a;"><component></span><span class="s0" style="color: #a9b7c6;">
</span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">component-type></span><span class="s0" style="color: #a9b7c6;">org.primefaces.component.DataTable</span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">/component-type></span><span class="s0" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">component-class></span><span class="s0" style="color: #a9b7c6;">be.rubus.web.primefaces.MyDataTable</span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">/component-class></span><span class="s0" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span style="color: #e8bf6a;">/component></span></pre>
</div>
<div class="p1">
<br /></div>
<div class="p1">
And if you now run the application, you will see that there is no top paginator bar and it isn’t even present in the generated HTML.</div>
<div class="p2">
<br /></div>
<div class="p1">
How can you know which value you need to use for <i>component-type</i>? Look in the PrimeFaces faces-config.xml file (you can find it in the META-INF directory of the PrimeFaces jar) and look for the component class you override. That is the value you need to use.</div>
<div class="p2">
<br /></div>
<h2>
Conclusion</h2>
<br />
<div class="p1">
You can easily override the default values for the PrimeFaces component properties. Just extend the PrimeFaces component class and put any value you like in the overriding method. You just have to specify then your component class in the faces-config.xml file.</div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-60819243277343590732014-09-21T21:03:00.000+02:002014-09-22T09:15:26.062+02:00Input in uppercase with JSF inputText, a TagHandler example<h2>
Introduction</h2>
<div class="p1">
Recently there was a requirement from a client to be able to input data all in uppercase within a JSF web application.</div>
<div class="p2">
<br /></div>
<div class="p1">
When you write a simple JSF converter and add a CSS style class to the component to uppercase all input client side, you’re done. You can find various posts on the internet where this solution is described.</div>
<div class="p2">
<br /></div>
<div class="p1">
This blog shows how you can improve the solution. You can create a JSF tagHandler which allows you to combine the adding of the converter and CSS style class, by defining your custom tag.</div>
<div class="p1">
It is convenient and typesafe. Typesafe Because it is a tag, so you have IDE autocompletion. Within the name of the converter and the CSS style class name, you can make some typos which leads to an incorrect behaviour.</div>
<h2>
TagHandler</h2>
<div class="p1">
What is a JSF TagHandler? The tagHandler is some piece of code executed when JSF encounters your custom tag that you have placed in the xhtml page. This code runs during the creation of the JSF component tree and thus ideal to tweak some components as we like to do for the uppercase scenario.</div>
<div class="p2">
<br /></div>
<div class="p1">
Your tagHandler should extend from the <i>javax.faces.view.facelets.TagHandler </i>JSF class. And all your work should go into the <i>apply</i> method. This method is called in response to the identification of your custom tag in the xhtml file.</div>
<div class="p2">
<br /></div>
<div class="p1">
This method has a <i>UIComponent</i> typed parameter representing the parent component your custom tag belongs to. So adding a converter and style class to your inputText component is very straightforward:</div>
<div class="p2">
<br /></div>
<pre><span class="s0" style="color: #cc7832;">public class </span><span class="s1" style="color: #a9b7c6;">UppercaseHandler </span><span class="s0" style="color: #cc7832;">extends </span><span class="s1" style="color: #a9b7c6;">TagHandler {
</span><span class="s0" style="color: #cc7832;">public </span><span class="s1" style="color: #a9b7c6;">UppercaseHandler(TagConfig config) {
</span><span class="s0" style="color: #cc7832;">super</span><span class="s1" style="color: #a9b7c6;">(config)</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
}
@Override
</span><span class="s0" style="color: #cc7832;">public void </span><span class="s1" style="color: #a9b7c6;">apply(FaceletContext ctx</span><span class="s0" style="color: #cc7832;">, </span><span class="s1" style="color: #a9b7c6;">UIComponent parent) </span><span class="s0" style="color: #cc7832;">throws </span><span class="s1" style="color: #a9b7c6;">IOException {
</span><span class="s0" style="color: #cc7832;">if </span><span class="s1" style="color: #a9b7c6;">(parent </span><span class="s0" style="color: #cc7832;">instanceof </span><span class="s1" style="color: #a9b7c6;">HtmlInputText) {
HtmlInputText inputText = (HtmlInputText) parent</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
inputText.setConverter(</span><span class="s0" style="color: #cc7832;">new </span><span class="s1" style="color: #a9b7c6;">UppercaseConverter())</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
String styleClass = inputText.getStyleClass()</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
</span><span class="s0" style="color: #cc7832;">if </span><span class="s1" style="color: #a9b7c6;">(styleClass == </span><span class="s0" style="color: #cc7832;">null</span><span class="s1" style="color: #a9b7c6;">) {
styleClass = </span><span class="s3" style="color: #6a8759;">""</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
}
</span><span class="s0" style="color: #cc7832;">if </span><span class="s1" style="color: #a9b7c6;">(!styleClass.contains(</span><span class="s3" style="color: #6a8759;">"uppercase"</span><span class="s1" style="color: #a9b7c6;">)) {
inputText.setStyleClass(styleClass + </span><span class="s3" style="color: #6a8759;">" uppercase"</span><span class="s1" style="color: #a9b7c6;">)</span><span class="s0" style="color: #cc7832;">;</span><span class="s1" style="color: #a9b7c6;">
}
}
}
} </span></pre>
<h2>
Configuration</h2>
<div class="p1">
The next step we have to do, is define the name of our custom tag and link the tagHandler class to it. This is done in the Facelets configuration file. Here you can define your new tag name and the tagHandler class name which is associated with it.</div>
<div class="p2">
<br /></div>
<pre><span class="s0" style="color: #e8bf6a;"><facelet-taglib </span><span class="s1" style="color: #bababa;">xmlns=</span><span class="s2" style="color: #a5c261;">"http://java.sun.com/xml/ns/javaee"</span><span class="s0" style="color: #e8bf6a;">
</span><span class="s1" style="color: #bababa;">xmlns:xsi=</span><span class="s2" style="color: #a5c261;">"http://www.w3.org/2001/XMLSchema-instance"</span><span class="s0" style="color: #e8bf6a;">
</span><span class="s1" style="color: #bababa;">xsi:schemaLocation=</span><span class="s2" style="color: #a5c261;">"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"</span><span class="s0" style="color: #e8bf6a;">
</span><span class="s1" style="color: #bababa;">version=</span><span class="s2" style="color: #a5c261;">"2.0"</span><span class="s0" style="color: #e8bf6a;">></span><span class="s3" style="color: #a9b7c6;">
</span><span class="s0" style="color: #e8bf6a;"><namespace></span><span class="s3" style="color: #a9b7c6;">http://www.c4j.be/rubus</span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">/namespace</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s3" style="color: #a9b7c6;">
</span><span class="s0" style="color: #e8bf6a;"><tag</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s3" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">tag-name</span><span style="color: #e8bf6a;">></span><span class="s3" style="color: #a9b7c6;">uppercase</span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">/tag-name</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s3" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">handler-class></span><span class="s3" style="color: #a9b7c6;">be.sezz.handler.UppercaseHandler</span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">/handler-class</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s3" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">/tag</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s3" style="color: #a9b7c6;">
</span><span class="s0" style="color: #e8bf6a;"></facelet-taglib</span><span style="color: #e8bf6a;">></span></pre>
<div class="p2">
<br /></div>
<div class="p1">
In other scenarios, you can assign tags to converters, custom defined components or user defined EL functions.</div>
<h2>
Example</h2>
<div class="p2">
In the Facelets Configuration file, we have defined a namespace(<span style="color: #a9b7c6;">http://www.c4j.be/rubus</span> in the example above) This namespace we can be used in the xhtml file and our custom tag can be used. An example could be.</div>
<div class="p2">
<br /></div>
<pre><span class="s1"><pre><span class="s0" style="color: #e8bf6a;"><?xml version='1.0' encoding='UTF-8' ?></span><span class="s1" style="color: #a9b7c6;">
</span><span class="s0" style="color: #e8bf6a;"><!DOCTYPE </span><span class="s2" style="color: #bababa;">html </span><span class="s0" style="color: #e8bf6a;">PUBLIC </span><span class="s3" style="color: #a5c261;">"-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #e8bf6a;"><html </span><span class="s2" style="color: #bababa;">xmlns=</span><span class="s3" style="color: #a5c261;">"http://www.w3.org/1999/xhtml"</span><span class="s0" style="color: #e8bf6a;">
</span><span class="s2" style="color: #bababa;">xmlns:h=</span><span class="s3" style="color: #a5c261;">"http://java.sun.com/jsf/html"</span><span class="s0" style="color: #e8bf6a;">
</span><span class="s2" style="color: #bababa;">xmlns:r=</span><span class="s3" style="color: #a5c261;">"http://www.c4j.be/rubus"</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s1" style="color: #a9b7c6;">
</span><span class="s1"><span style="color: #e8bf6a;">...</span></span><span class="s1" style="color: #a9b7c6;">
</span><span class="s0" style="color: #e8bf6a;"><h:body</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s1" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">h:form </span><span class="s2" style="color: #bababa;">id=</span><span class="s3" style="color: #a5c261;">"mainForm"</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s1" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">h:inputText </span><span class="s2" style="color: #bababa;">id=</span><span class="s3" style="color: #a5c261;">"field" </span><span class="s2" style="color: #bababa;">value=</span><span class="s3" style="color: #a5c261;">"</span><span class="s4" style="color: #cc7832; font-weight: bold;">#{</span><span class="s1" style="color: #a9b7c6;">someBean.value</span><span class="s4" style="color: #cc7832; font-weight: bold;">}</span><span class="s3" style="color: #a5c261;">"</span><span class="s0" style="color: #e8bf6a;">></span><span class="s1" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s1" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">r:uppercase/</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s1" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">/h:inputText</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s1" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s0" style="color: #e8bf6a;">/h:form</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #e8bf6a;"></h:body</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #e8bf6a;"></html</span><span style="color: #e8bf6a;">></span><span style="color: #a9b7c6;"> </span></pre>
</span></pre>
<h2>
Conclusion</h2>
<div class="p1">
The JSF TagHandler is a very convenient way of assigning a tag name to some custom functionality you have created. Better because it is ‘typesafe’ and thus you get warned when you should make a typo.</div>
<div class="p1">
In the example above, you saw how you can assign in a few lines a custom converter and CSS style class to a JSF inputText component.</div>
<div class="p2">
<br /></div>
<div class="p2">
<br /></div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-2454212815932179812014-07-06T14:37:00.001+02:002014-07-06T14:37:10.165+02:00Mavenize your Custom PrimeFaces Theme<h2>
Introduction</h2>
<div class="p1">
PrimeFaces relies on the ThemeRoller themes for the look of the components. There are more then 35 already available. But it is also possible to create your own custom ones. This blog not only describes the creation of such a new theme, which is already quit good documented, but also how you can wrap it in a maven project and add some further customisations.</div>
<h2>
Create custom theme</h2>
<div class="p1">
ThemeRoller has an <a href="http://jqueryui.com/themeroller/" target="_blank">online visual tool</a> to design your custom theme. You can specify Font and colour for various types of content like header, highlights, buttons and so on.</div>
<div class="p2">
<br /></div>
<div class="p1">
Once you are more or less comfortable with how the examples on the site looks, you are ready to download the theme.</div>
<div class="p1">
On the download page, it is very important to exclude all the components, you only need the skinning style. You have a convenient ‘toggle all’ checkbox to remove all the components. Also the 1.11 version of jQuery is NOT supported, so take one of the other 2 versions noted on the page.</div>
<div class="p2">
<br /></div>
<div class="p1">
This zip needs a few modifications before it can be used as custom theme for PrimeFaces. Luckily this is automated and can be done on <a href="https://themeroller.osnode.com/" target="_blank">this</a> page. </div>
<div class="p2">
<br /></div>
<div class="p1">
Here you can specify the custom name for your theme and after you upload the zip to the site, you are able to get a jar file which can be used directly in your application.</div>
<h2>
Mavenize </h2>
<div class="p1">
Most of the time you want to perform some modifications on the theme. Some of the modifications I made recently are described further on.</div>
<div class="p1">
So it can be very convenient to turn the jar file into a maven project where the maven package goal generates a valid PrimeFaces Theme.</div>
<div class="p1">
This is very easy to accomplish.</div>
<div class="p2">
<br /></div>
<div class="p1">
Just create a minimal POM file, you just need the groupId, artifactId and version info, nothing else, and extract the contents of the jar into the src/main/resources directory.</div>
<div class="p2">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi97OyOdl8FkcRLvQgUU9xMiJqFv3DetrsSKu6EY7TiGL8W8vV2jhE_4cfhys6ICo4PaHimzW_vYRSYtyRaCopd-dWK3-IrBrFBCyo05eL2DiNDYKcNinHkDNTcyimJq19wL3DT0L_CMJ6i/s1600/primefacesTheme.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi97OyOdl8FkcRLvQgUU9xMiJqFv3DetrsSKu6EY7TiGL8W8vV2jhE_4cfhys6ICo4PaHimzW_vYRSYtyRaCopd-dWK3-IrBrFBCyo05eL2DiNDYKcNinHkDNTcyimJq19wL3DT0L_CMJ6i/s1600/primefacesTheme.png" height="21" width="320" /></a></div>
<div class="p1">
<br /></div>
<div class="p2">
The directory structure should look like the image above. The contents of the downloaded jar file is extracted in the resources directory as indicated in the image.</div>
<div class="p2">
<br /></div>
<div class="p1">
From now on, you can generate the PrimeFaces theme with a simple mvm clean package command.</div>
<h2>
Customizations</h2>
<div class="p1">
In this section, I want to share you a few of the customisations I made in my recent project.</div>
<h3>
Font</h3>
<div class="p1">
One of the common questions on the PrimeFaces forum is how you can change the size of the text within PrimeFaces Components. This can be done by specifying a value for the <span class="s1"><span style="font-family: Courier New, Courier, monospace;">.ui-widget, .ui-widget .ui-widget</span> </span> CSS selector.</div>
<div class="p2">
<br /></div>
<div class="p1">
Instead of putting it into the css file of your application, you can also put this value in the theme and use it in all your applications.</div>
<div class="p1">
<br /></div>
<div class="p1">
Put the same font information also in the body selector as some components of your application are not from PrimeFaces (for example the h:outputText) and should look the same.</div>
<h3>
Table record selection</h3>
<div class="p1">
If you look closely to a selected record in a data table component, you see that the upper border isn’t highlighted like the 3 other borders. (look at the showcase with a theme like Blitzer, there you can see it easily).</div>
<div class="p2">
<br /></div>
<div class="p1">
You can ‘fix’ this in your theme CSS, look for the ui-state-highlight selector.</div>
<div class="p2">
<br /></div>
<div class="p5">
<span style="font-family: Courier New, Courier, monospace;">.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {</span></div>
<div class="p6">
<span style="font-family: Courier New, Courier, monospace;"> border: 1px <b>double</b> "yourColor"</span></div>
<div class="p6">
<span style="font-family: Courier New, Courier, monospace;"> ...</span></div>
<div class="p6">
<span style="font-family: Courier New, Courier, monospace;">}</span></div>
<div class="p2">
<br /></div>
<div class="p2">
Replace the solid with double and you wil see that all 4 borders are identical now.</div>
<div class="p2">
<br /></div>
<div class="p1">
Other then these 2 customisations, you can put anything you need in that theme file. Examples are</div>
<div class="p1">
- A different colour for the cancel type of buttons</div>
<div class="p1">
- A different colour for the default button</div>
<div class="p1">
- Error indication on a field with a validation error</div>
<div class="p1">
and so on.</div>
<h2>
Conclusion</h2>
<div class="p1">
Creating a custom PrimeFaces theme can be done quite easily. Starting from the ThemeRoller visual designer, you can convert it to a maven project which allows you to customise the theme even further.</div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-66880300270115202122014-06-02T10:09:00.000+02:002014-06-02T10:09:42.411+02:00Deploy Java EE in the cloud with JBoss OpenShift<h2>
Introduction </h2>
<div class="MsoNormal">
In the previous blog post I described how you could create
Web Applications using JSF and CDI that are running in the cloud with Google
App Engine.<o:p></o:p></div>
<div class="MsoNormal">
Using a database is also possible but is not available for
free on AppEngine and that was the reason I didn’t go into detail about it.<o:p></o:p></div>
<div class="MsoNormal">
But there exists another possibility to host your Java EE application
in the cloud, and it has even more possibilities and is much easier, OpenShift
of JBoss.<o:p></o:p></div>
<div class="MsoNormal">
And best of all, you can run them for free if your requirements
are not too high. </div>
<h2>
What is it?</h2>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
OpenShift is a so-called PaaS, platform as a service.<span style="mso-spacerun: yes;"> </span>So it is not only limited to a server that
you can use or a program, like a web server that is available, it is the
complete stack.<span style="mso-spacerun: yes;"> </span><o:p></o:p></div>
<div class="MsoNormal">
With OpenShift you can use for example a WildFly application
server and a database instance to deliver you an environment for the execution
of your web application. It has also a unique way of deploying you app using a
GIT repository.<o:p></o:p></div>
<div class="MsoNormal">
In this text I’ll describe the Java EE solution that you can
use, but there exists also other possibilities like PHP, Tomcat with Spring,
Continuous integration server, and many others.<span style="mso-spacerun: yes;">
</span>Have a look on their site about the supported environments.</div>
<h2>
Creating an application</h2>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
You first start by creating a domain.<span style="mso-spacerun: yes;"> </span>The domain will hold one or more of your
applications.<span style="mso-spacerun: yes;"> </span>The domain name is also
reflected in the URL. The structure is as follows <o:p></o:p></div>
<div class="MsoNormal">
<i><b>%application%-%domain%.rhcloud.com</b></i><o:p></o:p></div>
<div class="MsoNormal">
You can assign it an alias if you supply this URL to your
DNS provider.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Creating a domain is nothing spectacular, you just have to
specify the name for it.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Once you have the domain, you can create the web application
in it.<o:p></o:p></div>
<div class="MsoNormal">
And the first thing you have to do when you create an
application is to specify which type of application you want.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In my case, I want to have a Java EE environment in the
cloud, so I took the WildFly 8 possibility.<span style="mso-spacerun: yes;">
</span>As said there are a lot of possibilities and maybe one that I want to
mention here also is CapeDwarf. It implements fully the Google AppEngine API’s
so that you can migrate easily from Google to the JBoss cloud.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
In the next step you have to give some configuration
options, like the application name, as said part of the URL, and if you want to
have scaling and thus a load balancer for your application.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The creation of the application takes some time, as it is
preparing a machine for you with all the software you need.<o:p></o:p></div>
<div class="MsoNormal">
But when it is finished, you can already go the to URL and
see the welcome page of your application, which you want to customise of
course.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The overview page also gives some very important information
that you need to be able to deploy and use the application.<o:p></o:p></div>
<div class="MsoNormal">
In the case of WildFly, it gives the username and password
you need to be able to log on in the console of the application server.<span style="mso-spacerun: yes;"> </span><o:p></o:p></div>
<div class="MsoNormal">
It also states the GIT URL that you can use to clone the
source of the application locally and start developing your application.<o:p></o:p></div>
<div class="MsoNormal">
More on those later. </div>
<h2>
Database</h2>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
Since my test application needs some database to store
information, I can create it also on the OpenShift platform.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
The idea is that you can add additional ‘cartridges’ that
have certain functionality and allows you to create the ideal server for your
application.<o:p></o:p></div>
<div class="MsoNormal">
A database is the most common cartridge, but there exists
also others like for example a cartridge to execute some scheduled jobs (CRON
like)<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Regarding the databases, you can choose between MySQL and
PostGreSQL but you have also the possibility of using MongoDB.<o:p></o:p></div>
<div class="MsoNormal">
Configuration is not needed, you add the cartridge and you
receive the URL, username and password for the database to access it.<o:p></o:p></div>
<div class="MsoNormal">
In case of MySQL, the access is through phpMyAdmin that
needs to be added if you want console access directly to your database. </div>
<h2>
Web application</h2>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
I talked a lot about setting everything up, because creating
your web application is very easy.<o:p></o:p></div>
<div class="MsoNormal">
If you clone the GIT repository that was indicated on the
site, you see that it is maven based. So any maven based Java EE application
can be used.<o:p></o:p></div>
<div class="MsoNormal">
No special configuration needed, no adjustments like with
AppEngine. If it runs on your machine, it runs on OpenShift.</div>
<h2>
Database access</h2>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
The only thing that took a little bit of research was the
URL to my MySQL database that was created.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
I found <a href="https://www.openshift.com/kb/kb-e1076-default-database-connectivity-configurations-for-jboss-applications" target="_blank">this knowledge base article</a>, where it is clearly described.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
You first have to create a datasource for WildFly in the
configuration files. You can find the
standalone.xml file in the <i>.openshift/config/</i> directory when you
have checkout the GIT repository. <o:p></o:p></div>
<div class="MsoNormal">
You have to leave the placeholders,
like <i>${env.OPENSHIFT_MYSQL_DB_HOST}</i> in the configuration file so that it can
properly be resolved at deployment time. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Once you have defined it there, you can
define the datasource in your persistence XML file and the application is able to
connect to it.</span> </div>
<pre><span class="s3" style="color: #a9b7c6;"> </span><span class="s0" style="color: #e8bf6a;"><jta-data-source></jta-data-source></span><span class="s3" style="color: #a9b7c6;">java:jboss/datasources/MySQLDS</span><span class="s0" style="color: #e8bf6a;"></span></pre>
<span class="s3" style="color: #a9b7c6;"> </span><h2>
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Deploy</span></h2>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">When you push the changes to the remote
GIT repository, a lot of things are happening.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">First your application and WildFly
server are stopped.<span style="mso-spacerun: yes;"> </span>Then it is running
the mvn package on your new code. And then the server is started again with
your new version of the application deployed.<span style="mso-spacerun: yes;">
</span>So it can take a minute or more before your push ends due to these
tasks.</span></div>
<h2>
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Client tool</span></h2>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Besides the option to push the code,
you also have the RHC client tools. It is a ruby based tool that allows you to
connect to your server. You can perform various operations which this tool
which are also possible online.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">These include things like<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Getting started, like creating domain,
applications and adding cartridges.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Working with your app as looking at
your log, port forwarding so that you can open the WildFly console from your
browser, etc<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Account management like setting up ssh
connections, authorisation, key generation etc..</span></div>
<h2>
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Cost</span></h2>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">OpenShift can be used free of
charge.<span style="mso-spacerun: yes;"> </span>They work with the concept of
gears. Each feature uses one or more gears, categorised in small, medium and
large size.<span style="mso-spacerun: yes;"> </span><o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">A WildFly instance takes only 1 small
gear and you get 1 GB of space with it. The space calculation takes into
account the code and log size and also the database size.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">So the database isn’t taking up any
additional gear, a load balancer counts also for 1 small gear.<o:p></o:p></span></div>
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Since you have 3 small gears for free,
you can run up to 3 applications with a database on their platform.<o:p></o:p></span></div>
<div class="MsoNormal">
<br /></div>
<h2>
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">Conclusion</span></h2>
<!--[if gte mso 9]><xml>
<o:DocumentProperties>
<o:Revision>0</o:Revision>
<o:TotalTime>0</o:TotalTime>
<o:Pages>1</o:Pages>
<o:Words>1020</o:Words>
<o:Characters>5819</o:Characters>
<o:Company>c4j</o:Company>
<o:Lines>48</o:Lines>
<o:Paragraphs>13</o:Paragraphs>
<o:CharactersWithSpaces>6826</o:CharactersWithSpaces>
<o:Version>14.0</o:Version>
</o:DocumentProperties>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]-->
<!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>JA</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
<w:UseFELayout/>
</w:Compatibility>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
DefSemiHidden="true" DefQFormat="false" DefPriority="99"
LatentStyleCount="276">
<w:LsdException Locked="false" Priority="0" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" Priority="39" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" Name="toc 9"/>
<w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" Priority="10" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" Priority="11" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" Priority="22" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" Priority="59" SemiHidden="false"
UnhideWhenUsed="false" Name="Table Grid"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" SemiHidden="false"
UnhideWhenUsed="false" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" SemiHidden="false"
UnhideWhenUsed="false" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" SemiHidden="false"
UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" SemiHidden="false"
UnhideWhenUsed="false" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" SemiHidden="false"
UnhideWhenUsed="false" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" SemiHidden="false"
UnhideWhenUsed="false" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading"/>
</w:LatentStyles>
</xml><![endif]-->
<!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
mso-para-margin:0cm;
mso-para-margin-bottom:.0001pt;
mso-pagination:widow-orphan;
font-size:12.0pt;
font-family:Cambria;
mso-ascii-font-family:Cambria;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Cambria;
mso-hansi-theme-font:minor-latin;}
</style>
<![endif]-->
<!--StartFragment-->
<!--EndFragment--><br />
<div class="MsoNormal">
<span style="mso-bidi-font-family: "Times New Roman"; mso-fareast-font-family: "Times New Roman";">With OpenShift it becomes very easily
to deploy your Java EE application in the cloud. JBoss made it possible to use
a Maven based application that runs on WildFly to deploy it on their cloud
infrastructure. No changes needed, only some slight modification for the
datasource to access your database also hosted on their PaaS.<o:p></o:p></span></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-52548566716010352602014-04-24T13:00:00.002+02:002014-04-24T13:00:42.053+02:00PrimeFaces, JSF 2.2 and CDI on Google App Engine<h2>
Introduction</h2>
<div class="p2">
Recently we did a proof of concept on Google App Engine, the cloud solution of Google. The Java version, supports servlets and you can already find various resources on the internet where the procedure is described to have the technologies listed in the title working on the platform.</div>
<div class="p2">
<br /></div>
<div class="p1">
But some of them are already quit old or give only a partial solution. So I decided to put our findings together in this blog post. All the frameworks are from the Apache group or have the Apache License.</div>
<div class="p2">
<br /></div>
<div class="p1">
We used version 1.9.1 of the Java GAE SDK.</div>
<h2>
JSF</h2>
<div class="p2">
The most difficult technology of the list is JSF. You can find various posts where you have to create your custom version of Mojarra to be able to deploy it. This has to do with the use of JNDI sources which is not allowed on AppEngine.</div>
<div class="p2">
<br /></div>
<div class="p1">
We tried the Apache MyFaces 2.2.2 version and it went remarkable smooth. We made the following configuration options in the <i>appengine-web.xml</i> file.<br />
<br />
<pre><span class="s0" style="color: #a9b7c6;"> </span><span class="s1" style="color: #e8bf6a;"><sessions-enabled></span><span class="s0" style="color: #a9b7c6;">true</span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">/sessions-enabled></span><span class="s0" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">threadsafe></span><span class="s0" style="color: #a9b7c6;">true</span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">/threadsafe></span><span class="s0" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">static-files></span><span class="s0" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span class="s1" style="color: #e8bf6a;">exclude </span><span class="s2" style="color: #bababa;">path=</span><span class="s3" style="color: #a5c261;">"/**.xhtml" </span><span class="s1" style="color: #e8bf6a;">/></span><span class="s0" style="color: #a9b7c6;"> </span></pre>
<pre><span class="s0" style="color: #a9b7c6;"> </span><span style="color: #e8bf6a;"><</span><span style="color: #e8bf6a;">/static-files></span></pre>
<br />
<br />
The least obvious things was that we needed to tell AppEngine that xhtml files aren’t static, so that we can define it as an url pattern for the faces servlet. Using this url extension is a best practice so that you can’t retrieve the raw html files of JSF.</div>
<div class="p1">
<h2>
EL 2.2</h2>
</div>
<div class="p2">
At this point, we were already able to deploy a JSF application and had the hello world style application working. But if we tested with method expressions, like<br />
<br />
<pre><span class="s0" style="color: #e8bf6a;"><h:commandButton </span><span class="s1" style="color: #bababa;">value=</span><span class="s2" style="color: #a5c261;">"Greet" </span><span class="s1" style="color: #bababa;">actionListener=</span><span class="s2" style="color: #a5c261;">"</span><span class="s3" style="color: #cc7832; font-weight: bold;">#{</span><span class="s4" style="color: #a9b7c6;">testAction.doGreeting()</span><span class="s3" style="color: #cc7832; font-weight: bold;">}</span><span class="s2" style="color: #a5c261;">" </span><span class="s0" style="color: #e8bf6a;">/></span></pre>
<br />
<br />
We received an error that the brackets weren’t expected. So it was clear that only value expressions are recognised and not the method expressions.</div>
<div class="p2">
<br /></div>
<div class="p1">
We tried various EL expression factories, and it turned out that the one of JBoss worked best. But we weren’t able to use the latest version of the framework. we received following security exception</div>
<div class="p2">
<br /></div>
<div class="p1">
<b>access denied ("java.lang.RuntimePermission" "modifyThreadGroup")</b></div>
<div class="p2">
<br /></div>
<div class="p1">
Although it is a CR release, it did the job so we stayed with this maven artefact <i>org.jboss.el:jboss-el:1.0_02.CR6</i></div>
<div class="p1">
<h2>
PrimeFaces</h2>
</div>
<div class="p1">
Plain JSF applications aren’t attractive, that is why you use some component library like PrimeFaces which became the de facto standard. Adding this to artefact to the maven dependencies, we hit another issue, but this time we identified it as a <a href="http://code.google.com/p/googleappengine/issues/detail?id=8415" target="_blank">known GAE bug</a>.</div>
<div class="p2">
<br /></div>
<div class="p1">
It has to do with the handling of the If-Modified-Since request header. But we quickly found an excellent solution by <a href="http://java.wildstartech.com/Java-Platform-Enterprise-Edition/JavaServer-Faces/javaserver-faces-22/configuring-jsf-22-to-run-on-the-google-app-engine-using-eclipse" target="_blank">Derek Berube</a>.</div>
<div class="p2">
<br /></div>
<div class="p1">
Adding the 2 classes and define the filter in the web.xml file, the problem was solved.</div>
<div class="p2">
<br /></div>
<div class="p1">
We even tried the latest PrimeFaces 5.0 version (it was just before it went into his first CR release) and there was no other issue we could see at first glance. So this means you can now create web application targeted to mobile devices on Google App Engine.</div>
<div class="p1">
<h2>
CDI</h2>
</div>
<div class="p2">
As I’m a strong believer of Java EE, so I tried to use CDI for the middleware instead of the Spring approach too many people take without considering the alternatives.</div>
<div class="p2">
<br /></div>
<div class="p1">
There is an excellent Apache implementation of CDI, called OpenWebBeans. The following artefacts where added to the project</div>
<div class="p1">
<br />
<ul>
<li>openwebbeans-impl</li>
<li>openwebbeans-spi</li>
<li>openwebbeans-web</li>
<li>openwebbeans-jsf</li>
<li>openwebbeans-el22</li>
</ul>
</div>
<div class="p2">
<br /></div>
<div class="p1">
Regarding the configuration of OpenWebBeans, we just had to follow the procedure for a regular web server like Tomcat or Jetty.</div>
<div class="p1">
After adding an empty beans.xml file and define the <i>WebBeansConfigurationListener</i> in the web.xml, the dependency injection worked like a charm.</div>
<div class="p2">
<br /></div>
<div class="p1">
Just as with JSF, there exists also for CDI an extension beyond the basic stuf and I choose CODI (Apache MyFaces Extensions CDI). Just adding the dependency was enough to make it work.</div>
<div class="p1">
<h2>
Other technologies</h2>
</div>
<div class="p2">
We also added the JPA option and used a maven plugin to handle the deploy to Google App Engine automatically when a <i>mvn deploy</i> command is issued.</div>
<div class="p2">
<br /></div>
<div class="p1">
I find it a pity that there is no database solution available for free on Google App Engine. It doesn’t need to be very powerful. Just a simple schema that you can use for demonstration purposes of your application.</div>
<div class="p2">
<br /></div>
<div class="p1">
This is in contrast with the JBoss OpenShift offering, where you can have a full Java EE stack with a database for free. But that will be covered in another blog post.</div>
<div class="p1">
<h2>
Conclusion</h2>
</div>
<div class="p2">
Apart from one little issue (bug 8415) which can easily be bypassed, it was quit easy to assemble the required stack to have a JSF based web development environment on Google App Engine. This is in contrast with a few years back where various issues limited the possibilities.</div>
<div class="p2">
<br /></div>
<br />
<div class="p2">
<br /></div>
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-80196866889437303832014-01-30T09:30:00.000+01:002014-01-30T09:30:43.823+01:00PrimeFaces JBoss forge plugin updatedWith the announcement of the new CR release of JBoss Forge 2 (now final release), I remembered that once upon a time (already 2 years ago) I wrote a plugin for PrimeFaces for this tool.<br />
Since then, a lot happened and that version of the plugin doesn’t support PrimeFaces 4. Although it isn’t a big problem, you can manually update the version number of the artifact to 4 in the pom.xml file, I decided to spent some time again on the plugin.<br />
Mainly because the Forge 2 version uses a different concept and now you have the notion of addons. So a rework will be needed to keep the functionality in the new release of JBoss forge.<br />
<h2>
PrimeFaces 4</h2>
The new version of the plugin supports PrimeFaces 4 directly and you can use it to configure the Client Side Validation feature of PrimeFaces.<br />
<br />
What are the commands that you need to specify within JBoss Forge?<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">forge install-plugin primefaces</pre>
</pre>
<br />
This command will install the PrimeFaces plugin and is only required the one time.<br />
<br />
<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">new</span>-project --named demo --topLevelPackage be.rubus.forge.demo --type war</pre>
</pre>
<br />
This command will create a new maven project with packaging type war. You can choose of course the value for the –topLevelPackage attribute. The command will also ask some questions like the location where the project must be created.<br />
<br />
<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">faces setup</pre>
</pre>
<br />
This command will add the required maven dependencies for using JavaServer Faces development. And it will add also some resource files like web.xml, faces-config.xml and beans.xml if you want CDI (this is a question of the command)<br />
<br />
<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">primefaces setup</pre>
</pre>
<br />
Now the PrimeFaces dependency is added to the project. The version depends on selection you made and you are ready to go with your favourite IDE.<br />
<br />
<h2>
Additional goodies</h2>
<br />
The plugin also has some additional commands which can be handy<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">primefaces install-example-facelet</pre>
</pre>
<br />
This adds a JSF view file (index.xhtml) which uses templating and contains a Hello World type example of using PrimeFaces. This is handy is you are not familiar with PrimeFaces and shows you how to add the PrimeFaces namespace. It is also an example of using the JSF 2.x template feature.<br />
<br />
<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">primefaces set-theme</pre>
</pre>
<br />
If you execute this command, you see the list of available free themes for PrimeFaces. It adds the required maven artifact and configures the theme in the web.xml file.<br />
<br />
<br />
<pre><pre style="background-color: yellow; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">primefaces install-CSV</pre>
</pre>
<br />
This is a PrimeFaces 4 specific command which configures the Client Side Validation feature in the web.xml file. See the PrimeFaces users guide how you can use this feature.<br />
<br />
<h3>
JBoss Forge 2</h3>
<br />
For the new release of the tool, the plugin will be adapted and a short guide will be posted when the addon is available. But enjoy version 1.1 of the PrimeFaces plugin from today on.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-78654452857537384772014-01-05T10:10:00.000+01:002014-01-05T10:10:19.447+01:00Client Side Validation example of PrimeFaces<h2>
Introduction</h2>
With the latest version of PrimeFaces, version 4, you have the possibility to perform some validations on the client, by the browser.<br />
This features doesn’t replace the standard JSF validation on the server side but is an addition to it. The server side validation makes sure that any data posted to the server is valid before it is processed any further. The client side validation is there to inform user faster of data problems.<br />
By default, all the standard validations like required fields, minimum and maximum values, string lengths and so on are available. But you can also create the JavaScript version of your custom JSF validation.<br />
The feature is very good explained in the PrimeFaces users guide. This posts describes the steps that I have done to make a Visa card validation on the client side.<br />
<h2>
Configuration</h2>
In order to activate the feature, you need to put the following content parameter in the <em>web.xml</em> file.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">context</span>-<span style="color: red;">param</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">param</span>-<span style="color: red;">name</span><span style="color: blue;">></span>primefaces.CLIENT_SIDE_VALIDATION<span style="color: blue;"></</span><span style="color: maroon;">param</span>-name<span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">param</span>-<span style="color: red;">value</span><span style="color: blue;">></span>true<span style="color: blue;"></</span><span style="color: maroon;">param</span>-value<span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">context</span>-param<span style="color: blue;">></span></pre>
</pre>
<br />
Now, your application is ready to use the client side validation feature. And whenever you want to make use of it, you just have to specify the attribute <em>validateClient </em>on the commandButton tag for example.<br />
<br />
The standard validations known by PrimeFaces are then performed on the fields in the form. Any validation error is shown by the <i>messages </i>or <i>growl </i>tag which is also available in the form.<br />
<br />
Make sure you read the PrimeFaces users guide to know all the requirements and usages. The most import ones are<br />
<br />
<ul><br />
<li>Put a messages or growl tag within the form. others are not yet discovered. </li>
<li>Severity attribute of these tags is ignored. </li>
<li>Invalid fields are marked by a red border but associated label isn’t colored</li>
</ul>
<br />
These shortcomings will be removed in the next release of the framework.<br />
<br />
<h2>
Custom validation</h2>
It is also possible to have a client side validation variant of your custom validations. Therefor I created an example, a visa card number validation.<br />
<br />
You start by creating a standard JSF validator, so a class that implements Validator interface. For the Client Side Validation feature of PrimeFaces, you have to implement also the <em>org.primefaces.validate.ClientValidator</em> interface.<br />
<br />
It contains 2 methods, <em>getValidatorId</em> which defines the name of the JavaScript function that implements the validation on the client side. If the JavaScript function needs some values defined by the validator (like the minimum value for the range validation) you have to return it by the <em>getMetadata</em> method.<br />
<br />
This is the java side of the solution<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@FacesValidator("<span style="color: darkred;">custom.VisaCardCheck</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> VisaCardValidator <span style="color: blue;">implements</span> Validator, ClientValidator {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> Map<String, Object> getMetadata() {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> <span style="color: blue;">null</span>; <span style="color: green;">// No metadata required on client side</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> String getValidatorId() {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">custom.VisaCardCheck</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> <span style="color: blue;">void</span> validate(FacesContext someFacesContext, UIComponent someUIComponent, Object o) <span style="color: blue;">throws</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ValidatorException {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
</pre>
<br />
The JavaScript must be available on the page where we like to use it, the code is shown below.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">PrimeFaces.validator['custom.VisaCardCheck'] = {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> reverse: <span style="color: blue;">function</span> (s) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">var</span> o = '';</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">for</span> (<span style="color: blue;">var</span> i = s.<span style="color: blue;">length</span> - 1; i >= 0; i--)</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> o += s[i];</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> o;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> },</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> throwError: <span style="color: blue;">function</span>(detail) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">throw</span> {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> summary: 'Validation Error',</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> detail: detail</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> },</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> validate: <span style="color: blue;">function</span> (element, value) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">var</span> reg = /^\d+$/,</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> digits = <span style="color: blue;">this</span>.reverse(value).substring(1).split("<span style="color: darkred;"></span>"),</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> sum = 0;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (!value.match(reg)) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">this</span>.throwError("<span style="color: darkred;">Not all digits</span>");</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (value.<span style="color: blue;">length</span> < 13 || value.<span style="color: blue;">length</span> > 16) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">this</span>.throwError("<span style="color: darkred;">Length invalid</span>");</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (value.charAt(0) != '4') {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">this</span>.throwError("<span style="color: darkred;">Wrong start digit</span>");</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">for</span> (<span style="color: blue;">var</span> i = 0; i < digits.<span style="color: blue;">length</span>; i++) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (i%2 == 0) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> digits[i] = digits[i] * 2;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (digits[i] > 9) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> digits[i] = digits[i] - 9</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> sum += <span style="color: blue;">parseInt</span>(digits[i]);</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (value.charAt(value.<span style="color: blue;">length</span> - 1) != (sum % 10)) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">this</span>.throwError("<span style="color: darkred;">Check digit validation fails</span>");</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">};</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
</pre>
<br />
The important thing here is that the name of the validator in the JavaScript object, <i>custom.VisaCardCheck</i> in my case, is the same as the value returned by the <em>getValidatorId</em> method of the JSF validator.<br />
<br />
Usage of the validator at the JSF level is the same as usual.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: mediumvioletred;">p</span>:<span style="color: maroon;">inputText</span> <span style="color: red;">id</span>=<span style="color: blue;">"myValue"</span> <span style="color: red;">value</span>=<span style="color: blue;">"#{dataBean.myValue}"</span> <span style="color: red;">required</span>=<span style="color: blue;">"true"</span> <span style="color: red;">validator</span>=<span style="color: blue;">"custom.VisaCardCheck"</span> <span style="color: blue;">/></span></pre>
</pre>
<br />
<h2>
Conclusion</h2>
<br />
With the Client Side Validation framework, we can inform the user faster about issues with data, without the need to go to the server. <br />
<br />
The best thing is that it integrates very well with JSF and it is hard to tell if the message came from the client side validation or from the server side.<br />
<br />
The default validations are already available in their javaScript counterpart, also if you use BeanValidation. When you create a custom validation, you have to write the JavaScript yourself, of course.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-12805183077370400192013-11-10T14:36:00.000+01:002013-11-10T14:36:00.008+01:00GenericMessage for DeltaSpike supporting JSF and REST<h2>
Introduction</h2>
In the <a href="http://jsfcorner.blogspot.be/2013/01/deltaspike-jsf-message-system.html" target="_blank">post</a> of January 2013, I described the feature of DeltaSpike to have type safe messages from within a CDI bean which are displayed within the <h:messages> tag of JSF.<br />
It is a great feature which has a minor drawback, especially in the perspective of Java EE as a universal backend system. (see <a href="http://jsfcorner.blogspot.be/2012/12/java-ee6-as-universal-backend.html" target="_blank">this post</a> for the idea behind this)<br />
In the case a CDI bean, like a service type of bean, is used in the context of JSF and REST contexts, because you have multiple types of clients, there is an issue with JsfMessage of DeltaSpike.<br />
<h2>
Custom version</h2>
Since DeltaSpike is an open source project, you can easily find out how the feature is coded. And you can create something similar which isn’t tied to JSF quit easy as you can see in this post.<br />
First we need to define the alternative for the JsfMessage interface, lets call it BusinessMessage.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> BusinessMessage<T> {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> T failing();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> T warning();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> T information();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
We have 3 methods, so that we can define an error, warning and information message. <br />
<br />
The usage of this interface will be identical to the JsfMessage one of DeltaSpike. Se we need to define an interface which will be annotated as MessageBundle and we are ready to use it.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@MessageBundle</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> ApplicationMessages {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @MessageTemplate(value = "<span style="color: darkred;">Person already registered</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> String personAlreadyRegistered();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">
</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@ApplicationScoped</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> AttendeeService {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Inject</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> BusinessMessage<ApplicationMessages> message;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> <span style="color: blue;">void</span> addPerson(Person person) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: green;">//....</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> message.failing().personAlreadyRegistered();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
Within the implementation of the BusinessMessage interface we will make, we can now make sure it will work within a JSF and REST context.<br />
<h2>
BusinessMessage implementation details</h2>
I’m not going to describe all the implementation details in this post. In a few weeks, the code of a demo application will be made available that highlights almost all of the things that kept me busy the last year. And it is using the BusinessMessage described here.<br />
<br />
The code is using the org.apache.deltaspike.core.impl.message.MessageBundleInvocationHandler class of DeltaSpike to have a dynamic implementation of the @MessageBundle annotated interfaces like ApplicationMessages we have in the above example block.<br />
<br />
Once we have the message text the user wants, we will store it in a Thread local variable, maintained by a new class BusinessMessageContext. This class makes it possible to keep some messages independent of the view technology used. So it is supporting JSF and REST style of working.<br />
<h2>
Show the messages</h2>
The last step to solve our issue is that we need use the messages stored in the BusinessMessageContext and send it to the correct view.<br />
<br />
For JSF we can create a PhaseListener implementation which is triggered before each Render Response phase. It can add the messages to the JSF system using the facesContext.addMessage method.<br />
<br />
For REST, we can use a javax.ws.rs.container.ContainerResponseFilter concept explained in <a href="http://statelessprime.blogspot.be/2013/11/even-easier-jax-rs-for-java-ee7.html" target="_blank">this post</a>, to send the messages to the client as a JSON response. Some of the aspects will be described in more detail in a future post on that blog.<br />
<br />
In both cases, we need to do the clean up of the Thread local variable we have used to store the messages to reclaim the memory. Therefor the class BusinessMessageContext has a method <i>release()</i> to perform this clean up.<br />
<h2>
Conclusion</h2>
JsfMessage of DeltaSpike is a great feature to have type safe messages. But in some cases your CDI bean will be used in multiple ‘environments’, JSF and REST for example. In that case, we need an alternative which works almost the same but stores the messages, at least initially, in a view neutral way.<br />
<br />
Code will be available as part of the demo which will be released in a few weeks.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-90632080909274612582013-10-08T13:09:00.001+02:002013-10-08T13:09:45.981+02:00How to debug javascript in PrimeFaces 4.0<h2>
Introduction</h2>
With each new release of PrimeFaces, the JavaScript becomes more and more important in the framework.<br />
This is no surprise as JavaScript is needed to give the end user a rich user interface. And in the latest release there is quit a lot of new JavaScript code added for the client Side validation framework.<br />
But if you want to debug it in the browser, you see that the code is minified. And thus stepping through it line by line is not possible.<br />
This post describes how you can do it.<br />
<h2>
Build custom version</h2>
The source code of PrimeFaces contains the human readable code and the idea is that we build a custom jar file which contains that readable version of the JavaScript.<br />
As the code is open source, it is available on <a href="http://code.google.com/p/primefaces/source/checkout" target="_blank">Google code</a>. We can do a checkout with following command.<br />
<code>svn checkout <a href="http://primefaces.googlecode.com/svn/primefaces/tags/4_0" title="http://primefaces.googlecode.com/svn/primefaces/tags/4_0">http://primefaces.googlecode.com/svn/primefaces/tags/4_0</a></code><br />
<br />
Now we go to the<em> pom.xml</em> file and make some small changes.<br />
The most important one is the change of the version tag. I have changed it to 4.0-DEBUG (you can find it at the top of the pom.xml file)<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">modelVersion</span><span style="color: blue;">></span>4.0.0<span style="color: blue;"></</span><span style="color: maroon;">modelVersion</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">groupId</span><span style="color: blue;">></span>org.primefaces<span style="color: blue;"></</span><span style="color: maroon;">groupId</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">artifactId</span><span style="color: blue;">></span>primefaces<span style="color: blue;"></</span><span style="color: maroon;">artifactId</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">packaging</span><span style="color: blue;">></span>jar<span style="color: blue;"></</span><span style="color: maroon;">packaging</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">version</span><span style="color: blue;">></span>4.0-DEBUG<span style="color: blue;"></</span><span style="color: maroon;">version</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">name</span><span style="color: blue;">></span>primefaces<span style="color: blue;"></</span><span style="color: maroon;">name</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">url</span><span style="color: blue;">></span>http://www.primefaces.org<span style="color: blue;"></</span><span style="color: maroon;">url</span><span style="color: blue;">></span></pre>
</pre>
PrimeFaces uses a maven plugin to generate the JSF components and configuration files. <br />
This plugin is located in the PrimeFaces maven repository which you must include into the pom file. Otherwise the build will fail.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">pluginRepositories</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">pluginRepository</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">id</span><span style="color: blue;">></span>primeFaces_repository<span style="color: blue;"></</span><span style="color: maroon;">id</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">url</span><span style="color: blue;">></span>http://repository.primefaces.org/<span style="color: blue;"></</span><span style="color: maroon;">url</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">pluginRepository</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">pluginRepositories</span><span style="color: blue;">></span></pre>
</pre>
When you now execute the <em>mvn install</em> command, you will have a customized version of PrimeFaces in your local Maven repository which contains the non minified version of JavaScript.<br />
<br />
Using this version in your project, by specifying it in a profile so that it doesn’t go into production, you can do debugging in your favourite browser.<br />
<h2>
Conclusion</h2>
We following the above steps, you have a custom version of PrimeFaces where the JavaScript is not minified and thus can be debugged in the browser. Of course it is not suited to go to production with this version.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-68772060381053269102013-09-25T21:04:00.000+02:002013-09-25T21:04:34.776+02:00Generic JPA 2.1 converter for enum<h2>
Introduction</h2>
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.<br />
In the latest release of JPA, 2.1, there is support for custom converters so you can solve these kind of issues.<br />
<h2>
JPA 2 Converter</h2>
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:<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@Entity</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> Person {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Column</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Convert(converter = GenderEnumConverter.<span style="color: blue;">class</span>)</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> Gender gender;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
The converter class can look as this<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@Converter</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> GenderEnumConverter <span style="color: blue;">implements</span> AttributeConverter< Gender, String> {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> String convertToDatabaseColumn(Gender attribute) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> String result = "<span style="color: darkred;"></span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">switch</span> (attribute) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">case</span> MALE:</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> result = "<span style="color: darkred;">M</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">break</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">case</span> FEMALE:</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> result = "<span style="color: darkred;">F</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">break</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">default</span>:</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> result;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> Gender convertToEntityAttribute(String dbData) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> Gender result = <span style="color: blue;">null</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">switch</span> (dbData) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">case</span> "<span style="color: darkred;">M</span>":</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> result = Gender.MALE;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">break</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">case</span> "<span style="color: darkred;">F</span>":</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> result = Gender.FEMALE;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">break</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">default</span>:</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> result;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
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 <i>persistence.xml </i>file.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: maroon;">persistence</span>-<span style="color: red;">unit</span> <span style="color: red;">name</span>=<span style="color: blue;">"converter-unit"</span> <span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">description</span><span style="color: blue;">></span>Forge Persistence Unit<span style="color: blue;"></</span><span style="color: maroon;">description</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">class</span><span style="color: blue;">></span>be.rubus.web.ee7.jpa.converter.model.Person<span style="color: blue;"></</span><span style="color: maroon;">class</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">class</span><span style="color: blue;">></span>be.rubus.web.ee7.jpa.converter.jpa.GenderEnumConverter<span style="color: blue;"></</span><span style="color: maroon;">class</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: maroon;">persistence</span>-unit<span style="color: blue;">></span></pre>
</pre>
<br />
<h2>
Not OO</h2>
<br />
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.<br />
<br />
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.<br />
<br />
Since we need such functionality for each numeration that we use in the persistent objects, we can create an interface like <i>DatabaseEnum</i>.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> DatabaseEnum {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> Serializable getDatabaseValue();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
And change the enum to implement this interface.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> enum Gender <span style="color: blue;">implements</span> DatabaseEnum {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> MALE("<span style="color: darkred;">M</span>"), FEMALE("<span style="color: darkred;">F</span>");</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> Serializable databaseValue;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> Gender(Serializable databaseValue) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">this</span>.databaseValue = databaseValue;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> Serializable getDatabaseValue() {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> databaseValue;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
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 <i>type erasure</i>. Otherwise a converter like this could be possible.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@Converter</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> EnumConverter<T <span style="color: blue;">extends</span> DatabaseEnum> <span style="color: blue;">implements</span> AttributeConverter< T, Serializable> {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> Serializable convertToDatabaseColumn(T attribute) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> attribute.getDatabaseValue();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> T convertToEntityAttribute(Serializable dbData) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: green;">// There is no way we can create such a method</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> determineEnum(T, dbData);</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
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.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> EnumConverter(Class<T> enumType) {..}</pre>
</pre>
<br />
<h2>
Almost generic converter</h2>
<br />
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.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@Converter</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> GenderEnumConverter <span style="color: blue;">implements</span> AttributeConverter<DatabaseEnum, Serializable> {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> Serializable convertToDatabaseColumn(DatabaseEnum attribute) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> attribute.getDatabaseValue();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> Gender convertToEntityAttribute(Serializable dbData) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> DatabaseEnumUtil.getEnumValue(Gender.<span style="color: blue;">class</span>, dbData);</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
And the utility method can be small and generic thanks to the not very known method <b><i>getEnumConstants()</i></b> of the JVM core classes.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> <span style="color: blue;">static</span> <T <span style="color: blue;">extends</span> DatabaseEnum> T getEnumValue(Class<T> enumClass, Serializable dbValue) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> T result = <span style="color: blue;">null</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (dbValue != <span style="color: blue;">null</span>) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">for</span> (DatabaseEnum enumInstance : enumClass.getEnumConstants()) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (dbValue.equals(enumInstance.getDatabaseValue())) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> result = (T) enumInstance;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">break</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> result;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
</pre>
<br />
<h2>
Conclusion</h2>
<br />
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.<br />
<br />
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.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-57530122044001041942013-08-05T15:27:00.001+02:002013-09-25T20:56:34.251+02:00From CODI to DeltaSpike<h2>
Introduction</h2>
CODI is my favourite CDI extension framework where you can find all kind of goodies when you are working in a CDI environment.<br />
Some time ago, there was a decision to create a new CDI extension framework which brings together all the good features of CODI and Seam 3 and other features from other CDI extension libraries.<br />
<br />
They have gone through the incubation process at Apache and moving along steadily. The question is, can you already switch from CODI to DeltaSpike for an application?<br />
<br />
Not all features of CODI are implemented but my 2 favourites ones are<br />
- The additional scopes like ViewAccessScope<br />
- The fluent API for adding FacesMessages.<br />
So can we create a DeltaSpike application with these 2 features.<br />
<h2>
Scopes</h2>
In the current version of the DeltaSpike framework, version 0.4, there is no support for something like the CODI's ViewAccessScope .<br />
Therefor, Gerhard Petracek created an extension for DeltaSpike to have the missing scopes from CODI version 1.0.5 into DeltaSpike. See <a href="http://os890.blogspot.be/2013/07/add-on-codi-scopes-for-deltaspike.html" target="_blank">here.</a><br />
So adding the required dependency to the POM<br />
<br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: maroon;">repositories</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">repository</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">id</span><span style="color: blue;">></span>os890<span style="color: blue;"></</span><span style="color: maroon;">id</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">name</span><span style="color: blue;">></span>Gerhard personal repository<<span style="color: blue;">/</span><span style="color: maroon;">name</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">url</span><span style="color: blue;">></span>http://os890-m2-repository.googlecode.com/svn/tags/os890/<span style="color: blue;"></</span><span style="color: maroon;">url</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">layout</span><span style="color: blue;">></span>default<span style="color: blue;"></</span><span style="color: maroon;">layout</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">repository</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: maroon;">repositories</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: maroon;">dependency</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">groupId</span><span style="color: blue;">></span>org.os890.cdi.ext.scope.modules<span style="color: blue;"></</span><span style="color: maroon;">groupId</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">artifactId</span><span style="color: blue;">></span>os890-cdi-ext-jsf2-module-impl<span style="color: blue;"></</span><span style="color: maroon;">artifactId</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">version</span><span style="color: blue;">></span>1.0.5_0.4_01<span style="color: blue;"></</span><span style="color: maroon;">version</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">scope</span><span style="color: blue;">></span>runtime<span style="color: blue;"></</span><span style="color: maroon;">scope</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: maroon;">dependency</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
</pre>
<br />
The version of the extension is a concatenation of the 2 libraries it will bridge. So we have the structure <b>&CODI version&_&DS version&_&extension version&</b>.<br />
<br />
You only have to use the new package name to have the additional CODI scopes. The API is identical so that existing code which works for CODI, will also work with DeltaSpike.<br />
<br />
<br />
So for example for ViewAccessScope, <br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">import</span> org.apache.myfaces.extensions.cdi.core.api.scope.conversation.ViewAccessScoped;</pre>
</pre>
<br />
becomes <br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">import</span> org.os890.cdi.ext.scope.api.scope.conversation.ViewAccessScoped;</pre>
</pre>
So for any of the scope packages, you have to replace <i>org.apache.myfaces.extensions.cdi.core</i> with <i>org.os890.cdi.ext.scope. </i><br />
<br />
<h2>
Messaging</h2>
<br />
The support for a fluent messaging API is already present in DeltaSpike. So to have this kind of functionality, we don't need to use an extension as we did for having the scopes.<br />
<br />
But here we have the issue that the API is changed and thus we need to adapt existing code.<br />
<br />
<b>CODI version</b><br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">messageContext.message().text("<span style="color: darkred;">{msgKey}</span>").add();</pre>
</pre>
<br />
<b>DeltaSpike version</b><br />
<br />
Message defitions.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@MessageBundle</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">interface</span> AppMessages {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @MessageTemplate("<span style="color: darkred;">{msgKey}</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> String buttonClicked();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<br />
Within CDI bean<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Inject</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> JsfMessage<appmessages> jsfMessage;</appmessages></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"> </span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"> public</span> <span style="color: blue;">void</span> addTestMsg(ActionEvent actionEvent) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> jsfMessage.addInfo().buttonClicked();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
</pre>
<br />
<h2>
Servers</h2>
The DeltaSpike application was tested successful on Glassfish 3.1.2.2 and JBoss as 7.1.1.Final.<br />
<br />
Also the original CODI version was running without a problem on the new Glassfish 4 version.<br />
<br />
On this server, the DeltaSpike version had a problem. There was an exception thrown in the extension as there is no problem with the DeltaSpike code itself. All the integrations tests of DeltaSpike are running also on a Weld 2 version (used in the Glassfish 4) so you can expect that it is working on it without any problem.<br />
<br />
With the new WLS 12C server, version 12.1.2, there is also an issue running the DeltaSpike application. The application deployment fails during validation where it can't inject an Extension class into another bean.<br />
<br />
<h2>
Conclusion</h2>
With the help of the DeltaSpike extension, you can create already applications that uses a lot of the features of the CODI framework.<br />
So check what features you need and maybe you can already create your application with the DeltaSpike framework.<br />
<br />Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-49396873960072870912013-06-07T10:51:00.001+02:002014-04-07T14:48:14.495+02:00JSF 2.2 Pass-through attributes<h2>
Introduction</h2>
Until now, you could only use attributes on the JSF tags which where recognized by the component library.<br />
Until recently, this made sense. Those attributes are used to ‘configure’ the JSF tag and thus other attributes have no meaning for the component and thus not needed.<br />
But that changed with the HTML 5 specification. One of the additions is that you can define and use your own attributes which can be used by for instance by your javascript code.<br />
Now you no longer need to use class names to store metadata and thus your html code becomes cleaner.<br />
<h2>
JSF support</h2>
But this nice feature of HTML5 is a problem for the JSF framework. Since we have no way of specifying that additional parameters needs to be passed to the generated markup, there was no easy way of supporting them.<br />
Of course you could define them with the <f:attribute> tag and write extensions for the renderers, but native support is of course needed.<br />
And with the new JSF 2.2 specification, there is the possibility to support them. The feature is called pass-through attributes. And technically that is also what is happening. Those attributes are just passed to the generated markup.<br />
<h2>
Example, input placeholder</h2>
Now we can specify the hint for an input with the placeholder attribute without the need of the component library to support it (of course, our browser need to support the HTML 5 attribute)<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: maroon;">html</span> <span style="color: red;">xmlns</span>=<span style="color: blue;">"http://www.w3.org/1999/xhtml"</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: red;">xmlns</span>:<span style="color: red;">h</span>=<span style="color: blue;">"http://xmlns.jcp.org/jsf/html"</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: red;">xmlns</span>:<span style="color: red;">p</span>=<span style="color: blue;">"http://xmlns.jcp.org/jsf/passthrough"</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">head</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">head</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">body</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">form</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">inputText</span> <span style="color: red;">id</span>=<span style="color: blue;">"basic"</span> <span style="color: red;">value</span>=<span style="color: blue;">"#{bean.value}"</span> <span style="color: red;">p</span>:<span style="color: red;">placeholder</span>=<span style="color: blue;">"Enter text"</span><span style="color: blue;">/></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">form</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">body</span><span style="color: blue;">>;</span></pre>
</pre>
<br />
By marking attributes as belonging to the newly introduced namespace <i>http://xmlns.jcp.org/jsf/passthrough</i>, we tell the renderers that they need to copy it to the markup. Besides the support for literal values (like in the example above) EL expression are also allowed.<br />
<br />
As you can see, they have also changed the namespace to <i><b>xmlns.jcp.org</b></i> instead of <i><b>java.sun.com </b></i>to emphasis that the specs are a community process and not originating from a single company (or was it just to remove the name sun?).<br />
<br />
<h2>
Multiple attributes</h2>
<br />
If you have several pass-though attributes that you need to specify, there is another way of specifying them.<br />
<br />
The core namespace (xmlns:f="http://xmlns.jcp.org/jsf/core") has an additional tag now, called passThroughAttributes. It has a reference to a Map that contains all the attributes that needs to be added. The key of the map must be of String type, the value is an object or EL expression.<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: mediumvioletred;">f</span>:<span style="color: maroon;">passThroughAttributes</span> <span style="color: red;">value</span>=<span style="color: blue;">”#{service.nameValuePairs}”</span> <span style="color: blue;">/></span></pre>
</pre>
<br />
You no longer need to specify them one by one, but the drawback of it, if you ask me, is that those view related metadata is specified in Java code and not in the JSF view.<br />
<br />
<h2>
Support in component libraries</h2>
<br />
For those that are writing component libraries them self (or a few components), it is easy to support those pass-through attributes on your component as well.<br />
<br />
On the <i><b>UIComponent</b></i> class, they have introduced a new method <b><i>getPassThroughAttributes(boolean)</i></b> that you can use to retrieve the discovered attributes.<br />
<br />
It returns the info as a Map and you can iterate over this collection and write the information on the response stream.<br />
<br />
As this approach is generic, you can put the code in a utility class/method and call it for every component you like to have support for the pass-through components.<br />
<br />
<h2>
Conclusion</h2>
<br />
With the new pass-through feature of the JSF 2.2 spec, it becomes easy to support the HTML5 data attributes. It is as simple as specifying the attributes on the JSF tag prefixed with an alias for a specific namespace to identify them as pass-through.<br />
<br />
Also the code to support the in your custom widgets is less then 10 lines long.<br />
<br />
The only issue you could have is that for some JSF components, it is not always immediately clear where the pass-through attributes are placed in the HTML markup when the tag generates multiple JSF elements.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com1tag:blogger.com,1999:blog-7236465384582522183.post-78343270720297683572013-05-13T20:47:00.000+02:002013-05-13T20:47:22.124+02:00JSF 2.2 Stateless views explained<h2>
Introduction</h2>
The JSF 2.2 specification (JSR-344) is recently approved. There are a few examples available but there seems no detailed explanation yet of the new features.<br />
Although the development is still in progress, I like to start today already with the stateless view features which was fairly late added to the list of JSF 2.2 features.<br />
The ticket had many votes and stateless is hot, so for many people this is a very wanted feature which is added.<br />
But be aware of the implementation details and some other facts that are very good explained in this <a href="http://jdevelopment.nl/jsf-22/#1055" target="_blank">section</a> of the excellent overview of Arjan Tijms on JSF 2.2 features. <br />
<h2>
transient=”true”</h2>
The explanation of the feature is fairly simply. By specifying the attribute transient on the f:view tag, we are able to run that page in a stateless mode. Stateless here means that the JSF StateManager isn’t storing any data into the memory related to this view.<br />
During restore view phase, the view is created, as always, but now there isn’t any state applied to it.<br />
It is a fairly simple change but has a lot of consequences.<br />
<h2>
viewScoped beans</h2>
The most important effect of the stateless operation mode is that all viewScoped beans are lost. Those kind of beans, tied to a certain view, aren’t stored anymore and thus, when the same page is rendered again, a new version of the bean needs to be instantiated again.<br />
It can easily demonstrated by a ‘classic’ scope testing application, for example the one I used <a href="http://jsfcorner.blogspot.be/2012/01/codi-on-oracle-weblogic-server-12c.html" target="_blank">here</a> to test CODI on WLS 12c server. You create beans with a different scope, like requestScope, viewScope, sessionScope and applicationScope and initialize a timestamp in the constructor. The value of this property is then shown on screen where you can do a post to stay on the same page or go to another page which has the same beans on it.<br />
In the case of the transient view, even if you stay on the same page, a new instance of the viewScoped bean is created. The other scopes aren’t affected. <br />
I tried this with the Glassfish 4 promoted build 87 and a Tomcat 7 instance where I used the latest available Mojarra 2.2 snapshot.<br />
<h2>
viewScope != viewScope</h2>
Although not immediately linked to the stateless view features, there are now 2 ViewScoped annotation classes. We had already the RequestScoped, SessionScoped and ApplicationScoped from JSF (package javax.faces.bean) and the CDI version (in package javax.enterprise.context).<br />
As requested by many developers, there is now also a CDI version of the ViewScoped (from package javax.faces.bean) but defined in JSF (and not CDI). The new class is defined in javax.faces.view. Look careful to import the correct class in relation to the @ManagedBean or @Named annotation because mixing them will lead to unexpected behaviour.<br />
<h2>
When to use</h2>
What are the use cases for the stateless view operation mode. As already mentioned in the feature description by Arjan Tijms, performance and memory gain is minimal, except when you are working with very large pages that contains thousands of components.<br />
Besides the fact that ViewScoped beans behave differently, a lot of components are relying on the fact that they can save and restore their state within the view. So many components, standard ones but also from component libraries like PrimeFaces will not function properly anymore on stateless views.<br />
On the other side, views are stateless and this means you can even post your data back to the server, after your session has expired or even after a server reboot.<br />
<h2>
Conclusion</h2>
Since there is a large impact on AJAX behaviour, commonly used with ViewScoped beans, and the proper functioning of components, considering stateless views must be evaluated thoroughly and tested very profound.<br />
And initiatives like the one from <a href="http://www.industrieit.com/blog/2011/11/stateless-jsf-high-performance-zero-per-request-memory-overhead/" target="_blank">Industrie IT</a> should also be considered when you are interested in those kind of setups.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com3tag:blogger.com,1999:blog-7236465384582522183.post-19717847302964434732013-02-14T06:37:00.000+01:002013-02-14T06:37:42.906+01:00Client Behavior functionality with JSF 2.x (part 2)<h2>
Introduction</h2>
In the previous text, I described how you can create a button that ask for a confirmation. It showed the basic functionality of creating reusable client side functionality.<br />The example was very simple, just requiring one javaScript command. <br />
In this text, I'll show some more advanced usages where you need to include an external resource and have to respond on multiple events.<br />The example shows how you can create the hover functionality for an input field. And of course with most browsers you can specify it as a css selector<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> .<span style="color: maroon;">myHover</span>:<span style="color: maroon;">hover</span> {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: red;">background-color</span>: <span style="color: blue;">red</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
</pre>
Unfortunately, not all browsers supports this and it is a pity that IE9 fails to understand it. So lets write an universal hover functionality.<br /><h2>
Specify the event</h2>
For the change of color when the mouse is over a field, we need to respond to 2 events. The mouse that enters the field, mouseover event, to adjust the color and when the mouse leaves the field, mouseout event, to revert the color to his original one.<br />So we need a client behaviour tag, just like the confirmation tag we have created the last time, lets call it hover so that we can attach the functionality to a field. We have 2 events but we don't need to create 2 different tags. We are able to retrieve the intended event in the getScript method.<br />So let start with the definition of the tag in the facelet tag library<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">tag</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">tag</span>-<span style="color: red;">name></span><span style="color: blue;"></span>hover<<span style="color: blue;">/</span><span style="color: maroon;">tag</span>-name<span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">behavior></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">behavior</span>-<span style="color: red;">id></span><span style="color: blue;"></span>hover<<span style="color: blue;"></span><span style="color: maroon;">behavior</span>-id><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">behavior></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">tag</span><span style="color: blue;">>;</span></pre>
</pre>
This is identical to the confirmation functionality. And we can use it in the following way<br /><pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">inputText</span> <span style="color: red;">value</span>=<span style="color: blue;">"#{bean.prop}"</span> <span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">custom</span>:<span style="color: maroon;">hover</span> <span style="color: red;">event</span>=<span style="color: blue;">"mouseover"</span><span style="color: blue;">/></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">custom</span>:<span style="color: maroon;">hover</span> <span style="color: red;">event</span>=<span style="color: blue;">"mouseout"</span><span style="color: blue;">/></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">inputText</span><span style="color: blue;">></span></pre>
</pre>
We now specify the events we like to intercept and based on the event name, we can code the required javaScript <br /><pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> String getScript(ClientBehaviorContext behaviorContext) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (MOUSEOVER_EVENT.equals(behaviorContext.getEventName())) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">this.className += ' hoverClass '</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (MOUSEOUT_EVENT.equals(behaviorContext.getEventName())) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">this.className = this.className.replace( /(?:^|\\s)hoverClass(?!\\S)/g , '' )</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> <span style="color: blue;">null</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
</pre>
The event name is passed to the getScript method in the behaviorContext parameter. The code adds or removes a CSS class to the HTML element. So when the hoverclass is defined as a red background, the input text element becomes red when the mouse is over the field and returns to his 'normal' color when we move out of it.<br /><h2>
A single tag</h2>
The above solution is from a developers perspective not an ideal situation. The first improvement we will make is that you only need to specify 1 tag, and not 2.<br />The hover tag we created earlier was explicitly linked to the client behaviour functionality. You can also create a tag for other purposes like a converter or your new component. But there is also the possibility to create a tag for which you must implement the functionality, like this<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: maroon;">tag</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <<span style="color: blue;"></span><span style="color: maroon;">tag</span>-<span style="color: red;">name</span><span style="color: blue;">></span>myHover<span style="color: blue;"></</span><span style="color: maroon;">tag</span>-name<span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">handler</span>-<span style="color: red;">class</span><span style="color: blue;">></span>be.rubus.web.jsf.tutorial.clientbehaviour.HoverHandler<span style="color: blue;"></</span><span style="color: maroon;">handler</span>-class<span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">tag</span><span style="color: blue;">></span></pre>
</pre>
<br />Within the <i>HoverHandler</i>, you must program the behaviour that you want. Before you can start with it, you must know what the function of a handler class is. <br />
<br />This class will be used by the JSF system to convert the xhtml page to the component tree. Afterwards this component tree will be converted to the HTML which is sent to the browser in the Render Response phase of the JSF lifecycle.<br />With a handler class you can change the created component tree. You can manipulate the 'DOM tree' (or what will become the DOM tree) by adding, removing and rearranging nodes but also change the properties of the nodes in the component tree.<br />The HoverHandler looks like this<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> HoverHandler <span style="color: blue;">extends</span> TagHandler {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> HoverBehavior mouseOver = <span style="color: blue;">new</span> HoverBehavior();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> HoverBehavior mouseOut = <span style="color: blue;">new</span> HoverBehavior();</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> HoverHandler(TagConfig config) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">super</span>(config);</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> <span style="color: blue;">void</span> apply(FaceletContext ctx, UIComponent parent) <span style="color: blue;">throws</span> IOException {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (parent <span style="color: blue;">instanceof</span> ClientBehaviorHolder) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ClientBehaviorHolder comp = (ClientBehaviorHolder) parent;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> comp.addClientBehavior("<span style="color: darkred;">mouseover</span>", mouseOver);</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> comp.addClientBehavior("<span style="color: darkred;">mouseout</span>", mouseOut);</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
If you want to create a tag handler class of your own, you should extend it from <i>javax.faces.view.facelets.TagHandler</i> and do your work in the apply method. The method has a parameter parent and it is the immediate parent of the tag. In our case, the inputText.<br />Since we now have a reference to the component we like to modify, we can call the <i>addClientBehavior</i> method twice, once for the mouseover event and once for the mouseout event.<br />The <i>HoverBehaviour</i> class we pass along with the event names, is the same class as we used in the previous section. So it will generate the correct javaScript code for each event.<br />So now we have improved our hover functionality greatly from a developers standpoint. He doesn't have to type the event names (strings where he can make mistakes) and has to type a lot less characters.<br /><h2>
Resource dependency</h2>
The only thing that can go wrong now, is the definition of the CSS class. If we define it in the CSS file of the application, we have it available on every page. <br />
<br />But what if we decide to create some kind of reusable library so that we can use it for all the applications of the company. Or what if the javaScript code is large and we have placed it in an external file?<br />Maybe you know already that with a JSF renderer, you can specify the external resources the renderer depends on. Resources like javascript files and CSS files, just as we also need for the client behaviour functionality.<br />The good news is that there exists a special renderer for client behaviour, called <i>ClientBehaviorRenderer</i>. It has also a getScript method that we need to implement and we can specify the resources we need with the ResourceDependency annotation. This is the renderer version of the hover functionality<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@FacesBehaviorRenderer(rendererType="<span style="color: darkred;">hover</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@ResourceDependency(name = "<span style="color: darkred;">hover.css</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> HoverBehaviorRenderer <span style="color: blue;">extends</span> ClientBehaviorRenderer {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">final</span> String MOUSEOVER_EVENT = "<span style="color: darkred;">mouseover</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">private</span> <span style="color: blue;">static</span> <span style="color: blue;">final</span> String MOUSEOUT_EVENT = "<span style="color: darkred;">mouseout</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> String getScript(ClientBehaviorContext behaviorContext, ClientBehavior behavior) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (MOUSEOVER_EVENT.equals(behaviorContext.getEventName())) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">this.className += ' hoverCls '</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">if</span> (MOUSEOUT_EVENT.equals(behaviorContext.getEventName())) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">this.className = this.className.replace( /(?:^|\\s)hoverCls(?!\\S)/g , '' )</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> <span style="color: blue;">null</span>;</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
It is a straight copy, only the base class is different and has other annotations.<br />The client behavior itself becomes now empty, except for the definition of the renderer that must be used.<br /><pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@FacesBehavior(value = "<span style="color: darkred;">hover</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> HoverBehavior <span style="color: blue;">extends</span> ClientBehaviorBase {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> String getRendererType() {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">hover</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">}</pre>
</pre>
<h2>
Wrap up</h2>
We now have created a custom tag which allows us to have the 'hover' functionality using javascript functionalities. We only need a single tag and due to the renderer approach, we can package it in a jar file. When the file is in the classpath and we use the template, the correct coloring is applied to the 'hovered' field.<br />
<h2>
Conclusion</h2>
With the client side behavior of JSF 2, you have the possibilities to further enhance the components in a component library with some client side features in a reusable way. JSF remains mainly a server side framework but the client side representation can now greatly enhanced by the developer.<br />With these possibilities available, JSF can go along with the recent HTML5 and JavaScript frameworks raise in interest in the application development business.<br />
<br />You can find the code for this tutorial <a href="https://jsfcorner-blog.googlecode.com/svn/trunk/clientBehaviour" target="_blank">here</a>.<br />
<br />
<br />
<br />
<br />
Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com0tag:blogger.com,1999:blog-7236465384582522183.post-69914094300353886662013-02-03T20:22:00.000+01:002013-02-03T20:22:03.159+01:00Client Behavior functionality with JSF 2.x (part 1)<h2>
Introduction</h2>
One of the lesser know new features of JSF 2, is the ability to define some client behavior for a component in a reusable way. We all know the possibility to enhance a component with ajax, using the <f:ajax> tag. It is also based on the Client Behavior functionality but we can define our custom functionality.</f:ajax><br />
<br />
Just as you can define a validator for an input field, you can define a behavior which results in some JavaScript code which can be executed in the browser.<br />
<br />
These features shows that, although JSF is still mainly a server side framework, the importance and the popularity of the client side is acknowledged.<br />
<h2>
Confirm button</h2>
We start with a simple example where we like to make a button that first asks for a confirmation before it performs its action. A classic example is the button that deletes some information but first we ask the user for a confirmation if he is sure to execute this irreversible action.<br />
<br />
The key Java class for the Client Behavior is <i>ClientBehaviorBase</i>. It implements the <i>ClientBehavior</i> interface, common to all functionality related to client side behavior, and by implementing the getScript method, half of the work is already done.<br />
For our confirm functionality, we have a method like this<br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> @Override</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">public</span> String getScript(ClientBehaviorContext behaviorContext) {</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">return</span> "<span style="color: darkred;">return confirm('Are you sure ?');</span>";</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> }</pre>
</pre>
<br />
The return string is the JavaScript we like to execute in the browser, here it is the confirm method which pops-up a javascript ‘window’ with an OK and Cancel button.<br />
<br />
When the class is annotated with <i>@FacesBehavior</i>, The JSF system add our class to the list of implemented client behaviors.<br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;">@FacesBehavior(value = "<span style="color: darkred;">confirmation</span>")</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;">public</span> <span style="color: blue;">class</span> ConfirmBehavior <span style="color: blue;">extends</span> ClientBehaviorBase {</pre>
</pre>
<br />
The content of the value member is the, unique, name we can use to refer to our custom client behavior. This is needed when we define a tag for the behavior.<br />
<br />
A tag is needed so that we can specify in the xhtml files which components receive our javascript. In the facelet tag library we can define it as follows.<br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">namespace></span><span style="color: blue;"></span>http://www.rubus.be/jsf/tutorial<span style="color: blue;"></</span><span style="color: maroon;">namespace></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">tag></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">tag</span>-<span style="color: red;">name</span><span style="color: blue;">></span>confirmation<<span style="color: blue;">/</span><span style="color: maroon;">tag</span>-name><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">behavior></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: maroon;">behavior</span>-<span style="color: red;">id</span><span style="color: blue;">></span>confirmation<<span style="color: blue;">/</span><span style="color: maroon;">behavior</span>-id><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">behavior></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: maroon;">tag</span><span style="color: blue;">></span></pre>
</pre>
<br />
<br />
<br />
The behavior-id must match the value member of the FacesBehaviour annotation. The tag name can be freely chosen but here it happens to be the same as the behavior id.<br />
<br />
Assigning to a commandButton is not different than using any other custom tag that you have defined in a facelet tag library.<br />
<br />
<pre><pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: maroon;">html</span> <span style="color: red;">xmlns</span>=<span style="color: blue;">"http://www.w3.org/1999/xhtml"</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: red;">xmlns</span>:<span style="color: red;">h</span>=<span style="color: blue;">"http://java.sun.com/jsf/html"</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: red;">xmlns</span>:<span style="color: red;">r</span>=<span style="color: blue;">"http://www.rubus.be/jsf/tutorial"</span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">head</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">head></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">body</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">form></span><span style="color: blue;"></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">commandButton</span> <span style="color: red;">value</span>=<span style="color: blue;">"with confirmation"</span> <span style="color: red;">actionListener</span>=<span style="color: blue;">"#{bean.performAction}"</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"><</span><span style="color: mediumvioletred;">r</span>:<span style="color: maroon;">confirmation</span><span style="color: blue;">/></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">commandButton</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> <span style="color: blue;">>/</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">form</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"> ...</pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: mediumvioletred;">h</span>:<span style="color: maroon;">body</span><span style="color: blue;">></span></pre>
<pre style="background-color: white; font-family: consolas,'Courier New',courier,monospace; font-size: 11px; margin: 0em; width: 100%;"><span style="color: blue;"></</span><span style="color: maroon;">html</span><span style="color: blue;">></span></pre>
</pre>
<br />
When the user clicks now on the button, a confirmation is asked with the text ‘Are you sure?’. And when he clicks on the cancel button, the action listener method isn’t performed. In the case he has pressed on the OK button, the post to the server is executed as usual.<br />
<br />
<h2>
Which components</h2>
<br />
To what components can we attach a custom client behaviour? This is determined by the <i>ClientBehaviourHolder </i>interface. It has a few methods to handle the addition and retrieval of registered client behaviors and event names. More on event names in the next section.<br />
<br />
Well almost all components implement that interface. The most useful ones are of course all the input fields and the buttons. But also on the html body component we can attach a behaviour. More specifically, the load event can be used to attach some additional code to the page when rendered in the browser.<br />
<br />
<h2>
How to specify the event?</h2>
<br />
In our example with the confirmation question, the javascript method is attached to the onClick method of the button. This is because the click event is the default event for the commandButton component. If we like to attach the code to some other event, then we have to specify the event name with the event attribute of the tag. We will see an example of it in the second part of this blog.<br />
<br />
What are all the events which are supported? This differs from component to component. But the rule is that when you have the onXXX attribute on a component to attach some behaviour, the event XXX is available for creating a reusable client behaviour with the technique explained above.<br />
<br />
<h2>
Conclusion</h2>
<br />
It is very easy to specify some client behavior in a repeatable manner with JSF 2. And in the second part of this text I’ll explain some more advanced topics of the client behavior functionality.Rudyhttp://www.blogger.com/profile/02063576761910580068noreply@blogger.com1