nz.co.senanque.vaadinsupport.application.SpringApplicationLoader.java Source code

Java tutorial

Introduction

Here is the source code for nz.co.senanque.vaadinsupport.application.SpringApplicationLoader.java

Source

/*******************************************************************************
 * Copyright (c)2014 Prometheus Consulting
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package nz.co.senanque.vaadinsupport.application;

import java.util.concurrent.atomic.AtomicLong;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ConfigurableWebApplicationContext;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.XmlWebApplicationContext;

import com.vaadin.Application;

/**
 * This is a helper class that loads the local Spring context for the Vaadin application.
 * It also acts as a factory bean for the application class which is already instantiated by Vaadin.
 * Much of the code is cloned over from Archie Cobbs <a href="http://dellroad-stuff.googlecode.com/">The dellroad-stuff Project</a>.
 * The reason for not using Archie's technique directly is that it requires us to extend his
 * application class and Vaadin's Touchkit requires us to extend a different class. So the bits
 * I need are delegated to this helper class where I can use them from any flavour of the Application
 * class.
 * @author Roger Parkinson
 *
 */
public class SpringApplicationLoader {

    private static final AtomicLong UNIQUE_INDEX = new AtomicLong();
    private static Logger log = LoggerFactory.getLogger(SpringApplicationLoader.class);
    private static final ThreadLocal<Application> CURRENT_APPLICATION = new ThreadLocal<Application>();

    public static ApplicationContext loadContext(Application application, HttpServletRequest request) {

        // Logging
        log.info("loading application context for Vaadin application " + application.getClass().getSimpleName());
        CURRENT_APPLICATION.set(application);

        // Find the application context associated with the servlet; it will be the parent
        ServletContext servletContext;
        try {
            // getServletContext() is a servlet AIP 3.0 method, so don't freak out if it's not there
            servletContext = (ServletContext) HttpServletRequest.class.getMethod("getServletContext")
                    .invoke(request);
        } catch (Exception e) {
            servletContext = ContextLoader.getCurrentWebApplicationContext().getServletContext();
        }
        WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(servletContext);

        // Create and configure a new application context for this Application instance
        ConfigurableWebApplicationContext context = new XmlWebApplicationContext();
        context.setId(
                ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + servletContext.getContextPath()
                        + "/" + application.getClass().getSimpleName() + "-" + UNIQUE_INDEX.incrementAndGet());
        context.setParent(parent);
        context.setServletContext(servletContext);
        //context.setServletConfig(??);
        context.setNamespace(application.getClass().getSimpleName());

        // Refresh context
        context.refresh();

        CURRENT_APPLICATION.set(null);
        return context;
    }

    public Application get() {
        return CURRENT_APPLICATION.get();
    }
}