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

org.squirrelframework.foundation.component.SquirrelProvider Maven / Gradle / Ivy

Go to download

foundation module of squirrel framework which provided event driven infrastructure and a finite state machine implementation.

There is a newer version: 0.3.10
Show newest version
package org.squirrelframework.foundation.component;

import java.lang.reflect.Constructor;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.squirrelframework.foundation.util.ReflectUtils;
import org.squirrelframework.foundation.util.TypeReference;

/**
 * Central factory class for components used by squirrel-foundation.
 * 
 * @author Henry.He
 *
 */
public class SquirrelProvider implements SquirrelSingleton {

    private static SquirrelProvider instance = new SquirrelProvider();

    public static SquirrelProvider getInstance() {
        return instance;
    }

    public static void setInstance(SquirrelProvider instance) {
        SquirrelProvider.instance = instance;
    }

    private Map, Class> implementationRegistry = new ConcurrentHashMap, Class>();

    public  T newInstance(TypeReference typeRef) {
        return newInstance(typeRef, null, null);
    }
    
    public  T newInstance(TypeReference typeRef, Class[] argTypes, Object[] args) {
        Class clz = typeRef.getRawType();
        return clz.cast(newInstance(clz, argTypes, args));
    }
    
    /**
     * Create a new instance of the requested class using the internal registry.
     */
    public  T newInstance(Class clz) {
        return newInstance(clz, null, null);
    }
    
    /**
     * Create a new instance of the requested class using the internal registry.
     */
    public  T newInstance(Class clz, Class[] argTypes, Object[] args) {
        Class implementationClass = getImplementation(clz);
        if (args == null) {
            return postProcess(clz, ReflectUtils.newInstance(implementationClass));
        }
        Constructor constructor = ReflectUtils.getConstructor(implementationClass, argTypes);
        return postProcess(clz, ReflectUtils.newInstance(constructor, args));
    }
    
    private  T postProcess(Class clz, T component) {
        SquirrelPostProcessor postProcessor = 
                SquirrelPostProcessorProvider.getInstance().getPostProcessor(clz);
        if(postProcessor!=null && component!=null) {
            postProcessor.postProcess(component);
        }
        return component;
    }

    /**
     * Register the implementation class for a certain class. Note, if there is already an entry in the registry for
     * the class, then it will be overwritten.
     */
    public void register(Class clazz, Class implementationClass) {
        // TODO: handle the case that there is already an entry...
        implementationRegistry.put(clazz, implementationClass);
    }
    
    public void unregister(Class clazz) {
        implementationRegistry.remove(clazz);
    }
    
    public void clearRegistry() {
        implementationRegistry.clear();
    }

    /**
     * Return the current registered implementation. 
     * If class has register a implementation class, return register implementation class. If register class or implement 
     * class is an interface, try to find corresponding implementation class over naming convention. 
     * (implementation class simple name = interface class simple name + "Impl") First try to find the implementation class 
     * with conventional naming under the same package as interface class. If still not exist, try to find implementation class 
     * in (interface class package + ".impl").
     * 
     * @param clz registered class
     * @return current registered implementation
     */
    public  Class getImplementation(Class clz) {
        return resolveImplIfInterface(clz, new HashSet>());
    }

    private  Class resolveImplIfInterface(Class clz, Set> visited) {
        if (!visited.add(clz)) {
            throw new IllegalStateException("Registration cycles: " + visited);
        }

        if (!clz.isInterface()) {
            Class possibleImpl = fromRegistry(clz);
            if(possibleImpl!=null && !possibleImpl.isInterface()) 
                clz = possibleImpl;
            return clz;
        }

        Class possibleImpl = fromRegistry(clz);
        if (possibleImpl == null) {
            possibleImpl = findImplementationClass(clz);
            // We only register actual implementations so cannot introduce
            // cycles through this...
            register(clz, possibleImpl);
        }

        return resolveImplIfInterface(possibleImpl, visited);
    }

    private  Class fromRegistry(Class clz) {
        @SuppressWarnings("unchecked")
        Class impl = (Class) implementationRegistry.get(clz);
        return impl;
    }

    // find implementation class name according to programming convention
    @SuppressWarnings("unchecked")
    private  Class findImplementationClass(Class interfaceClass) {
        Class implementationClass = null;
        String implClassName = interfaceClass.getName() + "Impl";
        try {
            implementationClass = Class.forName(implClassName);
        } catch (ClassNotFoundException e) {
            implClassName = ReflectUtils.getPackageName(interfaceClass.getName())+
                    ".impl."+interfaceClass.getSimpleName()+"Impl";
            implementationClass = ReflectUtils.getClass(implClassName);
        }
        return (Class) implementationClass;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy