com.kurento.kmf.spring.KurentoApplicationContextUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.kurento.kmf.spring.KurentoApplicationContextUtils.java

Source

/*
 * (C) Copyright 2013 Kurento (http://kurento.org/)
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser General Public License
 * (LGPL) version 2.1 which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/lgpl-2.1.html
 *
 * 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.
 *
 */
package com.kurento.kmf.spring;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletContext;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.PropertyOverrideConfigurer;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.ServletContextResource;
import org.springframework.web.context.support.WebApplicationContextUtils;

public final class KurentoApplicationContextUtils {

    private static final Logger log = LoggerFactory.getLogger(KurentoApplicationContextUtils.class);

    private static final String KURENTO_SERVLET_CONTEXT_LISTENER_ATTRIBUTE_NAME = KurentoApplicationContextUtils.class
            + "AttributeName";

    // Is there any better mechanisms for enabling direct recovery of beans
    // (e.g. configurations)
    private static AnnotationConfigApplicationContext kurentoApplicationContextInternalReference;
    private static ConcurrentHashMap<String, AnnotationConfigApplicationContext> childContexts;

    private KurentoApplicationContextUtils() {
    }

    /**
     * This class returns the Spring KurentoApplicationContext, which is the
     * parent context for all specific Kurento Servlet contexts. In case a
     * pre-exiting Spring root WebApplicationContext if found, the returned
     * KurentoApplicationContext will be made child of this root context. When
     * necessary, this method creates the KurentoApplicationContext, so it
     * should never return null.
     * 
     * This method MUST NOT be called in ServletContextListeners, given that at
     * that stage there might not be information about the presence of a root
     * Spring root WebApplicationConext.
     * 
     * @param ctx
     * @return
     * 
     */
    public static AnnotationConfigApplicationContext createKurentoApplicationContext(ServletContext ctx) {
        Assert.notNull(ctx, "Cannot recover KurentoApplicationContext from a null ServletContext");
        Assert.isNull(kurentoApplicationContextInternalReference,
                "Pre-existing Kurento ApplicationContext found. Cannot create a new instance.");

        kurentoApplicationContextInternalReference = new AnnotationConfigApplicationContext();

        // Add or remove packages when required
        kurentoApplicationContextInternalReference.scan("com.kurento.kmf");

        // Recover root WebApplicationContext context just in case
        // application developer is using Spring
        WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(ctx);
        if (rootContext != null) {
            kurentoApplicationContextInternalReference.setParent(rootContext);
        }

        final String jbossServerConfigDir = System.getProperty("jboss.server.config.dir");
        final String kurentoPropertiesDir = System.getProperty("kurento.properties.dir");
        final String kurentoProperties = "/kurento.properties";
        InputStream inputStream = null;
        try {
            if (jbossServerConfigDir != null && new File(jbossServerConfigDir + kurentoProperties).exists()) {
                // First, look for JVM argument "jboss.server.config.dir"
                inputStream = new FileInputStream(jbossServerConfigDir + kurentoProperties);
                log.info("Found custom properties in 'jboss.server.config.dir': " + jbossServerConfigDir);
            } else if (kurentoPropertiesDir != null
                    && new File(kurentoPropertiesDir + kurentoProperties).exists()) {
                // Second, look for JVM argument "kurento.properties.dir"
                log.info("Found custom properties in 'kurento.properties.dir': " + kurentoPropertiesDir);
                inputStream = new FileInputStream(kurentoPropertiesDir + kurentoProperties);
            } else {
                // Third, look for properties in Servlet Context
                ServletContextResource servletContextResource = new ServletContextResource(ctx,
                        "/WEB-INF" + kurentoProperties);
                if (servletContextResource.exists()) {
                    log.info("Found custom properties in Servlet Context: /WEB-INF" + kurentoProperties);
                    inputStream = servletContextResource.getInputStream();
                }
            }

            if (inputStream != null) {
                Properties properties = new Properties();
                properties.load(inputStream);
                PropertyOverrideConfigurer propertyOverrideConfigurer = new PropertyOverrideConfigurer();
                propertyOverrideConfigurer.setProperties(properties);
                kurentoApplicationContextInternalReference.addBeanFactoryPostProcessor(propertyOverrideConfigurer);
                inputStream.close();
            }

        } catch (IOException e) {
            log.error("Exception loading custom properties", e);
            throw new RuntimeException(e);
        }

        kurentoApplicationContextInternalReference.refresh();
        return kurentoApplicationContextInternalReference;
    }

    public static boolean kurentoApplicationContextExists() {
        return kurentoApplicationContextInternalReference != null;
    }

    public static AnnotationConfigApplicationContext getKurentoApplicationContext() {
        return kurentoApplicationContextInternalReference;
    }

    /**
     * Returns a specific application context associated to a Kurento handler
     * servlet. This method returns null if the context does not exist.
     * 
     * @param servletClass
     * @param ctx
     * @return
     */
    public static AnnotationConfigApplicationContext getKurentoServletApplicationContext(Class<?> servletClass,
            String servletName) {
        Assert.notNull(servletClass, "Cannot recover KurentoServletApplicationContext from a null Servlet class");

        if (childContexts == null) {
            return null;
        }

        AnnotationConfigApplicationContext childAppContext = childContexts
                .get(servletClass.getName() + ":" + servletName);
        if (childAppContext == null) {
            return null;
        }

        return childAppContext;
    }

    public static AnnotationConfigApplicationContext createKurentoHandlerServletApplicationContext(
            Class<?> servletClass, String servletName, ServletContext sc, String handlerClassName) {
        Assert.notNull(sc, "Cannot create Kurento ServletApplicationContext from null ServletContext");
        Assert.notNull(servletClass, "Cannot create KurentoServletApplicationContext from a null Servlet class");
        Assert.notNull(servletClass, "Cannot create KurentoServletApplicationContext from a null Hanlder class");

        if (childContexts == null) {
            childContexts = new ConcurrentHashMap<String, AnnotationConfigApplicationContext>();
        }

        AnnotationConfigApplicationContext childContext = childContexts
                .get(servletClass.getName() + ":" + servletName);
        Assert.isNull(childContext, "Pre-existing context found associated to servlet class "
                + servletClass.getName() + " and servlet name " + servletName);

        childContext = new AnnotationConfigApplicationContext();
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClassName(handlerClassName);
        childContext.registerBeanDefinition(handlerClassName, beanDefinition);
        if (!kurentoApplicationContextExists()) {
            createKurentoApplicationContext(sc);
        }
        childContext.setParent(getKurentoApplicationContext());
        childContext.refresh();
        childContexts.put(servletClass.getName(), childContext);

        return childContext;
    }

    public static void closeAllKurentoApplicationContexts(ServletContext ctx) {
        Assert.notNull(ctx, "Cannot close contexts from a null ServletContext");

        if (childContexts != null) {
            for (AnnotationConfigApplicationContext childContext : childContexts.values()) {
                log.info("Closing Kurento Servlet Application Context " + childContext);
                childContext.close();
            }
        }
        childContexts = null;

        if (kurentoApplicationContextInternalReference != null) {
            log.info("Closing Kurento Application Context " + kurentoApplicationContextInternalReference);
            kurentoApplicationContextInternalReference.close();
        }
        kurentoApplicationContextInternalReference = null;
    }

    public static void processInjectionBasedOnApplicationContext(Object bean,
            AnnotationConfigApplicationContext appContext) {
        Assert.notNull(appContext,
                "Cannot process bean injection. Reason the specified ApplicationContext is null");
        Assert.notNull(bean, "Cannot process bean injection into null bean reference");
        AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
        bpp.setBeanFactory(appContext.getAutowireCapableBeanFactory());
        bpp.processInjection(bean);
    }

    public static void processInjectionBasedOnKurentoApplicationContext(Object bean) {
        Assert.notNull(kurentoApplicationContextInternalReference,
                "Cannot process bean injection. Reason Kurento ApplicationContext has not been initialized");
        Assert.notNull(bean, "Cannot process bean injection into null bean reference");
        AutowiredAnnotationBeanPostProcessor bpp = new AutowiredAnnotationBeanPostProcessor();
        bpp.setBeanFactory(kurentoApplicationContextInternalReference.getAutowireCapableBeanFactory());
        bpp.processInjection(bean);
    }

    public static <T> T getConfiguration(Class<T> configurationClass) {
        Assert.notNull(kurentoApplicationContextInternalReference,
                "Cannot access configuration before creating Kurento Application Context");

        T result = kurentoApplicationContextInternalReference.getBean(configurationClass);
        Assert.notNull(result,
                "No configuration has been found associated to type " + configurationClass.getName());

        return result;
    }

    public static Object getBean(String name, Object... args) {
        Assert.notNull(kurentoApplicationContextInternalReference,
                "Cannot get bean for the following reason: Kurento ApplicationContext has not been initlized.");
        return kurentoApplicationContextInternalReference.getBean(name, args);
    }

    public static Object getBean(String name) {
        Assert.notNull(kurentoApplicationContextInternalReference,
                "Cannot get bean for the following reason: Kurento ApplicationContext has not been initlized.");
        return kurentoApplicationContextInternalReference.getBean(name);

    }

    public static void registerKurentoServletContextListener(ServletContext ctx) {
        // Add listener for closing Kurento ApplicationContexts on container
        // shutdown

        if (ctx.getAttribute(KURENTO_SERVLET_CONTEXT_LISTENER_ATTRIBUTE_NAME) != null) {
            log.info("Kurento ServletContextListener already registered, we don't register it again ...");
            return;
        }
        log.info("Registering Kurento ServletContextListener ...");
        ctx.setAttribute(KURENTO_SERVLET_CONTEXT_LISTENER_ATTRIBUTE_NAME, "initialized");
        ctx.addListener(KurentoServletContextListener.class);
    }

    public static AnnotationConfigApplicationContext debugOnlyCreateKurentoApplicationContext() {
        Assert.isNull(kurentoApplicationContextInternalReference,
                "Pre-existing Kurento ApplicationContext found. Cannot create a new instance.");

        kurentoApplicationContextInternalReference = new AnnotationConfigApplicationContext();

        // Add or remove packages when required
        kurentoApplicationContextInternalReference.scan("com.kurento.kmf");

        kurentoApplicationContextInternalReference.refresh();
        return kurentoApplicationContextInternalReference;
    }
}