Sunday, March 20, 2011

Install Java 1.6 and Tomcat 6 under Ubuntu

I have installed Java und Tomcat on my VPS http://www.fractalsoft.net many times but never noted necessary steps. Here some helpful infos.

1) Issue following command to find out current jdk version in apt-get
apt-cache search jdk

2) Install java JRE with apt-get install
sudo apt-get install openjdk-6-jre

3) Set environment variable JAVA_HOME. Copy following statement and append to /etc/profile or .bashrc
export JAVA_HOME="/usr/lib/jvm/java-6-openjdk;"

4) Install Tomcat 6
sudo apt-get install tomcat6 tomcat6-admin tomcat6-common tomcat6-user tomcat6-docs tomcat6-examples

5) Change tomcat server to run on port 80 in
/var/lib/tomcat6/conf/server.xml (symbolic link) or etc/tomcat6/server.xml

7) Start tomcat server sudo /etc/init.d/tomcat6 start
Stop tomcat server sudo /etc/init.d/tomcat6 stop
Restart tomcat server sudo /etc/init.d/tomcat6 restart
Get tomcat server status sudo /etc/init.d/tomcat6 status

8) To enable admin web based features add the following lines to
/etc/tomcat6/tomcat-user.xml

<role rolename="manager"/>
<role rolename="admin"/>
<user name="admin" password="admin" roles="manager,admin"/>

Manager app http://www.fractalsoft.net/manager/html has now user / pwd = “admin”.

9) Adjust default Tomcat page below /var/lib/tomcat6/webapps/ROOT/index.html if nessesary.

Edit: If you get this exception
SEVERE: Exception sending context initialized event to listener instance of class com.sun.faces.config.ConfigureListener
java.lang.ExceptionInInitializerError
...
Caused by: java.security.AccessControlException: access denied (java.util.PropertyPermission com.sun.aas.installRoot read) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:342)
...
and the deployte web application doesn't start, set TOMCAT6_SECURITY=no (instead of yes) in the file /etc/init.d/tomcat6. Restart your Tomcat after that (login via ssh username@hostname and call sudo /etc/init.d/tomcat6 restart). Thanks to this post from ICEFaces forum!

Tuesday, March 8, 2011

How to validate multiple required fields all at once

Foreword:
The most desired feature in JSF is a multi-component validation. At the moment there is a lack of support for this feature because there is no standard way to attach one validator to multiple fields. There are proposed enhancements to JSF 2.1 which should cover this lack. These are "generic subtree validation" and "multi-component validation using bean validation". The aim of this article is to give an idea for multi-component validation. The main point is the validation of required fields in a real project.

Starting position:
Many required fields with required="true" attribute. They produce default messages from JSF implementation like: j_id_id19: Validation Error: Value is required. An end-user gets kinda confused.

Task definition:
Improve the required validation message with less costs and without any touch of existing code if possible. We would like to have messages with exact labels belong to fields, like "The required field 'User Name' is not filled in". The message severity should be WARNING and not ERROR as produced with the JSF standard validator. The solution should be reliable, maintainable and have a good performance.

We will go step by step, evaluate available solutions and figure out the best one.

1) The first Ad-hoc solution coming in mind is one with a custom validator for required fields I described in the previous post. Sure, it's not an ideal solution because we need to define the label text twice and to attach the validator to each field to be validated. It's not good maintainable as well, but there are cases (discussed below) where we need it.

2) BalusC wrote a useful post "Validator for multiple fields". His solution illustrates an idea how to attach a validator to the last component of the group (components are validated in the same order as defined) and gather Ids of the all component(s) to be validated. Nice, but hard-coded, not configurable and still needs many adjustments in the existing code.

3) Cagatay Civici presented in his blog a nice approach based on SystemEventListener and PreValidateEvent for HtmlOutputLabel components. Really interesting idea. But the first question coming in mind - why do we need to scan all labels and do the same work as it's already done by labels self? I mean, LabelRenderer looks for the corresponding editable component in order to find out a proper client Id in the RENDER_RESPONSE phase. It seems, we are doing the same job twice. I'm developing document management systems and we sometimes have about 100 labels on a form. Document's or folder's properties have them in DMS. If we have 100 labels and only 1-2 required fields, we don't need to treat all 100 labels from the view point of performance. We need to treat 1-2 required fields and only when validation has failed (in best case is nothing to do at all). In my opinion, we should look for invalid fields at first and then for corresponding labels. Not inverted as in the proposed approach. Furthermore, there are some limitations. This solution doesn't consider the cross-implementations algorithm for component referencing. Simple findComponent is not enough. Mojarra walks up the ancestor chain and call findComponent() for each component in the ancestor chain. If the root is reached, it walks down the successor chain. Obviously (if I got the picture), the value in "for" attribute and the Id of the corresponding editable component may not match in Mojarra. Result: If a label and its corresponding editable field are located in different forms for example, we are not always able to find the editable field starting from the label component. The last point is the fact that we can't use h:outputLabel in certain circumstances and depend on h:outputText. h:outputText should be considered too. Message severity is not customizable, so that we need a custom validator.

4) Another great idea which gave me the right direction comes from the Mkyong blog. The idea is to group components, e.g. with a h:panelGrid component, and attach the event tag f:event with PostValidateEvent to the group. f:event expects "listener" and "type" attributes which have to be registered declarative. We are worried with this approach about the listener method for PostValidateEvent, where we place it and how we write it, etc. It would be nice to hide this information and accomplish all work programmatically. The autor could probably achieve an optimization by extension of h:panelGrid like
<h:panelGrid columns="..." validateRequired="true">
The component HtmlPanelGrid would have processEvent method.
@ListenerFor(systemEventClass = PostValidateEvent.class)
public class HtmlPanelGrid extends javax.faces.component.html.HtmlPanelGrid
{
    protected enum PropertyKeys {
        validateRequired;
        ...
    }

    ...

    public void processEvent(ComponentSystemEvent event)
                       throws AbortProcessingException {
        if (isValidateRequired()) {
            ....
        }
    }
}
I would like to avoid extensions of any components, but general I like the idea of component subtree validation by means of PostValidateEvent. My idea is based on this system event and a custom TagHandler. I want to write a tag handler with a zero configuration and apply it to the body tag
<h:body>
   <custom:requiredFieldsValidator/>
   ...
</h:body>
or some other component acts as parent for required fields and their labels. Good candidates would be h:panelGroup, h:panelGrid or h:dataTable. Note: For Ajax requests <custom:requiredFieldsValidator/> should be placed within area being processed. For cases where we can't use h:outputLabel we would like to use h:outputText with <f:attribite name="for" value="..."/>. The custom validator for single editable fields (Ad-hoc solution mentioned above) should be applicable too because sometimes there is one label for two and more fields and other rare scenarios. It should also have the higher precedence than a multi-component validator. An example covering all cases:
<h:panelGrid columns="2">
  <custom:requiredFieldsValidator/>

  <h:outputLabel for="username" value="User name"/>
  <h:inputText id="username" value="#{bean.username}" required="true"/>
  <h:outputLabel for="password" value="Password"/>
  <h:inputText id="password" value="#{bean.password}" required="true"/>

  <h:outputText value="Confirm Password">
    <f:attribite name="for" value="confirmPassword"/>
  </h:outputText> 
  <h:inputText id="confirmPassword" 
               value="#{bean.confirmPassword}" required="true"/>

  <h:outputText value="Start date - End date">
  <h:panelGroup>
    <h:inputText value="#{bean.startDate}" required="true">
      <custom:requiredFieldValidator label="Start date"/>
    </h:inputText>
    <h:inputText value="#{bean.endDate}" required="true">
      <custom:requiredFieldValidator label="End date"/>
    </h:inputText>
  </h:panelGroup>
</h:panelGrid>
The tag handler is straightforward. It calls subscribeToEvent for PostValidateEvent and its listener ValidateRequiredFieldsEventListener (explained below).
import javax.faces.component.UIComponent;
import javax.faces.event.PostValidateEvent;
import javax.faces.event.SystemEvent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;
import java.io.IOException;

public class ValidateRequiredFieldsHandler extends TagHandler
{
    public ValidateRequiredFieldsHandler(TagConfig config) {
        super(config);
    }

    public void apply(FaceletContext fc, UIComponent parent) throws IOException {
        if (isNew(parent)) {
            Class<? extends SystemEvent> eventClass = PostValidateEvent.class;
            parent.subscribeToEvent(eventClass, new ValidateRequiredFieldsEventListener());
        }
    }

    protected static boolean isNew(UIComponent component) {
        UIComponent c = component;
        if (c != null) {
            UIComponent parent = c.getParent();
            if (parent != null) {
                if (UIComponent.isCompositeComponent(parent)) {
                    c = parent;
                }
            }
            return c.getParent() == null;
        } else {
            return false;
        }
    }
}
ValidateRequiredFieldsHandler is registered in a tag library
<tag>
    <description>Handler for validation of required fields</description>
    <tag-name>requiredFieldsValidator</tag-name>
    <handler-class>
        xyz.webapp.jsf.validator.ValidateRequiredFieldsHandler
    </handler-class>
</tag>
The message key for any empty required field is defined in the JSF 2 specification, chapter 2.5.2.4 "Localized Application Messages". We are going to redefine the message of this key in the own message bundle (registered in faces-config.xml) as follows
 
javax.faces.component.UIInput.REQUIRED=xyz.faces.component.UIInput.REQUIRED
 
The event listener ValidateRequiredFieldsEventListener iterates through all messages and looks for required fields which were empty. For each such field the corresponding label will be found and the message will be regenerated. The label will be present in the message which is more user friendly now.
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ComponentSystemEvent;
import javax.faces.event.ComponentSystemEventListener;
import java.io.Serializable;
import java.util.Iterator;
import java.util.ResourceBundle;

public class ValidateRequiredFieldsEventListener implements ComponentSystemEventListener, Serializable
{
    private static final long serialVersionUID = 20110227L;

    private static final String MESSAGE_SUMMARY_PLACEHOLDER =
            "xyz.faces.component.UIInput.REQUIRED";

    public void processEvent(ComponentSystemEvent event) throws AbortProcessingException {
        FacesContext fc = FacesContext.getCurrentInstance();
        UIComponent parent = event.getComponent();
        if (parent == null) {
            return;
        }

        Iterator<String> iterClientIds = fc.getClientIdsWithMessages();
        while (iterClientIds.hasNext()) {
            String clientId = iterClientIds.next();

            Iterator<FacesMessage> iterFacesMessages = fc.getMessages(clientId);
            while (iterFacesMessages.hasNext()) {
                FacesMessage facesMessage = iterFacesMessages.next();

                if (MESSAGE_SUMMARY_PLACEHOLDER.equals(facesMessage.getSummary())) {
                    iterFacesMessages.remove();

                    // find label
                    ValidateRequiredFieldsCallback vrfCallback = 
                       new ValidateRequiredFieldsCallback(parent);
                    parent.invokeOnComponent(fc, clientId, vrfCallback);

                    String message;
                    ResourceBundle resourceBundle = MessageUtils.getMessageBundle(fc);

                    // create new user friendly message
                    if (vrfCallback.getLabel() == null) {
                        message = MessageUtils.getMessageText(
                           resourceBundle, "validator.emptyMandatoryField.1");
                    } else {
                        message = MessageUtils.getMessageText(
                           resourceBundle, "validator.emptyMandatoryField.2",
                              vrfCallback.getLabel());
                    }

                    fc.addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_WARN,
                                  "", message));
                    break;
                }
            }
        }
    }
}
ValidateRequiredFieldsCallback is responsible for mentioned above cross-implementations algorithm for component referencing. I use visitTree method for component traversing. VisitLabelCallback encapsulates a check whether the corresponding label is encountered during the component traversing.
import javax.faces.component.ContextCallback;
import javax.faces.component.UIComponent;
import javax.faces.component.visit.VisitContext;
import javax.faces.context.FacesContext;

public class ValidateRequiredFieldsCallback implements ContextCallback
{
    private UIComponent parent;
    private String label;

    public ValidateRequiredFieldsCallback(UIComponent parent) {
        this.parent = parent;
    }

    public void invokeContextCallback(FacesContext fc, UIComponent component) {
        UIComponent currentParent = parent;
        VisitLabelCallback visitLabelCallback = new VisitLabelCallback(fc, component.getId());

        while (currentParent != null) {
            currentParent.visitTree(VisitContext.createVisitContext(fc), visitLabelCallback);

            if (visitLabelCallback.getLabel() != null) {
                label = visitLabelCallback.getLabel();
                return;
            }

            currentParent = currentParent.getParent();
        }

        fc.getViewRoot().visitTree(VisitContext.createVisitContext(fc), visitLabelCallback);
        label = visitLabelCallback.getLabel();
    }

    public String getLabel() {
        return label;
    }
}
Note: Start point from invalid fields brings us a nice bonus. We could highlight invalid fields. e. g. with red borders. After a new message has been added (s. ValidateRequiredFieldsEventListener), we could update the styleClass attribute
String originalStyleClass = component.getAttributes().get("styleClass");
component.getAttributes().put("styleClass", 
                          originalStyleClass + " invalidField");
CSS according to this
div.invalidField,
select.invalidField,
input.invalidField,
.invalidField input {
    border: solid 1px red;
    line-height: 1.4em;
    height: 1.4em;
}
What does VisitLabelCallback do exactly? It checks HtmlOutputLabel, UIOutput (like h:outputText) and a custom composite component (not considered here custom:requiredLabel). It uses a regular expression for values in „for“ attribute, so that valid definitions like
<h:outputLabel for=":mainForm:myTable:userName" .../>
<h:outputLabel for="mainForm:userName" .../>
<h:outputLabel for=":userName" .../>
are considered.
import javax.faces.component.UIComponent;
import javax.faces.component.UINamingContainer;
import javax.faces.component.UIOutput;
import javax.faces.component.html.HtmlOutputLabel;
import javax.faces.component.visit.VisitCallback;
import javax.faces.component.visit.VisitContext;
import javax.faces.component.visit.VisitResult;
import javax.faces.context.FacesContext;

public class VisitLabelCallback implements VisitCallback
{
    private String regExprForAttr;
    private String label;

    public VisitLabelCallback(FacesContext context, String idOfInvalidComp) {
        regExprForAttr = "(" + idOfInvalidComp + ")|.*[" + UINamingContainer.getSeparatorChar(context) + "]{1}(" + idOfInvalidComp + ")$";
    }

    public VisitResult visit(VisitContext context, UIComponent target) {
        if (target instanceof HtmlOutputLabel && ((HtmlOutputLabel) target).getFor() != null) {
            String forAttr = ((HtmlOutputLabel) target).getFor();
            if (forAttr.matches(regExprForAttr)) {
                label = (String) ((HtmlOutputLabel) target).getValue();

                return VisitResult.COMPLETE;
            }
        } else if (target instanceof UIOutput && target.getAttributes().get("for") != null) {
            String forAttr = (String) target.getAttributes().get("for");
            if (forAttr.matches(regExprForAttr)) {
                label = (String) ((UIOutput) target).getValue();

                return VisitResult.COMPLETE;
            }
        } else if (target != null && UIComponent.isCompositeComponent(target) && target.getAttributes().get("for") != null) {
            // TODO: do more reliable check for requiredLabel.xhtml, e.g. check resource name
            String forAttr = (String) target.getAttributes().get("for");
            if (forAttr.matches(regExprForAttr)) {
                label = (String) target.getAttributes().get("value");

                return VisitResult.COMPLETE;
            }
        }

        return VisitResult.ACCEPT;
    }

    public String getLabel() {
        return label;
    }
}
Other validators are possible too by this way. The validator from BaluC's example can be rewritten by means of PostValidateEvent, any "single" Date / Time / Number validators can be done multi-component capable, etc.

The end of a long story. Your feedback is welcome.

Tuesday, March 1, 2011

JSF form for container-based authentication

If you have a HTML form with j_security_check
 
<form method="post" action="j_security_check">
 
and want to rewrite it as JSF h:form, it's easy to do. You can write
 
<h:form id="login" onsubmit="document.login.action = j_security_check;">
 
or better (if you aren't sure about client Id of the form)
 
<h:form id="login" onsubmit="document.#{p:component('login')}.action='j_security_check';">
 
p:component is an EL function from the PrimeFaces library calculating client Id of any component. RichFaces has a similar function rich:component.