PBKDF2 with HMAC-SHA1 encryption class

Standard

Sensitive user data must insure confidentiality and integrity. The following class is a example of how to use a password based key derivation function (PBKDF2) algorithm to encode / decode data. Using the createHash method a salt and hash byte array is generated from a instance of the PBKDF2WithHmacSHA1 from the secretKeyFactory. The byte arrays that are returned serve as your encrypted data. You must have both to be able to validate.

Use case

A user signs up for a account on your website. They enter a username / password. The password that is entered is ran against the createHash method. The result (salt, hash) are stored in a database. This is the users login data encrypted. Whenever a user attempts to login with that username, the salt and hash are retrieved from the database and the validatePassword method is called. If the test passes you are assured they are a legitimate user and may proceed.

What is slowEquals?

When a password is validated it requires that slowEquals be true. SlowEquals is a method designed to prevent against timing attacks. What this does is assure that the attacker cannot determine how long it took for the password to fail. It iterates through all values in the byte array regardless if they are equal or not. This prevents the attacker from having enough information compute a off line attack.

public class HmacSHA1 {

    // Used in encryption for how many cycles
    private static final int PBKDF2_ITERATIONS = 2000;
    private static final Integer checkLoops = 10;
    private static final String password = "changeit";

    /**
     * Typical test case to assure that Encoding / Decoding / Encryption work
     * properly
     *
     * @param args
     */
    public static void main(String[] args) {

        System.out.println("Encryption Test\n");
        
        for (int i = 0; i <= checkLoops; i++) {
            
             try {
                // Create has in the form of (salt:hash)
                String hash = createHash(password);
                String[] params = hash.split(":");
                byte[] salt = fromHex(params[0]);
                byte[] hash5 = fromHex(params[1]);

                // Compare our generated bytes to the orignal
                if (validatePassword(password, hash5, salt)) {
                    System.out.println("valid password!");
                }
            } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
                System.out.println("ERROR: " + ex);
            }
        }
    }

    /**
     * Validates a password using a hash.
     *
     * @param password the password to check
     * @param hash
     * @param salt
     * @return true if the password is correct, false if not
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.spec.InvalidKeySpecException
     */
    public static boolean validatePassword(char[] password, byte[] hash, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {

        // Compute the hash of the provided password, using the same salt, iteration count, and hash length
        byte[] testHash = pbkdf2(password, salt, PBKDF2_ITERATIONS, hash.length);

        // Compare the hashes in constant time. The password is correct if both hashes match.
        return slowEquals(hash, testHash);
    }

    /**
     * Validates a password using a hash.
     *
     * @param password the password to check
     * @param hash
     * @param salt
     * @return true if the password is correct, false if not
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.spec.InvalidKeySpecException
     */
    public static boolean validatePassword(String password, byte[] hash, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {

        return validatePassword(password.toCharArray(), hash, salt);
    }

    /**
     * Computes the PBKDF2 hash of a password.
     *
     * @param password the password to hash.
     * @param salt the salt
     * @param iterations the iteration count (slowness factor)
     * @param bytes the length of the hash to compute in bytes
     * @return the PBDKF2 hash of the password
     */
    private static byte[] pbkdf2(final char[] password, final byte[] salt, final int iterationCount, final int keyLength) {

        try {
            return SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(new PBEKeySpec(password, salt, iterationCount, keyLength * 8)).getEncoded();
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Returns a salted PBKDF2 hash of the password.
     *
     * @param password the password to hash
     * @return a salted PBKDF2 hash of the password
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.spec.InvalidKeySpecException
     */
    public static String createHash(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
        return createHash(password.toCharArray());
    }

    /**
     * Returns a salted PBKDF2 hash of the password.
     *
     * @param password the password to hash
     * @return a salted PBKDF2 hash of the password in the form of SALT:HASH
     * @throws java.security.NoSuchAlgorithmException
     * @throws java.security.spec.InvalidKeySpecException
     */
    public static String createHash(char[] password) throws NoSuchAlgorithmException, InvalidKeySpecException {

        // Generate a random salt
        byte[] salt = getSalt().getBytes();

        // Hash the password
        byte[] hash = pbkdf2(password, salt, PBKDF2_ITERATIONS, 24);

        // Format salt:hash
        return toHex(salt) + ":" + toHex(hash);
    }

    /**
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    private static String getSalt() throws NoSuchAlgorithmException {
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        byte[] salt = new byte[16];
        sr.nextBytes(salt);
        return Arrays.toString(salt);
    }

    /**
     * Converts a byte array into a hexadecimal string.
     *
     * @param array the byte array to convert
     * @return a length*2 character string encoding the byte array
     */
    private static String toHex(byte[] array) {

        BigInteger bi = new BigInteger(1, array);
        String hex = bi.toString(16);
        int paddingLength = (array.length * 2) - hex.length();
        if (paddingLength > 0) {
            return String.format("%0" + paddingLength + "d", 0) + hex;
        } else {
            return hex;
        }
    }

    /**
     * Converts a string of hexadecimal characters into a byte array.
     *
     * @param hex the hex string
     * @return the hex string decoded into a byte array
     */
    public static byte[] fromHex(String hex) {

        byte[] binary = new byte[hex.length() / 2];
        for (int i = 0; i < binary.length; i++) {
            binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
        }
        return binary;
    }

    /**
     * Compares two byte arrays in length-constant time. This comparison method
     * is used so that password hashes cannot be extracted from an on-line
     * system using a timing attack and then attacked off-line.
     *
     * @param a the first byte array
     * @param b the second byte array
     * @return true if both byte arrays are the same, false if not
     */
    private static boolean slowEquals(byte[] a, byte[] b) {

        int diff = a.length ^ b.length;
        for (int i = 0; i < a.length && i < b.length; i++) {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }

}

The complete project is available on Github.

JAAS login module in Tomcat 7 example (Part 2)

Standard

Part 1 of this tutorial demonstrated how to implement a login module using JAAS + Tomcat 7. This next segment shows how to create a login form and call the login module.

Folder Structure:

/login.xhtml
/error.xhtml
/protected/index.html (protected via our web.xml file)

Simple JSF login page

The following is a simple form used to submit the username and password to a backing bean called loginBean. The form uses HTML5 passthrough elements, as well as built in JSF validators on the input fields. All errors are displayed using the h:messages output.

<h:form>
    <h3>Please sign in</h3>
    <h:inputText id="username" value="#{loginBean.username}" required="true" requiredMessage="Please enter your username" p:placeholder="Username" p:autofocus="true">
        <f:validateLength maximum="50" minimum="3" />
    </h:inputText>

    <h:inputSecret id="password" value="#{loginBean.password}" required="true" requiredMessage="Enter your password" p:placeholder="Password">
        <f:validateLength maximum="20" minimum="3" />
    </h:inputSecret>

    <h:messages/>

    <h:commandButton type="submit" value="Sign in" id="submit" action="#{loginBean.login()}"/>
</h:form>

Calling the login module

Once the form passes validation the login() action is called. The login action uses the submitted username / password to request a login from the servlet container. This will call the login module created in part 1 of this tutorial. If the request.login() servlet request fails, it throws a LoginException which is caught in the form of a ServletException below. If the login succeeds then the user is redirected to the protected page.

@ManagedBean(name = "loginBean")
@ViewScoped
public class LoginBean implements Serializable {
    
    private static final long serialVersionUID = 1L;

    private String username;
    private String password;

    /**
     *
     * @return
     */
    public String login() {

        try {

            // Get the current servlet request from the facesContext
            FacesContext ctx = FacesContext.getCurrentInstance();
            HttpServletRequest request = (HttpServletRequest) ctx.getExternalContext().getRequest();

            // Do login from the container (will call login module)
            request.login(username, password);

            return "/protected/index.xhtml?faces-redirect=true";

        } catch (ServletException ex) {

            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "An Error Occured: Login failed", null));
            Logger.getLogger(LoginBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        return "login.xhtml";
    }

    /**
     * @return the username
     */
    public String getUsername() {
        return username;
    }

    /**
     * @param username the username to set
     */
    public void setUsername(String username) {
        this.username = username;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

}

This concludes the configuration and implementation of JAAS container managed security. The original working copy of the complete project is available on Github.

JAAS login module in Tomcat 7 example (Part 1)

Standard

Implementing a login module using JAAS is an excellent way to secure URL’s in a web application. In this tutorial, it will walk through the steps in configuring JAAS authentication in Tomcat 7 using the form based authentication method.

Before looking at the code is it important to understand the purpose of JAAS authentication. JAAS or Java Authentication and Authorization Service is an optional package designed to work in a pluggable fashion. The JAAS component comes standard with many other servers such as Glassfish, Wildfly, and Jetty. Once the user is authorized, the JAAS component controls access to sensitive resources. In this article we will secure sensitive resources by URL patterns.

Understanding Principals

JAAS relies on users and roles to authorize the access to certain resources. In JAAS, the users and roles are separated into Principals. The separated Principals all represent the Subject identity. The Subject is an entity, such as a person or service. Lets begin by defining our user and roles Principals.

package com.sixthpoint.jaas;

import java.security.Principal;

/**
 * Holds the logged in users name
 *
 * @author sixthpoint
 */
public class UserPrincipal implements Principal {

    private String name;

    /**
     * Initializer
     *
     * @param name
     */
    public UserPrincipal(String name) {
        super();
        this.name = name;
    }

    /**
     * Set the name of the user
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get the name of the user
     *
     * @return
     */
    @Override
    public String getName() {
        return name;
    }
}
package com.sixthpoint.jaas;

import java.security.Principal;

/**
 * Holds a single role name that the user is in
 *
 * @author sixthpoint
 */
public class RolePrincipal implements Principal {

    private String name;

    /**
     * Initializer
     *
     * @param name
     */
    public RolePrincipal(String name) {
        super();
        this.name = name;
    }

    /**
     * Set the role name
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get the role name
     *
     * @return
     */
    @Override
    public String getName() {
        return name;
    }
}

Note the simplicity of the Principals. They both are similar and only require a name for referencing.

The Custom Login Module

The Login module must implement the javax.security.auth.spi.LoginModule interface. It is by inheritance that it will override the following methods:

  • initialize() – all options are loaded at this time, options can be configured in the jaas.conf file later in the tutorial
  • login() – used to perform verification logic
  • commit() – invoked after successful authentication from the login() method
  • abort() – called if something goes wrong with the login() or commit() methods
  • logout() – clears the Subject

The login module accepts the inputs from the end user and verifies they are valid through the login() method. The verification can be made in any number of ways: checking a database, a LDAP, remote API, etc. It is up to the developer to define the requirements for verification. For the purpose of this tutorial we are only verifying that the end user has entered values for the username / password. Once the verification is successful; roles are attached to the verified user. These roles are used for restricting access to resource locations in the web.xml. If an error occurs during the verification process or the assigning of roles the login() method must throw a LoginException. This will be gracefully handled by our application later in the tutorial.

The commit() method is invoked after a successful verification from the login() method. A UserPrincipal and all RolePrincipals associated with the verified user are stored in the Subject. The Subject is accessible in the javax.security.auth.Subject instance for the container managed security.

The final two methods are self explanatory. The logout() method clears all the subjects principals (user information). The abort() method nullifies the inputs (username / password), and principals if the commit failed but the user is authenticated. However, if the user is not verified or the commit() did succeed, then a standard logout() is performed.

public class CustomLoginModule implements LoginModule {

    private CallbackHandler handler;
    private Subject subject;
    private UserPrincipal userPrincipal;
    private RolePrincipal rolePrincipal;
    private List<String> userGroups;
    private Map options;
    private Map sharedState;

    // Configurable option
    private boolean debug = false;

    // Logger used to output debug information
    private static final Logger logger = Logger.getLogger(CustomLoginModule.class.getName());

    // User credentials
    private String username = null;
    private String password = null;

    private boolean isAuthenticated = false;
    private boolean commitSucceeded = false;

    /**
     * Constructor
     */
    public CustomLoginModule() {
        super();
    }

    /**
     * Initializer
     *
     * @param subject
     * @param callbackHandler
     * @param sharedState
     * @param options
     */
    @Override
    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {

        // Store the handler
        this.handler = callbackHandler;

        // Subject reference holds the principals
        this.subject = subject;

        this.options = options;
        this.sharedState = sharedState;

        // Setup a logging class / state
        if ("true".equalsIgnoreCase((String) options.get("debug"))) {
            ConsoleHandler consoleHandler = new ConsoleHandler();
            logger.addHandler(consoleHandler);
            debug = true;
        }
    }

    /**
     *
     * @return @throws LoginException
     */
    @Override
    public boolean login() throws LoginException {

        // If no handler is specified throw a error
        if (handler == null) {
            throw new LoginException("Error: no CallbackHandler available to recieve authentication information from the user");
        }

        // Declare the callbacks based on the JAAS spec
        Callback[] callbacks = new Callback[2];
        callbacks[0] = new NameCallback("login");
        callbacks[1] = new PasswordCallback("password", true);

        try {

            //Handle the callback and recieve the sent inforamation
            handler.handle(callbacks);
            username = ((NameCallback) callbacks[0]).getName();
            password = String.valueOf(((PasswordCallback) callbacks[1]).getPassword());

            // Debug the username / password
            if (debug) {
                logger.log(Level.INFO, "Username: {0}", username);
                logger.log(Level.INFO, "Password: {0}", password);
            }

            // We should never allow empty strings to be passed
            if (username == null || username.isEmpty() || password == null || password.isEmpty()) {
                throw new LoginException("Data specified had null values");
            }

            // Validate against our database or any other options (this check is a example only)
            if (username != null && password != null) {

                // Assign the user roles
                userGroups = this.getRoles();
                isAuthenticated = true;

                return true;
            }

            throw new LoginException("Authentication failed");

        } catch (IOException | UnsupportedCallbackException e) {
            throw new LoginException(e.getMessage());
        }

    }

    /**
     * Adds the username / roles to the principal
     *
     * @return @throws LoginException
     */
    @Override
    public boolean commit() throws LoginException {

        if (!isAuthenticated) {
            return false;
        } else {

            userPrincipal = new UserPrincipal(username);
            subject.getPrincipals().add(userPrincipal);

            if (userGroups != null && userGroups.size() > 0) {
                for (String groupName : userGroups) {
                    rolePrincipal = new RolePrincipal(groupName);
                    subject.getPrincipals().add(rolePrincipal);
                }
            }

            commitSucceeded = true;

            return true;
        }
    }

    /**
     * Terminates the logged in session on error
     *
     * @return @throws LoginException
     */
    @Override
    public boolean abort() throws LoginException {
        if (!isAuthenticated) {
            return false;
        } else if (isAuthenticated && !commitSucceeded) {
            isAuthenticated = false;
            username = null;
            password = null;
            userPrincipal = null;
        } else {
            logout();
        }
        return true;
    }

    /**
     * Logs the user out
     *
     * @return @throws LoginException
     */
    @Override
    public boolean logout() throws LoginException {
        isAuthenticated = false;
        isAuthenticated = commitSucceeded;
        subject.getPrincipals().clear();
        return true;
    }

    /**
     * Returns list of roles assigned to authenticated user.
     *
     * @return
     */
    private List<String> getRoles() {

        List<String> roleList = new ArrayList<>();
        roleList.add("admin");

        return roleList;
    }

}

 

Structuring the web application

Enabling the module above requires 3 files to be configured. Once complete this will secure access to the specified folder on the Java web application.

Begin by editing the context.xml file and defining the JAAS realm. This example uses the default JAASRealm for defining the user and role Principal classes which we defined above as UserPrincipal and RolePrincipal. The appName attribute is used to define which security module Tomcat will look to use.

<Context antiJARLocking="true" path="" reloadable="true">
    <Realm appName="CustomLogin" className="org.apache.catalina.realm.JAASRealm" roleClassNames="com.sixthpoint.jaas.RolePrincipal" userClassNames="com.sixthpoint.jaas.UserPrincipal"/>
</Context>

Finally, for the web application to load the security configuration a jaas.config file must be defined. This file will inform Tomcat what class file to load when processing login requests. Note that CustomLogin mirrors our appName in the context.xml. The CustomLoginModule is referenced from our java class above.

CustomLogin {
    com.sixthpoint.jaas.CustomLoginModule required debug=true;
};

Tomcat needs to know where the application security configuration file is located (jaas.config). A JVM argument needs to be added to the catalina.sh file. On server startup the server will load the custom login module.

JAVA_OPTS="-Djava.security.auth.login.config==$CATALINA_BASE/conf/jaas.config"

Securing Resource Locations

To prevent access to certain resource location the web.xml needs modification. Any number of security constraints can be added to map to resource locations. The auth-constraint can have multiple roles as shown.

<!-- URL constraints -->
<security-constraint>
    <web-resource-collection>
        <web-resource-name>Admin</web-resource-name>
        <url-pattern>/protected/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
        <role-name>staff</role-name>
    </auth-constraint>
    <user-data-constraint>
        <!-- transport-guarantee can be CONFIDENTIAL, INTEGRAL, or NONE -->
        <transport-guarantee>NONE</transport-guarantee>
    </user-data-constraint>
</security-constraint>
<!-- What roles are allowed -->
<security-role>
    <role-name>admin</role-name>
    <role-name>staff</role-name>
</security-role>
<!-- Force login by form -->
<login-config>
    <auth-method>FORM</auth-method>
    <form-login-config>
        <form-login-page>/login.xhtml</form-login-page>
        <form-error-page>/error.xhtml</form-error-page>
    </form-login-config>
</login-config>

This concludes the setup / configuration of JAAS on a java web application. The next tutorial demonstrates how to implement a JSF login page with JAAS.

A full copy of the complete project is available on Github.

QuickSort: comparing Java to PHP

Standard

QuickSort uses a divide and conquer technique to organize the arrays contents. The algorithm runs in:

worst case: O(n2)
best case: O(n log n) (simple partition)
or O(n) (three-way partition and equal keys)
average: O(n log n)

Motivation:

In the debate of Java vs PHP it was asked why use java when many tasks require less code in PHP. The answer while complex boils down to performance. This is a tiny example to show a performance comparison for each language.

The Algorithms

As a additional angle two separate implementations of the quicksort in Java have been added. One will use arrayLists while the other integer array. Additionally, JDK 7 / 8 will ran separately to analyze platform performance.

    
public static void quickSort(ArrayList<Integer> array, int start, int end) {
    
    // Align the left and right starting positions
    int leftPos = start;
    int rightPos = end;
    
    // if there is only one element in the partition, do not do any sorting
    if ((end - start) < 1) {
        return;
    }
    
    int pivot = array.get(start);
    
    // keep scanning because the left and right indecies have not met
    while (rightPos > leftPos) {
        
        while (array.get(leftPos) <= pivot && leftPos <= end && rightPos > leftPos) {
            leftPos++; // start left look for element greater than the pivot
        }
        
        while (array.get(rightPos) > pivot && rightPos >= start && rightPos >= leftPos) {
            rightPos--; // from right look for element not greater than the pivot
        }
        
        if (rightPos > leftPos) {
            swap(array, leftPos, rightPos); // if the left index is still smaller than the right index, swap the corresponding elements
        }
    }
    
    // after the indices have crossed, swap the last element in the left partition with the pivot
    swap(array, start, rightPos);
    
    // quicksort the left partition
    quickSort(array, start, rightPos - 1);
    
    // quicksort the right partition
    quickSort(array, rightPos + 1, end);
}

The PHP implementation uses a straight integer array.

public function quickSort(&$array, $start, $end) {
    
    // Align the left and right starting positions
    $leftPos = $start;
    $rightPos = $end;
    
    // if there is only one element in the partition, do not do any sorting
    if (($end - $start) < 1) {
        return;
    }
    
    $pivot = $array[$start];
    
    // keep scanning because the left and right indecies have not met
    while ($rightPos > $leftPos) {
        
        while ($array[$leftPos] <= $pivot && $leftPos <= $end && $rightPos > $leftPos) {
            $leftPos++; // start left look for element greater than the pivot
        }
        
        while ($array[$rightPos] > $pivot && $rightPos >= $start && $rightPos >= $leftPos) {
            $rightPos--; // from right look for element not greater than the pivot
        }
        
        if ($rightPos > $leftPos) {
            $this->swap($array, $leftPos, $rightPos); // if the left index is still smaller than the right index, swap the corresponding elements
        }
    }
    
    // after the indices have crossed, swap the last element in the left partition with the pivot
    $this->swap($array, $start, $rightPos);
    
    // quicksort the left partition
    $this->quickSort($array, $start, $rightPos - 1);
    
    // quicksort the right partition
    $this->quickSort($array, $rightPos + 1, $end);
}

Each algorithm is fed in X number of random integers. For Java to assure accuracy 50 iterations on the algorithm are performed to determine the run time. PHP is configured for 10 iterations due to the memory limit of 2 gigabytes. While one could argue that the data is inconsistent due to the randomized values, by increasing the iterations it gives a more accurate result.

Results:

[visualizer id=”472″]

I have omitted the PHP 10,000,000 array size test as is such a high number it skews the graph.

Conclusion:

JDK 7 appears to have a slight edge when it comes to arrayLists, however the difference while worth nothing does not conclude performance improvements. Therefore, Java 7 / 8 performance does not differ. As expected PHP performance is considerably worse that Java. PHP is not designed to nest over 100 functions. This can be configured as a variable as described below.

To run your own tests checkout either the PHP or Java repository on Github.

Possible errors:

PHP Fatal error: Maximum function nesting level of ‘100’ reached, aborting!

This error means that you need to increase the allowed number of nested calls. This can be configured by editing the php.ini file.

xdebug.max_nesting_level=200

Tech Specs
Java JDK 8 / 7
PHP 5.5 (2GB memory allocated)
AMD FX 8-core
16gb RAM 1600mhz

Creating JAR containing all classes of web application

Standard

Encapsulating all the web app’s source files into a singular JAR by modifying the pom.xml

Add the following information into the plugins section.

<plugin>
   <artifactId>maven-war-plugin</artifactId>
   <version>2.5</version>
   <configuration>
      <archiveClasses>true</archiveClasses>
   </configuration>
</plugin>

Cleaned and build the project to generate a snapshot of all class files. The log files will display the location of the jar that has been built.

Building jar: /PATH/TO/PROJECT/target/PROJECTNAME-1.0-SNAPSHOT/WEB-INF/lib/PROJECTNAME-1.0-SNAPSHOT.jar

Creating a simple JSF component: Google URL shortener

Standard

This article shows how to make a simple component in JSF. The component will utilize the google url shortener. The final result will have a custom taglib and can be passed any URL for shortening as follows:

<six:urlshortener id="googleURL" url="http://yoursite.com" />

The custom component will comprise of 4 files: API, Component, Renderer, and Taglib.xml.

The first file is the renderer which is responsible for the visual representation of the component. It extends the javax.faces.render.Renderer class. A responseWriter is used to open and close elements to be written to the DOM. A typical renderer may have both a encodeBegin / encodeEnd method, however for this example it is unnecessary as we only need render tags after encoding the URL from Google. The renderer can be identified by RENDERER_TYPE which corresponds to the Taglib.xml later in this article.

@FacesRenderer(componentFamily = UrlShortenerComponent.COMPONENT_FAMILY, rendererType = UrlShortenerRenderer.RENDERER_TYPE)
public class UrlShortenerRenderer extends Renderer {

    /**
     * * Renderer type of {@link UrlShortenerRenderer}.
     */
    public static final String RENDERER_TYPE = "com.sixthpoint.jsf.google.url.shortener.components.UrlShortenerRenderer";

    private static final Logger LOG = Logger.getLogger(UrlShortenerRenderer.class.getName());

    @Override
    public void encodeEnd(FacesContext context, UIComponent uicomponent) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        UrlShortenerComponent component = (UrlShortenerComponent) uicomponent;
        try {
            writer.startElement("a", component);
            writer.writeAttribute("id", component.getClientId(), "id");

            try {

                String url = component.getGoogleURL(component);
                writer.writeAttribute("href", url, "href");

                String style = (String) component.getAttributes().get("style");
                if (style != null) {
                    writer.writeAttribute("style", style, null);
                }

                writer.write(url);

            } catch (IOException ex) {
                writer.write(ex.getMessage());
                LOG.log(Level.SEVERE, "Could not generate Google short URL", ex);
            }

            writer.endElement("a");
        } catch (IOException ex) {
            LOG.log(Level.SEVERE, "Error generating markup", ex);
        }
    }
}

The renderer calls the component getGoogleUrl method. This component is inserted into the component tree by the componentFamily attribute which has been annotated by @FacesRenderer. The two important methods defined by the UrLShortenerComponent below are: getFamily, and getGoogleURL.

Since the rendering has been delegated, the getFamily method is overrides the extended UI Component. This override returns the identifier, which is used to refer to the component that can be rendered by the renderer. A StateHelper is used to store the value of the url attribute between requests.

The getGoogleURL method is called by the renderer and is intended to represent the meaning / purpose of the component. The class is extended from the javax.faces.component.UIComponent and is bound by its component name to the renderer during the request-processing lifecycle.

@FacesComponent(UrlShortenerComponent.COMPONENT_TYPE)
public class UrlShortenerComponent extends UIComponentBase {

    /**
     * * Component family of {@link UrlShortenerComponent}.
     */
    public static final String COMPONENT_FAMILY = "UrlShortener";

    /**
     * * Component type of {@link UrlShortenerComponent}.
     */
    public static final String COMPONENT_TYPE = "UrlShortener";

    /**
     * Attribute name constant for url.
     */
    private static final String URL_TAG = "url";

    /**
     * Default value for the url attribute.
     */
    private static final String URL_DEFAULT = "http://www.sixthpoint.com/";

    /**
     * Set the component tree family name
     *
     * @return
     */
    @Override
    public String getFamily() {
        return UrlShortenerComponent.COMPONENT_FAMILY;
    }

    /**
     * Perform API call
     *
     * @param component
     * @return
     * @throws IOException
     */
    public String getGoogleURL(UIComponent component) throws IOException {

        UrlShortenerAPI api = new UrlShortenerAPI();
        return api.getGoogleURL(getUrl());
    }

    /**
     * Get the tag value from the state helper
     *
     * @return
     */
    public String getUrl() {
        return (String) getStateHelper().eval(URL_TAG, URL_DEFAULT);
    }

    /**
     * Set the tag value to the state helper
     *
     * @param url
     */
    public void setUrl(String url) {
        getStateHelper().put(URL_TAG, url);
    }

}

The final piece of the puzzle is the API. This file is where the call to Google’s API to encode the URL is made. The URLShortenerAPI is a POJO class intended to separate UiComponent logic from business logic.

public class UrlShortenerAPI {

    /**
     * URL to the REST service.
     */
    private static final String API_URL = "https://www.googleapis.com/urlshortener/v1/url";

    /**
     * Property in the JSON output to be extracted.
     */
    private static final String PROPERTY_CONTAINING_OUTPUT = "id";

    /**
     * Gets the shortened URL from Google.
     *
     * @param url
     * @return String
     * @throws IOException
     */
    public String getGoogleURL(String url) throws IOException {

        OAuthRequest oAuthRequest = new OAuthRequest(Verb.POST, API_URL);

        // Set header content
        oAuthRequest.addHeader("Content-Type", "application/json");

        // Payload
        oAuthRequest.addPayload("{\"longUrl\": \"" + url + "\"}");

        // Send the request
        Response r = oAuthRequest.send();

        // Determine generic map type
        Type typeOfMap = new TypeToken<Map<String, String>>() {
        }.getType();

        // Json -> Map
        Map<String, String> responseMap = new GsonBuilder().create().fromJson(r.getBody(), typeOfMap);

        return responseMap.get(PROPERTY_CONTAINING_OUTPUT);

    }
}

To use this component properly you need to configure a taglib. This taglib file is to be placed in the /WEB-INF/googleurlshortener.taglib.xml. I have created my own namespace as seen below. Notice that it defines the same component-type, renderer-type, and attributes needed to statisfy the component.

<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
    version="2.0">
    <namespace>http://com.sixthpoint.google/urlshortener</namespace>
    <tlib-version>1.0</tlib-version>
    <jsp-version>2.2</jsp-version>
    <short-name>googleurlshortener</short-name>
    <uri>http://www.sixthpoint.com/</uri>
    <tag>
        <tag-name>urlshortener</tag-name>
        <component>
            <component-type>UrlShortener</component-type>
            <renderer-type>com.sixthpoint.jsf.google.url.shortener.components.UrlShortenerRenderer</renderer-type>
        </component>
        <attribute>
            <name>url</name>
            <type>java.lang.String</type>
            <description>The url that is to be shortened.</description>
        </attribute>
    </tag>
</facelet-taglib>

To use add the namespace to your file with whatever prefix you define and call the urlshortener method.

The complete project project code can be found on GitHub.

Binary search: comparing Java to PHP performance

Standard

Binary search finds the specified key in a given sorted array, then returns it’s position. The algorithm runs in:

worst case: O(log n)
best case: O(1)
average: O(log n)

Motivation:

In the debate of Java vs PHP it was asked why use java when many tasks require less code in PHP. The answer while complex boils down to performance. This is a tiny example to show a performance comparison for each language.

The Algorithms

As a additional angle I have added two separate implementations of the binary search in Java. One will use arrayLists while the other integer array. Additionally, JDK 7 / 8 will ran separately to analyze platform performance.

    
public static int binarySearch(ArrayList<Integer> array, int key) {

        int position, lower = 0, upper = array.size() - 1;

        // To start, find the subscript of the middle position.
        position = (lower + upper) / 2;

        while ((array.get(position) != key) && (lower <= upper)) {
            if (array.get(position) > key) {
                upper = position - 1;
            } else {
                lower = position + 1;
            }
            position = (lower + upper) / 2;
        }

        return ((lower <= upper) ? position : -1);
    }

The PHP implementation uses a straight integer array.

public function binary_search($a, $key) {

	$lo = 0;
	$hi = sizeof($a) - 1;
	$position = (int)(($lo + $hi) / 2);
	while (($a[$position] != $key) && ($lo <= $hi)) {
		if ($a[$position] > $key) {
			$hi = $position - 1;
		} else {
			$lo = $position + 1;
		}

		$position = (int)(($lo + $hi) / 2);
	}

	unset($a, $key);
	return (($lo <= $hi) ? $position : -1);
}

Each algorithm fed in X number of presorted ints. For java to assure accuracy 50 iterations on the algorithm is performed to determine the run time. PHP is configured for 10 iterations due to the memory limit of 2 gigabytes.

Results:

[visualizer id=”394″]

Conclusion:

Java 7 / 8 performance does not differ. An arrayList in has slightly more overhead compared to a pure integer array. As expected PHP performance is considerable worse that Java. PHP is not designed to hold 10 million ints in memory. To make this test work, the memory allocated to php had to be adjusted to 2gb. In conclusion, leave the large data sets to integer arrays in Java, not PHP to have the best performance.

To run your own tests checkout either the PHP or Java repository on Github.

Tech Specs
Java JDK 8 / 7
PHP 5.5 (2GB memory allocated)
AMD FX 8-core
16gb RAM 1600mhz

JSF session based queued flash messages

Standard

This article is intended to expand on the first article “JSF Bootstrap Style Validation” by adding sessions to store messages between views.

Other examples use getFlash() or phase listeners to intercept the messages:

context.getExternalContext().getFlash().setKeepMessages(true);

This solution uses session map instead to store the messages in between views. Using this class will allow for messages to sit in the queue until they are rendered out, this could happen 1,2,3…. pages later.

These two methods when added to the existing getMessages and queueMessage methods add session based messaging. Saving messages is handled by storing all queued messages into the existing faces session map. Then when we restore all messages it grabs the messages from the session map and adds them back to the current facesContext for rendering.

    /**
     * This is our session name
     */
    private static final String sessionToken = "MULTIPAGE-MESSAGES";

    /**
     * Saves all messages queued to the sessionToken
     *
     * @param facesContext
     */
    private static void saveMessages(final FacesContext facesContext) {

        // get existing messages map from session
        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        HashMap<String, List<FacesMessage>> messagesByIDMap = (HashMap<String, List<FacesMessage>>) sessionMap.get(sessionToken);

        // If it doesn't exist make one
        if (messagesByIDMap == null) {
            messagesByIDMap = new HashMap<>();
            sessionMap.put(sessionToken, messagesByIDMap);
        }

        // Iterate through all messages that are waiting in queue
        for (Iterator<String> iter = facesContext.getClientIdsWithMessages(); iter.hasNext();) {

            String clientId = iter.next();
            List<FacesMessage> messageList = messagesByIDMap.get(clientId);

            // If no messages for client ID yet create empty arrayList
            if (messageList == null) {
                messageList = new ArrayList<>();
                messagesByIDMap.put(clientId, messageList);
            }

            Iterator<FacesMessage> facesIterator = facesContext.getMessages(clientId);

            // Add all the messages for that client ID to the session
            while (facesIterator.hasNext()) {
                messageList.add(facesIterator.next());
            }
        }
    }

    /**
     * Finds all the messages in the sessionToken and adds them
     *
     * @param facesContext
     */
    private static void restoreMessages(final FacesContext facesContext) {

        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        HashMap<String, List<FacesMessage>> messagesByIDMap = (HashMap<String, List<FacesMessage>>) sessionMap.remove(sessionToken);

        if (messagesByIDMap == null) {
            return;
        }

        // Add all messages by client ID back to the facesContext
        for (String clientID : messagesByIDMap.keySet()) {
            List<FacesMessage> messages = messagesByIDMap.get(clientID);
            for (FacesMessage facesMessage : messages) {
                facesContext.addMessage(clientID, facesMessage);
            }
        }
    }

Looking for the rest of the code? View the first article “JSF Bootstrap Style Validation” or checkout the code on found on Github.

JSF Bootstrap style validation

Standard

In this example, I provide a solution to the problem of needing to display errors specific to a form on a page. This solution was developed due to the need to have multiple forms on the same page, while maintaining a simple way to display errors belonging to there ID’s. The point of this article is to show you how to make a simple profile page for submitting a first and last name that is validated.

The most important class is the FacesUtil.java which provides methods for queuing / retrieving facesMessages based on each inputs DOM id. I have defined 3 types for displaying errors based on the bootstrap 3 message classes (success, warning, and danger).

public class FacesUtil {

    /**
     * Options allowed for errors
     */
    private static List errorCodes = new ArrayList() {
        {
            add("danger");
            add("warning");
            add("success");
        }
    };

   /**
     *
     * @param str
     */
    public static void queueMessage(String str) {
        queueMessage(str, "warning");
    }

    /**
     *
     * @param str
     * @param severity
     */
    public static void queueMessage(String str, String severity) {

        // Did they enter a valid severity
        if (!errorCodes.contains(severity)) {
            Logger.getLogger(FacesUtil.class.getName()).log(Level.SEVERE, null, "Improper api usage");
            return;
        }

        FacesMessage message = new FacesMessage(str);

        switch (severity) {
            case "danger":
                message.setSeverity(FacesMessage.SEVERITY_ERROR);
                break;
            case "warning":
                message.setSeverity(FacesMessage.SEVERITY_WARN);
                break;
            default:
                message.setSeverity(FacesMessage.SEVERITY_INFO);
                break;
        }

        FacesContext.getCurrentInstance().addMessage(UIComponent.getCurrentComponent(FacesContext.getCurrentInstance()).getClientId(), message);
    }

    /**
     *
     * @param severity
     * @return
     */
    public static Collection getMessages(String severity) {
        return getMessages("", severity);
    }

    /**
     * Gets all messages in a array list of a given severity type. Specify
     * severity as "error", "warn", or "info"
     *
     * @param formId
     * @param severity
     * @return
     */
    public static Collection getMessages(String formId, String severity) {

        // Get the Faces Context
        FacesContext facesContext = FacesContext.getCurrentInstance();

        // Restore other messages
        restoreMessages(facesContext);

        // Get the root of the UIComponent
        UIViewRoot root = facesContext.getViewRoot();

        // Iterator to iterate through the client ID's
        Iterator iterator = facesContext.getClientIdsWithMessages();

        // Map all the messages by error level
        Map<String, Collection> map = new HashMap<>();

        // Did they enter a valid severity
        if (!errorCodes.contains(severity)) {
            Logger.getLogger(FacesUtil.class.getName()).log(Level.SEVERE, null, "Improper api usage");
            return map.get(severity);
        }

        // Determine error categories
        String errorLevel = "";
        switch (severity) {
            case "danger":
                errorLevel = "ERROR 2";
                break;
            case "warning":
                errorLevel = "WARN 1";
                break;
            default:
                errorLevel = "INFO 0";
                break;
        }

        // Iterate through the messages
        while (iterator.hasNext()) {

            // Retrieve the client ID
            String clientId = iterator.next();

            // Retrieve the item UI component
            UIComponent baseComponent = root.findComponent(clientId);

            // Find the the form UI component
            UIComponent parentForm = findParentForm(baseComponent);

            // If the form ID was specified and its not the true parent, we skip this iteration
            if (!formId.equals("") && (parentForm == null || (!formId.equals("") && !parentForm.getId().equals(formId)))) {
                continue;
            }

            // If the formId is not specified we always display it as a global message
            if (formId.equals("") || baseComponent != null) {

                // Return an Iterator over the FacesMessages
                Iterator facesIterator = facesContext.getMessages(clientId);

                // Build a list to return based on type specified
                while (facesIterator.hasNext()) {

                    FacesMessage facesMessage = facesIterator.next();
                    Collection values = map.get(errorLevel);
                    if (values == null) {
                        values = new ArrayList<>();
                        map.put(errorLevel, values);
                    }

                    // Only add if we don't have that value already
                    if (facesMessage.getSeverity().toString().equals(errorLevel) && !values.contains(facesMessage.getDetail())) {
                        values.add(facesMessage.getDetail());
                    }
                }
            }
        }

        return map.get(errorLevel);
    }

    /**
     *
     * @param component
     * @return
     */
    public static UIComponent findParentForm(UIComponent component) {
        if (component instanceof UIForm) {
            return component;
        }
        if (component == null) {
            return null;
        }
        return findParentForm(component.getParent());
    }

    /**
     * @return the errorCodes
     */
    public static List getErrorCodes() {
        return errorCodes;
    }

    /**
     * @param aErrorCodes the errorCodes to set
     */
    public static void setErrorCodes(List aErrorCodes) {
        errorCodes = aErrorCodes;
    }
}

Interfacing with the FacesUtil.java class is a viewScoped bean called viewProfile.java. This bean extends the methods of the FacesUtil class and is where our submit action lives. It also defines the first and last name that will be submitted from our profile page.

/**
 * Sample profile page
 *
 * @author sixthpoint
 */
@ManagedBean
@ViewScoped
public class ViewProfile implements Serializable {

    private String firstName;
    private String lastName;

    /**
     * Basic constructor
     */
    public ViewProfile() {

    }

    /**
     * On submit, we queue a success message
     */
    public void submit() {

        FacesUtil.queueMessage("we have success", "success");
    }

    /**
     * Returns a array of validation options
     *
     * @return
     */
    public List validationOptions() {
        return FacesUtil.getErrorCodes();
    }

    /**
     * Ask for validation messages based on a formId in the component tree
     * (success, warning, danger)
     *
     * @param formId
     * @param level
     * @return
     */
    public Collection validation(String formId, String level) {
        return FacesUtil.getMessages(formId, level);
    }

    /**
     * Omitted getters and setters
     */

The final page is the actual JSF view. It is simple to display all errors from the faces util class through the viewProfile bean. On inputText I have defined a validateLength and a requireMessage. These have been set to required. If those validation requirements are not met, the error will be displayed in the panelGroup block below. The FacesUtil class has the logic to grab all manually queued messages as well as messages queue from validation inputs.

<h:form id="profileForm">
    <h:inputText value="#{viewProfile.firstName}" p:placeholder="First Name" required="true" requiredMessage="Please enter a first name">
        <f:validateLength minimum="3"/>
    </h:inputText>
    <h:inputText value="#{viewProfile.lastName}" p:placeholder="Last Name" required="true" requiredMessage="Please enter a last name">
        <f:validateLength minimum="3"/>
    </h:inputText>
    <h:commandButton type="submit" value="Submit" action="#{viewProfile.submit}">
        <f:ajax execute="@form" render="@form :messages"/>
    </h:commandButton>
</h:form>

<h:panelGroup layout="block" id="messages">
    <c:forEach var="errorCode" items="#{viewProfile.validationOptions()}">
        <h:panelGroup layout="block" rendered="#{viewProfile.validation('profileForm', errorCode).size() gt 0}">
            <h:panelGroup layout="block" styleClass="alert alert-#{errorCode} alert-dismissable">
                <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&#xD7;</button>
                <ul>
                    <c:forEach var="m" items="#{viewProfile.validation('profileForm', errorCode)}">
                        <li>#{m}</li>
                    </c:forEach>
                </ul>
            </h:panelGroup>
        </h:panelGroup>
    </c:forEach>
</h:panelGroup>

 

Omitted are the bootstrap CDN’s libraries. A full working version of this code can be found on Github.

Bootstrap-datetimepicker with jsf change events

Standard

A datepicker is a great way to avoid having to require multiple inputs on a web application. This example shows you how to use the bootstrap-datepicker and tie it together with JSF.

We begin by creating our inputText field

Now to explain some of the attributes:

The p:data-date-format and p:placeholder are both pass through attributes that become html5 tags. I do this by defining my xmlns at the top of the page like so:


To get our date picker to work we must include the libraries. I choose to use a CDN for my libraries to reduce the configuration on my end. Initialize the datetimepicker to the startDate ID referenced from above. Then create an on change event for the datepicker. This is because the bootstrap-datepicker sits on top of the inputText field and when its value is changed, JSF does not get alerted of this. So inside the change event retrieve the document element of the inputText field then send a onchange event to all other scripts listening to that field. This will trigger the JSF on change event bound by the f:ajax.