Wednesday, December 11, 2013

Modular JSF applications

Everybody heard about portals which combine single web applications to a big one. A portal software works like mashups - content from several sources is picked up in a single service, mostly displayed in a single web page. A portal software also allows to change user settings, such as language or theme, across all single web applications (independent modules) embedded into the portal software. Furthermore, a single sign-on (SSO) is expected and it should work as well. That means, a single login permits an user to access all embedded web applications. It would be interesting to know if there is a simple and lightweight solution in the JEE world to develop modular JSF 2 applications, to gather and to present them in one portal-like web application automatically. Sure, there are OSGi and complex Portals Bridges providing support for JSR-168 or JSR-286 compliant Portlet development. But fortunately, JSF 2 already provides a simple possibility for that "under the hood". With less effort we can build a portal-like software. All what we need are JSF 2 and CDI - de-facto standard DI framework in the Java world.

The topic of this post is not new. You can find some discussions and ideas in the web. I would only mention here two links. The first one is the article "How-to: Modular Java EE Applications with CDI and PrettyFaces" in the ocpsoft's blog. The second one "Modular Web Apps with JSF2" was presented in the JBoss' wiki. The idea is to create JAR files containing single web applications and to supply them with a main WAR file. The WAR file bundles JARs during build process, e.g. via Maven dependencies. That means, JARs are located in the WAR under WEB-INF/lib/. XHTML files in JARs are placed below /META-INF/resources/ and will be fetched automatically by JSF 2. They are available to JSF as if they were in the /webapp/resources/ folder. You can e.g. include facelets from JARs with a quite common ui:include. This works like a charm. To be able to pick up generic informations about every JSF module at runtime, we also need empty CDI's beans.xml in JARs files. They are located as usually below the META-INF folder.

Now let's start with the coding. But first, let's define the project's structure. You can find a complete implemented example on the GitHub. This is just a proof of concept for a lightweight JSF 2 portal-like implementation with demo web apps (written with JSF 2.2). There are 5 sub-projects

jsftoolkit-jar Base framework providing interfaces and utilities for modular JSF applications.
modA-jar First web application (module A) which depends on jsftoolkit-jar.
modB-jar Second web application (module B) which depends on jsftoolkit-jar.
portal-jar Java part of the portal-like software. It also depends on jsftoolkit-jar.
portal-war Web part of the portal-like software. It aggregates all artefacts and is a deployable WAR.

The base framework (jsftoolkit-jar) has interfaces which should be implemented by every single module. The most important are
/**
 * Interface for modular JSF applications. This interface should be implemented by every module (JSF app.)
 * to allow a seamless integration into a "portal" software.
 */
public interface ModuleDescription {

    /**
     * Provides a human readable name of the module.
     *
     * @return String name of the module
     */
    String getName();

    /**
     * Provides a description of the module.
     *
     * @return String description
     */
    String getDescription();

    /**
     * Provides a module specific prefix. This is a folder below the context where all web pages and
     * resources are located.
     *
     * @return String prefix
     */
    String getPrefix();

    /**
     * Provides a name for a logo image, e.g. "images/logo.png" (used in h:graphicImage).
     *
     * @return String logo name
     */
    String getLogoName();

    /**
     * Provides a start (home) URL to be navigated for the module.
     *
     * @return String URL
     */
    String getUrl();
}

/**
 * Any JSF app. implementing this interface can participate in an unified message handling
 * when all keys and messages are merged to a map and available via "msgs" EL, e.g. as #{msgs['mykey']}.
 */
public interface MessagesProvider {

    /**
     * Returns all mesages (key, text) to the module this interface is implemented for.
     *
     * @param  locale current Locale or null
     * @return Map with message keys and message text.
     */
    Map<String, String> getMessages(Locale locale);
}
Possible implementations for the module A look like as follows:
/**
 * Module specific implementation of the {@link ModuleDescription}.
 */
@ApplicationScoped
@Named
public class ModADescription implements ModuleDescription, Serializable {

    @Inject
    private MessagesProxy msgs;

    @Override
    public String getName() {
        return msgs.get("a.modName");
    }

    @Override
    public String getDescription() {
        return msgs.get("a.modDesc");
    }

    @Override
    public String getPrefix() {
        return "moda";
    }

    @Override
    public String getLogoName() {
        return "images/logo.png";
    }

    @Override
    public String getUrl() {
        return "/moda/views/hello.jsf";
    }
}

/**
 * Module specific implementation of the {@link MessagesProvider}.
 */
@ApplicationScoped
@Named
public class ModAMessages implements MessagesProvider, Serializable {

    @Override
    public Map<String, String> getMessages(Locale locale) {
        return MessageUtils.getMessages(locale, "modA");
    }
}
The prefix of this module is moda. That means, web pages and resources are located under the folder META-INF/resources/moda/. That allows to avoid path collisions (identical paths) across all single web applications. The utility class MessageUtils (from the jsftoolkit-jar) is not exposed here. I will only show the class MessagesProxy. The class MessagesProxy is an application scoped bean giving an access to all available messages in a modular JSF web application. It can be used in Java as well as in XHTML because it implements the Map interface. All found available implementations of the MessagesProvider interface are injected by CDI automatically at runtime. We make use of Instance<MessagesProvider>.
@ApplicationScoped
@Named(value = "msgs")
public class MessagesProxy implements Map<String, String>, Serializable {

    @Inject
    private UserSettingsData userSettingsData;

    @Any
    @Inject
    private Instance<MessagesProvider> messagesProviders;

    /** all cached locale specific messages */
    private Map<Locale, Map<String, String>> msgs = new ConcurrentHashMap<Locale, Map<String, String>>();

    @Override
    public String get(Object key) {
        if (key == null) {
            return null;
        }

        Locale locale = userSettingsData.getLocale();
        Map<String, String> messages = msgs.get(locale);

        if (messages == null) {
            // no messages to current locale are available yet
            messages = new HashMap<String, String>();
            msgs.put(locale, messages);

            // load messages from JSF impl. first
            messages.putAll(MessageUtils.getMessages(locale, MessageUtils.FACES_MESSAGES));

            // load messages from providers in JARs
            for (MessagesProvider messagesProvider : messagesProviders) {
                messages.putAll(messagesProvider.getMessages(locale));
            }
        }

        return messages.get(key);
    }
    
    public String getText(String key) {
        return this.get(key);
    }
    
    public String getText(String key, Object... params) {
        String text = this.get(key);

        if ((text != null) && (params != null)) {
            text = MessageFormat.format(text, params);
        }

        return text;
    }

    public FacesMessage getMessage(FacesMessage.Severity severity, String key, Object... params) {
        String summary = this.get(key);
        String detail = this.get(key + "_detail");

        if ((summary != null) && (params != null)) {
            summary = MessageFormat.format(summary, params);
        }

        if ((detail != null) && (params != null)) {
            detail = MessageFormat.format(detail, params);
        }

        if (summary != null) {
            return new FacesMessage(severity, summary, ((detail != null) ? detail : StringUtils.EMPTY));
        }

        return new FacesMessage(severity, "???" + key + "???", ((detail != null) ? detail : StringUtils.EMPTY));
    }
    
    /////////////////////////////////////////////////////////
    // java.util.Map interface
    /////////////////////////////////////////////////////////

    public int size() {
        throw new UnsupportedOperationException();
    }

    // other methods ...
}
Well. But where the instances of the ModuleDescription are picked up? The logic is in the portal-jar. I use the same mechanism with CDI Instance. CDI will find out all available implementations of the ModuleDescription for us.
/**
 * Collects all available JSF modules.
 */
@ApplicationScoped
@Named
public class PortalModulesFinder implements ModulesFinder {

    @Any
    @Inject
    private Instance<ModuleDescription> moduleDescriptions;

    @Inject
    private MessagesProxy msgs;

    private List<FluidGridItem> modules;

    @Override
    public List<FluidGridItem> getModules() {
        if (modules != null) {
            return modules;
        }

        modules = new ArrayList<FluidGridItem>();

        for (ModuleDescription moduleDescription : moduleDescriptions) {
            modules.add(new FluidGridItem(moduleDescription));
        }

        // sort modules by names alphabetically
        Collections.sort(modules, ModuleDescriptionComparator.getInstance());

        return modules;
    }
}
We are equipped now for creating dynamic tiles in UI which represent entry points to the corresponding web modules.
<pe:fluidGrid id="fluidGrid" value="#{portalModulesFinder.modules}" var="modDesc"
              fitWidth="true" hasImages="true">
    <pe:fluidGridItem styleClass="ui-widget-header">
        <h:panelGrid columns="2" styleClass="modGridEntry" columnClasses="modLogo,modTxt">
            <p:commandLink process="@this" action="#{navigationContext.goToPortlet(modDesc)}">
                <h:graphicImage library="#{modDesc.prefix}" name="#{modDesc.logoName}"/>
            </p:commandLink>

            <h:panelGroup>
                <p:commandLink process="@this" action="#{navigationContext.goToPortlet(modDesc)}">
                    <h:outputText value="#{modDesc.name}" styleClass="linkToPortlet"/>
                </p:commandLink>

                <p/>
                <h:outputText value="#{modDesc.description}"/>
            </h:panelGroup>
        </h:panelGrid>
    </pe:fluidGridItem>
</pe:fluidGrid>
Tiles were created by the component pe:fluidGrid from PrimeFaces Extensions. They are responsive, means they get rearranged when resizing the browser window. The next picture demonstrates how the portal web app looks like after the starting up. It shows two modular demo apps found in the classpath. Every modular web app is displayed as a tile containing a logo, name and short description. Logos and names are clickable. A click redirects to the corresponsing single web app.

As you can see, on the portal's homepage you can switch the current language and the theme. The second picture shows what happens if the user clicks on the module A. The web app for the module A is shown. You can see the Back to Portal button, so a back navigation to the portal's homepage is possible.


Two notes at the end:
  1. It is possible to run every module as a standalone web application. We can check at runtime (again by means of CDI) if the module is within the "portal" or not and use different master templates. A hint is here.
  2. I didn't implement a login screen, but there is no issue with single sign-on because we only have one big application (one WAR). Everything is delivered there.

Monday, November 11, 2013

PrimeFaces Extensions 1.1.0 released. Introduction to flexible grid layout.

We are glad to announce the next release 1.1.0 of PrimeFaces Extensions. Beside fixed issues (full list on GitHub) we added a new JSF component FluidGrid. FluidGrid is a cascading grid layout component. It works by placing elements in optimal position based on available vertical space, sort of like a mason fitting stones in a wall. It is responsive, meaning the grid will reflow as the window size changes. Modern web sites are not imaginable without a responsive design. Good designed web sites look well on every device and with every screen resolution. The basic prerequisite for that is a dynamic fluid layout which fits any browser sizes. The new component FluidGrid allows to set up a nice tight grid with items that have variable heights and widths. Items inside of FluidGrid can have any content: text, images, links, input fields, etc. They can be defined in a static or in a dynamic way as in data iteration components.

Let me show some features to get a first impression what the component can. The first example demonstrates a simple usage with static items. Static items are defined by the tag pe:fluidGridItem which can be placed multiple times below the main tag pe:fluidGrid. Items can have different width / height specified by style classes. The main container for the pe:fluidGrid has the style class pe-fluidgrid and the container of the pe:fluidGridItem has the style class pe-fluidgrid-item.
<pe:fluidGrid hGutter="10" vGutter="10">
    <pe:fluidGridItem styleClass="ui-widget-header">Item 1</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h2">Item 2</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header h3">Item 3</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header h2">Item 4</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header w3">Item 5</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header">Item 6</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header">Item 7</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header h2">Item 8</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h3">Item 9</pe:fluidGridItem>
    <pe:fluidGridItem styleClass="ui-widget-header">Item 10</pe:fluidGridItem>
    ... etc. ...
</pe:fluidGrid>
            
<h:outputStylesheet id="fluidGridCSS">
    .pe-fluidgrid {
        max-width: 900px;
    }
    
    .pe-fluidgrid .pe-fluidgrid-item {
        width:  60px;
        height: 60px;
        border-radius: 5px;
        padding-top: 0.5em;
        text-align: center;
    }
    
    .pe-fluidgrid-item.w2 {width: 130px;}
    .pe-fluidgrid-item.w3 {width: 200px;}    
    .pe-fluidgrid-item.h2 {height: 100px;}
    .pe-fluidgrid-item.h3 {height: 130px;}
</h:outputStylesheet>
In the example we used two attributes hGutter and vGutter for horizontal and vertical space between items. The result look like


After browser resizing all items are rearranged according to the available browser window size. No horizontal scrollbar appears.


Dynamic items can be put in a collection or list of FluidGridItem instances. A FluidGridItem instance contains a data object (of any data types) and an optional property type to match the type attribute in pe:fluidGridItem (see the last example with dynamic form). Dynamic items can be accessed in XHTML via the value attribute and exposed via the var attribute.
<pe:fluidGrid value="#{fluidGridDynamicController.images}" var="image" fitWidth="true" hasImages="true">
    <pe:fluidGridItem>
        <h:graphicImage library="images" name="fluidgrid/#{image.name}"/>
    </pe:fluidGridItem>
</pe:fluidGrid>
The bean looks like
@ManagedBean
@ViewScoped
public class FluidGridDynamicController implements Serializable {

    private List<FluidGridItem> images;

    @PostConstruct
    protected void initialize() {
        images = new ArrayList<FluidGridItem>();

        for (int j = 0; j < 3; j++) {
            for (int i = 1; i <= 10; i++) {
                images.add(new FluidGridItem(new Image(i + ".jpeg")));
            }
        }
    }

    public List<FluidGridItem> getImages() {
        return images;
    }
}
The result and more details can be seen in the showcase (second use case).

The next example demonstrates how to specifies elements which are stamped within the grid layout. These are special layout elements which will not be laid out by FluidGrid. Rather, FluidGrid will layout items below stamped elements. To specify stamped elements, use the stamp attribute which can be any search expression supported by the PrimeFaces Search Expression Framework. The XHTML code looks as follows
<pe:fluidGrid stamp="@(.pe-fluidgrid .stamp)" resizeBound="false" widgetVar="fluidGridWdgt">
    <div class="stamp"></div>
    
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h2"/>
    <pe:fluidGridItem styleClass="ui-widget-header h3"/>
    <pe:fluidGridItem styleClass="ui-widget-header h2"/>
    <pe:fluidGridItem styleClass="ui-widget-header w3"/>
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    <pe:fluidGridItem styleClass="ui-widget-header h2"/>
    <pe:fluidGridItem styleClass="ui-widget-header w2 h3"/>
    <pe:fluidGridItem styleClass="ui-widget-header"/>
    ... etc. ...
</pe:fluidGrid>
More infos can be seen in the showcase (third use case). The next screenshots show a grid layout with a stamped element and without stamping after the button "Toggle stumped" was pressed.


 

Now the last, the most important example, the FluidGrid was implemented for. The example demonstrates how to design a responsive dynamic grid with input fields. This is similar to the DynaForm component in PrimeFaces Extensions, but the grid is not a fixed table in this case. It is responsive! The grid layout with input fields is placed within the center pane in pe:layout. The results before and after resizing the center layout pane are shown below. Try to resize the browser window of this example to see it in action.



The XHTML code looks like
<pe:fluidGrid id="fluidGrid" value="#{fluidGridDynaFormController.items}" var="data"
              resizeBound="false" hGutter="20" widgetVar="fluidGridWdgt">
    <pe:fluidGridItem type="input">
        <div class="dynaFormLabel">
            <p:outputLabel for="txt" value="#{data.label}"/>
        </div>
        <p:inputText id="txt" value="#{data.value}" required="#{data.required}"/>
    </pe:fluidGridItem>
    <pe:fluidGridItem type="select" styleClass="select">
        <div class="dynaFormLabel">
            <p:outputLabel for="menu" value="#{data.label}"/>
        </div>
        <p:selectOneMenu id="menu" value="#{data.value}" required="#{data.required}">
            <f:selectItems value="#{data.selectItems}"/>
        </p:selectOneMenu>
    </pe:fluidGridItem>
    <pe:fluidGridItem type="calendar" styleClass="calendar">
        <div class="dynaFormLabel">
            <p:outputLabel for="cal" value="#{data.label}"/>
        </div>
        <p:calendar id="cal" value="#{data.value}" required="#{data.required}" showOn="button"/>
    </pe:fluidGridItem>
</pe:fluidGrid>
The bean and model classes are straightforward.
@ManagedBean
@ViewScoped
public class FluidGridDynaFormController implements Serializable {

    private List<FluidGridItem> items;

    @PostConstruct
    protected void initialize() {
        items = new ArrayList<FluidGridItem>();

        List<SelectItem> selectItems = new ArrayList<SelectItem>();
        selectItems.add(new SelectItem("1", "Label 1"));
        selectItems.add(new SelectItem("2", "Label 2"));
        selectItems.add(new SelectItem("3", "Label 3"));

        items.add(new FluidGridItem(new DynamicField("First Label", null, true, null), "input"));
        items.add(new FluidGridItem(new DynamicField("Second Label", "Some default value", false, null), "input"));
        items.add(new FluidGridItem(new DynamicField("Third Label", null, false, selectItems), "select"));
        items.add(new FluidGridItem(new DynamicField("Fourth Label", "2", false, selectItems), "select"));
        items.add(new FluidGridItem(new DynamicField("Fifth Label", null, true, null), "calendar"));
        items.add(new FluidGridItem(new DynamicField("Sixth Label", new Date(), false, null), "calendar"));
        items.add(new FluidGridItem(new DynamicField("Seventh Label", null, false, null), "input"));
        items.add(new FluidGridItem(new DynamicField("Eighth Label", null, false, selectItems), "select"));
        items.add(new FluidGridItem(new DynamicField("Ninth Label", null, false, null), "calendar"));
    }

    public List<FluidGridItem> getItems() {
        return items;
    }
}

public class DynamicField implements Serializable {

    private String label;
    private Object value;
    private boolean required;
    private List<SelectItem> selectItems;

    public DynamicField() {
    }

    public DynamicField(String label, Object value, boolean required, List<SelectItem> selectItems) {
        this.label = label;
        this.value = value;
        this.required = required;
        this.selectItems = selectItems;
    }

    // getter / setter methods
    ...
}
Have fun with this release! Tip: it is also worth to check a new example for our JsonConverter. The example shows how to pre-initialize any UI forms on initial page load (GET request) with default values passed in URL. Any data types are supported (also Java Generics!).

Wednesday, October 30, 2013

What is your structure of JEE based web projects?

In this post I will try to discuss diverse organization structures of web based projects, mostly with JSF. The first thought when starting a new project is how to organize my Java packages? Imagine, you develop a web based user and group management system. A long time I used the following structure of Java packages which separates bean classes from model classes (model classes are sometimes called view helpers).


This is a good layout in my optinion, but it is not good enough if you have big projects. Why? Although some bean and model classes belong together, they are located far from each other. You have to navigate and scroll in your IDE between the bean and model packages. This can steal some time. Over the years I have realized that a grouping of classes according to their logical / semantic meaning may looks better. That means, model packages and classes are located in the same superordinated packages as beans they belong to. Common used beans and model classes can be placed in an extra package, say e.g. common.


But be careful here. Some developers prefer to blow up the count of beans. If you follow strict the MVC-pattern, you need backing beans, controller beans and view interfaces, beans. Backing beans take responsibility for component, value binding and delegation of events. They delegate the business logic's execution to the controller beans. Controller beans communicate with the underlying backend system(s). This fine-tuned separation of concepts increases the testability of small software pieces, but it leads to many classes and can complicate the project's structure under some circumstances.


What is about web pages? Here there are more or less the same two approaches. The first one follows the approach described e.g. in this article. There are three main folders: templates, views and sections. Templates are facelets templates used on (almost) every page. Views are full pages. They are bound to URLs in browsers. Views use templates. Sections are small pieces on a page. Sections are included by views (think on ui:include). The structure looks as follows:


You also see here a folder shared which contains some common used stuff. Pages for users and groups include a common section dialogs.xhtml. It is placed below /sections/shared/usergroups. As I aleady said, I realized that the grouping of pages and sections, when they belong together, could be a better approach. So, the next structure has two main folders pages and templates. Sections are located under includes in the same superordinated folders as pages which include them.


The grouping looks more efficient now in terms of IDE's navigation. It is also clear what parts belongs together. In the last picture you also see that the folder usergroups contains sub-folders users, groups and the common includes shared on different pages in the context of user / group management.

What is your preferred structure? Share your thoughts. Any feedback is welcome.

Monday, October 14, 2013

Hot Deployment with IntelliJ IDEA

Recently there was a voting in the PrimeFaces forum PrimeFaces IDE Poll for the best IDE used to develop PrimeFaces applications. The most people voted for NetBeans. NetBeans and Eclipse are free IDEs. My favorite IDE IntelliJ IDEA Ultimate is not free and I think this is a reason why there are less people using it on the job. I thought it would be a good idea to show some nice features in IntelliJ. This post will demonstrate how to configure IntelliJ for the hot deployment when developing web projects. Hot deployment means you can change web resources or classes at runtime and the changes will be recognized immediately without server restart. An useful feature during development process. In the example, I will take the application server JBoss 7, but any other server can be configured in the same manner as well. A good introduction to IntelliJ and JBoss there is in the IntelliJ Wiki. For a general information regarding working with application servers in IntelliJ please refer this help page.

We assume, the application server is already configured. The next step is to configure an exploded WAR artifact for the web project. An exploded WAR is a decompressed web application archive, a directory structure that is ready for deployment on an application server. IntelliJ creates it automatically, but nevertheless, you should go to File --> Project Structure --> Artefacts and ensure that the exploded web application ends with the extension .war. If you use Maven, the exploded WAR is created below the target folder. More info on the help page.


You should also check if the Hot Swap is enabled. Go to the File --> Settings --> Debugger --> HotSwap and ensure that all checkboxes are checked and the radio button "Reload classes after compilation" is set to "Always".


As next step, click on the "Edit Configurations..." and go to the configured server. In the "Run/Debug Configurations" dialog, select "Update resources" in the drop-down "On frame deactivation". That means, when you switch to the browser, IntelliJ will copy resource files (JavaScript, CSS) from the source location (src/main/webapp) to the directory where it builds the exploded WAR to deploy.


Hot deployment for changed Java classes is resticted by JVM. E.g. the hot deployment for classes with changed method signature(s) doesn't work. But if you changed a method body, it will work. So, if you don't use JRebel which allows the hot deployment for classes being structurally modified, you can still rely on IntelliJ. All what you need to do for changes in Java classes is to recompile them. For that, you can go to the menu Build --> Compile or simple hit Ctrl + Shift + F9. After that, go to the browser and refresh the page to see changes.


Thursday, October 10, 2013

Pass JavaScript function via JSON. Pitfall and solution.

JSON is a lightweight data-interchange format. It is well readable and writable for humans and it is easy for machines to parse and generate. The most of JavaScript libraries, frameworks, plugins and whatever are configurable by options in JSON format. Sometimes you have to parse a JSON string (text) to get a real JavaScript object. For instance, sometimes you have to read the whole JSON structure from a file and make it available on the client-side as an JavaScript object. The JSON text should be well-formed. Passing a malformed JSON text results in a JavaScript exception being thrown.

What does "well-formed" mean? A well-formed JSON structure consists of data types string, number, object, array, boolean or null. Other data types are not allowed. An example:
{
    "name": "Max",
    "address": {
        "street": "Big Avenue 5",
        "zipcode": 12345,
        "country": "USA"
    },
    "age": 35,
    "married": true,
    "children": ["Mike", "John"]
}
You see here string values for keys "name", "street" and "country", number values for "zipcode" and "age", boolean value for "married", object for "address" and array for "children". But what is about JavaScript functions? Some scripts allow to pass functions as values. For instance as in some chart libraries:
{
    "margin": "2px",
    "colors": ["#FFFFFF", "CCCCCC"],
    "labelFormatter": function(value, axis) {return value + ' degree';}
}
If you try to parse this JSON text, you will face an error because function(value, axis) {return value + ' degree';} is not allowed here. Try to put this structure into this online JSON viewer to see that JSON format doesn't accept functions. So, the idea is to pass the function as string:
{
    "borderWidth": "2px",
    "colors": ["#FFFFFF", "CCCCCC"],
    "labelFormatter": "function(value, axis) {return value + ' degree';}"
}
This syntax can be parsed. But we have another problem now. We have to make a real JavaScript function from its string representation. After trying a lot I found an easy solution. Normally, to parse a well-formed JSON string and return the resulting JavaScript object, you can use a native JSON.parse(...) method (implemented in JavaScript 1.7), JSON.parse(...) from json2.js written by Douglas Crockford or the jQuery's $.parseJSON(...). The jQuery's method only expects one parameter, the JSON text: $.parseJSON(jsonText). So, you can not modify any values with it. The first two mentioned methods have two parameters
 
JSON.parse(text, reviver)
 
The second parameter is optional, but exactly this parameter will help us! reviver is a function, prescribes how the value originally produced by parsing is transformed, before being returned. More precise: the reviver function can filter and transform the results. It receives each of the keys and values, and its return value is used instead of the original value. If it returns what it received, then the structure is not modified. If it returns undefined then the member is deleted. An example:
var transformed = JSON.parse('{"p": 5}', function(k, v) {if (k === "") return v; return v * 2;});

// The object transformed is {p: 10}
In our case, the trick is to use eval in the reviver to replace the string value by the corresponding function object:
var jsonText = ".....";  // got from any source

var jsonTransformed = JSON.parse(jsonText, function (key, value) {
    if (value && (typeof value === 'string') && value.indexOf("function") === 0) {
        // we can only pass a function as string in JSON ==> doing a real function
        eval("var jsFunc = " + value);
        return jsFunc;
    }
         
    return value;
});
I know, eval is evil, but it doesn't hurt here. Well, who doesn't like eval there is another solution without it.
var jsonTransformed = JSON.parse(jsonText, function (key, value) {
    if (value && (typeof value === 'string') && value.indexOf("function") === 0) {
        // we can only pass a function as string in JSON ==> doing a real function
        var jsFunc = new Function('return ' + value)();
        return jsFunc;
    }
         
    return value;
});

Friday, October 4, 2013

PrimeFaces Extensions: drag-and-drop feature in Timeline

Since the last release of the PrimeFaces Extensions, the Timeline component allows dragging items from the outside (an external list, etc.) and dropping them onto the Timeline. The picture shows the dragging / dropping process.


When an item is dragged and dropped, an event with an end date will be created. The end date is the start date + 10% of the timeline width. This default algorithm fits the most use cases. Tip: if events are editable, you can adjust the start / end date later by double clicking on an event.

To activate the built-in drag-and-drop feature, simple add p:ajax with event="drop" to the timeline tag.
<div style="float:left;">
    <strong>Drag and drop events</strong>
    <p/>
    <p:dataList id="eventsList" value="#{dndTimelineController.events}"
                var="event" itemType="circle">
        <h:panelGroup id="eventBox" layout="box" style="z-index:9999; cursor:move;">
            #{event.name}
        </h:panelGroup>
        
        <p:draggable for="eventBox" revert="true" helper="clone" cursor="move"/>
    </p:dataList>
</div>
    
<pe:timeline id="timeline" value="#{dndTimelineController.model}" var="event"
             editable="true" eventMargin="10" eventMarginAxis="0" minHeight="250"
             start="#{dndTimelineController.start}" end="#{dndTimelineController.end}"
             timeZone="#{dndTimelineController.localTimeZone}"
             style="margin-left:135px;" snapEvents="false" showNavigation="true"
             dropActiveStyleClass="ui-state-highlight" dropHoverStyleClass="ui-state-hover">
    <p:ajax event="drop" listener="#{dndTimelineController.onDrop}" global="false" update="eventsList"/>
    
    <h:outputText value="#{event.name}"/>
    ...  other properties can be displayed too
</pe:timeline>
In this example, the objects in the list (on the left side) have properties name, start date, end date.
public class Event implements Serializable {

    private String name;
    private Date start;
    private Date end;

    // constructors, getter / setter
    ...

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Event event = (Event) o;

        if (name != null ? !name.equals(event.name) : event.name != null) {
     return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }
}
The bean class defines the AJAX listener onDrop. The listener gets an instance of the class TimelineDragDropEvent. Besides start / end date and group, this event object also contains a client ID of the dragged component and dragged model object if draggable item is within a data iteration component.
public class DndTimelineController implements Serializable {

    private TimelineModel model;
    private TimeZone localTimeZone = TimeZone.getTimeZone("Europe/Berlin");
    private List<Event> events = new ArrayList<Event>();

    @PostConstruct
    protected void initialize() {
        // create timeline model
        model = new TimelineModel();

        // create available events for drag-&-drop
        for (int i = 1; i <= 13; i++) {
            events.add(new Event("Event " + i));
        }
    }

    public void onDrop(TimelineDragDropEvent e) {
        // get dragged model object (event class) if draggable item is within a data iteration component,
        // update event's start / end dates.
        Event dndEvent = (Event) e.getData();
        dndEvent.setStart(e.getStartDate());
        dndEvent.setEnd(e.getEndDate());

        // create a timeline event (not editable)
        TimelineEvent event = new TimelineEvent(dndEvent, e.getStartDate(), e.getEndDate(), false, e.getGroup());

        // add a new event
        TimelineUpdater timelineUpdater = TimelineUpdater.getCurrentInstance(":mainForm:timeline");
        model.add(event, timelineUpdater);

        // remove from the list of all events
        events.remove(dndEvent);

        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO,
                                            "The " + dndEvent.getName() + " was added", null);
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

    public TimelineModel getModel() {
        return model;
    }

    public TimeZone getLocalTimeZone() {
        return localTimeZone;
    }

    public List<Event> getEvents() {
        return events;
    }

    public Date getStart() {
        return start;
    }

    public Date getEnd() {
        return end;
    }
}
Please also consider the drag-and-drop related attributes dropHoverStyleClass, dropActiveStyleClass, dropAccept, dropScope. They are similar to corresponding attributes in p:droppable. There is only one difference - the datasource attribute is not needed. p:droppable in PrimeFaces has this attribute which represents an ID of an UIData component to connect with. I have never understood why we need this. It is possible to get the UIData component with a simple trick. The reading below is for advanced developers.

The drop callback from the jQuery Droppable gets an ui object with a reference to the draggable element. So we can look for a closest DOM element which is a container for an UIData component.
var params = [];

// Check if draggable is within a data iteration component.
// Note for PrimeFaces team: an additional unified style class ".ui-data" for all UIData components would be welcome here!
var uiData = ui.draggable.closest(".ui-datatable, .ui-datagrid, .ui-datalist, .ui-carousel");
if (uiData.length > 0) {
    params.push({
        name: this.id + '_uiDataId',
        value: uiData.attr('id')
    });
}

params.push({
    name: this.id + '_dragId',
    value: ui.draggable.attr('id')
});

// call the drop listener
this.getBehavior("drop").call(this, evt, {params: params, ...});
In the component itself, the current dragged object is extracted by this snippet
FacesContext context = FacesContext.getCurrentInstance();
Map<String, String> params = context.getExternalContext().getRequestParameterMap();
String clientId = this.getClientId(context);

Object data = null;
String dragId = params.get(clientId + "_dragId");
String uiDataId = params.get(clientId + "_uiDataId");

if (dragId != null && uiDataId != null) {
    // draggable is within a data iteration component
    UIDataContextCallback contextCallback = new UIDataContextCallback(dragId);
    context.getViewRoot().invokeOnComponent(context, uiDataId, contextCallback);
    data = contextCallback.getData();
}

TimelineDragDropEvent te = new TimelineDragDropEvent(this, behaviorEvent.getBehavior(), ... dragId, data);
The JSF standard method invokeOnComponent does the job. Now the data object is available in TimelineDragDropEvent. The class UIDataContextCallback is a simple implementation of the JSF ContextCallback interface.
public class UIDataContextCallback implements ContextCallback {

    private String dragId;
    private Object data;

    public UIDataContextCallback(String dragId) {
        this.dragId = dragId;
    }

    public void invokeContextCallback(FacesContext fc, UIComponent component) {
        UIData uiData = (UIData) component;
        String[] idTokens = dragId.split(String.valueOf(UINamingContainer.getSeparatorChar(fc)));
        int rowIndex = Integer.parseInt(idTokens[idTokens.length - 2]);
        uiData.setRowIndex(rowIndex);
        data = uiData.getRowData();
        uiData.setRowIndex(-1);
    }

    public Object getData() {
        return data;
    }
}

Thursday, October 3, 2013

PrimeFaces Extensions 1.0.0 released

We are glad to announce the final release 1.0.0 of PrimeFaces Extensions. The full list of closed issues is on the GitHub. This release is fully compatible with the PrimeFaces 4.0 which was also released today.

Now both, PrimeFaces and PrimeFaces Extensions are in the Maven central repo. See Getting Started how to use it.

Thanks to all for contribution.

Tuesday, September 17, 2013

Timeline component features lazy loading

The first release candidate 1.0.0.RC1 of the PrimeFaces Extensions brought one new of two planned features for the Timeline component. This component supports lazy loading of events during moving / zooming in the timeline. This makes sense when event's loading is time-consuming. Unlike Schedule component in the PrimeFaces it didn't introduce a new LazyTimelineModel. The model class stays the same - TimelineModel. Events are loaded lazy when p:ajax with event="lazyload" is attached to the pe:timeline tag. This new AJAX behaviour has several advantages in comparison to the approach with the "lazy model". It is consistent with other AJAX events such as add, delete, rangechanged, etc. You can disable / enable the "lazyload" AJAX behavior at runtime and execute a custom JS script on start / complete. Example:
<p:ajax event="lazyload" disabled="#{lazyTimelineController.disabled}"
            listener="#{lazyTimelineController.onLazyLoad}"  
            onstart="PF('dialogWidget').show()"   
            oncomplete="PF('dialogWidget').hide()"/>
And of course you can control exactly what should be executed and updated (process / update attributes). To understand how this new feature works (before posting a lot of code :-)) I sketched one diagram. Please read from top to down.


On intial page load, only events in the visible time range should be lazy loaded. After moving to the right or left direction, area on the right or left side is coming into the view. Only events in this new displayed time range should be loaded. Time range with already loaded events is cached internally (read line in the diagram). When you zoom out now, you will probably have two time ranges the events should be loaded for. This is demonstrated in the 4. use case. When you zoom in, no AJAX event for lazy loading is sent. It is very smart! As you can see, the "lazyload" listener is not invoked again when the visible time range (incl. some hidden ranges defined by preloadFactor) already has lazy loaded events.

What is preloadFactor? The preloadFactor attribute of the pe:timeline is a positive float value or 0 (default). When the lazy loading feature is active, the calculated time range for preloading will be multiplicated by the preload factor. The result of this multiplication specifies the additional time range which will be considered for the preloading during moving / zooming too. For example, if the calculated time range for preloading is 5 days and the preload factor is 0.2, the result is 5 * 0.2 = 1 day. That means, 1 day backwards and / or 1 day onwards will be added to the original calculated time range. The event's area to be preloaded is wider then. This helps to avoid frequently, time-consuming fetching of events. Note: the preload factor in the diagram above was 0.

Let me show the code now. The code is taken from this live example of the deployed showcase.
<div id="loadingText" style="font-weight:bold; margin:-5px 0 5px 0; visibility:hidden;">Loading ...</div>  
              
<pe:timeline id="timeline" value="#{lazyTimelineController.model}"  
             preloadFactor="#{lazyTimelineController.preloadFactor}"  
             zoomMax="#{lazyTimelineController.zoomMax}"  
             minHeight="170" showNavigation="true">  
    <p:ajax event="lazyload" update="@none" listener="#{lazyTimelineController.onLazyLoad}"  
            onstart="$('#loadingText').css('visibility', 'visible')"   
            oncomplete="$('#loadingText').css('visibility', 'hidden')"/>  
</pe:timeline>
You see a hidden "Loading ..." text and the timeline tag. The text is shown when a "lazyload" AJAX request is sent and gets hidden when the response is back. The bean class LazyTimelineController looks as follows
@ManagedBean
@ViewScoped
public class LazyTimelineController implements Serializable {

   private TimelineModel model;

   private float preloadFactor = 0;
   private long zoomMax;

   @PostConstruct
   protected void initialize() {
      // create empty model
      model = new TimelineModel();

      // about five months in milliseconds for zoomMax
      // this can help to avoid a long loading of events when zooming out to wide time ranges
      zoomMax = 1000L * 60 * 60 * 24 * 31 * 5;
   }

   public TimelineModel getModel() {
      return model;
   }

   public void onLazyLoad(TimelineLazyLoadEvent e) {
      try {
          // simulate time-consuming loading before adding new events
          Thread.sleep((long) (1000 * Math.random() + 100));
      } catch (Exception ex) {
          // ignore
      }

      TimelineUpdater timelineUpdater = TimelineUpdater.getCurrentInstance(":mainForm:timeline");

      Date startDate = e.getStartDateFirst(); // alias getStartDate() can be used too
      Date endDate = e.getEndDateFirst(); // alias getEndDate() can be used too

      // fetch events for the first time range
      generateRandomEvents(startDate, endDate, timelineUpdater);

      if (e.hasTwoRanges()) {
          // zooming out ==> fetch events for the second time range
          generateRandomEvents(e.getStartDateSecond(), e.getEndDateSecond(), timelineUpdater);
      }
   }

   private void generateRandomEvents(Date startDate, Date endDate, TimelineUpdater timelineUpdater) {
      Calendar cal = Calendar.getInstance();
      Date curDate = startDate;
      Random rnd = new Random();

      while (curDate.before(endDate)) {
          // create events in the given time range
          if (rnd.nextBoolean()) {
              // event with only one date
              model.add(new TimelineEvent("Event " + RandomStringUtils.randomNumeric(5), curDate), timelineUpdater);
          } else {
              // event with start and end dates
              cal.setTimeInMillis(curDate.getTime());
              cal.add(Calendar.HOUR, 18);
              model.add(new TimelineEvent("Event " + RandomStringUtils.randomNumeric(5), curDate, cal.getTime()),
                        timelineUpdater);
          }

          cal.setTimeInMillis(curDate.getTime());
          cal.add(Calendar.HOUR, 24);

          curDate = cal.getTime();
      }
   }

   public void clearTimeline() {
      // clear Timeline, so that it can be loaded again with a new preload factor
      model.clear();
   }

   public void setPreloadFactor(float preloadFactor) {
      this.preloadFactor = preloadFactor;
   }

   public float getPreloadFactor() {
      return preloadFactor;
   }

   public long getZoomMax() {
      return zoomMax;
   }
}
The listener onLazyLoad gets an event object TimelineLazyLoadEvent. The TimelineLazyLoadEvent contains one or two time ranges the events should be loaded for. Two times ranges occur when you zoom out the timeline (as in the screenshot at the end of this post). If you know these time ranges (start / end time), you can fetch events from the database or whatever. Server-side added events can be automatically updated in the UI. This happens as usally by TimelineUpdater: model.add(new TimelineEvent(...), timelineUpdater).

I hope the code is self-explained :-).


Monday, September 16, 2013

PrimeFaces Extensions 1.0.0.RC1 released

We are glad to announce the first release candidate 1.0.0.RC1 of PrimeFaces Extensions. This release is fully compatible with the PrimeFaces 4.0.RC1 (codename SENTINEL). Once the PrimeFaces 4.0 final is released, we will also release the 1.0.0 final version.

This is a big step forwards. The community can use this release with JSF 2.0 and JSF 2.2. The full list of closed issues is available on the GitHub.

Among other changes please consider the removing of ResetInput component since this functionality is now available in the PrimeFaces 4.0 and JSF 2.2. CKEditor was updated to the version 4, the Exporter and BlockUI components got many improvements. I have already blogged about some significant changes in BlockUI. The next post will be about new features in the Timeline component. It is e.g. capable to load events lazy.

Stay tuned and have fun!

Tuesday, September 3, 2013

New features in BlockUI of PrimeFaces Extensions

PrimeFaces users were worried if we will keep the BlockUI component in the PrimeFaces Extensions. Yes, we will keep it. It was done compatible with the upcoming PrimeFaces 4.0 and got some updates / new features.

The main features:
  • Page blocking. The entire page can be blocked if you don't define the target attribute.
  • Non-centered message. A non-centered message is defined by the css and centerX / centerY attributes. Furthermore, you can use the cssOverlay attribute to style the overlay (half-transparent mask).
  • Auto-unblocking. The timeout attribute is helpful for auto-unblocking. It defines time in millis to wait before auto-unblocking.

All featutes are demonstrated in the following code snippet and the screenshot
<p:commandButton value="Block this page!" type="button"
                 onclick="PF('blockUIWidget').block()"/>

<pe:blockUI widgetVar="blockUIWidget"
            css="{top: '10px', left: '', right: '10px', cursor: 'wait'}"
            cssOverlay="{backgroundColor: 'red'}"
            timeout="2000"
            centerY="false">
    <h:panelGrid columns="2">
        <h:graphicImage library="images" name="ajax-loader1.gif"
                        style="margin-right: 12px; vertical-align: middle;"/>
        <h:outputText value="This is a non-centered message. Please wait..." style="white-space: nowrap;"/>
    </h:panelGrid>
</pe:blockUI>


 Have fun!

Sunday, August 18, 2013

Simple and lightweight pool implementation

Object pools are containers which contain a specified amount of objects. When an object is taken from the pool, it is not available in the pool until it is put back. Objects in the pool have a lifecycle: creation, validation, destroying, etc. A pool helps to manage available resources in a better way. There are many using examples. Especially in application servers there are data source pools, thread pools, etc. Pools should be used in cases such as
  • High-frequency using of the same objects
  • Objects are very big and consume much memory
  • Objects need much time for initialization
  • Objects use massive IO operations (Streams, Sockets, DB, etc.)
  • Objects are not thread-safe
When I looked for a pool implementation for one of my Java projects, I found that many people reference the Apache Commons Pool. Apache Commons Pool provides an object-pooling API. There are interfaces ObjectPool, ObjectPoolFactory, PoolableObjectFactory and many implementations. A pool provides methods addObject, borrowObject, invalidateObject, returnObject to add, take, remove and return back objects. PoolableObjectFactory defines the behavior of objects within a pool and provides various callbacks for pool's operations.

After looking into the implementation details I found that Apache Commons Pool is not a lightweight implementation which is an overhead for my purposes. Furthermore, it uses the old Java's keyword synchronized for a lot of methods which is not recommended for using. Java 5 introduced Executor framework for Java concurrency (multi-threading). The Executor framework is preferable here. I decided to implement a simple and lightweight pool which I would like to present here. It is only one Java class. I think it is enough if you don't need callbacks and other advanced stuff. I created a project easy-pool on GitHub.

The pool implementation is based on ConcurrentLinkedQueue from the java.util.concurrent package. ConcurrentLinkedQueue is a thread-safe queue based on linked nodes. This queue orders elements by FIFO principle (first-in-first-out). My implementation for a generic pool looks as follows
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public abstract class ObjectPool<T>
{
    private ConcurrentLinkedQueue<T> pool;

    private ScheduledExecutorService executorService;

    /**
     * Creates the pool.
     *
     * @param minIdle minimum number of objects residing in the pool
     */
    public ObjectPool(final int minIdle) {
        // initialize pool
        initialize(minIdle);
    }

    /**
     * Creates the pool.
     *
     * @param minIdle            minimum number of objects residing in the pool
     * @param maxIdle            maximum number of objects residing in the pool
     * @param validationInterval time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread.
     *                           When the number of objects is less than minIdle, missing instances will be created.
     *                           When the number of objects is greater than maxIdle, too many instances will be removed.
     */
    public ObjectPool(final int minIdle, final int maxIdle, final long validationInterval) {
        // initialize pool
        initialize(minIdle);

        // check pool conditions in a separate thread
        executorService = Executors.newSingleThreadScheduledExecutor();
        executorService.scheduleWithFixedDelay(new Runnable()
        {
            @Override
            public void run() {
                int size = pool.size();
                if (size < minIdle) {
                    int sizeToBeAdded = minIdle - size;
                    for (int i = 0; i < sizeToBeAdded; i++) {
                        pool.add(createObject());
                    }
                } else if (size > maxIdle) {
                    int sizeToBeRemoved = size - maxIdle;
                    for (int i = 0; i < sizeToBeRemoved; i++) {
                        pool.poll();
                    }
                }
            }
        }, validationInterval, validationInterval, TimeUnit.SECONDS);
    }

    /**
     * Gets the next free object from the pool. If the pool doesn't contain any objects,
     * a new object will be created and given to the caller of this method back.
     *
     * @return T borrowed object
     */
    public T borrowObject() {
        T object;
        if ((object = pool.poll()) == null) {
            object = createObject();
        }

        return object;
    }

    /**
     * Returns object back to the pool.
     *
     * @param object object to be returned
     */
    public void returnObject(T object) {
        if (object == null) {
            return;
        }

        this.pool.offer(object);
    }

    /**
     * Shutdown this pool.
     */
    public void shutdown() {
        if (executorService != null) {
            executorService.shutdown();
        }
    }

    /**
     * Creates a new object.
     *
     * @return T new object
     */
    protected abstract T createObject();

    private void initialize(final int minIdle) {
        pool = new ConcurrentLinkedQueue<T>();

        for (int i = 0; i < minIdle; i++) {
            pool.add(createObject());
        }
    }
}
The abstract class ObjectPool provides two main methods: borrowObject to get the next free object from the pool and returnObject to return the borrowed object back to the pool. If the pool doesn't contain any objects, a new object will be created and given back to the caller of the method borrowObject. The object creation happens in the method createObject. Any class which extends the abstract class ObjectPool only needs to implement this method and the pool is ready to use. As you can see I also utilizes ScheduledExecutorService from the java.util.concurrent package. What it is good for? You can specifies minimum and maximum number of objects residing in the pool. ScheduledExecutorService starts a special task in a separate thread and observes periodical in a specified time (parameter validationInterval) the minimum and maximum number of objects in the pool. When the number of objects is less than the minimum, missing instances will be created. When the number of objects is greater than the maximum, too many instances will be removed. This is sometimes useful for the balance of memory consuming objects in the pool and more.

Let's implement test classes to show using of a concrete pool. First, we need a class representing objects in the pool which simulates a time-consuming process. This class, called ExportingProcess, needs some time to be instantiated.
public class ExportingProcess {

    private String location;

    private long processNo = 0;

    public ExportingProcess(String location, long processNo) {
        this.location = location;
        this.processNo = processNo;

        // doing some time expensive calls / tasks
        // ...

        // for-loop is just for simulation
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
        }

        System.out.println("Object with process no. " + processNo + " was created");
    }

    public String getLocation() {
        return location;
    }

    public long getProcessNo() {
        return processNo;
    }
}
The second class implements the Runnable interface and simulates some task doing by a thread. In the run method, we borrow an instance of ExportingProcess and return it later back to the pool.
public class ExportingTask implements Runnable {

    private ObjectPool<ExportingProcess> pool;

    private int threadNo;

    public ExportingTask(ObjectPool<ExportingProcess> pool, int threadNo) {
        this.pool = pool;
        this.threadNo = threadNo;
    }

    public void run() {
        // get an object from the pool
        ExportingProcess exportingProcess = pool.borrowObject();

        System.out.println("Thread " + threadNo + 
                ": Object with process no. " + exportingProcess.getProcessNo() + " was borrowed");

        // do something
        // ...

        // for-loop is just for simulation
        for (int i = 0; i < 100000; i++) {
        }

        // return ExportingProcess instance back to the pool
        pool.returnObject(exportingProcess);

        System.out.println("Thread " + threadNo + 
                ": Object with process no. " + exportingProcess.getProcessNo() + " was returned");
    }
}
Now, in the JUnit class TestObjectPool, we create a pool of objects of type ExportingProcess. This occurs by means of new ObjectPool<ExportingProcess>(4, 10, 5). Parameters are described in the comments below.
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class TestObjectPool
{
    private ObjectPool<ExportingProcess> pool;

    private AtomicLong processNo = new AtomicLong(0);

    @Before
    public void setUp() {
        // Create a pool of objects of type ExportingProcess. Parameters:
        // 1) Minimum number of special ExportingProcess instances residing in the pool = 4
        // 2) Maximum number of special ExportingProcess instances residing in the pool = 10
        // 3) Time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread = 5.
        //    When the number of ExportingProcess instances is less than minIdle, missing instances will be created.
        //    When the number of ExportingProcess instances is greater than maxIdle, too many instances will be removed.
        //    If the validation interval is negative, no periodical checking of minIdle / maxIdle conditions
        //    in a separate thread take place. These boundaries are ignored then.
        pool = new ObjectPool<ExportingProcess>(4, 10, 5)
        {
            protected ExportingProcess createObject() {
                // create a test object which takes some time for creation
                return new ExportingProcess("/home/temp/", processNo.incrementAndGet());
            }
        };
    }

    @After
    public void tearDown() {
        pool.shutdown();
    }

    @Test
    public void testObjectPool() {
        ExecutorService executor = Executors.newFixedThreadPool(8);

        // execute 8 tasks in separate threads
        executor.execute(new ExportingTask(pool, 1));
        executor.execute(new ExportingTask(pool, 2));
        executor.execute(new ExportingTask(pool, 3));
        executor.execute(new ExportingTask(pool, 4));
        executor.execute(new ExportingTask(pool, 5));
        executor.execute(new ExportingTask(pool, 6));
        executor.execute(new ExportingTask(pool, 7));
        executor.execute(new ExportingTask(pool, 8));

        executor.shutdown();
        try {
            executor.awaitTermination(30, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
A test output looks like
Object with process no. 1 was created
Object with process no. 2 was created
Object with process no. 3 was created
Object with process no. 4 was created
Thread 2: Object with process no. 2 was borrowed
Thread 1: Object with process no. 1 was borrowed
Thread 2: Object with process no. 2 was returned
Thread 3: Object with process no. 3 was borrowed
Thread 4: Object with process no. 4 was borrowed
Thread 1: Object with process no. 1 was returned
Thread 4: Object with process no. 4 was returned
Thread 8: Object with process no. 4 was borrowed
Thread 5: Object with process no. 1 was borrowed
Thread 7: Object with process no. 3 was borrowed
Thread 3: Object with process no. 3 was returned
Thread 6: Object with process no. 2 was borrowed
Thread 7: Object with process no. 3 was returned
Thread 5: Object with process no. 1 was returned
Thread 8: Object with process no. 4 was returned
Thread 6: Object with process no. 2 was returned
As can be seen, the first thread accessing the pool creates the minimum objects residing in the pool. Running this test class multiple times, we can discover that sometimes 4 objects get borrowed each after other and a new 5. object will be created in the pool. All test classes are available in the GitHub.

Friday, July 19, 2013

Monitor full page, non AJAX, requests to be notified

Recently, working on new charts and chart "exporting service" in JSF, I've faced a quite common problem. When you execute a long-running task (action), you would like to show a status "Please wait ..." dialog on start and close this dialog at the end, when the response arrives. This is not a problem for AJAX requests, but it is problematic for non AJAX requests which stream some binary content to the browser. To solve this issue, we can use the same technique as for instance the FileDownload component in PrimeFaces uses. We can set a special cookie in response and check this cookie periodically on the client-side if it is set. When this cookie is set, we can close the opened before dialog. The cookie can be set in JSF as
// set cookie to be able to ask it and close status dialog for example
FacesContext.getCurrentInstance().getExternalContext().addResponseCookie(
             "cookie.chart.exporting", "true", Collections.<String, Object>emptyMap());
Non AJAX button executes an JavaScript function, say monitorExporting, with two parameters which represent another JavaScript functions to be called at the beginning and the end of the request / response lifecycle.
<p:commandButton value="Export to PNG" ajax="false" action="#{combiChartController.exportToPng}"
             onclick="monitorExporting(start, stop)"/>
PrimeFaces already provides methods to check if cookies are enabled, to get and delete them. So, we can write
function monitorExporting(start, complete) {
    if(PrimeFaces.cookiesEnabled()) {
        if(start) {
           start();
        }
            
        window.chartExportingMonitor = setInterval(function() {
            var exportingComplete = PrimeFaces.getCookie('cookie.chart.exporting');
 
            if(exportingComplete === 'true') {
                if(complete) {
                    complete();
                }
                     
                clearInterval(window.chartExportingMonitor);
                PrimeFaces.setCookie('cookie.chart.exporting', null);
            }
        }, 150);
    }
}
The cookie is asked periodically with the setInterval(...). The function start shows the "Please wait ..." dialog and the function stop closes it.
<script type="text/javascript">
/* <![CDATA[ */
    function start() {
        statusDialog.show();
    }

    function stop() {
        statusDialog.hide();
    }
/* ]]> */
</script>
If cookies are disabled, nothing is shown of course, but it is normally a rare case.

Tuesday, July 2, 2013

Proper decoding of URL parameters on the server-side in JBoss

I spent many hours today to figure out how to force a proper decoding of encoded characters in JSF applications running on JBoss (using JBoss 7 Final). The problem occurs when you have e.g. chinese characters passed through URL. Assume you have ꌇäŗ‹, encoded as %E6%8C%87%E4%BA%8B. Surprise, but these characters arrive you on the server-side as Ć¦Å’‡Ć¤Āŗ‹. They are decoded by server automatically with ISO-8859-1. So, it doesn't matter if you try to decode it by yourself like
FacesContext fc = FacesContext.getCurrentInstance();
String param = fc.getExternalContext().getRequestParameterMap().get(name);
String decodedParam = java.net.URLDecoder.decode(param, "UTF-8");
It doesn't help because characters were already wrong decoded and you get them already wrong decoded from the request parameter map. It doesn't help too if you have on the page
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
To overcome this bug you need two things: a special character encoding filter and a configuration in JBoss' standalone.xml. The filter should set the configured encoding for both request and response.
public class CharacterEncodingFilter implements Filter {

    /** The default character encoding to set for request / response. */
    private String encoding = null;

    /** The filter configuration object. */
    private FilterConfig filterConfig;

    /** Should a character encoding specified by the client be ignored? */
    private boolean ignore = true;

    public void destroy() {
        encoding = null;
        filterConfig = null;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
        ServletException {
        // conditionally select and set the character encoding to be used
        if ((ignore || (request.getCharacterEncoding() == null)) && (encoding != null)) {
            request.setCharacterEncoding(encoding);
            response.setCharacterEncoding(encoding);
        }

        // pass control on to the next filter
        chain.doFilter(request, response);
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        this.encoding = filterConfig.getInitParameter("encoding");

        String value = filterConfig.getInitParameter("ignore");

        this.ignore = ((value == null) || value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes"));
    }
}
Note: It will not help if you only set the encoding for request. You should also set it for response by response.setCharacterEncoding(encoding). Configuration in web.xml looks like
<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>xyz.mypackage.CharacterEncodingFilter</filter-class>
    <init-param>
        <description>override any encodings from client</description>
        <param-name>ignore</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <description>the encoding to use</description>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>*.jsf</url-pattern>
</filter-mapping>
Now you have to add following system properties to the standalone.xml, direct after the closing <extensions> tag:
<system-properties>
    <property name="org.apache.catalina.connector.URI_ENCODING" value="UTF-8"/>
    <property name="org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING" value="true"/>
</system-properties>
From the docu:
  • org.apache.catalina.connector.URI_ENCODING specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.
  • org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING specifies if the encoding specified in contentType should be used for URI query parameters, instead of using the org.apache.catalina.connector.URI_ENCODING. This setting is present for compatibility with Tomcat 4.1.x, where the encoding specified in the contentType, or explicitely set using Request.setCharacterEncoding method was also used for the parameters from the URL. The default value is false.
JBoss looks now set character encoding for response and decodes URL parameters with it. I hope this info will help you to save your time.

Thursday, June 6, 2013

PrimeFaces Extensions 0.7.1 released

We are glad to announce a maintenance release of PrimeFaces Extensions 0.7.1. This release only contains fixed issues. The full list is on the GitHub. Updated components are Exporter, KeyFilter, Layout, TimePicker and Timeline.

The release is already available in the Maven central repository. Getting Started is as usually here. The theme of the showcase was changed to redmond. We are normally doing this to distinguish separate releases from each other.

Now it is a good time for some new components, so we will add a couple of them. Stay tuned.

Tuesday, June 4, 2013

Multiple dynamic includes with one JSF tag

Every JSF developer knows the ui:include and ui:param tags. You can include a facelet (XHTML file) and pass an object, which will be available in the included facelet, as follows
<ui:include src="/sections/columns.xhtml">
    <ui:param name="columns" value="#{bean.columns}"/>
</ui:include>
So, you can e.g. use it within a PrimeFaces DataTable with dynamich columns (p:columns)
<p:dataTable value="#{bean.entries}" var="data" rowKey="#{data.id}" ...>
    ...
    <ui:include src="/sections/columns.xhtml">
        <ui:param name="data" value="#{data}"/>
        <ui:param name="columns" value="#{bean.columns}"/>
    </ui:include>

</p:dataTable>
where the included facelet could contain this code
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:p="http://primefaces.org/ui"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                ...>
    <p:columns value="#{columns}" var="column">
        <f:facet name="header">
            <h:outputText value="#{msgs[column.header]}"/>
        </f:facet>

        // place some input / select or complex composite component for multiple data types here.
        // a simple example for demonstration purpose:
        <p:inputText value="#{data[column.property]}"/>
    </p:columns>
</ui:composition>
#{bean.columns} refers to a List of special objects which describe the columns. I will name such objects ColumnModel. So, it is a List<ColumnModel>. A ColumnModel has e.g. the attributes header and property.

Go on. Now, if we want to add a support for sorting / filtering, we can use dynamic paths which refer to specific facelet files containg sorting or / and filtering feature(s). Simple bind the src attribute to a bean property.
<ui:include src="#{bean.columnsIncludeSrc}">
   <ui:param name="data" value="#{data}"/>
   <ui:param name="columns" value="#{bean.columns}"/>
</ui:include>
The bean has something like
private boolean isFilterRight;
private boolean isSortRight

// setter / getter

public String getColumnsIncludeSrc() {
   if (isFilterRight && isSortRight) {
      return "/include/columnsTableFilterSort.xhtml";
   } else if (isFilterRight && !isSortRight) {
      return "/include/columnsTableFilter.xhtml";
   } else if (!isFilterRight && isSortRight) {
      return "/include/columnsTableSort.xhtml";
   } else {
      return "/include/columnsTable.xhtml";
   }
}
Different facelets are included dependent on the set boolean rights. So, the decision about what file to be included is placed within a bean. To be more flexible, we can encapsulate the table in a composite component and move the decision logic to the component class.
<cc:interface componentType="xxx.component.DataTable">
    <cc:attribute name="id" required="false" type="java.lang.String"
        shortDescription="Unique identifier of the component in a NamingContainer"/>
    <cc:attribute name="entries" required="true"
        shortDescription="The data which are shown in the datatable. This is a list of object representing one row."/>
    <cc:attribute name="columns" required="true" type="java.util.List"
        shortDescription="The columns which are shown in the datatable. This is a list of instances of type ColumnModel."/>
    ...
</cc:interface>
<cc:implementation>
    <p:dataTable value="#{cc.attrs.entries}" var="data" rowKey="#{data.id}" ...>
        ...
        <ui:include src="#{cc.columnsIncludeSrc}">
            <ui:param name="data" value="#{data}"/>
            <ui:param name="columns" value="#{cc.attrs.columns}"/>
        </ui:include>

    </p:dataTable>
</cc:implementation>
How does ui:include work? This is a tag handler which is applied when the view is being built. In JSF 2, the component tree is built twice on POST requests, once in RESTORE_VIEW phase and once in RENDER_RESPONSE phase. On GET it is built once in the RENDER_RESPONSE phase. This behavior is specified in the JSF 2 specification and is the same in Mojarra and MyFaces. The view building in the RENDER_RESPONSE is necessary in case the page author uses conditional includes or conditional templates. So, you can be sure that the src attribute of the ui:include gets evaluated shortly before the rendering phase.

But come to the point! What I wrote until now was an introduction for a motivation to extend ui:include. Recently, I got a task to use a p:dataTable with dynamic columns and p:rowEditor. Like this one in the PrimeFaces showcase. The problem is only - such editing feature doesn't support p:columns. My idea was to add p:column tags multiple times, dynamically, but with different context parameters. You can imagine this as ui:include with ui:param in a loop. In the example above we intend to iterate over the List<ColumnModel>. Each loop iteration should make an instance of type ColumnModel available in the included facelet. So, I wrote a custom tag handler to include any facelet multiple times.
package xxx.taghandler;

import xxx.util.VariableMapperWrapper;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.el.VariableMapper;
import javax.faces.component.UIComponent;
import javax.faces.view.facelets.FaceletContext;
import javax.faces.view.facelets.TagAttribute;
import javax.faces.view.facelets.TagAttributeException;
import javax.faces.view.facelets.TagConfig;
import javax.faces.view.facelets.TagHandler;

/**
 * Tag handler to include a facelet multiple times with different contextes (objects from "value").
 * The attribute "value" can be either of type java.util.List or array.
 * If the "value" is null, the tag handler works as a standard ui:include.
 */
public class InlcudesTagHandler extends TagHandler {

    private final TagAttribute src;
    private final TagAttribute value;
    private final TagAttribute name;

    public InlcudesTagHandler(TagConfig config) {
        super(config);

        this.src = this.getRequiredAttribute("src");
        this.value = this.getAttribute("value");
        this.name = this.getAttribute("name");
    }

    @Override
    public void apply(FaceletContext ctx, UIComponent parent) throws IOException {
        String path = this.src.getValue(ctx);
        if ((path == null) || (path.length() == 0)) {
            return;
        }

        // wrap the original mapper - this is important when some objects passed into include via ui:param
        // because ui:param invokes setVariable(...) on the set variable mappper instance
        VariableMapper origVarMapper = ctx.getVariableMapper();
        ctx.setVariableMapper(new VariableMapperWrapper(origVarMapper));

        try {
            this.nextHandler.apply(ctx, null);

            ValueExpression ve = (this.value != null) ? this.value.getValueExpression(ctx, Object.class) : null;
            Object objValue = (ve != null) ? ve.getValue(ctx) : null;

            if (objValue == null) {
                // include facelet only once
                ctx.includeFacelet(parent, path);
            } else {
                int size = 0;

                if (objValue instanceof List) {
                    size = ((List) objValue).size();
                } else if (objValue.getClass().isArray()) {
                    size = ((Object[]) objValue).length;
                }

                final ExpressionFactory exprFactory = ctx.getFacesContext().getApplication().getExpressionFactory();
                final String strName = this.name.getValue(ctx);

                // generate unique Id as a valid Java identifier and use it as variable for the provided value expression
                final String uniqueId = "a" + UUID.randomUUID().toString().replaceAll("-", "");
                ctx.getVariableMapper().setVariable(uniqueId, ve);

                // include facelet multiple times
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < size; i++) {
                    if ((strName != null) && (strName.length() != 0)) {
                        // create a new value expression in the array notation and bind it to the variable "name"
                        sb.append("#{");
                        sb.append(uniqueId);
                        sb.append("[");
                        sb.append(i);
                        sb.append("]}");

                        ctx.getVariableMapper().setVariable(strName,
                            exprFactory.createValueExpression(ctx, sb.toString(), Object.class));
                    }

                    // included facelet can access the created above value expression
                    ctx.includeFacelet(parent, path);

                    // reset for next iteration
                    sb.setLength(0);
                }
            }
        } catch (IOException e) {
            throw new TagAttributeException(this.tag, this.src, "Invalid path : " + path);
        } finally {
            // restore original mapper
            ctx.setVariableMapper(origVarMapper);
        }
    }
}
The most important call is ctx.includeFacelet(parent, path). The method includeFacelet(...) from the JSF API includes the facelet markup at some path relative to the current markup. The class VariableMapperWrapper is used for a name to value mapping via ui:param. For the example with columns the variable column will be mapped to expressions #{columns[0]}, #{columns[1]}, etc. before every includeFacelet(...) call as well. Well, not exactly to these expressions, at place of columns should be an unique name mapped again to the columns object (to avoid possible name collisions). The mapper class looks like as follows
package xxx.util;

import java.util.HashMap;
import java.util.Map;
import javax.el.ELException;
import javax.el.ValueExpression;
import javax.el.VariableMapper;

/**
 * Utility class for wrapping a VariableMapper. Modifications occur to the internal Map instance.
 * The resolving occurs first against the internal Map instance and then against the wrapped VariableMapper
 * if the Map doesn't contain the requested ValueExpression.
 */
public class VariableMapperWrapper extends VariableMapper {

    private final VariableMapper wrapped;

    private Map<String, ValueExpression> vars;

    public VariableMapperWrapper(VariableMapper orig) {
        super();
        this.wrapped = orig;
    }

    @Override
    public ValueExpression resolveVariable(String variable) {
        ValueExpression ve = null;
        try {
            if (this.vars != null) {
                // try to resolve against the internal map
                ve = this.vars.get(variable);
            }

            if (ve == null) {
                // look in the wrapped variable mapper
                return this.wrapped.resolveVariable(variable);
            }

            return ve;
        } catch (Throwable e) {
            throw new ELException("Could not resolve variable: " + variable, e);
        }
    }

    @Override
    public ValueExpression setVariable(String variable, ValueExpression expression) {
        if (this.vars == null) {
            this.vars = new HashMap<String, ValueExpression>();
        }

        return this.vars.put(variable, expression);
    }
}
Register the tag handler in a taglib XML file and you are done.
<tag>
    <tag-name>includes</tag-name>
    <handler-class>xxx.taghandler.InlcudesTagHandler</handler-class>
    <attribute>
        <description>
            <![CDATA[The relative path to a XHTML file to be include one or multiple times.]]>
        </description>
        <name>src</name>
        <required>true</required>
        <type>java.lang.String</type>
    </attribute>
    <attribute>
        <description>
            <![CDATA[Objects which should be available in the included XHTML files. This attribute can be either
            of type java.util.List or array. If it is null, the tag handler works as a standard ui:include.]]>
        </description>
        <name>value</name>
        <required>false</required>
        <type>java.lang.Object</type>
    </attribute>
    <attribute>
        <description>
            <![CDATA[The name of the parameter which points to an object of each iteration over the given value.]]>
        </description>
        <name>name</name>
        <required>false</required>
        <type>java.lang.String</type>
    </attribute>
</tag>
Now I was able to use it in a composite component as
<p:dataTable value="#{cc.attrs.entries}" var="data" rowKey="#{data.id}" ...>
    ...
    <custom:includes src="#{cc.columnsIncludeSrc}" value="#{cc.attrs.columns}" name="column">
        <ui:param name="data" value="#{data}"/>
    </custom:includes> 

</p:dataTable>
A typically facelet file (and the component tree) contains a quite regular p:column tag which means we are able to use all DataTable's features!
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:p="http://primefaces.org/ui"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                ...>
    <p:column headerText="#{msgs[column.header]}">
        <p:cellEditor>
            <f:facet name="output">
                <custom:typedOutput outputType="#{column.outputTypeName}"
                   typedData="#{column.typedData}"
                   value="#{data[column.property]}"
                   timeZone="#{cc.timeZone}"
                   calendarPattern="#{cc.calendarPattern}"       
                   locale="#{cc.locale}"/>
            </f:facet>

            <f:facet name="input">
                <custom:typedInput inputType="#{column.inputTypeName}"
                   typedData="#{column.typedData}"
                   label="#{column.inputTypeName}"
                   value="#{data[column.property]}"
                   onchange="highlightEditedRow(this)"
                   timeZone="#{cc.timeZone}"
                   calendarPattern="#{cc.calendarPattern}"
                   locale="#{cc.locale}"/>
            </f:facet>
        </p:cellEditor>
    </p:column>
</ui:composition>


Note: This approach can be applied to another components and use cases. The InlcudesTagHandler works universell. For instance, I can imagine to create a dynamic Menu component in PrimeFaces without an underlying MenuModel. A list or array of some model class is still needed of course :-).