org.beanlet.springframework.impl.SpringHelper.java Source code

Java tutorial

Introduction

Here is the source code for org.beanlet.springframework.impl.SpringHelper.java

Source

/*
 * ============================================================================
 * GNU Lesser General Public License
 * ============================================================================
 *
 * Beanlet - JSE Application Container.
 * Copyright (C) 2006  Leon van Zantvoort
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
 * 
 * Leon van Zantvoort
 * 243 Acalanes Drive #11
 * Sunnyvale, CA 94086
 * USA
 *
 * zantvoort@users.sourceforge.net
 * http://beanlet.org
 */
package org.beanlet.springframework.impl;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import org.beanlet.annotation.AnnotationDeclaration;
import org.beanlet.annotation.ConstructorElement;
import org.beanlet.annotation.ConstructorParameterElement;
import org.beanlet.annotation.Element;
import org.beanlet.annotation.MethodElement;
import org.beanlet.annotation.MethodParameterElement;
import org.beanlet.annotation.PackageElement;
import org.beanlet.annotation.TypeElement;
import org.beanlet.plugin.BeanletConfiguration;
import org.beanlet.springframework.SpringContext;
import org.beanlet.springframework.SpringResource;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReader;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.PropertiesBeanDefinitionReader;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContextException;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;

/**
 *
 * @author Leon van Zantvoort
 */
public final class SpringHelper {

    private static final WeakHashMap<ClassLoader, Map<SpringContext, ListableBeanFactory>> factories = new WeakHashMap<ClassLoader, Map<SpringContext, ListableBeanFactory>>();

    private SpringHelper() {
    }

    public static synchronized ListableBeanFactory getListableBeanFactory(BeanletConfiguration<?> configuration,
            Element element) {
        SpringContext springContext = getSpringContext(configuration, element);
        if (springContext == null) {
            throw new ApplicationContextException("No spring context specified.");
        }
        final ClassLoader loader = configuration.getComponentUnit().getClassLoader();
        Map<SpringContext, ListableBeanFactory> map = factories.get(loader);
        if (map == null) {
            map = new HashMap<SpringContext, ListableBeanFactory>();
            factories.put(loader, map);
        }
        ListableBeanFactory factory = map.get(springContext);
        if (factory == null) {
            ClassLoader org = null;
            try {
                org = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
                    public ClassLoader run() {
                        // PERMISSION: java.lang.RuntimePermission getClassLoader
                        ClassLoader org = Thread.currentThread().getContextClassLoader();
                        // PERMISSION: java.lang.RuntimePermission setContextClassLoader
                        Thread.currentThread().setContextClassLoader(loader);
                        return org;
                    }
                });
                if (springContext.applicationContext()) {
                    factory = new GenericApplicationContext();
                } else {
                    factory = new DefaultListableBeanFactory();
                }
                // Do not create spring context in priviliged scope!
                for (SpringResource r : springContext.value()) {
                    String path = r.value();
                    Resource resource = null;
                    BeanDefinitionReader reader = null;
                    switch (r.type()) {
                    case CLASSPATH:
                        resource = new ClassPathResource(path);
                        break;
                    case FILESYSTEM:
                        resource = new FileSystemResource(path);
                        break;
                    case URL:
                        resource = new UrlResource(path);
                        break;
                    default:
                        assert false : r.type();
                    }
                    switch (r.format()) {
                    case XML:
                        reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) factory);
                        break;
                    case PROPERTIES:
                        reader = new PropertiesBeanDefinitionReader((BeanDefinitionRegistry) factory);
                        break;
                    default:
                        assert false : r.format();
                    }
                    if (resource != null && resource.exists()) {
                        reader.loadBeanDefinitions(resource);
                    }
                }
                if (factory instanceof ConfigurableApplicationContext) {
                    ((ConfigurableApplicationContext) factory).refresh();
                }
                map.put(springContext, factory);
            } catch (RuntimeException e) {
                throw e;
            } catch (Exception e) {
                throw new ApplicationContextException("Failed to construct spring "
                        + (springContext.applicationContext() ? "application context" : "bean factory") + ".", e);
            } finally {
                final ClassLoader tmp = org;
                AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    public Object run() {
                        // PERMISSION: java.lang.RuntimePermission setContextClassLoader
                        Thread.currentThread().setContextClassLoader(tmp);
                        return null;
                    }
                });
            }
        }
        return factory;
    }

    public static SpringContext getSpringContext(BeanletConfiguration<?> configuration, Element element) {
        return getSpringContext(configuration, element, false);
    }

    public static SpringContext getSpringContext(BeanletConfiguration<?> configuration, Element element,
            boolean memberOnly) {
        final SpringContext springContext;
        AnnotationDeclaration<SpringContext> declaration = configuration.getAnnotationDomain()
                .getDeclaration(SpringContext.class);
        SpringContext tmp = declaration.getDeclaredAnnotation(element);
        if (tmp != null) {
            springContext = tmp;
        } else {
            if (element instanceof MethodParameterElement) {
                tmp = configuration.getAnnotationDomain().getDeclaration(SpringContext.class)
                        .getAnnotation(MethodElement.instance(((MethodParameterElement) element).getMethod()));
            } else if (element instanceof ConstructorParameterElement) {
                tmp = configuration.getAnnotationDomain().getDeclaration(SpringContext.class).getAnnotation(
                        ConstructorElement.instance(((ConstructorParameterElement) element).getConstructor()));
            }
            if (tmp != null) {
                springContext = tmp;
            } else if (!memberOnly) {
                Class<?> type = element.getMember().getDeclaringClass();
                tmp = declaration.getDeclaredAnnotation(TypeElement.instance(type));
                if (tmp != null) {
                    springContext = tmp;
                } else {
                    tmp = declaration.getDeclaredAnnotation(PackageElement.instance(type.getPackage()));
                    if (tmp != null) {
                        springContext = tmp;
                    } else {
                        springContext = null;
                    }
                }
            } else {
                springContext = null;
            }
        }
        return springContext;
    }
}