My blog has moved!

You should automatically be redirected in 6 seconds. If not, visit
http://blogs.i2m.dk/allan
and update your bookmarks.

Wednesday, 31 December 2008

Setting JAVA_HOME on Ubuntu

A thing that always annoys me about installing Java is that it doesn't automatically set up the JAVA_HOME environment variable after installation. I guess this is to avoid having problems when you have multiple virtual machines installed. Anyway, I use Ubuntu Linux to host the majority of my Java Application Server. It is easy install Java (sudo apt-get install sun-java6-jdk) but there always seems to be a debate about where to set the JAVA_HOME environment variable. Some instructions say you should add it to your personal profile (e.g. ~/.bashrc) others suggest adding it to the global profile (i.e. /etc/profile), some people even suggest adding it directly in the init script for the services that need the variable. My suggest is to add an executable shell script to /etc/profile.d/ called javahome.sh. The content of the file would be: export JAVA_HOME=/usr/lib/jvm/java-6-sun. All shell scripts (i.e. executable files with the extension .sh) located in the /etc/profile.d/ directory are loaded upon login and would therefore work for all users without having to change system files that may change upon the next O/S upgrade. To test the script simply type source /etc/profile This will reload the profile for the current user. To verify that the environment variable has been initialised type export|grep JAVA_HOME

Enjoy!

Monday, 24 November 2008

Getting value expressions from f:attributes

If you have a custom converter or validator you may provide these with the option of letting developers specify attributes. For example, let's say that we are creating a converter that will allow the formatting of a Calendar object. Note, that the <f:convertDateTime /> is for Date objects (which can be easily retrieved from a Calendar, but that is beside the point). So the custom converter I'll create here is for converting/formatting Calendar objects.


package com.blogspot.bigallan.converters;

import java.text.*;
import java.util.*;
import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;

public class CalendarConverter implements Converter {

/**
* Not implemented as the converter is one-way only.
*/
public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
return null;
}

public String getAsString(FacesContext ctx, UIComponent component, Object value) {

// Get the Calendar to convert
Calendar calendar = (Calendar) value;

String pattern = "";

// Obtain attributes specified along with the converter
Map<String, Object> attributes = component.getAttributes();

// Check if the pattern attribute was specified
if (!attributes.containsKey("pattern")) {
System.out.println("pattern was not specified");
return "";
} else {
pattern = (String)attributes.get("pattern");
}

// Create a DateFormatter for the pattern
DateFormat outputFormat = new SimpleDateFormat(pattern);

// Format the calendar
try {
Date date = originalFormat.parse(calendar.getTime());
return outputFormat.format(originalDate));
} catch (ParseException ex) {
ex.printStackTrace()
return "";
}
}
}


In faces-config.xml you would declare the converter like this:


<converter>
<converter-id>calendarConverter</converter-id>
<converter-class>com.blogspot.bigallan.converters.CalendarConverter</converter-class>
</converter>


We can now use the converter in a view:


<h:outputText value="#{myBean.calendarObject}">
<f:converter converterId="calendarConverter" />
<f:attribute name="pattern" value="d. MMMM yyyy" />
</h:outputText>


When the code is rendered in the browser you'll get the calendar converter to something like this 24. November 2008. So far so good. However, what if we didn't specify the date pattern as static text, but rather bind it to a value. This technique is efficient when you reuse the pattern in many places and want to keep the pattern in a central place. So say that we had a managed-bean called common with a method getDateFormat() : String that would provide the pattern. The code would look like this:


<h:outputText value="#{myBean.calendarObject}">
<f:converter converterId="calendarConverter" />
<f:attribute name="pattern" value="#{common.dateFormat}" />
</h:outputText>


When the code is rendered in the browser you'll get a blank response and see the following in the log, "pattern was not specified". The log statement is generated from out code above where we check for the attribute named "pattern". This is because of a requirement in the JSF 1.2 specification (JSR-252) that states (Section 9.4.2) that literal (static) text should be stored in the attribute map of the component and non-literal texts should be stored in the value expression map of the component. So to get the pattern from the value expression map we modify the getAsString method as follows:



public String getAsString(FacesContext ctx, UIComponent component, Object value) {

// Get the Calendar to convert
Calendar calendar = (Calendar) value;

String pattern = "";

// Obtain attributes specified along with the converter
Map<String, Object> attributes = component.getAttributes();

// Check if the pattern attribute was specified
if (!attributes.containsKey("pattern")) {

ValueExpression ve = component.getValueExpression("pattern");
if (ve == null) {
System.out.println("pattern was not specified");
return "";
} else {
pattern = (String) ve.getValue(ctx.getELContext());
}
} else {
pattern = attributes.get("pattern");
}

// Create a DateFormatter for the pattern
DateFormat outputFormat = new SimpleDateFormat(pattern);

// Format the calendar
try {
Date date = originalFormat.parse(calendar.getTime());
return outputFormat.format(originalDate));
} catch (ParseException ex) {
ex.printStackTrace()
return "";
}
}


The difference is that we now first check to see if there is a literal value specified. If not, we check if there is a value expression, and if there is no value expression either we will fail. If there is a value express we evaluate it and use it as our pattern.

Tuesday, 28 October 2008

Open Source vs. Commercial Software

Today I stumbled upon the following article about Open Source vs Commercial Software. It's quite entertaining and shows may of the pros and cons for both open source and commercial software licensing.

http://www.isitedesign.com/insight/08_07/open-source-versus-commercial-web-software.cfm

Enjoy!

Friday, 24 October 2008

Replacing TopLink Essentials with OpenJPA as my persistence provider

During the development of my latest pet project I decided to go head-on with many of the latest Java Enterprise APIs. One of these was the Java Persistence API (JPA), which I had already used in a handful of projects before. On previous projects the persistence requirements were very simple. I could use JPA out-of-the-box with TopLink Essentials which is the standard set-up for a JPA project in NetBeans/GlassFish. However, for this new pet project of mine I was in need of storing large binary objects (BLOBs). I was shocked to discover that TopLink Essentials doesn't support the Fetching configuration for relationships and properties. Instead it will Fetch.EAGER everything in a relationship and property. This made my application crash hard (OutOfMemoryException) when ever I would query for all entities containing the BLOB. So, I set out to replace the persistence provider. First I looked at Hibernate. I used Hibernate before JPA was released and never had much trouble with it. Unfortunately I found that Hibernate also doesn't support the fetching configuration (in JPA mode). That lead me to OpenJPA which really surprised me. It is well documented, clean, easy to use, and support the fetch configuration. I've now replaced the persistence provider on two projects with OpenJPA and the performance has increased significantly. However, here are a few gotchas that you have to look out for:


  • Auto-generated identity fields must not have a preset value in your JavaBean (hence, this would give you problems:

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id = 0L


    Instead you should write

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


  • Collections are Fetch.LAZY by default, so if you got an existing using TopLink Essentials, you have to double check that your relations are not throwing LazyInitializationException upon fetching outside the transation.

  • Remember to specify the Fetch depth (openjpa.MaxFetchDepth) in persistence.xml for using the Fetch.EAGER configuration

  • TopLink Essentials compiles named queries when your application is deploy on the application server, OpenJPA on the other hand compiles the named queries upon first usage.

  • When enabling SQL DDL on OpenJPA it doesn't generate foreign key constraints, unlike TopLink Essentials



That's all for now. I'd love to hear about your experiences with OpenJPA or any other persistence provide you find suitable for your need.

Friday, 10 October 2008

Cycling

For the past week I've been cycling to and from work. That might not sound like a big deal to you, but it has certainly been a challenge for me. In the past it has been all to easy to jump into the car and head off for work. No more, I've decided. The distance to work is very do-able, 5.5 KM each way. It's better for me and it's better for the environment. The biggest problem so far has been the uphill route on my way back. Nevertheless, I've made great progress already. The first day was absolutely hell! When I got to work I could barely breathe and I had to spend several minutes in the bike shed to compose myself. On the third day I managed to cut off 5 minutes from the ride, and today I was only plagued by fatigue in my joints. I'm looking forward to seeing how I'll be feeling on Monday and if I can take another week.

Thursday, 9 October 2008

MyFaces and Facelets - The Definitive Guide

For the past five months or so, I've had the pleasure of participating as a contributing author and editor of the recently released Apress publication, "MyFaces and Facelets - The Definitive Guide".



It was a great experience that I hope that I'll be able to relive in the near future on other book writing projects. What I liked about the book was the focus on the array of JSF components under the MyFaces Apache project. Most people seem to think that MyFaces is simply an implementation of the JavaServer Faces specification. MyFaces is an umbrella project for JavaServer Faces related technologies. The most famous of the sub-projects is the Tomahawk components project which provides a lot of useful JSF component that I certainly couldn't live without.

The focus of the book is on technologies under the Apache MyFaces project as well as the Facelets technology. Facelets is another very important JSF technology that deserves more attention from the community. There are lots of people using Facelets, but little development is going on to make it truly professional.

The book is not for newcomers to JSF, but for programmers already familiar with the basics of JSF. If you are looking to get familiar with JSF I can highly recommend JSF In Action by Kito D. Mann published by Manning.

Thanks to Zubin Wadia and Hazem Saleh for making the project a great experience!

Monday, 1 September 2008

On the road again... (Uganda)

I'm on the road again again. This time I'm in Uganda. Uganda has to be one of my absolute favorite countries. I've be dropping in and out of Uganda the past nine years and even lived here for a few years. What I like about Uganda is the friendliness of the people. Ugandans have to be the friendliest people in the world! That is not to say that there are no dodgy Ugandans, but overall they are very easy people to get along with.

This time I'm not travelling for the company. Instead I'm here to assess some business opportunities for the near future. You would be surprised how many IT-related business opportunities you will find in a developing economy.

Anyways, just wanted to drop a post on the blog to show that I'm still alive and well. More about my trip later.

By the way, if you are ever in Uganda there are two things you must try; 1) A whole deep fried tilapia from the Lake Victoria 2) Roasted pork. Both usually come with a range of accessories such as avocado, cassava, and matoke.

Wednesday, 6 August 2008

Project-based formatting in NetBeans 6.5

Being part of the NetBeans Community Acceptance Testing (NetCAT) Programme has definate advantages. For one, you get to try out all the new features planned and influence how they will work before being released to the general public (that is not quite true....anyone can download the daily development builds).



One of the features in the upcoming NetBeans 6.5 that I'm particularly happy about is Formatting by project. In NetBeans it has always been one configuration for all projects. This is slowly changing. During NetCAT for 6.1 the "Shared Library" feature was implemented to detach library management from NetBeans and thereby making projects more portable. So, this time the brilliant guys on the NetBeans development team implemented a feature making it possible to do project-based formatting. This is a great feature when you work on many different projects with different formatting requirements. Way to go! My hope is that for the next version of NetBeans they will also have made template management project-based.

Wednesday, 25 June 2008

On the road again...

After a lovely week back home in Denmark with my family, I am once again on the road. This time I'm in Zambia to conduct training and hand-over a system we have built for COMESA. I've been to Zambia twice before and always enjoy coming here as it is clean and people are friendly. Anyways, I still hope this will be must last trip this year as I really need to spend some time at home with my family.

Note: If you are planning on going to Zambia I can highly recommend staying at the Intercontinental. At my first visit I was staying at Holiday-Inn. The food and service was excellent but the rooms were terrible!

Thursday, 12 June 2008

Finalised my mission in Djibouti and Kenya

Today, I finalised my mission to Djibouti and Kenya. I've still got another three days until I'm back home, but at least my work is done. While in Djibouti I carried out four days of System Administration training for the Web Portal I'm putting into place. That was followed by a one day steering committee meeting and four days workshop on Portal Management in Nairobi. It has been a very exhausting trip as I caught a food poisoning in Djibouti two days after having arrived. The food poisoning persisted until yesterday (almost a week) after which I had to go see a doctor. Fortunately, Nairobi Hospital is located just opposite the venue where I was conducting the workshop. So after having consulted a doctor and taken a few samples, I was given some medicine that would hope initially until they had time to examine my samples. So, today I got a call from the doctor explaining that I had a fungus growing in my stomach that was developing into a yest infection. I was then given some antibiotica and now feeling very fine. However, the last week was hell. Imagine having to do presentation from morning till afternoon with a constant stomach ache and having to run off to the wash room after every meal. Anyways, it is now being treated and I'm feeling much better.

Besides my illness I got to talk and meet some wonderful people from around Eastern Africa. Tomorrow morning I'm off to Dubai where I'll spend one day before heading home to the family! Traveling can be very tiring and stressful when you'd rather spend time with your wife and baby.

That's all for now folks.

Sunday, 1 June 2008

Dubai is hot!!

Dubai is hot, in more than one sense. I'm currently on my way to Djibouti to finalise some work on a project. On my way I stopped in Dubai for two days as I've always been curious about the place. I was very pleasantly surprised as people were nice, the place was clean, and the city was beautiful!

The real hotness though is the weather. I couldn't help laughing when I saw the sticker on the window in my hotel room.



It says "WARNING - Humidity from outside may activate the fire alarm". I can testify to the hotness (between 40 and 50 degrees celcius) as I spent a whole day on the top deck of a Big Bus tour around Dubai (if you only got a day in Dubai I would strongly suggest the Big Bus Tour - it' is excellent!).

Of all the places I've been I'd give it a 9 out of 10.

That's all for now - I'm off to Djibouti in a few minutes.

Thursday, 8 May 2008

Using Facelets with NetBeans 6.1 (without nbfaceletssupport)

--
Update 27. May 2008: You can download the Facelets NetBeans plug-in for 6.1 from: http://project-template.googlecode.com/files/nbfaceletssupport-6.1.zip
--

I'm a fan of Facelets when it comes to templating for JSF applications. Prior to version 6.1 of NetBeans I was using the nbfaceletssupport plug-in. Sure, it had its quirks, but overall it was a good plug-in. After installing NetBeans 6.1 and really got into using all the new cool features (shared libraries being the most significant) I realised that the nbfaceletssupport plug-in for NetBeans 6.0 didn't work and a fix had not yet been released at the nbfaceletssupport project site (note: Po-Ting Wu of Sun Microsystems has provided instructions on how to re-compile the plug-in for NetBeans 6.1). This also happened when I switched from NetBeans 5.5.1 to 6.0, so I anticipate that this will also happen in the future. So, I thought to myself, why not use the powerful XML support already built-in NetBeans to give me what I need. What I really needed the plug-in for is code completion. So, here goes. First I decided to drop JSP pages (.jsp) for JSP documents (.jspx). The difference being that .jspx is pure XML and .jsp is HTML.

Facelets file as a JSP page (.xhtml):


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>JSP facelets file</title>
</head>
<body>

<ui:composition template="/resources/templates/page.xhtml">
<ui:define name="pageTitle">This is a page title</ui:define>
<ui:define name="pageContent">This is the page content</ui:define>
</ui:composition>

</body>
</html>



Facelets file as a JSP document (.jspx):

<jsp:root version="2.0" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:t="http://myfaces.apache.org/tomahawk" xmlns:c="http://java.sun.com/jstl/core" xmlns:jsfExt="http://java.sun.com/jsf/extensions/dynafaces">
<ui:composition template="templates/page.xhtml">
<ui:define name="pageTitle">This is a page title</ui:define>
<ui:define name="pageContent">This is the page content</ui:define>
</ui:composition>
</jsp:root>



When creating facelets file as JSP document in NetBeans you will automatically get code completion (without any third-party plug-ins).



For this to work, ensure that the following configuration is set it web.xml:


<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.jspx</param-value>
</context-param>



and that the faclets tag library descriptor (TLD) is accessible in the classpath (eg. /WEB-INF/tlds).




References:

Tuesday, 6 May 2008

Yearly conference at the local Danish IT Society branch

Last week I went to the yearly conference for my local Danish IT Society branch. The topic of the conference was Enterprise Architecture. I was a bit unsure about attending as I was expecting some obscure high-level talks that has never seen the light of day. I was pleasantly surprised! All the speakers did a great job and managed to cover the various facets (from theory, to best practice, to practice) of Enterprise Architecture. What especially caught my attention was the excellent governance and organisational re-structuring implemented at NyKredit headed by their CIO (and president of Danish IT Society) Lars Mathiesen (You can read articles about Mathiesen on Computerworld.dk). From a vendor point-of-view the Vice President SOA Strategy, Ivo Totev of Software AG flew in from Germany. Last year I went for another meeting arranged by Danish IT Society with Scrum founder Jeff Sutherland. I wasn't too impressed as there was too much "going-around-the-bush" and not a clear business case for Scrum. Anyways, I didn't know what to expect from Ivo Totev's presesentation. However, I was very impressed with his presentation about the best practices of Enterprise Architecture coupled with anecdotes about what was working and not working with their clients. If you've got interest in Enterprise Architecture, Service-oriented Architecture (SOA), and Business Process Management, I suggest visiting Software AG's customer community at http://communities.softwareag.com/ where you'll interesting resources such as podcasts, blogs, discussion groups and even a freely downloadable PDF version of the book "BPM Basics for Dummies".

Friday, 18 April 2008

Creating a generic error page for JSF

Sometimes using FacesMessages is not sufficient for reporting errors. For example, if you have a runtime error (invalid JSF mark-up or NullPointerExceptions) it is difficult to report them using FacesMessage.

Creating a generic error page for JSF is similar to creating a generic error page for plain JSP applications. You'll need a configuration in web.xml to tell the servlet container to redirect errors to a given page. Then you'll need to create that page as well as a backing bean that can show you the stacktrace or error message.

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

... markup for your web app ...

<error-page>
<error-code>500</error-code>
<location>/Error.jsp</location>
</error-page>

</web-app>


With that we will get the servlet container to forward any Internal Server Errors (HTTP 500) to the page Error.jsp.

Okay, now we need to create a bean that will prepare the error message based on the exception that was thrown:

Error.java

package bigallan.beans;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;
import javax.faces.context.FacesContext;
import javax.servlet.ServletException;

public class Error {

public Error() {}

public String getStackTrace() {

// Get the current JSF context
FacesContext context = FacesContext.getCurrentInstance();
Map requestMap = context.getExternalContext().getRequestMap();

// Fetch the exception
Throwable ex = (Throwable) requestMap.get("javax.servlet.error.exception");

// Create a writer for keeping the stacktrace of the exception
StringWriter writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);

// Fill the stack trace into the write
fillStackTrace(ex, pw);

return writer.toString();
}

/**
* Write the stack trace from an exception into a writer.
*
* @param ex
* Exception for which to get the stack trace
* @param pw
* PrintWriter to write the stack trace
*/
private void fillStackTrace(Throwable ex, PrintWriter pw) {
if (null == ex) {
return;
}

ex.printStackTrace(pw);

// The first time fillStackTrace is called it will always be a ServletException
if (ex instanceof ServletException) {
Throwable cause = ((ServletException) ex).getRootCause();

if (null != cause) {
pw.println("Root Cause:");
fillStackTrace(cause, pw);
}
} else {
// Embedded cause inside the ServletException
Throwable cause = ex.getCause();

if (null != cause) {
pw.println("Cause:");
fillStackTrace(cause, pw);
}
}
}
}


Now that we have the Backing Bean we need to register it in faces-config.xml:


.. usual faces-config stuff ..

<managed-bean>
<managed-bean-name>Error</managed-bean-name>
<managed-bean-class>bigallan.beans.Error</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>


And lastly the JSP page (Error.jsp) displaying the error:

.. usual JSP header stuff ..

<h:panelGrid>
<h:outputText value="The follow error occured:" />
<h:inputTextarea style="width: 100%;" rows="20" readonly="true" value="#{Error.stackTrace}" />
</h:panelGrid>


That's all!

Enjoy.

Wednesday, 2 April 2008

Tomato juice on airplanes

I've just returned from a two week business trip and there is something that just keeps puzzling me when I fly. The amount of people that drink tomato juice on airplanes just amazes me. I have never dined with anyone who ordered tomato juice neither I have ever tasted it. However, on airplanes it seems like people have the urge to drink tomato juice. Flying back from Uganda (via Nairobi) to Amsterdam, an 8+ hours journey my co-passenger only had tomato juice! Tomorrow I've got to go buy myself some tomato juice to see what the craze is all about.

Saturday, 29 March 2008

Using my Nokia 6120 for presentations

Today I noticed a cool feature of my new Nokia 6120 mobile phone. From it's download menu I was able to download a presentation tool from Nokia that turns the phone into a remote control for my PC. I've been thinking about getting a separate presentation device as I do a fair share of presentations and hate having to walk back to my PC everytime I want to move to the next slide. So, the way it works is by having a java application on the phone that emulates the mouse and an application on the PC that turns the keypresses on the phone into mouse movesments on the PC. I've tried it out with PowerPoint and works great. The tool also supports other applications out of the box such as Winamp and Media Player. The desktop tool can futhermore configure the remote control for other programs as well by specifying what should happen when each individual key on the phone is pressed.



The application (containing both the desktop application and the Java ME application) can be downloaded from the Nokia Community Portal: Mosh.

Links:

Wednesday, 19 March 2008

Shared libraries finally made it to NetBeans

Today I installed NetBeans 6.1 beta. I've always been a great fan of NetBeans and participated in the Community Acceptance Testing programme (NetCAT) for version 4.0 and 6.0.

I haven't had time to go through all the changes yet, but one thing caught my attention immediately, the "Shared Library" functionality. It has always amazed me that this feature was not implemented way sooner. I have never used the built-in library manager for third-party libraries as the information about the libraries were not included with the projects, i.e. when I create a third-party library in the Library manager for say Apache Commons Configuration and use that in my project, it will break the built for not only other developers by also my continuous integration server. The alternative is to simply add the third-party library directly to the project as jars. The downside about that is that you can't attach the source and JavaDocs, so the inline code completion becomes almost useless. A third alternative is to manage dependencies completely outside of the IDE using Ant and Maven build scripts. I use to do this when using Eclipse, however then you have to update the dependencies in both the IDE and the build script = twice the work.

Back to NetBeans 6.1. When creating a project you now get the offer to enable "sharable libraries". When enabling this feature you are asked to specify the location where the libraries should be saved. By default it will suggest ..\libraries, which is a bit strange considering that it is outside the project folder. I guess it depends on the configuration management practices used on the project. Personally I always check in third-party libraries (as long as there are no licensing issues preventing it). In that way I alaways know that I can build the software anywhere on any machine (that includes my CI box).



After having enabled sharable libraries, NetBeans will automatically copy library to the specified folder when you add dependencies to your project. Furthermore, if you find out that you'd rather have your sharable libraries in a different location, you can simply change the location click "Save" and it will re-create the sharable libraries. Very neat!

I can imagine that they will continue working on the feature at NetBeans and this feature will become even better before the next release.

Tuesday, 18 March 2008

Example of using custom facelet tags

Rather than using includes when creating templates you can create your own custom facelet tags without the husle of creating a JSF component from scratch. As an example, I'll create a menu tag that can be used to switch a selected menu item on and off.

Here is the menu (save it as /WEB-INF/facelets/tags/menu.xhtml):


<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:panelGrid columns="10">
<h:outputText styleClass="menuItem" value="Home" />
<h:outputText styleClass="menuItem" value="Some page" />
<h:outputText styleClass="menuItem" value="Another page" />
<h:outputText styleClass="menuItem" value="Third page" />
</h:panelGrid>
</ui:composition>


Here is the cascanding style sheet:

.menuItem {
border: 1px solid black;
}

.menuItemSelected {
background: red;
color: white;
font-weight: bold;
}


To make the menu into a tag you create a facelets tag library. I'll call it mytags.taglib.xml and place it in /WEB-INF/facelets/:


<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://bigallan.blogspot.com/mytags
<tag>
<tag-name>menu</tag-name>
<source>tags/menu.xhtml</source>
</tag>
</facelet-taglib>


To make the web application recognise your tag library you need to update add the following context parameter to web.xml:

<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/facelets/mytags.taglib.xml</param-value>
</context-param>


If you have more than one custom tag library you can separate them with semicolons (;)

On your pages you can now include the menu tag:


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:mytags="http://bigallan.blogspot.com/mytags">
<head>
<title>My page</title>
<link href="css/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<mytags:menu home="true" />
</body>
</html>


All we need to do now is to look out for the attributes of the custom tag. Attributes are automatically turned into variables on the tag pages, so we simply make the following changes to /WEB-INF/facelets/tags/menu.xhtml:


<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
<h:panelGrid columns="10">
<h:outputText styleClass="menuItem #{home == 'true' ? 'menuItemSelected' : ''}" value="Home" />
<h:outputText styleClass="menuItem #{somePage == 'true' ? 'menuItemSelected' : ''}" value="Some page" />
<h:outputText styleClass="menuItem #{anotherPage == 'true' ? 'menuItemSelected' : ''}" value="Another page" />
<h:outputText styleClass="menuItem #{thirdPage == 'true' ? 'menuItemSelected' : ''}" value="Third page" />
</h:panelGrid>
</ui:composition>


To turn all menu items on you code do the following:


<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:mytags="http://bigallan.blogspot.com/mytags">
<head>
<title>My page</title>
<link href="css/styles.css" rel="stylesheet" type="text/css" />
</head>
<body>
<mytags:menu home="true" somePage="true" anotherPage="true" thirdPage="true" />
</body>
</html>


Enjoy!

Suggested reading on the subject:

Monday, 17 March 2008

Creating timers in EJB3

While the EJB 3.1 expert group is working on the improved timer service using annotations (See New Features in EJB 3.1) I thought that I'd just bring a small entry on using the timer service in EJB 3.

The timer service works by telling the service when it should timeout (i.e. when shall the "alarm" go off). You can add to this by telling it when it should timeout the first time, and how often (in ms) it should timeout after that. You define which methods on the bean that should be invoked upon timeout by annotating them @Timeout. The timer service is initialised by annotating a TimerService object as a @Resource.

Okay, before I show the code, these are the methods that we need:


  • A method for starting the timer

  • A method for stopping the timer

  • One or more listener methods that will be invoked when the timer has timed-out




@Stateless
public class MyTimerBean implements MyTimerLocal {

/** Service used for scheduling tasks. */
@Resource private TimerService timerService;

/**
* Starts the scheduler.
*
* @param startDate
* Start date
* @param interval
* Interval at which the timeout shall repeat
* @param timerName
* Timer to start
*/
public void startTimer(Date startDate, Long interval, String timerName) {
this.timerService.createTimer(startDate, interval, timerName);
}

/**
* Stops a given scheduler.
*
* @param timerName
* Timer to stop
*/
public void stopTimer(String timerName) {
for (Timer timer : (Collection) this.timerService.getTimers()) {
if (timer.getInfo() instanceof String) {
if (((String) timer.getInfo()).equals(timerName)) {
timer.cancel();
return;
}
}
}
}

/**
* {@link Timeout} event handler for generating a report.
*
* @param timer
* Timer that timed out
*/
@Timeout
public void generateReport(Timer timer) {
if (timer.getInfo() instanceof String) {
if (((String) timer.getInfo()).equals("Generate Report")) {
... do some processing ...
}
}
}

/**
* {@link Timeout} event handler for cleaning the cache.
*
* @param timer
* Timer that timed out
*/
@Timeout
public void cleanCache(Timer timer) {
if (timer.getInfo() instanceof String) {
if (((String) timer.getInfo()).equals("Clean Cache")) {
... do some processing ...
}
}
}
}


Right, so we have a method for starting a timer (startTimer). This method needs to be invoked in order to start the timer. This is one of the drawbacks of the TimerService, you cannot tell it to just start when the application is deployed (will be there in EJB3.1). Instead I use a Servlet Context Listener to invoke the startTimer method when the accompaying webapplication is deployed:


public class TimerInitialisationListener implements ServletContextListener {

/** Local interface for {@link MyTimerBean}. */
@EJB private MyTimerLocal myTimer;

/**
* Initialises the timer service.
*
* @param event
* Event that invoked the listener
*/
public void contextInitialized(ServletContextEvent event) {
Calendar now = Calendar.getInstance();
now.set(Calendar.HOUR_OF_DAY, 0);
now.set(Calendar.MINUTE, 0);
now.set(Calendar.SECOND, 0);
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH);
int dayOfMonth = now.get(Calendar.DAY_OF_MONTH);
int hourOfDay = now.get(Calendar.HOUR_OF_DAY);
int minute = now.get(Calendar.MINUTE);
Long repeat = 60000L * 60L * 24L;
LogFactory.getLog(TimerInitialisationListener.class).info("Start time: " + now.getTime());
LogFactory.getLog(TimerInitialisationListener.class).info("Repeat every: " + repeat + " ms (" + (repeat / 3600000L) + " hrs)");

myTimer.startTimer(new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute).getTime(), 60000L * 60L * 24L, "Generate Report");
}

/**
* Context is uninstalled from the servlet container.
*
* @param event
* Event that invoked the listener
*/
public void contextDestroyed(ServletContextEvent event) {
LogFactory.getLog(TimerInitialisationListener.class).info("Stopping timer");
myTimer.stopTimer("Generate Report");
}
}


When you deploy the enterprise application you will see that the timer is set to start at midnight and execute every 86400000 ms (i.e. every 24 hours). What you will notice is that it is only the generateReport method that is executed fully at every timeout as I've put in a check to ensure that it is the correct action being executed. Instead of using a String as the identifier of the Timer you can create create your own custom objects as pass them instead (just remember to make it serializable).

That's all for now. I'll bring another entry when EJB3.1 has been released and the new timer service annotations have been implemented.

On a side note, I've used Quartz before and it's great - I just like to stick to the standards if it can do the job.

Checkout the JavaDocs for the TimerService for more information.

UPDATE: 6. May 2008: Yesterday I was preparing some code using the timer service and I noticed that only the first method annotated with @TimeOut is executed upon timeout. Therefore, use only one @TimeOut method per SessionBean.

Saturday, 15 March 2008

Yippiee my new phone arrived

For a long time my old phone has been way past retirement. It was a Qtec 2020 (I believe). I've always loved smartphones and hated the glorified music players (e.g. Sony Ericsson). I don't see the point in the fancy music player phones, but that is probably because I'm perfectly happy with my iPod and have no plans of replacing it for something less cool.

Anyways, the Qtec acted up a long time ago. I used it as my organiser, phone and GPS for the car. When it suddenly started losing all its memory and at the same time I misplaced my stylus, I thought that it was high time to get a new phone. So this time I decided not to get a smartphone (mostly because the complete lack of market for smartphones in Denmark - this makes it very expensive!). Instead I got myself a Nokia 6120 with all the latest services provided on the 3G network (Skype, MSN, MobileTV, etc).

From the End-to-End Web Service Tutorial on NetBeans.org So far I'm loving the phone! It is fully compatible with Java MIDP 2.0 - so I'll have to get cracking with Java ME to make some applications soon. Can anybody recommend a good starting point for Java ME programming? My background in Java is purely enterprise and web. NetBeans got some cool mobile development aids that I'll be trying out - but I'd really like to know the basics before I start all the dragging and dropping. In anycase I think this is a good place to start: NetBeans 6.0 Mobility Documentation. It's got a pretty good tutorial for creating a mobile Dilbert browser.

Ordered the certification books

I've finally ordered the certification books that I mentioned in a previous post (SCJP Sun Certified Programmer for Java 5 Study Guide (Exam 310-055): Study Guide Exam 310-055 and Sun Certified Enterprise Architect for Java EE Study Guide (Exam 310-051): Study Guide Exam 310-051).

It is my personal goal to have taken both certifications before the end of April. I was tempted to also get the Certification Press book about Sun Certified Business Components Developer, but it got such bad reviews on Amazon that I didn't dare to get it. Unfortunately it seem to be the only study guide for Business Components Development.

Anyways, I'm looking forward to the books getting here so that I can get started!

Friday, 15 February 2008

Riots in Gellerup

This is a photo from a fire started just outside my appartment. The fire was dangerously close to my car but luckily the skilled firemen got the fire under control very quickly. The reason for the riot is apparently because of the re-publication of the famous Muhammad drawings in the Danish newspapers. I really think that "Respect" should be a mandatory course taught in primary school. To me it seems like respect for one another has simply disappear from this world. Everyday I see the lack of respect between people, whether it's between men and women, christians and muslims, employers and employees, buyers and sellers, children and adults. Oh dear oh dear, what has this place come to. Please, if you read this, respect the people and things around you!

Tuesday, 12 February 2008

Creating a custom JSF message component

The other day I was tasked with creating feedback messages for a JSF-based application as JavaScript alert dialogues. JSF already got a tag for displaying messages attached to components (<h:message /> and <h:messages />), however they are limited to render the text using a given cascading style sheet class for each level of severity.

This entry will show how to build a custom JSF message tag for rendering the messages as a JavaScript alert.

There are many excellent tutorials and blog entries out there describing JSF component development much better than I am capable of. So, I'll just focus on what is needed to create this specific component. My instructions are based on NetBeans 6.0, but they don't including anything that is not possible to do in other IDEs, so you should be able to translate the instructions into your own IDE.

We will keep the tag simple with one attribute, for, which will specify for which component the messages should be displayed. The signature of the tag will therefore be: <jc:alertMessage for="myForm" />.

1. Fire up NetBeans

2. Create a new Java Class Library Project (I've called mine jsf-components)

Before we continue let me briefly explain what we need:


META-INF/jsf-components.tld

Tag library descriptor declaring your tag and defining its attributes

META-INF/faces-config.xml

Declares the tag in the faces application

components/AlertMessage.java

Class representing the user interface component with properties for each attribute supported by the tag. It's recommended to sub-class one of the existing components to avoid doing all the work yourself.

components/AlertMessageRenderer.java

Class for rendering the content of the tag. This is the class where we will actual construct the HTML/Javascript code that is outputted to the browser.

components/AlertMessageTag.java

Class representing the actual tag.




Now that we know what to do - lets get on with it.

3. Create the components package in the Source Packages


3a) Right click Source Packages
3b) Select 'New'
3c) Select 'Other'
3d) Select 'Java'
3e) Select 'Java Package'
3f) Click 'Next'
3g) Enter components as the package name
3h) Click 'Finish'

4. Create the tag library descriptor
4a) Right click Source Packages
4b) Select 'New'
4c) Select 'Other'
4d) Select 'Web'
4e) Select 'Tag Library Descriptor'
4f) Click 'Next'
4g) Enter the following information:


  • TLD name: jsf-components

  • URI: http://jsf-components

  • Prefix: jc


4h) Click 'Finish'

5. Add the javaee.jar from the GlassFish project (%GLASSFISH%/lib) to the library dependencies of the project.

6. Create the Java class for the UI component, AlertMessage subclassing the UIMessage component.


package components;

import javax.faces.component.UIMessage;

public class AlertMessage extends UIMessage {

private static final String MSG_COMPONENT_TYPE = "components.alertmessage";
private static final String MSG_COMPONENT_FAMILY = "javax.faces.Message";

@Override
public String getFamily() {
return MSG_COMPONENT_FAMILY;
}

@Override
public String getRendererType() {
return MSG_COMPONENT_TYPE;
}

@Override
public String getFor() {
return super.getFor();
}

@Override
public void setFor(String forParam) {
super.setFor(forParam);
}
}


7. Create the Java class for the tag, AlertMessageTag subclassing the UIComponentELTag tag.


package components;

import javax.el.ValueExpression;
import javax.faces.component.UIComponent;
import javax.faces.webapp.UIComponentELTag;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

public class AlertMessageTag extends UIComponentELTag {

private ValueExpression forParam;

private static final String MSG_COMPONENT_TYPE = "components.alertmessage";

private static final String MSG_RENDERER_TYPE = "components.alertmessage";

@Override
public String getComponentType() {
return MSG_COMPONENT_TYPE;
}

@Override
public String getRendererType() {
return MSG_RENDERER_TYPE;
}

@Override
protected void setProperties(UIComponent component) {
super.setProperties(component);
AlertMessage em = (AlertMessage) component;
em.setValueExpression("for", forParam);
}

@Override
public int doEndTag() throws JspException {
return super.doEndTag();
}

@Override
public int doStartTag() throws JspException {
return super.doStartTag();
}

@Override
public void setPageContext(PageContext ctx) {
super.setPageContext(ctx);
}

@Override
public void setParent(Tag tag) {
super.setParent(tag);
}

public void setFor(ValueExpression forParam) {
this.forParam = forParam;
}
}


9. Create the Java class for rendering the tag, AlertMessageRenderer subclassing the JSF Renderer.


package components;

import java.io.IOException;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.render.Renderer;
import org.apache.commons.lang.StringEscapeUtils;

public class AlertMessageRenderer extends Renderer {

@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
AlertMessage alertMessage = (AlertMessage) component;

// Locate the component for which to display messages
UIComponent forComponent = alertMessage.findComponent(alertMessage.getFor());

// If the component could not be found end processing
if (forComponent == null) {
return;
}

// Iterate through messages for the component
Iterator iter = context.getMessages(forComponent.getClientId(context));
if (iter.hasNext()) {
ResponseWriter writer = context.getResponseWriter();

// Start the script tag
writer.startElement("script", alertMessage);
writer.writeAttribute("type", "text/javascript", null);

// Construct one big string of all messages
StringBuffer message = new StringBuffer();
while (iter.hasNext()) {
FacesMessage msg = (FacesMessage) iter.next();
if (message.length() > 0) {
// Separate each message with the JavaScript escape code
// for newline
message.append("\n");
}

message.append(msg.getSummary());
}

// Escape the constructed string to be outputable as a JavaScript
String displayMessage = StringEscapeUtils.escapeJavaScript(message.toString());

// Output the javascript code for displaying the alert dialogue
String jsAlert = "alert('" + displayMessage + "');";
writer.writeText(jsAlert.toCharArray(), 0, jsAlert.length());

// End the script tag
writer.endElement("script");
}
}

@Override
public void decode(FacesContext ctx, UIComponent component) {
if (ctx == null || component == null) {
throw new NullPointerException();
}
}
}


Notice that I'm using StringEscapeUtils.escapeJavaScript(String) from the Apache Commons Lang library to ensure the correct output of the JavaScript code.

10. Update the tag library descriptor to reflect the created component:


<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">
<tlib-version>1.0</tlib-version>
<short-name>jc</short-name>
<uri>http://jsf-components</uri>
<tag>
<name>AlertMessage</name>
<tag-class>components.AlertMessageTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<description>
The ID of the component whose attached FacesMessage object
(if present) should be diplayed by this component.
</description>
<name>for</name>
<required>true</required>
<deferred-value/>
</attribute>
</tag>
</taglib>


11. Create the faces configuration (META-INF/faces-config.xml) for the component:

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
<component>
<component-type>components.alertmessage</component-type>
<component-class>components.AlertMessage</component-class>
</component>

<render-kit>
<renderer>
<description>Renderer for the alert message component.</description>
<component-family>javax.faces.Message</component-family>
<renderer-type>components.alertmessage</renderer-type>
<renderer-class>components.AlertMessageRenderer</renderer-class>
</renderer>
</render-kit>
</faces-config>


12. Build the class library

All you need to do now is to place the jsf-components.jar into your web application, declare the tag library (<%@taglib prefix="jc" uri="http://jsf-components" %>) on the pages where you want to use the tag (<jc:alertMessage for="componentId" />). Example:


<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="jc" uri="http://jsf-components" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Example of AlertMessage component</title>
</head>
<body>
<f:view>
<h:form>
<jc:AlertMessage for="numberField" />
<h:inputText id="numberField">
<f:validateLength minimum="5" maximum="10" />
<f:validateLongRange minimum="10000" maximum="222222" />
</h:inputText>
<h:commandButton value="Submit" action="reload" />
</h:form>
</f:view>
</body>
</html>





UPDATE (30. July 2008): Facelets Support

You can use the component with Facelets by providing a Facelets Tag Library descriptor. In this example I name the tag library descriptor mycomponents.taglib.xml and place in the WEB-INF/ directory.

The contents of the descriptor is:


<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">

<facelet-taglib>
<namespace>http://jsf-components</namespace>
<tag>
<tag-name>alertMessage</tag-name>
<component>
<component-type>components.alertmessage</component-type>
<renderer-type>components.alertmessage</renderer-type>
</component<
</tag<
</facelet-taglib<


Next you need to reference the descriptor in web.xml using the facelets.LIBRARIES context parameter:


<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/mycomponents.taglib.xml</param-value>
</context-param>


Remember that if you have more than one Facelets Tag Library Descriptor, to separate them using semicolons (;)

Wednesday, 6 February 2008

Getting to know Solaris

The past ten years I've been working comfortably with various distributions of Linux (Ubuntu, Kubuntu, Gentoo, Mandrake, RedHat, Debian, Suse) and I have really enjoyed what they have to offer. During the four years where I was self-employed all my machines were running one or the other distribution of Linux (My favourite to this day is Ubuntu closely followed by Gentoo).

Anyways, lately I've become curious about Solaris and would like to use it for a Java build server that I'm setting up. The server will host a versioning system (Subversion), a continuous integration system (CruiseControl most likely) and an issue tracking system (Mantis most likely).

Last weekend I started my project to set-up Solaris. It's been quite a struggle as I thought that I could just transfer all my Linux skills to Solaris - but little did I know at that time.

Status as of now is that I've



One thing that has thoroughly annoyed me is package management. When you're use to apt-get (Debian) its hard getting use to tinker around so much to get packages to compile and configure properly.

So here I am... I've been contemplating how to continue from here, and that is when I saw an announcement about free Solaris training in Sun Learning Centre with the added bonus of being part of a $50,000 sweepstake!

For any other people considering Solaris I'd recommend signing up for the free training while it lasts as it will give you a head start on the nitty gritty of Solaris.

More about my adventures into Solaris later.

Custom code folding in NetBeans

When you got large source files it can sometimes be helpful to create foldings for certain sections of your code. NetBeans got a nifty functionality for this using non-intrusive XML code (similar to Visual Studio).

To create a custom code folding section simply insert the following before the content to fold:


//<editor-fold defaultstate="collapsed" desc="My custom code folding">


and the following after the content to fold:


//</editor-fold>
.

So for example, if you had a JSF backing bean where you want to create a custom code folding for your properties, action listeners, and action handlers you could do as follows:


package backingbeans;

import javax.faces.model.*;
import javax.faces.event.*;

public class MyBackingBean {

private String prop1 = "";

public MyBackingBean() {
}

//<editor-fold defaultstate="collapsed" desc="Properties">
public String getProp1() {
return this.prop1;
}

public void setProp1(String prop1) {
this.prop1 = prop1;
}
//</editor-fold>


//<editor-fold defaultstate="collapsed" desc="Action listeners">
public void myFirstListener(ActionEvent event) {
... do something ...
}

public void mySecondListener(ActionEvent event) {
... do something else ...
}
//</editor-fold>

//<editor-fold defaultstate="collapsed" desc="Action handlers">
public String myFirstActionHandler() {
... do something ...
return "OUTCOME1";
}

public String mySecondActionHandler() {
... do something else ...
return "OUTCOME2";
}
//</editor-fold>
}


This will create three custom folders that are collapsed by default when the file is opened.

If you like this, I'd suggest setting up a coding template for inserting the XML code as it can otherwise be tricky to remember. This is done by following these steps:


  1. Click Tools -> Options

  2. Select "Editor" from the top options

  3. Select the "Code Templates" tab

  4. Select "Java" in the Language dropdown

  5. Click the "New" button

  6. Enter the shorthand for inserting the template, for example I use 'efold'

  7. Click the "OK" button

  8. The template has been created, now enter the following code into the Expanded Text textbox:

    //<editor-fold defaultstate="collapsed" desc="${cursor}">

    //</editor-fold>

  9. Click the "OK" button.



You can try out the template by opening a Java source file, place the cursor where you want to insert the folding and type efold followed by the tab key. It will now have inserted the complete editor-fold and place the cursor ready for you to enter a description for the folding.

Monday, 4 February 2008

Using the "License" functionality in NetBeans 6

NetBeans 6 comes with a brand new functionality for including project-based licenses in source files. This enables you to easily use different licenses in the headers depending on the project you are working on.

Using the functionality is simple, here are the steps:

  1. Add your licenses to the NetBeans templates
  2. Update the project.properties to specify the desired license
Simple, eh?

Okay, first we add a license to the NetBeans template. For the sake of this example I'll add the GPL license:

  1. Click Tools -> Templates
  2. Expand the "Licenses" folder
  3. Select "Default License"
  4. Click the "Duplicate" button (a new template is created called license-default_1.txt)
  5. Select license-default_1.txt
  6. Click the "Rename" button
  7. Name the new license license-gpl.txt (notice, the name should follow the format: license-.txt)
  8. Select license-gpl.txt
  9. Click "Open in Editor"
  10. Enter the following text (GPL license) into the editor:

    <#if licenseFirst??>
    ${licenseFirst}
    </#if>
    ${licensePrefix}${name}.java
    ${licensePrefix}
    ${licensePrefix}Copyright (C) ${date?date?string("yyyy")} Allan Lykke Christensen
    ${licensePrefix}
    ${licensePrefix}This program is distributed in the hope that it will be useful,
    ${licensePrefix}but WITHOUT ANY WARRANTY; without even the implied warranty of
    ${licensePrefix}MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    ${licensePrefix}GNU General Public License for more details.
    ${licensePrefix}
    ${licensePrefix}You should have received a copy of the GNU General Public License
    ${licensePrefix}along with this program. If not, see <http://www.gnu.org/licenses/>.
    <#if licenseLast??>
    ${licenseLast}
    </#if>


  11. Replace the author name

  12. Save and close the template (CTRL+S followed by CTRL+W)


You have successfully added the template to NetBeans for use in future projects.

To use the license in a project do the following:

  1. Open the "Files" view (CTRL+2)
  2. Expand the nbproject folder of your project
  3. Open the project.properties file
  4. Add project.license=gpl in the end of the file, or if you already have a line starting project.license replace it.
  5. Save and close the file


Alright, you are ready to try out the license. Create a new Java class in your Source Packages and viola, the source file is using the newly created license.

In a future version of NetBeans I expect that it will be possible to select the license from the project properties page rather than you having to tinker around with project.properties.

Considering Java certification

As one of my new year resolutions I promised myself that I'd get some sort of technical certification this year. Basically what I'm interested in is the Java Programmer Certification, Web Component Developer Certification and Enterprise Architect Certification. For the three certifications I've found the following prep literature:

  • SCJP Sun Certified Programmer for Java 5 Study Guide (Exam 310-055): Study Guide Exam 310-055 (Certification Press) - Link
  • Sun Certified Web Component Developer Study Guide (Exam 310-081) - Link
  • Sun Certified Enterprise Architect for Java EE Study Guide (Exam 310-051): Study Guide Exam 310-051 (Certification Press) - Link

On the project management side I'm considering the Scrum Master Certification or Prince 2 Certification.

Any recommendation?

Concatenating strings in JSF

To start the day off I though I'd share a quick tip using JSF. Say you have a list of messages:

quicktip.Messages:


ITEM_1=First item
ITEM_2=Second item
ITEM_3=Third item

Now, on your JSF page you would like to show one of these messages depending on the ID of the item to display. For example, you might have an list of beans containing items you'd like to display:

quicktip.Item

package quicktip;

public class Item {

/** Unique ID of the item. */
private int id;

/** Number of items. */
private int count;

public Item() {}

...usual getters and setters...

}


So, in your backing bean to the JSF page you have a method that constructs a DataModel containing items (I won't go into those details as it's not very exciting). For the sake of this example the signature of the method is public DataModel getItems();

Finally we get to the interesting bit, the actual JSF page.

... usual jsf stuff ...
<html>
<f:loadbundle basename="quicktip.Messages" var="msgs" />
<body>
<h:datatable value="#{backingBean.items}" var="item">
<h:column>
<c:set var="key" value="ITEM_#{item.id}" />
<h:outputtext value="#{msgs[key]}" />
</h:column>
<h:column>
<h:outputtext value="#{item.count}" />
</h:column>
</h:dataTable>
</body>
</html>


That's it. So, the real gist of the tip is that you can use the jstl tag to concatenating a string that you can re-use to fetch values from maps.

He's back!

Hello people!

I'm back after a long hiatus! This time I intend to keep up the blogging and keep it at the same domain.

Watch this space!