Strategy Pattern and Overloading in Java

The Software Engineering world is filled with a number of commonly known design patterns. One known to many programmers in general but seldomly by name is the strategy pattern. Wikipedia defines it as follows:
In computer programming, the strategy pattern (also known as the policy pattern) is a software design pattern that enables an algorithm’s behavior to be selected at runtime.

  • The strategy pattern
    defines a family of algorithms,
  • encapsulates each algorithm, and
  • makes the algorithms interchangeable within that family.

In Java this can often be implemented by using method overloads.

    void foobar(A arg) {…}
    void foobar(B arg) {…}

Later you can just call the method as usual.

    A instance1 = new A();
    B instance2 = new B();
    foobar(instance1)
    foobar(instance2)

The compiler will take care of correct linking and thus will select the correct strategy for you. This is really useful and well known but it also has its limitations. For example this approach will not work if you have classes which are sharing a common hierarchy. An Example would be Vehicle, Car, Bus. Java would complain about the method not accepting the Superclass and thus throw a compile error.
To circumvent this you could define a common interface and implement an expert for each type. Then put those experts into a Map and select on runtime which expert you will call, depending on the supplied entity type. This is still a good approach and certainly sufficient for most use cases.
In my example I am doing that and also I’d like to take it a step further. Here the population of the expert map happens automatically during startup. See for yourself.

I am using Java reflections to parse the method signatures of my host class. Each Method represents a strategy relevant for a different entity type – in this case different runtime exceptions. Then I put the methods into a Map. During Runtime an exception is received and the correct strategy is selected from the auto-populated map. The only thing that a programmer has to take care of is the correct naming of the strategy functions.

Now lets get into the details of the Class.
We have two strategies for logging exceptions. One for the Arithmetic Exception and one for the NullPointerException

    public void log(ArithmeticException arg) {
        System.out.println("found a log function for " + ArithmeticException.class);
    }

    public void log(NullPointerException arg) {
        System.out.println("found a log function for " + NullPointerException.class);
    }

Also we have a selector map which holds the type signature and a reference to the strategy method. During the receive method this map is queried for the reference to the method. As a last step the method is invoked.

    Map<String, Method> r3s0lvr = new HashMap<String, Method>(); 

    public void receive(RuntimeException arg) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NullPointerException {
        String clazzName = arg.getClass().getName();

        //Select the correct method to invoke
        Method method = this.r3s0lvr.get(clazzName);

        //TODO null pointer cases have to be handled correctly
        method.invoke(this, arg);
    }

Now we come to the point where the magic happens. The init() method scans the current class for all methods which have the correct name and the correct signature pattern. If a method matches the

criteria it is added to the map. In case a developer likes to extend the functionality of this Class we even get the methods from the current object instead of the StrategyPattern.class.

public void init() {
    for (Method cur : this.getClass().getMethods()) {
        if (cur.getName().equals(LOG_METHOD_NAME) == false)
            //wrong name ==> skip
            continue;

        Class<?>[] types = cur.getParameterTypes();
        if (types.length != 1)
            //wrong number of arguments ==> skip
            continue;

        Class<?> type = types[0];
        if (RuntimeException.class.isAssignableFrom(type) == false)
            //wrong parameter type ==> skip
            continue;

        @SuppressWarnings("unchecked")
        Class<? extends RuntimeException> targetType = (Class<? extends RuntimeException> type;

        //put method into r3s0lvr
        this.r3s0lvr.put(targetType.getName(), cur);
    }
}

The complete source code of  StrategyPattern.java

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

public class StategyPattern {
    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        StategyPattern test = new StategyPattern();
        test.init();
        test.receive(new ArithmeticException());
        test.receive(new NullPointerException());
    }

    private static String LOG_METHOD_NAME = "log";
    Map<String, Method> r3s0lvr = new HashMap<String, Method>();

    /**
    * fills the r3s0lvr hash map with the correct functions for later invocations.
    */
    public void init() {
        for (Method cur : this.getClass().getMethods()) {
            if (cur.getName().equals(LOG_METHOD_NAME) == false)
                //wrong name ==> skip
                continue;
            Class<?>[] types = cur.getParameterTypes();
            if (types.length != 1)
                //wrong number of arguments ==> skip
                continue;

            Class<?> type = types[0];
            if (RuntimeException.class.isAssignableFrom(type) == false)
                //wrong parameter type ==> skip
                continue;

            @SuppressWarnings("unchecked")
            Class<? extends RuntimeException> targetType = (Class<? extends RuntimeException> type;

            //put method into r3s0lvr
            this.r3s0lvr.put(targetType.getName(), cur);
        }
    }

    public void receive(RuntimeException arg) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NullPointerException {
        String clazzName = arg.getClass().getName();

        //Select the correct method to invoke
        Method method = this.r3s0lvr.get(clazzName);

        //TODO null pointer cases have to be handled correctly
        method.invoke(this, arg);
    }

    public void log(ArithmeticException arg) {
        System.out.println("found a log function for " + ArithmeticException.class);
    }

    public void log(NullPointerException arg) {
        System.out.println("found a log function for " + NullPointerException.class);
    }
}

Apache FTP – a Java based FTP Server implementation

Apache FTP is a fully functioning ftp server completely implemented in Java. It is easily configurable via it’s java API and therefore ideal for testing.

Introduction
Using the Apache Server in your project is as easy as including the maven dependency.

<dependency>
            <groupId>org.apache.ftpserver</groupId>
            <artifactId>ftpserver-core</artifactId>
            <version>1.0.6</version>
</dependency>

and calling a couple of simple java methods.

new FtpServerFactory().createServer().start();

Well granted, the server would be rather useless, but it would be a fully fledged to server. Now onto some configuration.
For listening to a custom port you first need a listener factory, to create a listener and attach it to the server factory.

ListenerFactory listenerFactory = new ListenerFactory();
listenerFactory.setPort(this.port);
serverFactory.addListener("default", listenerFactory.createListener());

Further, to add users to your ftp server you need to add a User Manager:

UserManager um = new PropertiesUserManagerFactory().createUserManager();
BaseUser user = new BaseUser();
...
um.save(user);

Apache FTP Server inside a WAR deployed Web App
To deploy the server inside a webapp is a little bit tricky, because the file paths for the server’s root folder, as well as users’ home directories are configured as String properties. Fortunately we can use Spring to help us with determining the current folder.

<bean id="ftpServer" class="com.systemkern.ftp.server.FtpServerExample">
        <!-- ftp root relative to the context root -->
        <property name="ftpRoot" value="ftp"/>
</bean>

and use the File object provided by Spring to find out the absolute path:

public void setFtpRoot(File ftpRoot) {
    this.ftpRoot = ftpRoot;
}
 
...
 
String fullUserHome = this.ftpRoot.getAbsolutePath() +"/";
if (user.getHomeDirectory() != null
        && "/".equals( user.getHomeDirectory() ) == false)
    fullUserHome += user.getHomeDirectory();
cur.setHomeDirectory(fullUserHome);

Complete Reference File

The Spring Configuration

<bean id="ftpServer" class="com.systemkern.ftp.server.FtpServerExample">
    <property name="port" value="1234"/>
    <!-- ftp root relative to the context root -->
    <property name="ftpRoot" value="ftp"/>
    <property name="users">
        <list>
            <bean class="org.apache.ftpserver.usermanager.impl.BaseUser">
                <property name="name">          <value>user</value></property>
                <property name="password">      <value>pass</value></property>
                <property name="homeDirectory"> <value>/</value></property>
            </bean>
        </list>
    </property>
</bean>

The Java Test Class

package com.systemkern.ftp.server;
 
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PasswordEncryptor;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;

public class FtpServerTest {
    public static void main(String[] args) throws FtpException, IOException {
        FtpServerTest test = new FtpServerTest();
        test.users = new ArrayList<BaseUser>();
        BaseUser user = new BaseUser();
        user.setName("user");
        user.setPassword("pass");
        user.setHomeDirectory("ftp");
        test.users.add(user);
        test.init();
    }

    FtpServerFactory serverFactory = new FtpServerFactory();
    int port=21;
    ListenerFactory listenerFactory = new ListenerFactory();
    PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
    List<BaseUser> users = null;
    File ftpRoot; 
    FtpServer server;

    @PostConstruct
    public void init() throws FtpException, IOException {
        // set the port of the listener
        this.listenerFactory.setPort(this.port);
        // replace the default listener
        this.serverFactory.addListener("default", this.listenerFactory.createListener());
        //give write access to every user
        UserManager um = this.userManagerFactory.createUserManager();
        List<Authority> auths = Arrays.asList(new Authority[]{new WritePermission()});
        for (BaseUser cur : this.users) {
            String fullUserHome = this.ftpRoot.getAbsolutePath() +"/";
            if (cur.getHomeDirectory() != null && "/".equals( cur.getHomeDirectory() ) == false)
                fullUserHome += cur.getHomeDirectory();
            cur.setAuthorities(auths);
            cur.setHomeDirectory(fullUserHome);
            um.save(cur);
        }
         
        //start new server
        this.serverFactory.setUserManager( um );
        // start the server
        this.server = this.serverFactory.createServer();
        this.server.start();
         
    }
     
    @PreDestroy
    public void shutdown() {
        this.server.stop();
    }
     
     
/*
 * Getters and Setters
 */
    public void setPort(int port) {
        this.port = port;
    }

    public void setUsers(List<BaseUser> userList) {
        this.users = userList;
    }

    public void setFtpRoot(File ftpRoot) {
        this.ftpRoot = ftpRoot;
    }
}

How to configure SSH Key-Based authentification

SSH Key-Based authentication can be configured in two easy steps.
All you have to do is add the user-machine’s public key to the server’s authorized_keys file.
Therefore you have to:

  1. create a public key for your user-machine
  2. write the key to the server’s ~/.ssh/authorized_keys textfile

On your local machine a private-public ssh key pair is easily created executing the following command in your terminal app:
ssh-keygen

which will yield following output

Generating public/private rsa key pair.
Enter file in which to save the key (/Users/systemkern/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/systemkern/.ssh/id_rsa.
Your public key has been saved in /Users/systemkern/.ssh/id_rsa.pub.
The key fingerprint is:
11:22:33:44:55:66:77:88:99:00:aa:bb:cc:dd:ee:ff systemkern@systemkerns-mac
The key's randomart image is:
+--[ RSA 2048]----+
| S *+ . |
| .. |
| o B + |
| o . |
| . o . |
| ... |
| * . oo o |
| . =E + |
| . o |
+-----------------+
systemkerns-mac:~$

The program will ask you where the key file should be created also showing the default name in the output. In this exapmple the private key file will be created under ~/.ssh with the name id_rsa. The public key can be found in the same directory in the file id_rsa.pub

The optional passphrase will provide some additional protection to your login. Only if the passphrase is entered the key based authentication will work.

you can then issue the following command to save the public key on the server:
cat ~/.ssh/id_rsa.pub | ssh user@server “mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys”

voila!
you can now log in to your server authenticated by ssh instead of by password.

Generic Singletons with C#

C# gives you most of the generic powers that also Java has. So if one were so inclined he could write a generic singleton class. This approach would free implementing classes (and their developers) from handling the instance reference and providing the getInstance() method. Granted this is not a lot of work per instance but even an avalanche is made up from tiny snowflakes.

This example was written to be used inside the Unity game development framework. Unity takes care of the initialisation, so we only have to worry about keeping the reference.

Two base classes are needed to get around some limitations of C# generic implementations. An untyped class which stands at the root of the inheritance tree (“AbstractValueController”) and a typed Class which extends this BaseClass (“ValueController”).

1) The untyped BaseClass which I chose to declare abstract to make it more distinguishable:

public class AbstractValueController : MonoBehaviour {
}

2) The typed Class which contains the actual singleton logic:

public abstract class ValueController<SubType> : AbstractValueController
		where SubType : AbstractValueController {

	//the reference is saved as the root type but gets casted upon retrieval
	protected static AbstractValueController instance;
	public static SubType Instance { get { return (SubType) instance; } }

	//the Awake() Method is part of the UnityFramework and very similar to a constructor
	public virtual void Awake() {
		instance = this;
	}
}

3) An example implementing class which you want to be a singleton:

//class is typed with its own type for the singleton logic to work
public class Controller : ValueController<Controller> {
	//no singleton code needed  ... neat
}

Fuzzy Logic with jFuzzyLogic

jFuzzyLogic is an easy to use library for fuzzy logic computations.
After adding the Package to your projects classpath you only need a couple of lines of code to include and run fuzzy logic computations. Basically it is just a matter of setting variables, running the computation and then later retrieving the output parameters.

fis.setVariable("input1", arg1);
fis.setVariable("input2", arg2);

// Evaluate
fis.evaluate();
Variable out = fis.getVariable("out");
System.out.println("Output = "+out.getValue());

Sources: