demetrio812

13 October 2007

Creating a JSF component using RichFaces CDK

Hi,
this time I will explain how to create a simple output component using the Ajax4Jsf/Richfaces CDK framework.

CDK is a framework that simplifies the JSF component creation process so you can concentrate on developing the component functionalities instead of thinking to all the boiler code that this kind of work need.

There isn't an official manual on how to use it (it's still on development) so you have to look on richfaces forum and wiki, and some article you can find on net (see the links at the end of this post).

Before starting I want to point that I'm learning this stuff too and I'm not an expert on jsf component making and I'm still learning. Every suggestion is welcome.

Also you have to assure to have maven installed and working on your system, you have also to configure it for Ajax4Jsf/RichFaces CDK as it is written here.

We are going to make a skypecall component: it insert a link that permit to call a person from the web page via skype.

Let's start!

First of all create a new directory to start from (use a short and without space path);

After that create a file named pom.xml and put this content (modify values with your data if you want):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>it.novaware</groupId>
<artifactId>ui</artifactId>
<url>http://www.novaware.it</url>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Novaware JSF components library</name>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<modules>

</modules>
</project>

Now open a shell, go in the root directory and execute this command:

mvn archetype:create -DarchetypeGroupId=org.richfaces.cdk -DarchetypeArtifactId=maven-archetype-jsf-component -DarchetypeVersion=3.1.5-GA -DgroupId=it.novaware -DartifactId=skypecall
with skypecall as the name of your component.

In the new generated directory there is a pom.xml file. Open it and add this code after the </build> tag:

<dependencies>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupid>org.richfaces.framework</groupid>
<artifactid>richfaces-impl</artifactid>
<version>3.1.1-GA</version>
</dependency>
</dependencies>

Using the shell, enter in the new directory (cd skypecall).

Execute this command to create the new component structure:
mvn cdk:create -Dname=skypecall
Now you can try it compiling it and making the jar:
mvn install

(To clean the build you can execute: mvn clean)

Mvn install must say BUILD SUCCESSFUL.

Now we are ready to personalize the new component!

Go in the generated src/main directory of skypecall directory: you will find 4 new subfolders with generated files.

Let's start from the config: edit the skypecall/src/main/config/component/skypecall.xml file to insert the component attributes. We are going to insert 5 attributes:

  1. img: the kind of image to insert. You can use the "default" value to show the default image (see color and size attributes),
    the "none" value to show no image, or directly put the URL to show the image you like. So possible value are: default, none, url_of_image. Default is "default".

  2. color: the color of the default image. It works if "image" attribute is "default". It can be "green" or "blue". Default is "blue".

  3. size: the size of the default image. It works if "image" attribute is "default". Possible values are: small, medium, big. Default is "medium".

  4. number: skype number to call. Default is null.

  5. type: the type of skype link to create. Possible values are: call, chat, voicemail, add, userinfo, sendfile. Default is call.

So the final code of skypecall.xml is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//AJAX4JSF//CDK Generator config/EN" "https://ajax4jsf.dev.java.net/nonav/dtds/component-config.dtd" >
<components>
<component>
<name>org.richfaces.Skypecall</name>
<family>org.richfaces.Skypecall</family>
<classname>org.richfaces.component.html.HtmlSkypecall</classname>
<superclass>org.richfaces.component.UISkypecall</superclass>
<description>
<![CDATA[
A component that insert a link that permit to call a person from the web via skype.
]]>
</description>
<renderer generate="true" override="true">
<name>org.richfaces.SkypecallRenderer</name>
<template>org/richfaces/htmlSkypecall.jspx</template>
</renderer>
<tag>
<name>skypecall</name>
<classname>org.richfaces.taglib.SkypecallTag</classname>
<superclass>
org.ajax4jsf.webapp.taglib.HtmlComponentTagBase
</superclass>
</tag>
<!--
<taghandler>
<classname>org.ajax4jsf.tag.TestHandler</classname>
</taghandler>
-->
&ui_component_attributes;
&html_events;
&html_style_attributes;
<property>
<name>img</name>
<classname>java.lang.String</classname>
<description>The kind of image to insert. You can use the "default" value to show the default image (see color and size attributes),
the "none" value to show no image, or directly put the URL to show the image you like. So possible value are: default, none, url_of_image. Default is "default".
</description>
<defaultvalue>"default"</defaultvalue>
</property>
<property>
<name>color</name>
<classname>java.lang.String</classname>
<description>The color of the default image. It works if "image" attribute is "default". It can be "green" or "blue". Default is "blue".
</description>
<defaultvalue>"blue"</defaultvalue>
</property>
<property>
<name>size</name>
<classname>java.lang.String</classname>
<description>The size of the default image. It works if "image" attribute is "default". Possible values are: small, medium, big. Default is "medium".
</description>
<defaultvalue>"medium"</defaultvalue>
</property>
<property>
<name>number</name>
<classname>java.lang.String</classname>
<description>Skype number to call. Default is null.
</description>
<defaultvalue>""</defaultvalue>
</property>
<property>
<name>type</name>
<classname>java.lang.String</classname>
<description>The type of skype link to create. Possible values are: call, chat, voicemail, add, userinfo, sendfile. Default is call.
</description>
<defaultvalue>"call"</defaultvalue>
</property>
<!--
<property>
<name>param</name>
<classname>java.lang.String</classname>
<description>
</description>
<defaultvalue>"default"</defaultvalue>
</property>
-->
</component>
</components>

Now we have to modify the jspx template that will generate the renderer, edit src/main/templates/it/novaware/htmlSkypecall.jspx, it might look like that:


<?xml version="1.0" encoding="UTF-8"?>
<f:root
xmlns:f="http://ajax4jsf.org/cdk/template"
xmlns:c=" http://java.sun.com/jsf/core"
xmlns:ui=" http://ajax4jsf.org/cdk/ui"
xmlns:u=" http://ajax4jsf.org/cdk/u"
xmlns:x=" http://ajax4jsf.org/cdk/x"
class="it.novaware.renderkit.html.SkypecallRenderer"
baseclass="org.ajax4jsf.renderkit.AjaxComponentRendererBase"
component="it.novaware.component.UISkypecall"
>

<f:clientid var="clientId"/>
<!--
I can't use this because I can't use parameter inside the name attribute
<f:resource var="skypeImage2" name="/images/green-medium.png" />-->

<jsp:scriptlet>
<![CDATA[
/* See what I have to do with internal image */
String skypeImage = null;
String image=(String) component.getAttributes().get("img");

if (image.compareToIgnoreCase("default")==0) {
/* dynamically compose the default image name */
skypeImage = getResource( "images/"+(String)component.getAttributes().get("color")+"-"+(String)component.getAttributes().get("size")+".png" ).getUri(context, component);
} else if (image.compareToIgnoreCase("none")==0) {
/* skypeImage stays null */
} else {
/* put the url of the image */
skypeImage=image;
}

variables.setVariable("skypeImage",skypeImage);
]]>
</jsp:scriptlet>
<a id="#{clientId}"
name="#{clientId}"
x:passThruWithExclusions="value,name,type,id,number,size,color"
href="skype:#{component.attributes['number']}?#{component.attributes['type']}"
>
<jsp:scriptlet>
<![CDATA[
if (variables.getVariable("skypeImage")!=null) {
]]>
</jsp:scriptlet>
<img src="#{skypeImage}" border="0"/>
<jsp:scriptlet>
<![CDATA[
}
]]>
</jsp:scriptlet>
<vcp:body>
<f:call name="renderChildren" />
</vcp:body>
</a>
</f:root>

Notice that I have to point a dynamic named image (it is composed by the color and the size, look at the code) so I can't use the f:resource tag and I have to use a scriptlet.

I also called renderChilder using the f:call tag to be able to put other components inside the skypecall anchor tag.

I think that it is clear what the code do: if the img attribute of the component is none it doesn't put the img tag; if it is default or omitted it uses the color and size attribute to find a default image (that we'll copy in the resource directory in the next final step); if not it uses the passed value as URL for the src attribute of the img tag.

As I said, the final step is to copy the resources images in the appropriate directory so go to skypecall/src/main/resources and insert the it/novaware/renderkit/html/images directories: go inside and copy the default image files that you can find here.

You have finished!

After that you can come back to your shell at skypecallskypecall directory and launch mvn install.

Let's try it!

If you look inside the generatedskypecall/target directory you will find a jar library called skypecall-1.0-SNAPSHOT.jar: you have to copy it in the WEB-INF/libdirectory of your project.

To use it in an xhtml page just use the following namespace:

http://www.novaware.it/skypecall
So if you are using Facelets add:
<xmlns:nw="http://www.novaware.it/skypecall">
If you are using JSP add:
<%@ taglib uri="http://www.novaware.it/skypecall" prefix="nw"%>
to each page that uses the component.

Here some example of use:


<nw:skypecall img="default" color="blue" number="echo123" type="call" size="small" ></nw:skypecall>

<nw:skypecall size="big" color="green" number="echo123" ></nw:skypecall>

<nw:skypecall size="medium" color="green" number="echo123" ></nw:skypecall>

<nw:skypecall img="default" color="green" number="echo123" type="call" size="small" ></nw:skypecall>

<nw:skypecall img="none" number="echo123" type="call" >call me!</nw:skypecall>

That would produce the following:


Use can also download the source files from here and the compiled library from here.

Here some links you can start from:

As I said, every suggestion is welcome!!

Demetrio

Labels:

03 October 2007

Install JBoss AS 4.2.1.GA on Debian

Hi,
I just got a new server and I installed Debian Linux. I wanted to install JBoss AS 4.2.1.GA and it's really simple: just download the file, unzip, copy in /usr/local, make jboss user, and chown the jboss directory and it's subdirectories (you can find a good explanation here).

After that I wanted to use the jboss_init_redhat.sh script to automatically starts the server as service, so I just had to modify a little bit the file:
  1. I wanted to bind the server to an ip address so before the JBOSS_BIND_ADDR I added the following line (XX.XX.XX.XX is the server address):
    JBOSS_HOST=${JBOSS_HOST:-"XX.XX.XX.XX"}

  2. Coz of an error running the script I had to modify the SUBIT variable adding the --preserve-environment option, so the line now look like that:
    SUBIT="su - $JBOSS_USER --preserve-environment -c "

  3. Because of a bug of JBoss I had to modify the stop script adding the bind address and the port of JNP server, so the JBOSS_CMD_STOP now look like this:
    JBOSS_CMD_STOP=${JBOSS_CMD_STOP:-"java -classpath $JBOSSCP org.jboss.Shutdown --shutdown -s $JBOSS_HOST:1099"}

After that, to install the script as a service do that:
  1. Copy the jboss_init_redhat.sh script to /etc/init.d/ directory;
  2. Esecute the following command:
    update-rc.d jboss_init_redhat.sh defaults
The output of the last command is:

Adding system startup for /etc/init.d/jboss_init_redhat.sh ...
/etc/rc0.d/K20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh
/etc/rc1.d/K20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh
/etc/rc6.d/K20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh
/etc/rc2.d/S20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh
/etc/rc3.d/S20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh
/etc/rc4.d/S20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh
/etc/rc5.d/S20jboss_init_redhat.sh -> ../init.d/jboss_init_redhat.sh


It means that the command added the script as startup script for all the defaults runlevels.

You can find more informations about System V Init (Unix systems init) functionalities here and here.

Demetrio

Labels: