Monday, November 5, 2012

Login twice in Wicket

Since the last time I upgraded my Wicket application, I noticed I had to login twice to be authenticated in the application. After careful research using the number one research tool (Google), I found the cause of this problem. The problem is that my login page is stateless. Wicket will create a temporary dummy session for stateless pages, which will not be saved internally in the session store. The solution is to let the session stick after authentication by calling bind in the session:
@Override
public boolean authenticate(String userName, String password) {
    // Your authentication code here...

    // Only reach this when authenticated...

    if (isTemporary()) {
        bind();
    }
}

Saturday, November 3, 2012

Reload JQuery when DOM is changed by Wicket/AJAX

I'm using many jQuery plugins in my Wicket application. When Wicket AjaxBehaviors change the DOM of the page, the initial changes made by the jQuery plugins are often lost. To solve this, we have to initiate the jQuery plugins again when the AjaxBehavior executes. We can do that by appending the plugin initialization JavaScript code like below:
aTextField.add(new OnChangeAjaxBehavior() {
    @Override
    protected void onUpdate(AjaxRequestTarget target) {
        target.add(aContainerThatIsRefreshed);
        target.appendJavaScript("$('.jQueryPluginClass').initiatePlugin();");
    }
});
Change the ".jQueryPluginClass" CSS class, and ".initiatePlugin()" plugin call for your specific project.

Saturday, August 4, 2012

Java Collection Matrix

Looking for a Java Collection class for your project, but don't know which one to use or is available? The link below will take you to a Java Collection Matrix, which lists the summarized properties of the standard Java Collection implementations.

http://www.janeve.me/articles/which-java-collection-to-use

Thursday, July 26, 2012

Custom Wicket FeedbackPanel markup

I had to add custom static markup to the Wickets FeedBackPanel for a project I'm currently working on. The markup has to be visible only when the the feedback panel itself is visible. The easiest way to do this is to extend the original class, and provide a corresponding HTML file with the custom markup.
package com.javaeenotes;

import org.apache.wicket.feedback.IFeedbackMessageFilter;
import org.apache.wicket.markup.html.panel.FeedbackPanel;


public class ErrorPanel extends FeedbackPanel {
    private static final long serialVersionUID = 1L;


    public ErrorPanel(String id, IFeedbackMessageFilter filter) {
        super(id, filter);
    }


    public ErrorPanel(String id) {
        super(id);
    }
}
<wicket:panel>
  <div class="feedbackPanel" wicket:id="feedbackul">
    <b>Error</b>
    <div class="errorlevel" wicket:id="messages">
      <span class="errorlevel" wicket:id="message">A message</span>
    </div>
  </div>
</wicket:panel>
The HTML file is basically the same as the original file. I added an error header as an example.

Wednesday, May 2, 2012

Configurable, and modular Java classes using Annotations and Enumerations

In todays blog post, I'm showing how I implemented highly configurable, and modular classes with the help of annotations, and enumerations. From now on, let's call these modular classes "modules". Let's suppose we have the following architectural problem:

  1. There is a need for modules that are highly configurable.
  2. The modules implement the same interface.
  3. The configuration parameters vary.
  4. Some configuration parameters are required.
  5. Some configuration parameters have a default value.
  6. A configuration parameter should have an explanation for the enduser.
  7. It should also be easy to add new modules.

UML Class Diagram

ModuleFactory and ModuleFactoryImpl

The module factory is responsible for creating a configured module. It takes the class name, and Properties object as parameters. I'm using a class name here instead of a class type, because the list of supported modules are stored in the database as names. The Properties object contains the configuration for the module to be created.

ModuleType

This enumeration is basically a list of supported types by the factory. When a new module is implemented, it should be added to this enumeration, otherwise the factory doesn't know how to translate the class name to the actual class. I tried to find a way to avoid the need of this enumeration, like searching in the class path for classes that correspond to the name. Unfortunately, this is too complex to achieve without adding a lot of boilerplate code. If you find a better way to solve this problem, please let me know in the comments.

Module

This interface formalizes the methods implemented by all modules. Their parameters are defined in an enumeration of type ModuleParameter. Every module should have a corresponding ModuleParameter enumeration. An example implementation for this demo is called "ExampleModule", and it uses "ExampleModuleParameter" to define its configuration.

ModuleParameter

This interface specifies the required methods for every subclass enumeration implementation. The enumeration is basically a list of configuration parameters for a module. Per configuration parameter, it also defines: if the parameter is required, the default value, and a brief explanation. An example implementaton for this demo is called "ExampleModuleParameter", and it has two configuration parameters.

The Implementation

ModuleParameter

package com.javaeenotes.modules;


// This interface enforces required methods for the parameter enumerator.
public interface ModuleParameter {

    boolean isRequired();

    String getDefaultValue();

    String getExplanation();
}

This interface defines the methods used to retrieve the properties of the configuration parameter.

ExampleModuleParameter

package com.javaeenotes.modules;


// This enum class contains the parameters used to configure a module.
public enum ExampleModuleParameter implements ModuleParameter {
    PARAM1("param1", true, "DEFAULT", "This is parameter 1."),
    PARAM2("param2", false, null, "This is parameter 2.");

    // Code below is boiler plate code. It is not possible to move the
    // code to an abstract class, because enumerators are not allowed
    // to extend classes.

    private final String name;
    private final boolean isRequired;
    private final String defaultValue;
    private final String explanation;


    private ExampleModuleParameter(
            String name,
            boolean isRequired,
            String defaultValue,
            String explanation) {

        this.name = name;
        this.isRequired = isRequired;
        this.defaultValue = defaultValue;
        this.explanation = explanation;
    }


    @Override
    public String toString() {
        return name;
    }


    @Override
    public boolean isRequired() {
        return isRequired;
    }


    @Override
    public String getDefaultValue() {
        return defaultValue;
    }


    @Override
    public String getExplanation() {
        return explanation;
    }
}

Everything you should know about the specific parameters is defined here, and nowhere else (high cohesion)! It forces the developer who is adding new parameters to define the extra properties as required.

I tried to eliminate the boiler plate code, by moving them to a shared abstract enumeration class, but that is not possible. Now we have to copy the same code for every new "ModuleParameter" implementation. Is there a better solution for this?

Module

package com.javaeenotes.modules;


public interface Module {
    void doBusinessStuff();
}

Just the interface of a module, containing a common method.

ExampleModule

package com.javaeenotes.modules;


// Annotate this module with parameter class that contains the
// configurable parameters for this module.
@ParameterClass(parameterClass = ExampleModuleParameter.class)
public class ExampleModule implements Module {

    private String param1;
    private String param2;


    @Override
    public void doBusinessStuff() {
        System.out.println("Hello, I am "
                + this.getClass().getSimpleName()
                + ". I am configured with param1='" + param1
                + "', and param2='" + param2 + "'.");
    }


    public void setParam1(String param1) {
        this.param1 = param1;
    }


    public void setParam2(String param2) {
        this.param2 = param2;
    }
}

This is an example implementation of a module. As you can see, it's just a POJO, making it very easy to write new ones. The class is linked to its parameter class using the annotation placed just before the class definition. The attributes and setters are important here. The names must correspond with the names defined in the parameter class.

ParameterClass

package com.javaeenotes.modules;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


// Only usable on classes.
@Target(ElementType.TYPE)
// Annotation must be available during runtime.
@Retention(RetentionPolicy.RUNTIME)
public @interface ParameterClass {
    Class<? extends ModuleParameter> parameterClass();
}

This is the annotation, which links the module to its parameter class. The factory uses this annotation to find out which configuration values to set.

ModuleType

package com.javaeenotes.modules;


// This is basically a list of supported modules by the factory.
public enum ModuleType {
    EXAMPLE_MODULE(ExampleModule.class);

    private Class<? extends Module> moduleClass;


    private ModuleType(Class<? extends Module> moduleClass) {
        this.moduleClass = moduleClass;
    }


    public Class<? extends Module> getModuleClass() {
        return moduleClass;
    }
}

This enumeration is a list of supported modules. The purpose of this enumeration is to map the name to its class type. This information is required by the module factory to instantiate the correct module class.

ModuleFactory

package com.javaeenotes.modules;

import java.util.Properties;


public interface ModuleFactory {
    Module getModule(String moduleName, Properties configuration)
            throws Exception;
}

The interface of the module factory. It requires the class name, and a "Properties" object containing the configuration of the module.

ModuleFactoryImpl

package com.javaeenotes.modules;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;


public class ModuleFactoryImpl implements ModuleFactory {

    private Map<String, ModuleType> nameToModuleType;


    public ModuleFactoryImpl() {
        // The Map contains all the supported module types.
        nameToModuleType = new HashMap<String, ModuleType>();

        for (ModuleType moduleType : ModuleType.values()) {
            nameToModuleType.put(
                    moduleType.getModuleClass().getSimpleName(),
                    moduleType);
        }
    }


    @Override
    public Module getModule(String moduleName, Properties configuration)
            throws Exception {

        if (nameToModuleType.containsKey(moduleName)) {
            ModuleType moduleType = nameToModuleType.get(moduleName);
            Module module = moduleType.getModuleClass().newInstance();
            configureModule(module, configuration);
            return module;
        }

        throw new IllegalArgumentException(
                "Class not supported: " + moduleName);
    }


    private void configureModule(
            Module module, Properties configuration)
            throws Exception {

        if (module.getClass().isAnnotationPresent(ParameterClass.class)) {
            Map<String, Method> methodNameToMethod =
                    getMethodNameToMethod(module);

            for (ModuleParameter param : getModuleParameters(module)) {
                String configValue = configuration.getProperty(
                        param.toString());

                // Set default value if configuration value is empty.
                if (configValue.isEmpty()) {
                    configValue = param.getDefaultValue();
                }

                // Check if value is required.
                if ((configValue == null || configValue.isEmpty())
                        && param.isRequired()) {

                    throw new IllegalArgumentException(
                            "Configuration value missing for: "
                            + param.toString());
                }

                // Set configuration value in module.
                invokeParameterSetter(methodNameToMethod, module,
                        param.toString(), configValue);
            }
        }
    }


    private Map<String, Method> getMethodNameToMethod(Module module) {
        Map<String, Method> methodNameToMethod =
                new HashMap<String, Method>();

        for (Method method : module.getClass().getMethods()) {
            methodNameToMethod.put(method.getName(), method);
        }

        return methodNameToMethod;
    }


    private ModuleParameter[] getModuleParameters(Module module) {
        return module.getClass()
                .getAnnotation(ParameterClass.class)
                .parameterClass().getEnumConstants();
    }


    private void invokeParameterSetter(
            Map<String, Method> methodNameToMethod,
            Module module, String paramName, String configValue)
            throws Exception {

        String setterMethodName = getSetterMethodName(paramName);

        if (methodNameToMethod.containsKey(setterMethodName)) {
            methodNameToMethod.get(setterMethodName).invoke(
                    module, configValue);
        } else {
            throw new IllegalArgumentException(
                    "No setter found for: " + paramName);
        }
    }


    private String getSetterMethodName(String paramName) {
        return "set" + Character.toUpperCase(paramName.charAt(0))
                + paramName.substring(1);
    }
}

Using the name of the module class, this factory instantiates the correct class with the help of the "ModuleType" enumeration class. Then it tries to find out if this module requires configuration, by detecting the annotation. The annotation specifies the use of the "ExampleModuleParameter" enumeration for configuration. Using the enumeration, and the "Properties" object, it calls the setters with the configuration values. It also checks if a required configuration value is present. The result is a module with all required configuration values set.

A drawback is that the method name of the setters is restricted. It must be the same as the name of the parameter (excluding the "set" string), which is defined in the enumeration. A solution for this is to use annotations in the setter method definition to specify which configuration parameter it corresponds to. Using string literals to tie things together makes the code brittle.

Main

package com.javaeenotes.modules;

import java.util.Properties;


public class Main {
    public static void main(String[] args) {
        // Build the configuration properties.
        Properties configuration = new Properties();
        configuration.setProperty(
                ExampleModuleParameter.PARAM1.toString(), "");
        configuration.setProperty(
                ExampleModuleParameter.PARAM2.toString(), "param2");

        try {
            // Get instance of configured module from factory.
            Module module = new ModuleFactoryImpl()
                .getModule("ExampleModule", configuration);

            // Run the module.
            module.doBusinessStuff();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This class demonstrates the whole solution. If run, it prints: Hello, I am ExampleModule. I am configured with param1='DEFAULT', and param2='param2'.

Conclusion

As you can see, writing new modules is very easy by implementing just the two interfaces. All the configuration code is centralized in the factory implementation.

If you have ideas for improvements or better solutions, please don't hesitate to share them in the comments.

Monday, March 5, 2012

Quick introduction to OpenSSL

OpenSSL is an open source Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) implementation. I exclusively use this for handling SSL related tasks, and diagnostics. I will explain the OpenSSL commands I frequently use in this blog post. Before we go to the commands, let's do a quick explanation of the terminology used in SSL:
  • Certificate Signing Request (CSR): a message format for a certificate signing request for a Certificate Authority. This message is required for generating/requesting certificates.
  • Public/Private key: a private key should be kept secret by the owner, and can be used to sign data, or decrypt messages encrypted with the public key. The public key is used to encrypt message which are only to be read by the owner of the private key. The encryption/decryption process tends to be slow compared to using a symmetric encryption key.
  • Symmetric key: one key for encrypting and decrypting. This process is fast. When we use SSL in our browser, the public/private key is only used to negotiate a symmetric key encryption method. The actual data transfer encryption is therefore symmetric (fast).
  • (Root) Certificate: a certificate contains identification information, a public key that can be used to encrypt messages, and a signature of a Certificate Authority. The signature tells us that the identification information is trusted/verified by the Certificate Authority. If we trust the Certificate Authority, then we also trust the identity of the owner of the certificate (authentication).
  • Certificate Authority (CA): an organization we consider to be trusted. A CA will sign and issue certificates. Using the root certificate of a CA, we can verify if other certificates are indeed signed by this particular CA. Your browser has a standard set of root certificates of commonly recognized CA's.

Common commands

To generate a CSR for a certificate with a 2048-bit private key:
openssl req -out certificate.csr -new
  -newkey rsa:2048 -nodes -keyout private.key
Generate a self-signed certificate (we are our own CA):
openssl req -x509 -nodes -days 365 -newkey rsa:2048
  -keyout private.key -out certificate.crt
Print out the information contained in a certificate, such as identification, and the public key:
openssl x509 -in certificate.crt -text -noout
To check a web server for its SSL-certificates:
openssl s_client -showcerts -connect google.com:443 </dev/null

References: