All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.squirrelframework.foundation.fsm.StateMachineBuilderFactory Maven / Gradle / Ivy

package org.squirrelframework.foundation.fsm;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.squirrelframework.foundation.component.SquirrelProvider;
import org.squirrelframework.foundation.util.TypeReference;

/**
 * State machine builder factory to create the state machine builder. Here we use {@link SquirrelProvider} to create the 
 * builder, so user can register different implementation class of {@link StateMachineBuilder} to instantiate different 
 * builder. And also user can register different type of post processor to post process created builder.
 * 
 * @author Henry.He
 *
 */
public class StateMachineBuilderFactory {
    
    public static UntypedStateMachineBuilder create(Class stateMachineClazz) {
        return create(stateMachineClazz, new Class[0]);
    }
    
    public static UntypedStateMachineBuilder create(Class stateMachineClazz, 
            Class... extraConstParamTypes) {
        final StateMachineBuilder builder = 
                create(stateMachineClazz, Object.class, Object.class, Object.class, extraConstParamTypes);
        return create(builder);
    }
    
    public static UntypedStateMachineBuilder create(
            final StateMachineBuilder builder) {
        return (UntypedStateMachineBuilder) Proxy.newProxyInstance(
                UntypedStateMachineBuilder.class.getClassLoader(), 
                new Class[]{UntypedStateMachineBuilder.class}, 
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args)
                            throws Throwable {
                        try {
                            String methodName = method.getName();
                            if(methodName.equals("newUntypedStateMachine") || methodName.equals("newAnyStateMachine")) {
                                Object fsmInstance = null;
                                if(args.length==3 && StateMachineConfiguration.class.isAssignableFrom(args[1].getClass()) && 
                                        (args[2]==null || args[2].getClass().isArray())) {
                                    fsmInstance = builder.newStateMachine(args[0], 
                                            (StateMachineConfiguration)args[1], (Object[])args[2]);
                                } else if(args.length==2 && (args[1]==null || args[1].getClass().isArray())) {
                                    fsmInstance = builder.newStateMachine(args[0], (Object[])args[1]);
                                } else if(args.length==1) {
                                    fsmInstance = builder.newStateMachine(args[0]);
                                } else {
                                    throw new IllegalArgumentException("Illegal argument number.");
                                }
                                return fsmInstance;
                            }
                            return method.invoke(builder, args);
                        } catch(InvocationTargetException e) {
                            throw e.getTargetException();
                        }
                    }
                });
    }
    
    public static , S, E, C> StateMachineBuilder create(
            Class stateMachineClazz, Class stateClazz, Class eventClazz, Class contextClazz) {
        return create(stateMachineClazz, stateClazz, eventClazz, contextClazz, new Class[0]);
    }
    
    public static , S, E, C> StateMachineBuilder create(
            Class stateMachineClazz, Class stateClazz, Class eventClazz, Class contextClazz, 
            Class... extraConstParamTypes) {
        return SquirrelProvider.getInstance().newInstance(new TypeReference>() {}, 
                new Class[] { Class.class, Class.class, Class.class, Class.class, Class[].class }, 
                new Object[] { stateMachineClazz, stateClazz, eventClazz, contextClazz, extraConstParamTypes });
    }
}