Friday, December 26, 2014

ExecutorService Conundrum

I was asked by someone to solve a problem with threads that they were having. They wanted to cancel a Future that was sent to an ExecutorService. I told them to look at a previous posts I had done on the subject. However, they insisted that this was different. So I took a look at the code. Alas, it was slightly different, but like most folks including me, they were too close to the problem to see the answer. I looked at it, and at first glance I thought something was askew, but it was not.

The code for this project can be downloaded here: runnable-example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
--- exec-maven-plugin:1.2.1:exec (default-cli) @ runnable-example ---
Future cancelled? false
Future done? false
Future cancelled? true
Future done? true
Interrupted
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Sleeping...
Interrupted
Breaking out of run loop.
As you can see from the results of the run, the future is canceled, but still keeps running. Then it gets interrupted, and breaks. So the question is why is it still running after being canceled.

Here is the Runnable and the main class to execute it:

MyRunnable.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.bluelotussoftware.examples.threads;
 
/**
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
public class MyRunnable implements Runnable {
 
    private int counter = 0;
 
    @Override
    public void run() {
 
        boolean running = true;
 
        while (running) {
            try {
                Thread.sleep(1000);
                System.out.println("Sleeping...");
 
            } catch (InterruptedException e) {
                counter++;
                System.out.println("Interrupted");
                if (counter > 1) {
                    System.out.println("Breaking out of run loop.");
                    running = false;
                }
            }
        }
    }
}

Main.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.bluelotussoftware.examples.threads;
 
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
 
/**
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
public class Main {
 
    public static void main(String[] args) throws InterruptedException {
        // Example #1 Old School
//        Thread t = new Thread(new MyRunnable());
//        t.start();
//        Thread.sleep(5000);
//        t.interrupt();
//        Thread.sleep(2000);
//        t.interrupt();
 
        // Example #2
        ExecutorService es = Executors.newSingleThreadExecutor();
        MyRunnable r = new MyRunnable();
        Future<?> future = es.submit(r);
 
        // Sleep the current thread
 
        // Check the future
        System.out.println("Future cancelled? " + future.isCancelled());
        System.out.println("Future done? " + future.isDone());
 
        future.cancel(true);
 
        // Check to make sure it really is canceled.
        System.out.println("Future cancelled? " + future.isCancelled());
        System.out.println("Future done? " + future.isDone());
 
        // Execute an orderly shutdown of our service.
        es.shutdown();
 
        // Wait patiently for 10 seconds for the Threads to cleanup
        if (!es.awaitTermination(10, TimeUnit.SECONDS)) {
            // Kill the service regardless of Thread state.
            es.shutdownNow();
        }
    }
 
}
So the do you have an answer? The answer is at the bottom of the blog. Don't peek... think!

Reference

Answer

Simply because you have canceled it, and even interrupted it; it is still a running thread. It is not scheduled, so you are not canceling it before execution.

Sunday, December 21, 2014

JSF 2.x Dynamic Encoding

Encoding Examples
In an Internationalized world, we need to be able to change the encoding of a JSF page dynamically. In this case, we have some characters encoded in UTF-8, but we want to be able to change the encoding on the page, and have the framework handle the character conversions for our web page.

So how do we do it?

One of the simplest ways is to wrap our page in a <f:view /> tag. The tag wraps the <head/> and <body/> elements in our HTML page. In the example above this is accomplished as shown below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
    <f:view encoding="#{encodingBean.encoding}">
        <h:head>
            <title>모든 좋은 사람들이 자신의 나라의 원조에 오기를이 시간입니다</title>
        </h:head>
        <h:body>
            <h1>
Encoding Examples</h1>
<p>
                JSF handles encoding very well. If you don't believe it, change the encoding in the dropdown menu,
                and then check the page source of the rendered page.
            </p>
<p>
                This example uses UTF-8 encoded text, and then allows the user to switch the encoding type.
                Note that JSF handles most cases, but some cases are not covered. Here is the original quote:
            </p>
<blockquote>
                <h:outputText value="#{encodingBean.weller}"/>
            </blockquote>
<h2>
Translated Quotes</h2>
<h:outputText value="Tämä on aikaa kaikille hyvää miestä tulla auttamaan maansa"/> (Finnish)
             
 
 
            Tämä on aikaa kaikille hyvää miestä tulla auttamaan maansa (Finnish)
             
 
             
 
            這是時間對所有的好男人來到他們的國家的援助 (Chinese - Simplified)
             
 
 
            모든 좋은 사람들이 자신의 나라의 원조에 오기를이 시간입니다 (Korean)
             
 
            <h:form id="form1">
                <h:selectOneMenu value="#{encodingBean.encoding}"  onchange="document.forms['form1'].submit();">
                    <f:selectItems value="#{encodingBean.items}"/>
                </h:selectOneMenu>
            </h:form>
        </h:body>
    </f:view>
</html>
The code for the backing bean is shown below:

EncodingBean.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.bluelotussoftware.encoding;
 
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.SortedMap;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.model.SelectItem;
 
/**
 *
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
@ManagedBean
@ViewScoped
public class EncodingBean implements Serializable {
 
    private static final long serialVersionUID = -2585222706903579334L;
 
    private String encoding = "UTF-8";
    private final String weller = "Now is the time for all good men to come to the aid of their country";
 
    public EncodingBean() {
    }
 
    public String getEncoding() {
        return encoding;
    }
 
    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }
 
    public List<selectitem> getItems() {
        List<selectitem> items = new ArrayList<>();
        SortedMap<String, Charset> charsets = Charset.availableCharsets();
        Set<string> keys = charsets.keySet();
        for (String key : keys) {
            items.add(new SelectItem(key));
        }
 
        return items;
    }
 
    public String getWeller() {
        return weller;
    }
 
}
The Netbeans Maven project can be found here: JSF Dynamic Encoding

Thursday, October 09, 2014

How do I check if a Class is an instanceof another Class without initializing it?

Illustration: Cathy Wilcox
We had a recent security audit and a question was posed about how to check a Class without doing an instanceof. This turned out to be a great learning experience. There were a couple of issues that needed to be resolved, first we were loading a Class by passing in its name using something similar to the line below:
1
Class<?> clazz = Class.forName("com.bluelotussoftware.example.assignable.SoilentGreen");
This will load the Class, but from here how do we check that it is an instanceof without instantiating it?
This can be solved by using isAssignableFrom(Class clazz) as shown below. In this case we are checking if SolientGreen is Green. Some of you will find the moral paradox of being "Green" with Soilent Green.
1
2
3
public static boolean isGreen(Class clazz) {
        return Green.class.isAssignableFrom(clazz);
    }

The second issue is a more potential security problem. How do we load the Class without initializing it. If the Class has a static initializer, the code is executed when the class is loaded. Alas, this is handled by using a variation of Class.forName(String name, boolean initialize, ClassLoader loader) which takes a boolean to determine if the class should be initialized, and a ClassLoader if you want to specify a specific loader.

Finally, we can check the Class like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) throws ClassNotFoundException,
        InstantiationException, IllegalAccessException {
 
    Class<?> clazz = Class.forName("com.bluelotussoftware.example.assignable.StaticInitializerImpl",
                                   false, ClassLoader.getSystemClassLoader());
    boolean check = isGreen(clazz);
    System.out.println("Passed? " + check);
    System.out.println("You shouldn't see: \"The static initializer was called.\"");
}
 
public static boolean isGreen(Class clazz) {
    return Green.class.isAssignableFrom(clazz);
}
When this is run, you will not see the message. Very nice indeed!

So here is the remaining code for education and entertainment:
1
2
3
4
5
6
7
package com.bluelotussoftware.example.assignable;
 
public interface Green {
 
    String getFoodType();
 
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.bluelotussoftware.example.assignable;
 
public class SoilentGreen implements Green {
 
    @Override
    public String getFoodType() {
        return "people";
    }
 
    public boolean isPeople() {
        return true;
    }
 
}
1
2
3
4
5
6
7
8
9
package com.bluelotussoftware.example.assignable;
 
public class StaticInitializerImpl {
 
    static {
        System.out.println("The static initializer was called.");
    }
 
}
The code for the project can be downloaded from Bitbucket here: assignable

Friday, October 03, 2014

Cassandra Ruby Gem Issues on Mac OS X 10.9.5

I was trying to resolve some issues with building the cassandra gem on Mac OS X 10.9.5. The solution was a multipart solution. You first need to build thrift first which has a known issue, and then build cassandra. This technical tip is very simple. I didn't want to lose it, and I am sure that there are other people out there who will need it.
Note: Please make sure you have updated all the gems in your repository before executing these commands.
1
2
sudo gem install thrift -- --with-cppflags='-D_FORTIFY_SOURCE=0'
sudo gem install cassandra -- --with-cppflags='-D_FORTIFY_SOURCE=0'
This will build both required gems.

Tuesday, August 19, 2014

JSF 2.1 Tip of the Day: Clearing the @ViewScope

Introduction

I was trying to solve an issue in our code where the @ViewScope beans were not being garbage collected. I spoke a number of times with Manfred Riem at Oracle about the weirdness of this issue. The issue simply put was that we were facing a memory leak where the instances of @ViewScope objects were not being removed from the view map. As a result, the pages were being kept in memory. The view map is limited to 32 views which helped to hide the issue. In most cases, it would not appear to normal users of our application. The issue was suddenly evident when the view contained tens of thousands of objects. 32 x 10k is REALLY BIG! It really never made it to 32, the system would stall and crash at about 6 instances.

The Culprit

We had implemented our own custom NavigationHandler. This was working quite well on JSF 2.0.x, but a couple of things happened. The JSF implementation was changed to handle another view scope issue, and our implementation of the NavigationHandler was changed from my original code. The new handler did not handle cleaning up the @ViewScope object view map which is stored in the session. Oh, yeah, the view map in the session was the change to the API too.

The Solution

The solution turned out to be something simple, re-implement the same mechanism in the default NavigationHandler to clear the @ViewScope objects from the view map in the session.

Interesting Observations

I was trying to come up with a mechanism to clear the view map data from the session, and came up with a SystemEventListener to test out some ideas. I thought I would share the code for people to see how the map is cleared. This is an approach to the issue, but as I noted, it was actually something missed in our NavigationHandler. I thought I should post the code for anyone who was looking for ideas on how to manipulate the map, or clear data in it. So without further hesitation. Here is the code.

ViewMapSystemEventListener.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.bluelotussoftware.jsf.listener;
 
import com.sun.faces.application.view.ViewScopeManager;
import java.util.Map;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
 
/**
 *
 * @author John Yeary
 * @version 1.0
 */
public class ViewMapSystemEventListener implements SystemEventListener {
 
    private String currentId;
 
    @Override
    public void processEvent(SystemEvent event) throws AbortProcessingException {
        /*
         * 1. Get the source of the event and its view id.
         * 2. Check if the currentId is null, if so, set it to the source id.
         * 3. Check the currentId and the new id.
         *     a. If they are the same, continue. We are on the same page.
         *     b. If they are different, clear the view map, and remove from Session map.
         */
        UIViewRoot uivr = (UIViewRoot) event.getSource();
        String id = uivr.getViewId();
        FacesContext fctx = FacesContext.getCurrentInstance();
        ViewScopeManager vsm = ViewScopeManager.getInstance(fctx);
 
        if (currentId == null) {
            currentId = id;
        }
 
        if (!currentId.equals(id)) {
            //Clear map and set currentId to new id.
            vsm.clear(fctx);
            String key = (String) uivr.getTransientStateHelper().getTransient(ViewScopeManager.VIEW_MAP_ID);
            uivr.getViewMap().clear();
            Map<String, Object> viewMaps = (Map<String, Object>) fctx.getExternalContext().getSessionMap().get(ViewScopeManager.ACTIVE_VIEW_MAPS);
            viewMaps.remove(key);
            currentId = id;
        }
 
    }
 
    @Override
    public boolean isListenerForSource(Object source) {
        return (source instanceof UIViewRoot);
    }
 
}
To implement the listener, you need to add an entry to the faces-config.xml file as shown below.

faces-config.xml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.1"
              xmlns="http://java.sun.com/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <application>
         
        <system-event-listener>
            <source-class>javax.faces.component.UIViewRoot</source-class>
            <system-event-listener-class>com.bluelotussoftware.jsf.listener.ViewMapSystemEventListener</system-event-listener-class>
            <system-event-class>javax.faces.event.PostConstructViewMapEvent</system-event-class>
        </system-event-listener>
         
    </application>
     
</faces-config>

Saturday, July 26, 2014

JSF 1.2: Project Woodstock Application using JPA

Woodstock Dataprovider Entity Example
Here is another example of using Project Woodstock along with JPA in an Enterprise Application. The project requires the sample database included in NetBeans.

The project was updated using NetBeans 6.5.1.


The code for the project can be found on Bitbucket here: WoodstockJPAApplication

Friday, July 25, 2014

JSF 1.2: Project Woodstock Multiple Selection Table Example

Multiple Selection Table

This is another example of a Project Woodstock project that was converted from Project Rave and Sun Studio Creator 2. This example details a multiple selection table, and was originally created by Winston Prakash.

I have updated the project using NetBeans 6.5.1 and tested on GlassFish 2.1.1.

The updated project can be found on BitBucket here: MultipleSelectionTable

Thursday, July 24, 2014

JSF 1.2: Project Rave Single Selection Table

Single Selection Table
Here is another example Project Rave/Woodstock project originally written by Winston Prakash for Sun Studio Creator 2. It has been updated using NetBeans 6.5.1 and tested on Glassfish 2.1.1.

The project can be found on BitBucket here: SingleSelectionTable

JSF 1.2: Woodstock Collapsible Group Table Example

Collapsible Group Table Example
Here is another example of a Project Rave data table converted to Project Woodstock. Project Woodstock was a great idea and the implementation with Visual JSF was the right path to go with JSF development. It is a shame that the project was canceled by Sun. I met a lot of great people who worked on the projects, and are still friends today. The code for this project was originally developed by Winston Prakash at Sun.

The code was developed using NetBeans 6.5.1 and can be downloaded from BitBucket here: CollapsibleGroupTable


Monday, July 14, 2014

JSF 1.2: Project Woodstock Button Facet Table

I was going through some old code examples. I found one created with Sun Studio Creator. Yes, it was very old.

The original example was developed by Winston Prakash.

I did some updates to Project Woodstock from the original Project Rave, and came up with a pretty new example page.

The project can be downloaded here: ButtonHeaderTable

Note: You will need to use NetBeans 6.5.1, or 6.7.1 to run it.

Sunday, July 13, 2014

JSF 1.2: Visual Web Pack (Project Woodstock) Java Persistence API Example

Master-Detail Example
This is some example code that I have for a Visual Web Pack (VWP) project that demonstrates some complex data table examples.

I often fantasize about being able to get the band back together and make Woodstock 2.0. Here is an example of why. This was complex for JSF 1.2.

The code can be downloaded from: vwpjpaexamples

I would strongly recommend using NetBeans 6.5.1 to build and run the example project.

Thursday, July 10, 2014

A simple practical "pragmatic" Formatter for java.util.logging.Logger

I have quite a trove of code examples I have collected over the years. Here is another example of a Formatter used with the java.util.logging.Logger to generate a standard output.

PragmaticFormatter.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package com.bluelotussoftware.logging;
 
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
 
/**
 * <p>
 * A formatter that generates a standard message as shown below.</p>
* <pre>
 * [17/10/2014 22:17:01.348 EDT] com.example.project.App INFO main This is informational message!
 * </pre>
*
 * @author John Yeary <jyeary@bluelotussoftware.com>
 * @version 1.0
 */
public class PragmaticFormatter extends Formatter {
 
    private static final String DATEFORMATPATTERN = "mm/dd/yyyy HH:mm:ss.SSS z";
    private SimpleDateFormat dateFormatter = new SimpleDateFormat(DATEFORMATPATTERN);
 
    /**
     * Default constructor.
     */
    public PragmaticFormatter() {
    }
 
    /**
     * {@inheritDoc}
     */
    public String format(final LogRecord record) {
        StringBuilder sb = new StringBuilder();
        sb.append("[").append(dateFormatter.format(new Date(record.getMillis()))).append("] ");
        sb.append(record.getSourceClassName()).append(" ");
        sb.append(record.getLevel().getName()).append(" ");
        sb.append(record.getSourceMethodName()).append(" ");
        sb.append(record.getMessage()).append("\n");
        return sb.toString();
    }
 
    /**
     * This returns the {@link SimpleDateFormat} used by the {@link Formatter}.
     *
     * @return {@link SimpleDateFormat} used by the {@link Formatter}.
     */
    public SimpleDateFormat getDateFormatter() {
        return dateFormatter;
    }
 
    /**
     * Sets the {@link SimpleDateFormat} used by the {@link Formatter}
     *
     * @param dateFormatter The {@link SimpleDateFormat} to be set.
     */
    public void setDateFormatter(final SimpleDateFormat dateFormatter) {
        this.dateFormatter = dateFormatter;
    }
}
The next question is how do you use it? Easy enough... here is an example for you.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.project;
 
import com.bluelotussoftware.logging.PragmaticFormatter;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
 
public class App {
 
    private static final Logger LOGGER = Logger.getLogger(App.class.getName());
 
    public App() {
    }
 
    public static void main(String[] args) {
        ConsoleHandler handler = new ConsoleHandler();
        handler.setFormatter(new PragmaticFormatter());
        LOGGER.addHandler(handler);
        LOGGER.log(new LogRecord(Level.INFO, "This is informational message!"));
    }
}
The code for the project is located here: pragmatic-logging-formatter

JSF 2.x Tip of the Day: Encoding Text for XML

I have a simple method to encode text to display inside an XML page, or to use inside other XML/JS for example SyntaxHighlighter.

XMLEncode


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static String XMLEncode(final String text) {
    StringBuilder result = new StringBuilder();
 
    for (int i = 0; i < text.length(); i++) {
        char value = text.charAt(i);
        if (!((value >= 'a' && value <= 'z')
                || (value >= 'A' && value <= 'Z')
                || (value >= '0' && value <= '9'))) {
            MessageFormat.format("&#{0};", (int) value);
            result.append(MessageFormat.format("&#{0};", (int) value));
        } else {
            result.append(value);
        }
    }
    return result.toString();
}

Creating a BLOB Image Table

I am going through some old code while I wait for my Windows VM to update. I came across some code to create an image BLOB table on MySQL. I thought I would publish it before deleting it from my system. It might be helpful to someone.

CreateImagesTable.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.bluelotussoftware.database.utils;
 
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
 
/**
 * Creates an Image BLOB table on the target database.
 *
 * @author John Yeary
 * @version 1.0
 */
public class CreateImagesTable {
 
    // The URL connection string to the MySQL Database
    // This can be modified to attach to another database
    // The user and password need to be modified accordingly
    private final String URL = "jdbc:mysql://localhost/images?user=XXXX&password=YYYYYY";
 
    // SQL string to create images table
    private final String SQL = "CREATE TABLE IMAGES (ID INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,"
            + "FILENAME VARCHAR(255) NOT NULL, "
            + "BINARYIMAGEDATA MEDIUMBLOB NOT NULL);";
 
    // This needs to be changed if you use another database driver
    private final String driver = "com.mysql.jdbc.Driver";
 
    private Connection con = null;
    private Statement stmt = null;
 
    /**
     * Creates a new instance of CreateImagesTable
     */
    public CreateImagesTable() {
    }
 
    /**
     * Creates an Image table for BLOB images on the target database.
     */
    public void create() {
        try {
            Class.forName(driver);
            con = DriverManager.getConnection(URL);
            stmt = con.createStatement();
            stmt.execute(SQL);
        } catch (ClassNotFoundException e) {
            System.err.println(e.getMessage());
        } catch (SQLException e) {
            System.err.println(e);
        } finally {
            try {
                if (con != null) {
                    con.close();
                }
            } catch (SQLException ignored) {
            }
        }
    }
 
    public static void main(String args[]) {
        CreateImagesTable table = new CreateImagesTable();
        table.create();
    }
 
}

cat: How do I list the contents of a text file?

I was asked by a new developer how you would cat the contents of a file in Java. I thought for a second and here is what I came up with. I thought I would just share it. Note: This is my 30s answer, and probably could be cleaned up.

Cat.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.bluelotussoftware.utilities;
 
import java.io.*;
import java.text.MessageFormat;
 
public class Cat {
 
    public static void cat(File named) {
        String line;
 
        try (RandomAccessFile input = new RandomAccessFile(named, "r")) {
            while ((line = input.readLine()) != null) {
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            System.out.println(MessageFormat.format("File: {0} not found.", named.getName()));
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } finally {
        }
    }
 
    public static void main(String[] args) {
        Cat.cat(new File(args[0]));
    }
}

Monday, June 16, 2014

Clickjacking and Java EE: Some Practical Solutions

©Technology Personalized

Introduction

What is Clickjacking?

Clickjacking, also known as a "UI redress attack", is when an attacker uses multiple transparent or opaque layers to trick a user into clicking on a button or link on another page when they were intending to click on the the top level page. Thus, the attacker is "hijacking" clicks meant for their page and routing them to other another page, most likely owned by another application, domain, or both.
Using a similar technique, keystrokes can also be hijacked. With a carefully crafted combination of stylesheets, iframes, and text boxes, a user can be led to believe they are typing in the password to their email or bank account, but are instead typing into an invisible frame controlled by the attacker.

What does this mean for Java EE developers?
 
We don't operate inside of a vacuum. HTML/JS technologies are the backbone of most EE applications. This makes them subject to this kind of attack just like any other HTML/JS technologies. In fact, we often abstract away a lot of the underlying HTML/JS from the developer, this can make us more susceptible to this kind of attack unless we are cognizant and diligent in applying defenses.

Fortunately, there are a number of simple things that developers can do to add additional layers of security to their applications in an unobtrusive way. Those methods include adding X-Frame-Options, and frame busting.

X-Frame-Options

The first solution is to add a header to our pages to offer a browser a "suggestion" on how to handle pages that contain frames. The options include DENY, SAMEORIGIN, and ALLOWFROM. The latter is a new addition and may not be supported. The DENY option advises the browser not to allow any content to be displayed if it comes inside a frame. The SAMEORIGIN option advises the browser to only display framed content, if the content is coming from the same origin as the original request. The ALLOWFROM option takes a parameter (URI) that advises that content from a given URI can be framed. As previously noted, this may not be supported on all browsers. You will need to examine your target browser for compliance. Make no assumptions about your users though. They will use a browser of convenience. The implementation of adding the header is simple. The OWASP has come-up with a simple filter to handle the X-Frame-Options.

Frame Busting

The second solution is simple too. It involves using CSS/JS to do something called "frame busting". There are a number of examples on the web. I would recommend that you examine them carefully. I have found that the code I use is simple, elegant, and does not leave a lot of room for attack vectors. This does not imply that it is invulnerable, but does provide a good defense.

In the frame busting method I use, the CSS sets the style attribute body{display:none !important;} on the <body /> tag of the page as soon as the page is loaded. This is followed by a JS function that checks to see if the page is inside a <frame />, if it is then it attempts to set the body as the top location. Thus it breaks the frame. If it is successful, it removes the body{display:none !important;}styling. Otherwise, the <body /> of page will not display. Simple.

Examples

I have created a NetBeans Maven project on Bitbucketclickjacking-examples

The examples include comments and instructions to see the various issues, and possible solutions. Examples include HTML, JSF, and JSP pages. These examples were developed on GlassFish and tested on Apache Tomcat. The code for frame busting is included below for reference using JSF.

Frame Busting Code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
<h:head>
     <title>Clickjacking Example #1</title>
     <!-- Anti-Clickjacking frame busting code. -->
            
     <style id="antiClickjack" type="text/css">body{display:none !important;}</style>
     <script type="text/javascript">
         if (self === top) {
             var antiClickjack = document.getElementById("antiClickjack");
             antiClickjack.parentNode.removeChild(antiClickjack);
         } else {
             top.location = self.location;
         }
     </script>
</h:head>

References

Thursday, June 12, 2014

JSF 2.2 Tip of the Day: Hidden Field Validation

Hidden Mines

Introduction

How often do you have validators on your hidden fields? I recently performed a security audit of an application that did not have validators associated with the hidden fields on the page. I suspect that the out of sight, out of mind mentality prevailed. Admittedly, I have often short circuited some development and put hidden fields in a JSF page without a validator. My expectation is that the data in the field would be used to provide information that may be needed by the application. However, if these fields have setters... and the results are stored in a database... I think you get the picture.

Methodology

I decided to create a more complex than really necessary example to show how to validate a <h:inputHidden /> field. In the example, you can enter names into an <h:inputText /> which will use JavaScript to update the hidden field. The validation will be activated on form submission. Additionally, a value change listener will update the planet name, and update the planet to the new planet. The validation will prevent putting in planets that don't exist in the enum for current Planets. You can confirm this by entering a bogus name, or poor Pluto that was kicked out of the planetary club.

Code

The code for this example was developed using NetBeans 8.0 IDE on GlassFish 4+ and Apache Tomcat 8+ using JSF 2.2 (Mojarra).

The code for the project can be downloaded from Bitbuckethidden-field-validation


Planets.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package com.bluelotussoftware.example;
 
import javax.json.Json;
import javax.json.JsonObject;
 
/**
 * An {@literal enum} that represents the planets in our solar system, and their
 * position from the Sun.
 *
 * @author John Yeary
 * @version 1.0
 */
public enum Planets {
 
    Mercury(1), Venus(2), Earth(3), Mars(4), Jupiter(5), Saturn(6), Uranus(7), Neptune(8);
 
    /**
     * Private constructor that sets solar position.
     *
     * @param position The planetary orbital position.
     */
    private Planets(final int position) {
        this.position = position;
    }
    private final int position;
 
    /**
     * {@inheritDoc}
     *
     * @return a JSON string representing the planet name and its position e.g. <pre>
     * {"planet":"Earth","position":2}
     * </pre>
*/
    @Override
    public String toString() {
        JsonObject job = Json.createObjectBuilder()
                .add("planet", this.name())
                .add("position", this.ordinal())
                .build();
        return job.toString();
    }
}

PlanetValidator.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.bluelotussoftware.example;
 
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
 
/**
 * This {@link Validator} is used to confirm if a submitted {@link Planets} name
 * is a valid planet.
 *
 * @author John Yeary
 * @version 1.0
 */
@FacesValidator(value = "com.bluelotussoftware.example.PlanetValidator")
public class PlanetValidator implements Validator {
 
    /**
     * {@inheritDoc}
     *
     * @param context
     * @param component
     * @param value
     * @throws ValidatorException
     */
    @Override
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String planetName = (String) value;
        if (planetName != null && !planetName.isEmpty()) {
            System.out.println("Validating " + planetName);
            try {
                Planets.valueOf(planetName);
            } catch (IllegalArgumentException ex) {
                FacesMessage fm;
                if ("Pluto".equalsIgnoreCase(planetName)) {
                    fm = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "Planet invalid.",
                            "Poor Pluto... its a planetoid not a planet anymore.");
                } else {
                    fm = new FacesMessage(FacesMessage.SEVERITY_ERROR,
                            "Planet invalid.", "The submitted planet is invalid.");
                }
                throw new ValidatorException(fm, ex);
            }
        }
    }
}

IndexBean.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package com.bluelotussoftware.example;
 
import java.io.Serializable;
import java.text.MessageFormat;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ValueChangeEvent;
 
/**
 *
 * @author John Yeary
 * @version 1.0
 */
@ManagedBean
@ViewScoped
public class IndexBean implements Serializable {
 
    private static final long serialVersionUID = 7770102269253088141L;
    private Planets planet = Planets.Earth;
    private String planetName;
 
    public IndexBean() {
    }
 
    @PostConstruct
    private void init() {
        planetName = planet.name();
    }
 
    public String getPlanetName() {
        return planetName;
    }
 
    public void setPlanetName(String planetName) {
        this.planetName = planetName;
    }
 
    public void setPlanet(Planets planet) {
        this.planet = planet;
    }
 
    public Planets getPlanet() {
        return planet;
    }
 
    public String planetaryAction() {
        return null;
    }
 
    public void planetaryValueChangeListener(ValueChangeEvent event) {
        System.out.println(MessageFormat.format("Old: {0} New: {1}",
                event.getOldValue(), event.getNewValue()));
        String value = (String) event.getNewValue();
        if (value != null && !value.isEmpty()) {
            planetName = value;
            planet = Planets.valueOf(value);
        }
    }
}

index.xhtml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Home</title>
    </h:head>
    <h:body>
        <h:messages globalOnly="#{true}"/>
        <h:form id="form1">
            <h:outputText value="Current Planet: #{indexBean.planet.toString()}"/>
            <h:panelGrid columns="2">
                <h:inputText id="inputText1" value="#{indexBean.planetName}"
                             valueChangeListener="#{indexBean.planetaryValueChangeListener}"
                             onkeyup="document.getElementById('form1\:inputHidden1').value = this.value;">
                    <f:validator validatorId="com.bluelotussoftware.example.PlanetValidator"/>
                </h:inputText>
                <h:message for="inputText1"/>
                <h:inputHidden id="inputHidden1" value="#{indexBean.planetName}">
                    <f:validator validatorId="com.bluelotussoftware.example.PlanetValidator"/>
                </h:inputHidden>
                <h:message for="inputHidden1"/>
            </h:panelGrid>
            <h:commandButton value="Submit" action="#{indexBean.planetaryAction()}"/>
        </h:form>
    </h:body>
</html>

Thursday, May 01, 2014

JSF 2.2 Tip of the Day: JavaScript Popup Window with Dynamic URL Link

Introduction

There are times when you need to have a JavaScript popup window that opens to another URL based on user input.  The JavaScript is usually added to the onclick event on the JSF component. The dynamic link in JSF is more difficult to accomplish since binding the onclick using Expression Language (EL) is determined at page rendering time. As a result, this means that the JavaScript is not dynamic. As a result, the link is not dynamic either.

A Solution

I have created a project that has three examples that demonstrate the different types of JSF links including the dynamic link. The last example includes <f:param /> elements that are appended to the dynamic URL that is generated.

The dynamic example still uses the onclick event, but the JSF action performs a redirect of the newly opened window. Additionally, and of the parameters that are added to the JSF component are converted to query parameters and appended to the redirect URL.

The Apache Maven project created with NetBeans is located on BitBucket here: jsf-link-examples

The project was tested on GlassFish 4 using Mojarra  JSF 2.2, but the technique should work on other application servers and JSF 2.x versions.

Index.xhtml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>JSF Link Examples</title>
    </h:head>
    <h:body>
        <h1>
JSF Link Examples</h1>
<p>
            Example HTML Anchor (<a />) elements using JSF to redirect to an external web site.
        </p>
<ul>
<li>
                <h:outputLink value="#{indexBean.redirectLink}" target="_blank">
                    #{indexBean.linkName}
                </h:outputLink> - Open the link in a new page.
            </li>
<li>
                <h:outputLink onclick="#{indexBean.JSPopup()}">
                    #{indexBean.linkName}
                </h:outputLink> - Open link in a JS popup window.
            </li>
<li>
                <h:form id="form1">
                    <h:commandLink id="popupLink" value="#{indexBean.linkName}"
                                   target="popUpWindow"
                                   onclick="javascript: void window.open('', 'popUpWindow', 'status=0,toolbar=0,location=0,menubar=0,resizable,width=750,height=500,scrollbars,left=0,top=0');"
                                   action="#{indexBean.redirect()}" binding="#{indexBean.popupLink}">
                        <f:param name="p1" value="#{indexBean.param1}"/>
                        <f:param name="p2" value="#{indexBean.param2}"/>
                    </h:commandLink> - Open link in a JS popup window using a dynamic URL and parameters.
                </h:form>
            </li>
</ul>
</h:body>
</html>

IndexBean.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.bluelotusoftware.example;
 
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIParameter;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.context.FacesContext;
 
/**
 *
 * @author John Yeary
 * @version 1.0
 */
@ManagedBean
@RequestScoped
public class IndexBean {
 
    private final String linkName = "Union of Concerned Scientists";
    private HtmlCommandLink popupLink;
    private final String param1 = "Hello";
    private final String param2 = "World";
 
    public String getRedirectLink() {
        return "http://ucsusa.org";
    }
 
    public String JSPopup() {
        return "javascript:void window.open('" + getRedirectLink() + "','" + linkName + "','width=700,height=500,toolbar=0,menubar=0,location=0,status=0,scrollbars=0,resizable=1,left=0,top=0');return false;";
    }
 
    public String getLinkName() {
        return linkName;
    }
 
    public HtmlCommandLink getPopupLink() {
        return popupLink;
    }
 
    public void setPopupLink(HtmlCommandLink popupLink) {
        this.popupLink = popupLink;
    }
 
    public String getParam1() {
        return param1;
    }
 
    public String getParam2() {
        return param2;
    }
 
    public String redirect() {
        List<uicomponent> children = popupLink.getChildren();
        Map<String, List<string>> parameters = getParameters(children);
        FacesContext fc = FacesContext.getCurrentInstance();
 
        try {
            String url = fc.getExternalContext().encodeRedirectURL(getRedirectLink(), parameters);
            fc.getExternalContext().redirect(url);
        } catch (IOException e) {
            fc.addMessage(popupLink.getClientId(), new FacesMessage("The link could not be redirected.", e.getMessage()));
        }
        return null;
    }
 
    private Map<String, List<string>> getParameters(final List<uicomponent> components) {
        Map<String, List<string>> parameters = null;
         
        if (components != null) {
            parameters = new HashMap<>(components.size());
 
            for (UIComponent component : components) {
                if (component instanceof UIParameter) {
                    final UIParameter parameter = (UIParameter) component;
                    parameters.put(parameter.getName(), new ArrayList<string>() {
                        private static final long serialVersionUID = 3109256773218160485L;
 
                        {
                            add((String) parameter.getValue());
                        }
                    });
                }
            }
        }
        return parameters;
    }
}

Cross-Site Scripting (XSS) and Playing with JSoup

Introduction

I have used Beautiful Soup with Python in the past for screen scraping. I was immediately excited at the possibilities. JSoup is a Java API for extracting data, and manipulating the DOM in HTML.
jsoup implements the WHATWG HTML5 specification, and parses HTML to the same DOM as modern browsers do.
I did a quick proof of concept just to see what it would do with my "dirty" code.

It results in an interesting output that could be useful if used properly. If you put in garbage, you will get "less" garbage out. It is better than nothing.

I decided that this still could be really useful especially combined with Hibernate Validators and JSF.

Hibernate Validator - @SafeHtml

I was looking at the Hibernate Validators to see about cleaning up some input from users to prevent XSS issues. I noticed that there was a validator called @SafeHtml(whitelistType=, additionalTags=, additionalTagsWithAttributes=). It uses the JSoup HTML parser.

Alas, I am full of sorrow. I can not seem to get the <code>@SafeHtml</code> annotation to work. GlassFish vomits and complains it can not find it. I even tried to add it to every lib directory in GlassFish without success. Failing to succeed, I tried Tomcat 8 next. Again, nothing but bitterness and disappointment. It just will not get picked up.

I tried looking for a working example of the validator, and didn't find any that worked. I am not sure of the what is going on, but if I can't figure it out. I imagine I am not alone. I just blog about it. ;-)

Undeterred

Well I decided that I didn't need Hibernate anyway! I feel like I should be in Aesop's Fables. I mentioned my Proof of Concept (POC) earlier. I figured I would look at trying to remove some <script /> tags from my code and even encoded them too to see what it would do. The whole point here is to help prevent XSS.

Here is my Apache Maven project on BitBucket: jsoup-cleaner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.bluelotusoftware.poc.jsoup;
 
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
 
/**
 *
 * @author John Yeary
 * @version 1.0
 */
public class CleanerExample {
 
    private static final String dirty = "<script type=\"text/javascript\">alert('test');</script>"
            + "John is awesome. <script type=\"text/javascript\"> alert('test');</script>"
            + "<script type=\"text/javascript\">alert('test');</script> X=Y, Y=\"ZZ\"";
 
    public static void main(String[] args) {
         
        String clean = Jsoup.clean(dirty, Whitelist.none());
         
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println("DIRTY CODE");
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println(dirty);
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println("CLEAN CODE");
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println(clean);
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    }
 
}
 
Note: See the actual code for a more complete representation of the actual code I am trying to strip. The Syntaxhighlighter is having issues with the nested script tags. The same applies to the output.

I was surprised by the result actually. It stripped out the <script /> tags, but totally missed the encoded tags. That is a major issue.

Improvements

I was looking for some solutions for the encoded JavaScript issue when I discovered a blog post called Jersey Cross-Site Scripting XSS Filter for Java Web Apps.

This was not exactly what I needed, but it did contain a method which used JSoup and another framework called ESAPI. Enterprise Security API (ESAPI) was developed by OWASP to enhance the security of Enterprise applications. OWASP has a lot more than this framework.  ESAPI can strip out the encoded bits to help prevent XSS.
I shamelessly used the following method from the blog post.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
 * <p>
 * Strips any potential XSS threats out of the value.</p>
 * <p>See <a
 * Cross-Site Scripting XSS Filter for Java Web Apps</a> for more details on
 * this method.</p>
 *
 * @param value The {@code String} to be evaluated for HTML tags.
 * @return a {@code String} that has HTML tags removed.
 */
public String stripXSS(String value) {
    if (value != null) {
        // Use the ESAPI library to avoid encoded attacks.
        value = ESAPI.encoder().canonicalize(value);
 
        // Avoid null characters
        value = value.replaceAll("\0", "");
 
        // Clean out HTML
        value = Jsoup.clean(value, Whitelist.none());
    }
    return value;
}

This does effectively remove any encoded <script /> tags from the output. It does not however prevent errors in judgement on the part of the developer. For example taking the results of the output and using them directly in an HTML JavaScript attribute like onmouseover, or onclick.

I created an example project called XSS Scripter's Delight which I demonstrated at the Greenville Java Users Group. It demonstrates what happens when you don't validate inputs from users. The name is satirical, but does demonstrate in a non-malicious way what you can do if you are not careful.

The Apache Maven project developed with NetBeans can be found on Bitbucket here: xss-scripters-delight.

Monday, April 28, 2014

Arquillian Graphene 2: JavaScript Unit Testing Examples

I have been doing work with Arquillian for a while. If you need to do integration and unit testing on your JSF application. This is definitely the path to take. It makes testing so much easier to accomplish.

Recently, I have been trying to use Arquillian Graphene 2 to do JavaScript unit testing. I spent a lot of time trying to get the examples on the Graphene 2 - JavaScript Interface wiki to work. I discovered that they were slightly incorrect and the source of my grief. One of the great things about an Open Source world is that I updated the wiki with the correct information.

I have created a couple of Proof of Concept (POC) projects to demonstrate how to use Graphene to do JS testing. The first example uses Graphene in stand-alone mode. This mode allows you to test your JavaScript outside of a container, but using a browser implementation like: PhantomJS, Chrome, Firefox, or Safari.

The Apache Maven NetBeans 8.0 project can be downloaded from Bitbucket here: graphene-js-poc

You will need to execute this from the command line, or use the JS Unit Test custom goal in NetBeans.

1
mvn -Dbrowser=phantomjs clean test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.bluelotusoftware.example;
 
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.javascript.JavaScript;
import org.jboss.arquillian.junit.Arquillian;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
 
/**
 *
 * @author John Yeary
 * @version 1.0
 */
@RunWith(Arquillian.class)
public class GreetingTest {
 
    @JavaScript
    private Greeting greeting;
    @Drone
    private WebDriver driver;
 
    @Test
    public void testGreeting() {
        assertEquals("Hello John", greeting.greeting("John"));
    }
    @Test
    public void testWarning() {
        assertNull(greeting.warning("John"));
    }
}
The next project is simply a combination of the code from the Arquillian Graphene 2 wiki combined into a more complex project. This project is designed to run in a container. In my case, Glassfish is the container of choice. The slickness of this approach becomes quite apparent when you see the application server start-up, execute the tests, and shutdown gracefully.

The Apache Maven NetBeans 8.0 project can be downloaded from Bitbucket here: graphene-poc.

The project includes a JSF example along with testing JavaScript.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.bluelotusoftware.example;
 
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.graphene.javascript.JavaScript;
import org.jboss.arquillian.junit.Arquillian;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openqa.selenium.WebDriver;
 
@RunWith(Arquillian.class)
public class HelloWorldTest {
     
    // Required browser injection
    @Drone
    private WebDriver browser;
 
    @JavaScript
    private HelloWorld helloWorld;
 
    @Test
    public void testHelloWorld() {
        assertEquals("Hello World!", helloWorld.hello());
    }
}
If you need to do unit testing of your JavaScript, this may be an option to consider. Please make sure you read the wiki and understand the limitations of the approach however. You can use my code as an example to help guide you along the path.

Friday, April 18, 2014

JSF 2.2 Tip of the Day: Naughty Expression Language (EL)

Unexpected Effects

Many of you may know this already, but I was reminded the other day how this can catch even some of the most brilliant JSF developers. When you comment out a component in your xhtml page that has EL bindings, you may not be REALLY disabling it.
Expression Language (EL) is parsed and evaluated as the page is being rendered. As a result, any exposed EL syntax will be processed including functions which could have deleterious effects. For example, take a look at the following code, and guess what it will do.
1
2
3
4
<!-- #{indexBean.doSomething()} -->
<!-- #{indexBean.doSomething} -->
<!-- <h:commandButton action="#{indexBean.doSomethingElse()}" value="Submit"/> -->
<!-- <h:commandButton action="#{indexBean.doSomethingElse}" value="Submit"/> -->

So what happens?

Scary things happen....
  1. It executes
  2. Parser exception. The parser will try to find a property called doSomething
  3. It will execute, please note that there is no <h:form/>. It is not required since we are evaluating the EL.
  4. Parser exception. The parser will try to find a property called doSomethingElse

Sensei what do I do?

You have a couple of options. The first option is the easiest, and it is likely what you want anyway with your JSF pages. You can disable the comments. No need to transmit your development comments to the end users anyway. The second option is to add a - between the # and the { like this #-{indexBean.doSomethingElse()}.
The first option is handled by adding a configuration parameter to the web.xmlfile as shown below.
1
2
3
4
<context-param>
    <param-name>facelets.SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
</context-param>
Here is a more complete example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:h="http://java.sun.com/jsf/html">
    <h:head>
        <title>Naughty EL</title>
    </h:head>
    <h:body>
        <h1>
Naughty EL</h1>
<p>
            Expression Language (EL) is parsed and evaluated as the
        </p>
<p>
<strong>Note:</strong> You can disable the comments including the EL which may not be disabled by using the following
            configuration parameter in the <strong>web.xml</strong>.
        </p>
<pre>
            <context-param>
                <param-name>facelets.SKIP_COMMENTS</param-name>
                <param-value>true</param-value>
            </context-param>
        </pre>
<p>
If you want to see the EL and its associated issues, please look at the source code and comments</p>
<!-- This example will execute because the EL ends with () -->
        <!-- #{indexBean.doSomething()} -->
        <!-- The result is the following -->
        <p>
Did the EL execute: <h:outputText value="#{indexBean.message}"/></p>
<!-- This example will not execute, but will result in a parse error because their is no property called doSomething -->
        <!-- You would need to remove the - from between # and { -->
        <!--#-{indexBean.doSomething}-->
 
        <!-- Oh, so you thought you disabled the component didn't you? Guess what? It is also not in a h:form ...-->
        <!--<h:commandButton action="#{indexBean.doSomethingElse()}" value="Submit"/>-->
        <!-- The result will be displayed in the messages below -->
        <h:messages globalOnly="true"  style="color:red; font-size: 32px;"/>
        <!-- <h:commandButton action="#-{indexBean.doSomethingElse}" value="Submit"/> -->
    </h:body>
</html>
The result of the code is as follows:

The complete code example was developed using NetBeans 8.0 and GlassFish 4.0 on JDK 8. The code can be found here: auto-execute-el

Wednesday, February 12, 2014

JSF 2.2 Tip of the Day: Using JSF AJAX Events

Please wait...

Introduction

The JSF framework provides an easy to use AJAX event handling mechanism. The jsf.js library is included in Mojarra and MyFaces. There are two particular methods of interest: jsf.ajax.addOnError(callback) and jsf.ajax.addOnEvent(callback). I will be covering the latter handler.

The JsDoc does not really explain the jsf.ajax.addOnEvent(callback) code very well. Since it is Javascript, you can read it, but I think a simple example of its flexibility with some comments might work better.

Using the addOnEvent is very simple. You register the callback, and it gets called during the lifecycle. The important thing here to remember is that the callback must be a function. Otherwise, it will throw an error. You can control what event processing occurs during the lifecycle.

Events

The callback is invoked during the AJAX request and response lifecycle. The status passed to the callback are listed below.

Event Description
begin This is the start of the AJAX request.
complete This is invoked right after AJAX response is returned.
success This is invoked right after successful processing of AJAX response and update of HTML DOM.


Based on the status, we can take appropriate action on the AJAX event. A great example to demonstrate AJAX event handling is to provide feedback to the user to indicate the status of their request. I will demonstrate how to create an AJAX based progress loader to demonstrate the events.

Code

The code for our AJAX loader is very simple, and could be moved into a composite component if necessary. The NetBeans developed Maven project can be downloaded from the references section below.

index.xhtml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>AJAX Loader Example</title>
        <h:outputStylesheet library="css" name="loader.css"/>
        <h:outputScript library="javax.faces" name="jsf.js" target="head"/>
    </h:head>
    <h:body>
        <h:form>
            <h:commandButton value="Submit" action="#{indexBean.sleep()}">
                <f:ajax execute="@form"/>
            </h:commandButton>
        </h:form>
        <div class="modal">
<!-- Place at bottom of page before JS --></div>
<script type="text/javascript">
            function handleAjax(data) {
                var status = data.status;
 
                switch (status) {
                    case "begin":
                        // This is the start of the AJAX request.
                        document.getElementsByTagName('body')[0].className = 'loading';
                        break;
 
                    case "complete":
                        // This is invoked right after AJAX response is returned.
                        break;
 
                    case "success":
                        // This is invoked right after successful processing of AJAX response and update of HTML DOM.
                        document.getElementsByTagName('body')[0].className = '';
                        break;
                }
            }
            // Setup the statusUpdate function to hear all events on the page
            jsf.ajax.addOnEvent(handleAjax);
        </script>
    </h:body>
</html>

This code controls our progress bar by making changes to the CSS in DOM. The CSS idea is not mine, but it is clever. Here is the CSS.

loader.css


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* Start by setting display:none to make this hidden.
 * Then we position it in relation to the viewport window
 * with position:fixed. Width, height, top and left speak
 * speak for themselves. Background we set to 80% white with
 * our animation centered, and no-repeating
*/
.modal {
    display:    none;
    position:   fixed;
    z-index:    1000;
    top:        0;
    left:       0;
    height:     100%;
    width:      100%;
    background: rgba( 255, 255, 255, .8 );
    background-image: url('#{facesContext.externalContext.requestContextPath}/resources/images/ajax-loader.gif');
    background-position: 50% 50%;
    background-repeat: no-repeat;
}
 
/* When the body has the loading class, we turn
 * the scrollbar off with overflow:hidden
*/
body.loading {
    overflow: hidden;  
}
 
/* Anytime the body has the loading class, our
 * modal element will be visible
*/
body.loading .modal {
    display: block;
}

A simple CSS layout, and our Javascript callback to jsf.ajax.addOnEvent(callback) is all it takes to make a cool progress loader.

References

Monday, January 20, 2014

RichFaces 4.3.x Tip of the Day: Complex RichFaces Data Tables

Introduction

I have been working on JSF tables for the various projects I have been involved with over the years. Starting in 2012, I began looking at RichFaces <rich:dataTable /> for some projects at my day job. The research into how to handle a number of complex situations has been enlightening to say the least.

The table is the most complex component in HTML. It is seemingly boundless in its extensibility. You can have multi-column headers that span multiple rows, you can multi-row cells, or multi-column cells. Tables can be displayed left-to-right, or right-to-left, top-to-bottom and vice-versa. As a result, when developing components for JSF, or any component framework, decisions must be made on how to generate them.

A couple of the component frameworks like PrimeFaces, and RichFaces allow developers to create more complex tables with more ease. However there are limitations with each of these frameworks. We trade flexibility for consistency, and this is fine in most cases.

The demonstration code in this post is about getting some of the flexibility back, or taking advantage of the flexibility that comes with a framework like RichFaces. We will gain the flexibility back, but it is a function of complexity. The examples will show you techniques for doing the "same thing" in multiple ways. For example, sorting can be done on the server, client, or a combination of both.

The question is where we put the complex bits. The answer to that question depends on you as a developer. You need to examine the problem domain, and understand the limits to the techniques presented.

Solutions

Please let me confess something. I like building HTML objects programmatically. There I said it. In this case I am trading the ease of development for flexibility. The solutions below will demonstrate the different techniques for accomplishing the same functionality. Please examine the code carefully before discounting it. I spent a lot of time playing with it to make it look simple.

The code for this project was developed using NetBeans and Apache Maven. The code was tested on GlassFish 3.1.2.2 and 4.0. It should work on other application servers, but I have not tested it on other servers. This project assumes you are using NetBeans which includes a sample database that these examples require. If you are not using NetBeans, you will need to create your own database with sample data to display some of the tables.

The code can be downloaded from Bitbucket at the link below, or in the references section at the end of the post.

richfaces-tables-poc

Dynamic Data Table with Sorting

Dynamic Table with Sorting
This example uses the binding attribute of the <rich:dataTable /> to bind our table to a CDI @ManagedBean. The bean is responsible for generating the table programmatically, and returning it back to the page. The data is sortable by column.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.org/rich">
    <h:head>
        <title>Dynamic Data Table Design #1</title>
    </h:head>
    <h:body>
        <h1>
Dynamic Data Table Design #1</h1>
<p>
            The table is bound to the page backing bean, and is generated dynamically.
  
            Please use the Source and Code links to see the details.
        </p>
<h:form id="form1">
            <rich:dataTable id="dataTable" binding="#{dataTable1.dataTable}"/>
        </h:form>
        <div style="padding-top: 5px;">
            <a href="#{facesContext.externalContext.requestContextPath}">Index</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/dataTable1.xhtml">Source</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/resources/src/dataTable1.java">Code</a>
        </div>
</h:body>
</html>
As you can see the page is very simple. In fact, most of the page is plumbing and navigation. The <rich:dataTable /> is the smallest part of the page. The code to generate the table is much more complex.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
package com.bluelotussoftware.example.richfaces;
 
import com.bluelotussoftware.example.richfaces.model.Customer;
import com.bluelotussoftware.example.richfaces.ssb.CustomerFacade;
import com.bluelotussoftware.jsf.utils.JSFUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.Application;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.richfaces.component.SortOrder;
import org.richfaces.component.UIColumn;
import org.richfaces.component.UIColumnGroup;
import org.richfaces.component.UICommandLink;
import org.richfaces.component.UIDataTable;
 
/**
 * <p>
Proof of Concept #1 Programmatic RichFaces data table
 * <code><rich:dataTable/></code> with server side sorting</p>
*
 * <p>
<strong>Note:</strong> Please note that the scope must be set to session
 * for the object holding a reference to the bound datatable.</p>
*
 * @author John Yeary
 * @version 1.0
 */
@Named
@SessionScoped
public class DataTable1 implements Serializable {
 
    private static final long serialVersionUID = 3733919546663290317L;
    private List<customer> customers;
    private SortOrder nameSortOrder = SortOrder.unsorted;
    private SortOrder creditSortOrder = SortOrder.unsorted;
    private SortOrder phoneSortOrder = SortOrder.unsorted;
    @EJB
    private CustomerFacade cf;
    private UIDataTable dataTable;
 
    public DataTable1() {
        customers = new ArrayList<customer>();
    }
 
    @PostConstruct
    private void init() {
        customers.addAll(cf.findAll());
 
        Class<?>[] klazz = new Class<?>[]{};
        Application application = FacesContext.getCurrentInstance().getApplication();
 
        // Create RichFaces Table <rich:dataTable/>
        dataTable = (UIDataTable) application.createComponent(UIDataTable.COMPONENT_TYPE);
        dataTable.setVar("customer");
        dataTable.setValue(customers);
 
        // Create A4J CommandLink <a4j:commandLink/> Column Headers
        UICommandLink clink = (UICommandLink) application.createComponent(UICommandLink.COMPONENT_TYPE);
        clink.setValueExpression("value", JSFUtils.createValueExpression("#{dataTable1.customerColumnHeader}", String.class));
        clink.setActionExpression(JSFUtils.createMethodExpression("#{dataTable1.nsort()}", String.class, klazz));
        clink.setRender("dataTable");
 
        UICommandLink clink1 = (UICommandLink) application.createComponent(UICommandLink.COMPONENT_TYPE);
        clink1.setValue("Phone");
        clink1.setActionExpression(JSFUtils.createMethodExpression("#{dataTable1.psort()}", String.class, klazz));
        clink1.setRender("dataTable");
 
        UICommandLink clink2 = (UICommandLink) application.createComponent(UICommandLink.COMPONENT_TYPE);
        clink2.setValue("Credit Limit");
        clink2.setActionExpression(JSFUtils.createMethodExpression("#{dataTable1.csort()}", String.class, klazz));
        clink2.setRender("dataTable");
 
        // Create Data Elements
        HtmlOutputText htmlOutputText = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        htmlOutputText.setValueExpression("value", JSFUtils.createValueExpression("#{customer.name}", String.class));
 
        HtmlOutputText htmlOutputText1 = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        htmlOutputText1.setValueExpression("value", JSFUtils.createValueExpression("#{customer.phone}", String.class));
 
        HtmlOutputText htmlOutputText2 = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        htmlOutputText2.setValueExpression("value", JSFUtils.createValueExpression("#{dataTable1.format(customer.creditLimit)}", String.class));
        htmlOutputText2.setValueExpression("rendered", JSFUtils.createValueExpression("#{customer.creditLimit gt 25000}", Boolean.class));
 
        // Create RichFaces Columns <rich:column/>
        UIColumn column = (UIColumn) application.createComponent(UIColumn.COMPONENT_TYPE);
        column.setValueExpression("sortBy", JSFUtils.createValueExpression("#{customer.name}", String.class));
        column.setValueExpression("sortOrder", JSFUtils.createValueExpression("#{dataTable1.nameSortOrder}", SortOrder.class));
 
        UIColumn column1 = (UIColumn) application.createComponent(UIColumn.COMPONENT_TYPE);
        column1.setValueExpression("sortBy", JSFUtils.createValueExpression("#{customer.phone}", String.class));
        column1.setValueExpression("sortOrder", JSFUtils.createValueExpression("#{dataTable1.phoneSortOrder}", SortOrder.class));
        column1.setValueExpression("comparator", JSFUtils.createValueExpression("#{dataTable1.phoneComparator}", Comparator.class));
 
        UIColumn column2 = (UIColumn) application.createComponent(UIColumn.COMPONENT_TYPE);
        column2.setValueExpression("sortBy", JSFUtils.createValueExpression("#{customer.creditLimit}", String.class));
        column2.setValueExpression("sortOrder", JSFUtils.createValueExpression("#{dataTable1.creditSortOrder}", SortOrder.class));
        column2.setValueExpression("comparator", JSFUtils.createValueExpression("#{dataTable1.creditComparator}", Comparator.class));
 
        // Assemble Columns and values
        column.setHeader(clink);
        column.getChildren().add(htmlOutputText);
 
        column1.setHeader(clink1);
        column1.getChildren().add(htmlOutputText1);
 
        column2.setHeader(clink2);
        column2.getChildren().add(htmlOutputText2);
 
        // Create Table Header
        UIColumn hcolumn = (UIColumn) application.createComponent(UIColumn.COMPONENT_TYPE);
        hcolumn.setColspan(3);
        HtmlOutputText columnText = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        columnText.setValue("Customer Information");
        hcolumn.getChildren().add(columnText);
        UIColumnGroup columnGroup = (UIColumnGroup) application.createComponent(UIColumnGroup.COMPONENT_TYPE);
        columnGroup.getChildren().add(hcolumn);
 
        // Assemble Table
        dataTable.setHeader(columnGroup);
        dataTable.getChildren().add(column);
        dataTable.getChildren().add(column1);
        dataTable.getChildren().add(column2);
 
    }
 
    public UIDataTable getDataTable() {
        return dataTable;
    }
 
    public void setDataTable(UIDataTable dataTable) {
        this.dataTable = dataTable;
    }
 
    public List<customer> getCustomers() {
        return customers;
    }
 
    public SortOrder getNameSortOrder() {
        return nameSortOrder;
    }
 
    public SortOrder getCreditSortOrder() {
        return creditSortOrder;
    }
 
    public SortOrder getPhoneSortOrder() {
        return phoneSortOrder;
    }
 
    /**
     * Customer name sorting enumeration "three position switch":
     * default (unsorted), ascending, and descending.
     */
    public void nsort() {
        creditSortOrder = SortOrder.unsorted;
        phoneSortOrder = SortOrder.unsorted;
 
        switch (nameSortOrder) {
            case unsorted: {
                nameSortOrder = SortOrder.ascending;
                break;
            }
            case ascending: {
                nameSortOrder = SortOrder.descending;
                break;
            }
            case descending: {
                nameSortOrder = SortOrder.unsorted;
                break;
            }
        }
    }
 
    /**
     * Credit limit sorting enumeration "three position switch":
     * default (unsorted), ascending, and descending.
     */
    public void csort() {
        nameSortOrder = SortOrder.unsorted;
        phoneSortOrder = SortOrder.unsorted;
 
        switch (creditSortOrder) {
            case unsorted: {
                creditSortOrder = SortOrder.ascending;
                break;
            }
            case ascending: {
                creditSortOrder = SortOrder.descending;
                break;
            }
            case descending: {
                creditSortOrder = SortOrder.unsorted;
                break;
            }
        }
    }
 
    /**
     * Phone sorting enumeration "three position switch": default
     * (unsorted), ascending, and descending.
     */
    public void psort() {
        nameSortOrder = SortOrder.unsorted;
        creditSortOrder = SortOrder.unsorted;
 
        switch (phoneSortOrder) {
            case unsorted: {
                phoneSortOrder = SortOrder.ascending;
                break;
            }
            case ascending: {
                phoneSortOrder = SortOrder.descending;
                break;
            }
            case descending: {
                phoneSortOrder = SortOrder.unsorted;
                break;
            }
        }
    }
 
    public Comparator<customer> getPhoneComparator() {
 
        return new Comparator<customer>() {
            @Override
            public int compare(Customer o1, Customer o2) {
                return o1.getPhone().compareTo(o2.getPhone());
            }
        };
    }
 
    public Comparator<customer> getCreditComparator() {
        return new Comparator<customer>() {
            @Override
            public int compare(Customer o1, Customer o2) {
                return o1.getCreditLimit().compareTo(o2.getCreditLimit());
            }
        };
    }
 
    /**
     * This method returns the customer name header with the specified sort
     * order based on the current {@link SortOrder}.
     *
     * @return customer name header with the specified sort order.
     */
    public String getCustomerColumnHeader() {
        switch (nameSortOrder) {
            case unsorted: {
                return "Customer Name";
            }
            default: {
                return "Customer Name (" + nameSortOrder + ")";
            }
        }
    }
 
    /**
     * Generates custom formatted USD currency value based on {@code Integer}.
     *
     * @param value The value to be formatted.
     * @return $USD formatted value.
     */
    public String format(Integer value) {
        return String.format("$ %1$,d", value);
    }
}
As you can see we have traded simplicity in the page for complexity in the @ManagedBean. If you are satisfied with this technique, lets take a look at another one.

Dynamic Data Table with Sorting Revisited

Dynamic Table
This table uses the same dynamic binding as the example above on the JSF page, but uses helper utilities to create JSF components dynamically from a library that I have written. It is a separate project that you can download (Please see references). This reduces the chances for errors creating common components, but it is still a lot of code. To check our sorting, I have made a "random" data generator for the table data for the code to sort.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.org/rich">
    <h:head>
        <title>Dynamic Data Table Design #2</title>
    </h:head>
    <h:body>
        <h1>
Dynamic Data Table Design Design #2</h1>
<p>
            The table is bound to the page backing bean, and is generated dynamically.
  
            Please use the Source and Code links to see the details.
        </p>
<h:form id="form1">
            <rich:dataTable id="dataTable" binding="#{dataTable2.dataTable}"/>
        </h:form>
        <div style="padding-top: 5px;">
            <a href="#{facesContext.externalContext.requestContextPath}">Index</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/dataTable2.xhtml">Source</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/resources/src/dataTable2.java">Code</a>
        </div>
</h:body>
</html>

The more simplified code in the @ManagedBean is shown below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.bluelotussoftware.example.richfaces;
 
import com.bluelotussoftware.jsf.utils.JSFUtils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.application.Application;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.richfaces.component.SortOrder;
import org.richfaces.component.UIColumn;
import org.richfaces.component.UICommandLink;
import org.richfaces.component.UIDataTable;
 
/**
 * <p>
Proof of Concept #2 Programmatic RichFaces data table
 * <code><rich:dataTable/></code> with server side sorting</p>
*
 * <p>
<strong>Note:</strong> Please note that the scope must be set to session
 * for the object holding a reference to the bound datatable.</p>
*
 * @author John Yeary
 * @version 1.0
 */
@Named
@SessionScoped
public class DataTable2 implements Serializable {
 
    private static final long serialVersionUID = -2771295649562837525L;
    private SortOrder sorting = SortOrder.unsorted;
    private static final String DATA_TABLE_NAME = "dataTable";
    private UIDataTable dataTable;
 
    public DataTable2() {
    }
 
    @PostConstruct
    private void init() {
        FacesContext context = FacesContext.getCurrentInstance();
        Application application = context.getApplication();
        // ~~~~~~~~~~~~~~~~~~~~ Data Table
        dataTable = (UIDataTable) application.createComponent(UIDataTable.COMPONENT_TYPE);
        dataTable.setVar("v");
        dataTable.setValue(getData());
        UIColumn column0 = createUIColumn(context, "#{v.get(0).value}", String.class, "#{dataTable2.sorting}");
        UIColumn column1 = createUIColumn(context, "#{v.get(1).value}", String.class, "#{dataTable2.sorting}");
        UICommandLink commandLink0 = createUICommandLink(context, "Column 0", DATA_TABLE_NAME, "#{dataTable2.sort()}");
        UICommandLink commandLink1 = createUICommandLink(context, "Column 1", DATA_TABLE_NAME, "#{dataTable2.sort()}");
        HtmlOutputText htmlOutputText0 = createHtmlOutputText(context, "#{v.get(0).value}", String.class);
        HtmlOutputText htmlOutputText1 = createHtmlOutputText(context, "#{v.get(1).value}", String.class);
        column0.setHeader(commandLink0);
        column0.getChildren().add(htmlOutputText0);
        column1.setHeader(commandLink1);
        column1.getChildren().add(htmlOutputText1);
        dataTable.getChildren().add(column0);
        dataTable.getChildren().add(column1);
    }
 
    public SortOrder getSorting() {
        return sorting;
    }
 
    public void setSorting(SortOrder sorting) {
        this.sorting = sorting;
    }
 
    public UIDataTable getDataTable() {
        return dataTable;
    }
 
    public void setDataTable(UIDataTable dataTable) {
        this.dataTable = dataTable;
    }
 
    public void sort() {
        switch (sorting) {
            case unsorted: {
                sorting = SortOrder.ascending;
                break;
            }
            case ascending: {
                sorting = SortOrder.descending;
                break;
            }
            case descending: {
                sorting = SortOrder.unsorted;
                break;
            }
        }
    }
 
    public UICommandLink createUICommandLink(final FacesContext context, final String value, final String render, final String methodExpression) {
        Class<?>[] clazz = new Class<?>[]{};
        UICommandLink link = (UICommandLink) context.getApplication().createComponent(UICommandLink.COMPONENT_TYPE);
        link.setValue(value);
        link.setRender(render);
        link.setActionExpression(JSFUtils.createMethodExpression(methodExpression, String.class, clazz));
        return link;
    }
 
    public UIColumn createUIColumn(final FacesContext context, final String sortByValueExpression, final Class<?> sortByType, final String sortOrderValueExpression) {
        UIColumn column = (UIColumn) context.getApplication().createComponent(UIColumn.COMPONENT_TYPE);
        column.setValueExpression("sortBy", JSFUtils.createValueExpression(sortByValueExpression, sortByType));
        column.setValueExpression("sortOrder", JSFUtils.createValueExpression(sortOrderValueExpression, SortOrder.class));
        return column;
    }
 
    public HtmlOutputText createHtmlOutputText(final FacesContext context, final String valueValueExpression, Class<?> valueType) {
        HtmlOutputText text = (HtmlOutputText) context.getApplication().createComponent(HtmlOutputText.COMPONENT_TYPE);
        text.setValueExpression("value", JSFUtils.createValueExpression(valueValueExpression, valueType));
        return text;
    }
 
    public List<List<valueholder>> getData() {
        List<List<valueholder>> datax = new ArrayList<List<valueholder>>();
 
        for (int i = 0; i < 10; i++) {
            List<ValueHolder> subelement = new ArrayList<valueholder>();
 
            for (int j = 0; j < 10; j++) {
                ValueHolder vh = new ValueHolder(String.format("Row %1$d Element %2$d", i, j));
 
                List<ValueHolder> sub = new ArrayList<valueholder>();
                for (int k = 0; k < 3; k++) {
                    ValueHolder sube = new ValueHolder("SubElement " + k);
 
                    List<ValueHolder> subsub = new ArrayList<valueholder>();
                    for (int l = 0; l < 10; l++) {
                        ValueHolder subx = new ValueHolder("SubSubElement " + l);
                        subsub.add(subx);
                    }
                    sube.setSubValues(subsub);
                    sub.add(sube);
                }
 
                vh.setSubValues(sub);
                subelement.add(vh);
            }
            datax.add(subelement);
        }
 
        Collections.shuffle(datax);
        return datax;
    }
}

The code above was written before I added more functionality to my jsf-utils project. The new methods would shorten this considerably, but it would still be fairly complex.

Dynamic Table using JSP/JSTL Tags with JSF

JSF/JSTL Dynamic Table
Let me start this example with a warning. If you are using JSP/JSTL tags in your JSF pages, you may encounter very bad behavior. This technique should only be used as a last resort. I will not labor a point. If you don't understand why this is a bad idea, take a look at this post for links: JSF 2.x Tip of the Day: Great Blog Posts Explaining JSTL vs. JSF.
In this example, I will generate the rows and columns using <c:forEach />. This transfers a lot of the complexity to the page and away from the @ManagedBean. Since we are using <c:forEach />, our mechanism for sorting has to change. I used Query jquery.tablesorter.js to allow sorting of the headers.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.org/rich">
    <h:head>
        <title>Dynamic Data Table Design #3</title>
    </h:head>
    <h:body>
        <h1>
Dynamic Data Table Design Design #3</h1>
<p>
            The table is bound to the page backing bean, and is generated dynamically using <code><c:forEach /></code> to create the column elements.
 
            This technique is not recommended unless you understand the limitations of using JSP/JSTL tags with JSF. This is a good working example of the technique.
 
            This table also uses jQuery <i>jquery.tablesorter.js</i> to allow sorting of the headers. Click on the headers to sort.
        </p>
<p>
            Please use the Source and Code links to see the details.
        </p>
<h:form id="form1">
            <rich:dataTable id="dataTable" value="#{dataTable3.customers}" var="customer"
                            rowKeyVar="idx" styleClass="tablesorter">
                <c:forEach items="#{dataTable3.customerByIndex(idx)}" var="cx">
                    <f:facet name="header">
                        <rich:columnGroup>
                            <rich:column colspan="2">
                                <h:outputText value="Customers"/>
                            </rich:column>
                            <rich:column breakRowBefore="true">
                                <h:outputText value="Name"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Phone"/>
                            </rich:column>
                        </rich:columnGroup>
                    </f:facet>
                    <rich:column>
                        <h:outputText value="#{cx.name}"/>
                        <f:facet name="footer">
                            Number of Customers: #{dataTable3.customers.size()}
                        </f:facet>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{cx.phone}"/>
                        <f:facet name="footer"/>
                    </rich:column>
                </c:forEach>
            </rich:dataTable>
            <rich:jQuery/>
            <h:outputScript name="jquery.tablesorter.js" library="js"/>
        </h:form>
        <div style="padding-top: 5px;">
            <a href="#{facesContext.externalContext.requestContextPath}">Index</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/dataTable3.xhtml">Source</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/resources/src/dataTable3.java">Code</a>
        </div>
<script type="text/javascript">
            $(document).ready(function() {
                $('#form1\\:dataTable').tablesorter();
            });
        </script>
    </h:body>
</html>
As you can see we have much simpler code in the page bean. It looks like what you would expect for a normal JSF data table.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.bluelotussoftware.example.richfaces;
 
import com.bluelotussoftware.example.richfaces.model.Customer;
import com.bluelotussoftware.example.richfaces.ssb.CustomerFacade;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
 
/**
 * Proof of Concept #3 Client Side Sorting using jQuery TableSorter 2.0
 *
 * @author John Yeary
 * @version 1.0
 */
@Named
@RequestScoped
public class DataTable3 {
 
    private static final long serialVersionUID = -1246509549850361939L;
    private List<customer> customers;
    @EJB
    private CustomerFacade customerFacade;
 
    public DataTable3() {
        customers = new ArrayList<customer>();
    }
 
    @PostConstruct
    private void init() {
        customers.addAll(customerFacade.findAll());
    }
 
    public List<customer> getCustomers() {
        return customers;
    }
 
    /**
     * This method is used by
     * <code><c:forEach/></code>
     * <code>items</code> attribute which requires a {@code Collection}, or an
     * array to iterate over;
     *
     * @param index the {@link Customer} at the index position in the customer
     * list.
     * @return a list containing a single customer at the specified index.
     */
    public List<customer> customerByIndex(final int index) {
        List<customer> customer = new ArrayList<customer>();
        customer.add(customers.get(index));
        return customer;
    }
}

Complex Data Table Design

Complex Table Design
This table has a lot of really cool features, but the code is complex in the page, and the page bean is relatively simple.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      xmlns:a4j="http://richfaces.org/a4j"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:rich="http://richfaces.org/rich">
    <h:head>
        <title>Complex Data Table Design</title>
    </h:head>
    <h:body>
        <h:form id="form1">
            <h1>
Complex Data Table Design</h1>
<p>
                This example demonstrates how to use the <code><rich:columnGroup /></code> tag, along with Expression Language (EL)
 
                formatting of column output. It also demonstrates how to use AJAX sorting of the customer name.
            </p>
<p>
                Please use the Source and Code links to see the details.
            </p>
<rich:dataTable id="dataTable" value="#{complexDataTable.customers}" var="customer">
                <f:facet name="header">
                    <rich:columnGroup>
                        <rich:column colspan="6">
                            <h:outputText value="Customers"/>
                        </rich:column>
                        <rich:column breakRowBefore="#{true}" rowspan="2" colspan="2"/>
                        <rich:column colspan="2">
                            <h:outputText value="Address"/>
                        </rich:column>
                        <rich:column>
                            <h:outputText value="Contact Information"/>
                        </rich:column>
                        <rich:column rowspan="2">
                            <h:outputText value="Credit Limit" />
                        </rich:column>
                        <rich:column breakRowBefore="#{true}">
                            <h:outputText value="City"/>
                        </rich:column>
                        <rich:column>
                            <h:outputText value="State"/>
                        </rich:column>
                        <rich:column>
                            <h:outputText value="Phone"/>
                        </rich:column>
                    </rich:columnGroup>
                </f:facet>
                <rich:column>
                    <f:facet name="header">
                        <h:outputText value="Sales Code Word"/>
                    </f:facet>
                    <h:outputText rendered="#{customer.creditLimit eq 50000
                                              || customer.creditLimit eq 70000
                                              || customer.creditLimit eq 90000}"
                                  value="Partner"/>
                    <h:outputText rendered="#{customer.creditLimit eq 5000000}"
                                  value="Head Kahuna"/>
                    <h:outputText rendered="#{customer.creditLimit eq 100000}"
                                  value="Big Tuna"/>
                </rich:column>
                <rich:column sortBy="#{customer.name}" sortOrder="#{complexDataTable.sorting}">
                    <f:facet name="header">
                        <a4j:commandLink render="dataTable" value="#{complexDataTable.customerColumnHeader}" action="#{complexDataTable.sort()}"/>
                    </f:facet>
                    <h:outputText value="#{customer.name}"/>
                </rich:column>
                <rich:column>
                    <h:outputText value="#{customer.city}"/>
                </rich:column>
                <rich:column>
                    <h:outputText value="#{customer.state}"/>
                </rich:column>
                <rich:column>
                    <h:outputText value="#{customer.phone}"/>
                </rich:column>
                <rich:column>
                    <h:outputText value="#{complexDataTable.format(customer.creditLimit)}"/>
                </rich:column>
            </rich:dataTable>
        </h:form>
        <div style="padding-top: 5px;">
            <a href="#{facesContext.externalContext.requestContextPath}">Index</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/complexLayout.xhtml">Source</a>
            <a href="#{facesContext.externalContext.requestContextPath}/source/resources/src/complexDataTable.java">Code</a>
        </div>
</h:body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.bluelotussoftware.example.richfaces;
 
import com.bluelotussoftware.example.richfaces.model.Customer;
import com.bluelotussoftware.example.richfaces.ssb.CustomerFacade;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import org.richfaces.component.SortOrder;
 
/**
 * Proof of Concept #4 Complex layout table with server side sorting on single
 * column.
 *
 * @author John Yeary
 * @version 1.0
 */
@Named
@SessionScoped
public class ComplexDataTable implements Serializable {
 
    private static final long serialVersionUID = -5343878110987753773L;
    private List<customer> customers;
    @EJB
    private CustomerFacade customerFacade;
    private SortOrder sorting = SortOrder.unsorted;
 
    public ComplexDataTable() {
        customers = new ArrayList<customer>();
    }
 
    @PostConstruct
    private void init() {
        customers.addAll(customerFacade.findAll());
    }
 
    public List<customer> getCustomers() {
        return Collections.unmodifiableList(customers);
    }
 
    public SortOrder getSorting() {
        return sorting;
    }
 
    /**
     * Sorting enumeration "three position switch": default
     * (unsorted), ascending, and descending.
     */
    public void sort() {
        switch (sorting) {
            case unsorted: {
                sorting = SortOrder.ascending;
                break;
            }
            case ascending: {
                sorting = SortOrder.descending;
                break;
            }
            case descending: {
                sorting = SortOrder.unsorted;
                break;
            }
        }
    }
 
    /**
     * This method returns the customer name header with the specified sort
     * order based on the current {@link SortOrder}.
     *
     * @return customer name header with the specified sort order.
     */
    public String getCustomerColumnHeader() {
        switch (sorting) {
            case unsorted: {
                return "Customer Name";
            }
            default: {
                return "Customer Name (" + sorting + ")";
            }
        }
    }
 
    /**
     * Generates custom formatted USD currency value based on {@code Integer}.
     *
     * @param value The value to be formatted.
     * @return $USD formatted value.
     */
    public String format(Integer value) {
        return String.format("$ %1$,d", value);
    }
}

Conclusion

RichFaces supports complex table designs, and produces nice results. The amount of work required to create dynamic data tables depends on the technique chosen, and limitations on the data being presented. There is no "one good way" to create data tables. Suffice to say that the easiest path should be chosen.

References

Popular Posts