Package com.kurento.kmf.spring

Source Code of com.kurento.kmf.spring.KurentoApplicationContextUtils

/*
* (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;

import com.kurento.kmf.common.exception.KurentoException;

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 the context
   *
   */
  public static synchronized 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();

    // We can't scan whole com.kurento.kmf package because there are classes
    // in classpath not designed to work with content-api
    kurentoApplicationContextInternalReference
        .scan("com.kurento.kmf.spring");
    kurentoApplicationContextInternalReference
        .scan("com.kurento.kmf.content");
    kurentoApplicationContextInternalReference
        .scan("com.kurento.kmf.repository");

    // 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"
        log.info("Found custom properties in 'jboss.server.config.dir': "
            + jbossServerConfigDir);
        inputStream = new FileInputStream(jbossServerConfigDir
            + kurentoProperties);

      } 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) {
      throw new KurentoException("Exception loading custom properties", 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 servletName
   * @return the context
   */
  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 synchronized 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<>();
    }

    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 synchronized 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 synchronized 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");

    try {
      ctx.addListener(KurentoServletContextListener.class);
    } catch (NullPointerException e) {
      // TODO: Workaround to make it compatible with/without SpringBoot.
      // This exception is thrown when this class is used with SpringBoot.
      // As workaround, SpringBoot application has to define the following
      // @Bean in a @Configuration class:
      //
      // @Bean
      // public ServletListenerRegistrationBean
      // <KurentoServletContextListener> listener(){
      // return new ServletListenerRegistrationBean<>(
      // new KurentoServletContextListener());
      // }
    }
  }

  public static synchronized 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;
  }
}
TOP

Related Classes of com.kurento.kmf.spring.KurentoApplicationContextUtils

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.