java.net member

Rechercher dans ce site

JSF2 Reuse composite components – Packaging in a Jar file - English Article

>> 22 February 2011

L'article en français

JSF2 gives the components oriented development all its energy. One of these powerful features is using composite components.

I'll be back in future articles to developing and using composite components in JSF2

The real power of composite components in JSF is to reuse them with a minimum effort. It's always off course possible, especially in development phase to copy resources folder and reuse these components. But to achieve a write once run many, with a minimum effort for the user, you can package the composite components inside a .jar file. Like this the user has only to add this .jar into war/WEB-INF/lib folder in any project and use it normally with its name-space.

This tutor begins by what you can do manually to package correctly all what you need in a .jar file, this is explained only to let you understand how this can be done under the hood. You can do this , very easily using an ant script for instance. At the end there is a really minimal Ant script to automatically do all the manual steps.

This tutor is written using Eclipse Helios, GAEJ (Google App Engine for Java) platform and MyFaces Core 2.0.4.


Put in META.INF


Copy "resources" folder

Copy "resources" folder, from Webapp (war) folder to src/META-INF. Inside "resources", there are sup-folders for composite components, and other resources libraries, like css, images,javascript, etc. I have called my sub-folder for composite components "ka" in this example.

Copy faces-config.xml into META.INF

Create under META.INF a taglib file

Do this, only if you want to use customized name-space. This file must be called libraryName.taglib.xml (libraryName is the name of the sub-folder of resources containing the composite components).

META.INF/
            resources/
                               ka/            (library with composite components)
                               css/           stylesheets
                               images/    images   
                               js/                  Javascript
              
        faces-config.xml

         ka.taglib.xml   


The bean class(es) associated with the composite components (if any), will be put in .jar's root with it's package.

ka.taglib.xml

<facelet-taglib 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-facelettaglibrary_2_0.xsd"
version="2.0">

<namespace>http://www.java_javafx.com/ka</namespace>
<composite-library-name>ka</composite-library-name>
</facelet-taglib>


faces-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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_2_0.xsd"
 version="2.0">

<application>


<resource-bundle>
<base-name>com.java_javafx.ka.composite.localizedMessages</base-name>
<var>msgsc</var>
</resource-bundle>
<!-- set locales -->
<locale-config>
<default-locale>en</default-locale>
<supported-locale>fr</supported-locale>
<supported-locale>de</supported-locale>
<supported-locale>ar</supported-locale>

</locale-config>
<!-- end locals -->
</application>




 </faces-config>


logo.xhtml

Note:
"home" is the name of the ManagedBean. This is an example of a composite component. This example displays an image with a url. Primefaces, the excellent library is used here to display a dialog before leaving the site.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui"

>
<composite:interface>

<composite:attribute name="image" required="true" />
<composite:attribute name="url" required="true" />
<composite:attribute name="styleClass" default="icon"/>
<composite:attribute name="isDialog" default="false"/>


</composite:interface>

<composite:implementation>

<h:outputStylesheet library="css" name="jsf.css" target="head"/>
<h:outputStylesheet library="css" name="primeFacesThemes/ui-lightness/skin.css" target="head"/>

<h:inputHidden binding="#{home.hiddenComponent}">
<f:attribute name="url" value="#{cc.attrs.url}"/>
</h:inputHidden>

<h:panelGrid rendered="#{cc.attrs.isDialog}" style="border:0">
<h:commandLink onclick="cd.show()">
<h:graphicImage url="#{cc.attrs.image}" styleClass="#{cc.attrs.styleClass}" border="0"/>
</h:commandLink>
<!-- confirm dialog -->
<p:confirmDialog message="#{msgsc.quit_message} ?"
    header="#{msgsc.quit_header}" severity="alert" widgetVar="cd" modal="true">
    <h:panelGrid columns="2" style="border:0" >
   
    <h:commandButton value="#{msgsc.quit_yes}" action="#{home.go}" oncomplete="cd.hide()" ajax="false"/>
   
    <h:commandButton value="#{msgsc.quit_no}" onclick="cd.hide();"/>
   
    </h:panelGrid>
   
</p:confirmDialog>
</h:panelGrid>

<h:panelGrid rendered="#{!cc.attrs.isDialog}" style="border:0">
<h:commandButton action="#{home.go}" image="#{cc.attrs.image}" styleClass="#{cc.attrs.styleClass}"/>

</h:panelGrid>

</composite:implementation>
</html>

Export .jar file

Right click on the project in the PackageExplorer -> Export




Select Java -> Jar file



 


Go to war -> WEB-INF -> classes -> select "com" and "META.INF" folders.
Uncheck ".classpath" and ".project". Enter a name and a path for the "JAR file"
Select to export only the class files or to export classes and source files
Click on "Finish"


Recomposing the jar

In the final .jar, the exported folders are all gathered under war/ folder, along side a newely created META-INF folder. This is not what we need. We need our META-INF directory at the root of the .jar. In the root folder we need also ours classes inside their packages. Here is what we shall do for a correct .jar structure.


Unzip the .jar file

In the produced folder

Merge war/WEB-INF/classes/META.INF with the root's META-INF folder, and move
war/WEB-INF/classes/com to the root folder




Here is the root folder



In a terminal type followed by Enter:

jar -cvf fileName.jar *




Installing the .jar as a library

Copy the produced .jar file to any another project in
war -> WEB-INF -> lib

Add the added jar into project's Java Build Path

Ant Build File

Please note that this example is only a quick and dirty one. I'm sure that you can add some powerful instructions and adapt it to suite your need.


<?xml version="1.0" encoding="UTF-8"?>
<project name="createJar" basedir="." default="makejar">
   
    <property name="war" value="${basedir}/war" />
    <property name="classes" value="${basedir}/war/WEB-INF/classes" />

      <!--change the destination .jar file -->
    <property name="jarFile" value="/home/kas/hello777.jar" />
   
     <!--choose a destination tmp folder to copy the components -->
     <property name="tmpDir" value="/home/kas/tmp-6_fev_2010_n777" />   
     <property name="webInf" value="${basedir}/war/WEB-INF" />
   
    <target name="makejar">
       
        <mkdir dir="${tmpDir}"/>

    <!--These instructions are used to write .taglib.xml file on the fly
          This file is optional and needed only if you want to use your own name-space when using composite components -->

        <echo file="${tmpDir}/ka.taglib.xml" ><![CDATA[<facelet-taglib 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-facelettaglibrary_2_0.xsd"
            version="2.0">

            <namespace>http://www.java_javafx.com/ka</namespace>
            <composite-library-name>ka</composite-library-name>
            </facelet-taglib>
           
            ]]></echo>
        <copy todir="${tmpDir}" >
            <fileset dir="${war}">
            <include name="resources/" />
            </fileset>
        </copy>
      <!--you can copy into resources folder any other folders you need -->
        <copy todir="${tmpDir}/resources" >
                            <fileset dir="${war}">
                            <include name="css/" />
                            <include name="images/"/>
                            <include name="primeFacesThemes/" />
                            </fileset>
                        </copy>
               
        <jar destfile="${jarFile}"  basedir="${classes}" includes="com/">
                                    
                        <metainf dir="${tmpDir}" >
                            <include name="resources/" />
                            <include name="ka.taglib.xml"/>
                            </metainf>
                        <metainf dir="${webInf}">
                            <include name="faces-config.xml"/>
                        </metainf>
                  </jar>
           
        <delete dir="${tmpDir}" />
    </target>

   

</project>

0 comments:

Post a Comment

  © Blogger template Simple n' Sweet by Ourblogtemplates.com 2009

Back to TOP