Thursday, June 24, 2010

JSF composite component

On my latest project we used RichFaces as a component library. Our client didn't like to fill out the time with the RichFaces calendar. They wanted two combo boxes to fill out the time. I don't think this is the most user friendly way to solve picking a time (I like this timepicker) but our customer is king.

I thought that there would be someone on the internet who already created a component like that, but I could not find any so I made my own. JSF 2 will introduce a new component creation method. It will be simpler to create components and you do not have to write java code to make them work. But until we have JSF 2 available on all major application servers we will have to program some java for our components to work.

The plan I had for creating it was simple enough just take two HtmlSelectOneMenu components and fill them with default options.

So I ended with something like this:


private void createChildComponents(FacesContext context) {
Application application = context.getApplication();
hourInput = (HtmlSelectOneMenu) application.createComponent(HtmlSelectOneMenu.COMPONENT_TYPE);
minuteInput = (HtmlSelectOneMenu) application.createComponent(HtmlSelectOneMenu.COMPONENT_TYPE);
List<UIComponent> children = getChildren();
children.add(hourInput);
HtmlOutputText sparator = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
sparator.setValue(":");
children.add(sparator);
children.add(minuteInput);

UISelectItems hourItems = createSelectItems(application, 24, 1);
hourInput.getChildren().add(hourItems);

UISelectItems minuteItems = createSelectItems(application, 60, 5);
minuteInput.getChildren().add(minuteItems);
delegateProperties();
}

private UISelectItems createSelectItems(Application application, int number, int step) throws FacesException {
UISelectItems selectItems = (UISelectItems) application.createComponent(UISelectItems.COMPONENT_TYPE);
List<SelectItem> items = new ArrayList<SelectItem>();
for (int i = 0; i < number; i += step) {
items.add(new SelectItem(StringUtils.leftPad(String.valueOf(i), 2, "0")));
}
selectItems.setValue(items);
return selectItems;
}


Rendering this was not hard but to extract the selected value and store the submitted value back into the value binding, that was not so easy. First I tried to override the validate method but that didn't "sound" right, doing it in the updateModel was much better.

The only weird thing I was still facing was that, sometimes the value from the hour and minute components were converted to Integer but sometimes they where not. So I ended up with this construction to ensure that they were always Integer.


@Override
public void updateModel(FacesContext context) {
super.updateModel(context);

hourInput.validate(context);
minuteInput.validate(context);

ValueExpression valueExpression = getValueExpression("value");
Date value = (Date) valueExpression.getValue(context.getELContext());
if (value != null && hourInput.getValue() != null
&& minuteInput.getValue() != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(value);
Integer hour = Integer.valueOf(hourInput.getValue().toString());
calendar.set(Calendar.HOUR_OF_DAY, hour);
Integer minute = Integer.valueOf((minuteInput.getValue().toString()));
calendar.set(Calendar.MINUTE, minute);

valueExpression.setValue(context.getELContext(), calendar.getTime());
}
}


Here I'm using the Java Date API. That of course is extremely sadistic so we could change it to use joda-time.

Now to use it we first register it as a component in components.taglib.xml

<facelet-taglib>
<namespace>http://ctp-consulting.com/components</namespace>
<!--
usage: <ctp:timepicker value="date"/>
-->
<tag>
<tag-name>timepicker</tag-name>
<component>
<component-type>com.ctp.web.components.Timepicker</component-type>
</component>
</tag>


Then make sure you have the components.taglib.xml registered in you're web.xml

<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/tags/components.taglib.xml;</param-value>
</context-param>

And here an example of use, fist add the namespace on the top of you're page:

xmlns:ctp="http://ctp-consulting.com/components"

Then in our page you can do something like:

<ctp:timepicker value="#{catering.deliveryTime}"/>

Maybe this is not the best solution, if you have comments or tips, feel free drop them directly on this post. I'm interested in what you have to say!

Saturday, June 5, 2010

Jazoon 2010

As a Java developer you'll need to stay on-top of what is new and noteworthy. A great way to do this is to go to a conference, because this is an interactive way to learn about new stuff. Together with Douglas,  I was attending Jazoon, an international conference held in Zurich, it is my first time here. Like Devoxx it's also held in a movie theater. Although Jazoon is also an international conference there are of course a lot of Swiss here and it's a little smaller. But that just means I have more change to win an iPad :D (didn't happen, too bad).

After the keynote the first presentation I attend is about REST. Stefan Tilkov is the presenter and he does a nice job bashing web frameworks like JSF that do not do REST at all. He has a point, the web is about URI (Unified Resource Indicator) and a document should be identified with that. That has always been the way of the web. And "modern" web application frameworks have a tendency not to change the URI for every resource and use only one HTTP method (e.g. POST) instead of all 7 of them. Stefan calls this abusing the web, or even desktop applications in disguise. I must agree to what he has to say about a lot of things. Search engines like Google work because of this and even if we are writing applications that are used inside intranets they are still web applications and they should be able to work accordingly. I'll need to investigate what people developing JSF thoughts are about this.

Next up Blueprint by Costin Leau, he works for SpringSource. I personally have not used Spring since  they were hesitant to adopt annotations and was rather using JBoss Seam ever since. But as we have customers interested in doing something with OSGi it will be interesting to see how they eased the way to develop something for OSGi. When I heard about Spring the first time, I was amazed and wondered why I didn't think of that. Now I have the same feeling with OSGi, it can be a lot simpler when you use IoC in combination with it. Blueprint is only a spec and there are 2 implementations. I really need to take a look at it because it looks really helpful.


On Thursday we had a nice Java roundtable to discuss all the news.
Erik was all excited! :D


On day 2 the keynote is from Ken Schwaber he is one of the founders of SCRUM. In his presentation he made the point that a lot of people who think they are doing scrum are actually not: Because they don't finish their user stories. This is due to the fact that we don't include enough when we say it's done. When is a user story done? When user acceptance testing has taken place? Load test integration test and refactoring? When things like these are kept to the very end of the project a lot of work still remains to be done when the project should have been finished. According to Ken this work will be exponentially more then when you do it after each sprint. All in all it was quite a mood breaker because Ken tried to emphasize that a lot of software projects still fail and that we should be professional and fix that by changing what we call done.

Peter Lubers (he must be Dutch :D ) had a talk about HTML 5 Websockets. I've heard about a couple of things that are going to be in the HTML 5 spec but I did not know about this! And this is very exiting:  there are a lot of projects that have tried to solve the problem how to push data to a web browser client. All of the implementations are not ideal. There are a couple of polling solutions, but the overhead that you get when making a request, on average, is about 800k. That does not look like much but if you want to scale your applications it is a lot. The way Websockets work is to "upgrade" your standard HTTP  connection to a socket where you can then send and receive data over. He showed a working example of this with Google Chrome the only browser that supports this right now- At the end of the presentation he said he talked to one of the technical guys from Microsoft and he has a strong feeling it will not be in IE9, how nice is that (the IE6 story all over).

The two talks I went to after lunch were both about alternative languages on the JVM namely Groovy and Scala. And they we're both about Distributed Computing. I thought it was really exciting, all we need now is a customer with a large set of data and a need to compute something with. That is the only problem with distributed computing and with cloud computing even more so, it needs lot of data to work with. Otherwise there is no need to use it. This is even more true when you already use web applications. They scale very easy because they use the request response model. Every request could be handled by a separate thread or instance in a cluster. So interesting things are happening here and a lot of development is going into solutions based on distributed computing and cloud computing.


Douglas and Daniel trying to get more infos about Web Sockets...
Well...isn't that a game on that iPad?


Last Day

On the last day of the conference the keynote was about Gaia the satellite that is going to map a lot of stars in our milky way. It was interesting to see that they use Java to analyse the huge amount of data. And that there are still debates about Java being fast enough. Come on people it's 2010 Java is blazing fast!!

The whole last day was more or less about testing. There were a lot of talks in this area and only one that I would like to mention here. There was a way to short talk about Arquillian. I don't think that the presenters wanted to have a small slot but I guess they we're forced to use a small one. Arquillian is a cool way to test EJBs inside the container. The project is brand new and they still need to add support for a couple of containers. But it's looking really promising. I got a cool shirt at their presentation so I'll definitely keep an eye on this project :-).

Thoughts

All in all Jazoon was great to see and to be at. But if I would have to choose between Jazoon or Devoxx  I'd rather go for Devoxx. The idea I get is that Jazoon is younger than Devoxx and still has to proof itself as important and unique besides Devoxx. Of course Jazoon is better organized, everybody knows that people from Belgium are chaotic ( :D sorry guys), but that is not enough of course. At Jazoon I don't get yet the atmosphere you get from a Devoxx, this hold true for the size and quality of speakers too.

But I do have a lot of new things I have to look at! So all in all it was a positive experience. I hope Jazoon gets more popularity so it will attract more people from around the world.