Tuesday, November 8, 2011

Self InclusiveTemplating in JSF 2.0

Page template is a nice feature in JSF 2.0. Combined with EL 2.2, it is so powerful that you can do self inclusive templating in a production environment. Here is an example:

1) client file - index.xhtml:

    <ui:composition xmlns="http://www.w3.org/1999/xhtml"
         xmlns:ui="http://java.sun.com/jsf/facelets"
         xmlns:f="http://java.sun.com/jsf/core"
         xmlns:h="http://java.sun.com/jsf/html"
        
template="/templates/template.xhtml">

      
<ui:define name="title">Page Title</ui:define> 

       <ui:define name="body">Page Body</ui:define>
   </ui:composition>



Here it is using the template.xhtml as the template, then define 2 elements "title" and "body" to pass to template.xhtml.

2) template file - template.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:h="http://java.sun.com/jsf/html"
      xmlns:ui="http://java.sun.com/jsf/facelets">
 

<h:head>
 <title><ui:insert name="title">Title</ui:insert></title>
 <ui:include src="/templates/header.xhtml"/> 

</h:head>
 

<h:body>
  <div id="col2" class="clearfix">

   <div id="col2a">
    <ui:insert name="body">Body</ui:insert>
    <ui:include src="/templates/footer.xhtml"/>
   </div>
 
   <div id="col2b">
    <div id="nav-container">
     <ul id="nav-main">
       <ui:include src="/templates/submenu.xhtml">
        <ui:param name="submenu" value="#{sessionSupport.menuService.getSubMenu(currentSectionUrl)}" />
        <ui:param name="level" value="1" />
      </ui:include>
     </ul>
    </div>
   </div>

  </div>
</h:body>
 

</html>


The two "ui:insert" are the place-holders for page title and body, which are provided from the client file (index.xhtml); "ui:include" pieces are convenient to include a few html snippets to make the code clean and neat. Among them submenu.xhtml is the most interesting one.


3) self inclusive snippet file - submenu.xhml:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
   xmlns:ui="http://java.sun.com/jsf/facelets"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:c="http://java.sun.com/jsp/jstl/core">
 

<c:set var="url" value="#{sessionSupport.breadCrumbs[level+1].url}"/>
<c:set var="requestURI" value="#{sessionSupport.requestURI}" />

<c:forEach items="#{submenu}" var="menuItem" varStatus="status">

<c:choose>
<c:when test="#{sessionSupport.menuService.isSelf(menuItem, requestURI)}">
 <li class="active"><a href="#{menuItem.url}">#{menuItem.name}</a>
   <ul>
    <ui:include src="/templates/submenu.xhtml">
    <ui:param name="submenu" value="#{sessionSupport.getSubMenu(
url
)}"/>
    <ui:param name="level" value="#{level+1}" />
    </ui:include>
   </ul>
  </li>
</c:when>
<c:otherwise>
  <li><a href="#{menuItem.url}">#{menuItem.name}</a></li>
</c:otherwise>
</c:choose>
</c:forEach>


</ui:composition>



The code loops through the menu items at the current level and then calls itself, passing the sub-menu of the next level as a parameter, and then goes on and on, until it walks through the whole tree structure.

Setting up JSF 2.0 and EL 2.2 on Glassfish v2

I am migrating our JSF 1.1 application to JSF 2. Since we are still running Glassfish 2.1.1, I can't use the latest version of JSF (2.1.3), which targets Servlet 3.0 containers like Glassfish v3. So I settled with JSF 2.0. One of the nice features of JSF 2.0 is the build-in page templating support, which is a big help to clean up those messy jsp files.

While setting up the templates, I found that we need to pass parameters to methods in the jsf/xhtml file. But this is NOT supported by default in Glassfish 2.1.1. Comes EL 2.2 for the rescue.

It is kind of easy to set up JSF 2.0 and EL 2.2 on Glassfish v2:

1) Add el-impl-2.2.jar in your project pom.xml (assuming you use maven), which will install two jar files (el-impl-2.2.jar and el-api-2.2.jar) in your WEB-INF/lib after build:

    <dependency>
      <groupId>org.glassfish.web</groupId>
      <artifactId>el-impl</artifactId>
      <version>2.2</version>
    </dependency>

2) Copy el-impl-2.2.jar and el-api-2.2.jar to %Glassfish_Home%/lib/

3) Download jsf 2.0 from http://javaserverfaces.java.net/, then copy jsf-impl.jar and jsf-api.jar to %Glassfish_Home%/lib/

4) Add "classpath prefix" in glassfish domain configuration file domain.xml (or you can use the Admin console: Application Server -> JVM Settings -> Path Settings -> Classpath Prefix):

<java-config classpath-prefix="${com.sun.aas.installRoot}/lib/jsf-api.jar${path.separator}${com.sun.aas.installRoot}/lib/el-api-2.2.jar"
...


You are all set to roll!

Saturday, August 27, 2011

Set up Apache for site maintenace

We want to set up the site maintenance page from 5am to 3pm on a certain day to do database upgrade. Then we want to test the site internally before opening to the public. This is what I would do in Apache configuration:

# rewrite condition1: 5am to 3pm
# rewrite condition2: allow only internal ip
# rewrite condition3: any database driven page (".dyn", ".jsp", or ".vm")

RewriteCond %{TIME_HOUR}%{TIME_MIN} >0500
RewriteCond %{TIME_HOUR}%{TIME_MIN} <1500
RewriteCond %{REMOTE_ADDR} !^255.255.0.0*$
RewriteCond %{REQUEST_URI} \.(dyn|jsp|vm)$
RewriteRule ^/(.+)$ http://my.site.com:80/sitedown.html [L,R]

Wednesday, August 10, 2011

Can't deploy / undeploy web applications on Glassfish

When we tried to publish a new web application to Glassfish (v2.1.1) this morning, we got the following mystic message:

CLI171 Command deploy failed : While redeploying, trying to stop the application in target server failed; Error Flushing ConfigContext com.sun.enterprise.config.ConfigContext: Url=$glassfish_home/domains/release/config/domain.xml, ReadOnly=false, ResolvePath=true, LastModified Timestamp=1312828827000, isChanged=false, Autocommit=false, isConfigBeanNull=false

It took us a while to realize that somehow domain.xml lost the write permission overnight, so Glassfish cannot add or delete the web application in domain.xml.

Glassfish team should hire someone who can write messages for a normal human being :)

How to start/stop all the cron jobs on Linux

Log in as root on the server:

All the cron jobs are defined in /var/spool/cron

To stop all cron jobs: /etc/init.d/crond stop

To start all cron jobs: /etc/init.d/crond start

Wednesday, May 25, 2011

Distinguish between different kinds of JSF beans

Name: Model Bean
Typical Scope: Session
Description: This type of managed-bean participates in the "Model" concern of the MVC design pattern. When you see the word "model" -- think DATA. A JSF model-bean should be a POJO that follows the JavaBean design pattern with getters/setters encapsulating properties. The most common use case for a model bean is to be a database entity, or to simply represent a set of rows from the result set of a database query.

Name: Backing Bean
Typical Scope: request
Description: This type of managed-bean participates in the "View" concern of the MVC design pattern. The purpose of a backing-bean is to support UI logic, and has a 1::1 relationship with a JSF view, or a JSF form in a Facelet composition. Although it typically has JavaBean-style properties with associated getters/setters, these are properties of the View -- not of the underlying application data model. JSF backing-beans may also have JSF actionListener and valueChangeListener methods.

Name: Controller Bean
Typical Scope: request
Description: This type of managed-bean participates in the "Controller" concern of the MVC design pattern. The purpose of a controller bean is to execute some kind of business logic and return a navigation outcome to the JSF navigation-handler. JSF controller-beans typically have JSF action methods (and not actionListener methods).

Name: Support Bean
Typical Scope: session / application
Description: This type of bean "supports" one or more views in the "View" concern of the MVC design pattern. The typical use case is supplying an ArrayList to JSF h:selectOneMenu drop-down lists that appear in more than one JSF view. If the data in the dropdown lists is particular to the user, then the bean would be kept in session scope. However, if the data applies to all users (such as a dropdown lists of provinces), then the bean would be kept in application scope, so that it can be cached for all users.

Name: Utility Bean
Typical Scope: application
Description: This type of bean provides some type of "utility" function to one or more JSF views. A good example of this might be a FileUpload bean that can be reused in multiple web applications.

More details can be found at http://java.dzone.com/articles/making-distinctions-between