Package org.apache.james.protocols.lib.mock

Source Code of org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader

package org.apache.james.protocols.lib.mock;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.configuration.Configuration;
import org.apache.james.protocols.api.handler.ProtocolHandler;
import org.apache.james.protocols.lib.handler.ProtocolHandlerLoader;

public class MockProtocolHandlerLoader implements ProtocolHandlerLoader{

    @Override
    public ProtocolHandler load(String name, Configuration config) throws LoadingException {
        try {
            ProtocolHandler obj = create(name);
            injectResources(obj);
            postConstruct(obj);
            synchronized (this) {
                loaderRegistry.add(obj);
            }
            return obj;
        } catch (Exception e) {
            throw new LoadingException("Unable to load protocolhandler", e);
        }
    }

    private final Map<String, Object> servicesByName = new HashMap<String, Object>();
    public Object get(String name) {
        Object service = servicesByName.get(name);
        return service;
    }

    public void put(String role, Object service) {
        servicesByName.put(role, service);
    }

    private final List<Object> loaderRegistry = new ArrayList<Object>();

    protected ProtocolHandler create(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (ProtocolHandler) Thread.currentThread().getContextClassLoader().loadClass(className).newInstance();
    }

    /**
     * Dispose all loaded instances by calling the method of the instances which
     * is annotated with @PreDestroy
     */
    public synchronized void dispose() {
        for (Object aLoaderRegistry : loaderRegistry) {
            try {
                preDestroy(aLoaderRegistry);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        loaderRegistry.clear();
    }

    private void postConstruct(Object resource) throws IllegalAccessException, InvocationTargetException {
        Method[] methods = resource.getClass().getMethods();
        for (Method method : methods) {
            PostConstruct postConstructAnnotation = method.getAnnotation(PostConstruct.class);
            if (postConstructAnnotation != null) {
                Object[] args = {};
                method.invoke(resource, args);

            }
        }
    }

    private void preDestroy(Object resource) throws IllegalAccessException, InvocationTargetException {
        Method[] methods = resource.getClass().getMethods();
        for (Method method : methods) {
            PreDestroy preDestroyAnnotation = method.getAnnotation(PreDestroy.class);
            if (preDestroyAnnotation != null) {
                Object[] args = {};
                method.invoke(resource, args);

            }
        }
    }

    private void injectResources(Object resource) {
        final Method[] methods = resource.getClass().getMethods();
        for (Method method : methods) {
            final Inject injectAnnotation = method.getAnnotation(Inject.class);
            if (injectAnnotation != null) {
                String name = null;
                Annotation[][] paramAnnotations = method.getParameterAnnotations();
                if (paramAnnotations.length == 1) {
                    if (paramAnnotations[0].length ==1) {
                        if (paramAnnotations[0][0].annotationType().equals(Named.class)) {
                            name = ((Named) paramAnnotations[0][0]).value();
                        }
                    }
                }
                if (name == null) {
                    throw new UnsupportedOperationException("@Inject annotation without @Named specified is not supported by this implementation");
                } else {
                    // Name indicates a service
                    final Object service = getObjectForName(name);
                    if (service == null) {
                        throw new RuntimeException("Injection failed for object " + resource + " on method " + method + " with resource name " + name + ", because no mapping was found");
                    } else {
                        try {
                            Object[] args = { service };
                            method.invoke(resource, args);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException("Injection failed for object " + resource + " on method " + method + " with resource " + service, e);
                        } catch (IllegalArgumentException e) {
                            throw new RuntimeException("Injection failed for object " + resource + " on method " + method + " with resource " + service, e);
                        } catch (InvocationTargetException e) {
                            throw new RuntimeException("Injection failed for object " + resource + " on method " + method + " with resource " + service, e);
                        }
                    }
                }
            }
        }
    }

    public Object getObjectForName(String name) {
        return get(name);
    }

}
TOP

Related Classes of org.apache.james.protocols.lib.mock.MockProtocolHandlerLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.