View Javadoc

1   /**
2    * Copyright 2005-2006 the original author or authors.
3    *
4    * Licensed under the Gnu General Pubic License, Version 2.0 (the
5    * "License"); you may not use this file except in compliance with
6    * the License. You may obtain a copy of the License at
7    *
8    *      http://www.opensource.org/licenses/gpl-license.php
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13   * See the Gnu General Public License for more details.
14   */
15  package org.figure8.join.core;
16  
17  import org.figure8.join.util.LogUtil;
18  
19  import org.apache.commons.logging.Log;
20  import org.springframework.context.ApplicationContext;
21  import org.springframework.context.ApplicationContextException;
22  import org.springframework.context.event.ContextRefreshedEvent;
23  import org.springframework.web.context.ContextLoader;
24  import org.springframework.web.context.support.WebApplicationContextUtils;
25  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
26  
27  import javax.servlet.ServletContext;
28  /**
29   * This is a wrapper around Spring applicative main context.
30   * @author <a href="mailto:laurent.broudoux@free.fr">Laurent Broudoux</a>
31   * @version $Revision: 1.2 $
32   */
33  public class ContainerContextHandler{
34  
35     // Static -------------------------------------------------------------------
36  
37     /** Get a commons logger */
38     private static Log log = LogUtil.getLog(ContainerContextHandler.class);
39  
40  
41     // Attributes ---------------------------------------------------------------
42  
43     /** Singleton own instance */
44     private static ContainerContextHandler me = null;
45  
46     /** The servlet context for whom handling Spring context */
47     private ServletContext servletContext = null;
48     /** The handled Sptring context */
49     private ApplicationContext applicationContext = null;
50     /** The handled Spring bean factory */
51     private DefaultListableBeanFactory beanFactory = null;
52  
53  
54     // Constructors -------------------------------------------------------------
55  
56     /** Creates a new instance of ContainerContextHandler */
57     private ContainerContextHandler(){
58        beanFactory = new DefaultListableBeanFactory(null);
59     }
60  
61     
62     // Public -------------------------------------------------------------------
63  
64     /** @return true if context is setup (ie. <b>applicatinoContext</b> not null) */
65     public boolean isSetup(){
66        return applicationContext != null;
67     }
68  
69     /**
70      * Assign the servlet context for whom Spring context will be handled
71      * @param context The servlet context for whom handling Spring context
72      */
73     public void setServletContext(ServletContext context){
74        servletContext = context;
75        setApplicationContext(WebApplicationContextUtils.getWebApplicationContext(context));
76     }
77     /** @return The servlet context for whom Spring context is handled */
78     public ServletContext getServletContext(){
79        return servletContext;
80     }
81  
82     /**
83      * Set the handled Spring applicative context.
84      * @param appContext The context to wrapp
85      * @throws ApplicationContextException if problem occurs during beanFactory initialization
86      */
87     public void setApplicationContext(ApplicationContext appContext) throws ApplicationContextException{
88        applicationContext = appContext;
89        beanFactory = new DefaultListableBeanFactory(appContext);
90     }
91     /** @return Handled String context (if any) */
92     public ApplicationContext getApplicationContext(){
93        return applicationContext;
94     }
95  
96     /**
97      * Retrieve a component from Spring handled context.
98      * @param key Key identifier of the component to retrieve
99      * @return The component denoted by <b>key</b>
100     * @throws IllegalStateException if no Spring context is handled
101     * @throws InvalidParameterException if key is null or component cannot be found.
102     */
103    public Object getComponent(String key) throws IllegalStateException, InvalidParameterException{
104       if (applicationContext == null){
105          log.fatal("Spring Application context has not been set");
106          throw new IllegalStateException("Spring Application context has not been set");
107       }
108       if (key == null){
109          log.error("The component key cannot be null");
110          throw new InvalidParameterException("The component key cannot be null");
111       }
112       try{
113          // Try getting bean, wrap exception into invalid parameter one.
114          return applicationContext.getBean(key.toString());
115       }
116       catch (Exception e){
117          log.error("The component denoted by '" + key + "' cannot be found within context");
118          throw new InvalidParameterException("'" + key + "' component cannot be found within context", e);
119       }
120     }
121 
122    /**
123     * Register a component as a singleton within Spring handled application
124     * context and the web tier servlet context if present.
125     * @param key The key to use for registring singleton
126     * @param component The component to register
127     * @throws IllegalStateException if no Spring context is handled
128     * @throws InvalidParameterException if key is null or component already exists
129     */
130    public void registerComponent(String key, Object component) throws IllegalStateException, InvalidParameterException{
131       if (applicationContext == null){
132          log.fatal("Spring Application context has not been set");
133          throw new IllegalStateException("Spring Application context has not been set");
134       }
135       if (key == null){
136          log.error("The component key cannot be null");
137          throw new InvalidParameterException("The component key cannot be null");
138       }
139       if (applicationContext.containsBean(key)){
140          log.error("A component with the key '" + key + "' already exists in Application context");
141          throw new InvalidParameterException("A component with this key already exists in context");
142       }
143       try{
144          // Register this component within bean factory of application context.
145          beanFactory.registerSingleton(key, component);
146          // Register this component as a servlet context attribute.
147          servletContext.setAttribute(key, component);
148       }
149       catch (Exception e){
150          throw new InvalidParameterException("A component with this key already exists in context");
151       }
152    }
153 
154    /**
155     * Refresh or create the handled String applicative context.
156     * If it exists, it is first closed. Then, it is loaded using
157     * the <code>ContainerContextLoader</code> implementation.
158     */
159    public synchronized void refresh(){
160       ContextLoader loader = new ContainerContextLoader();
161       ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
162       if (ctx != null)
163          loader.closeWebApplicationContext(getServletContext());
164       loader.initWebApplicationContext(getServletContext());
165       if (getApplicationContext() == null)
166          setApplicationContext(WebApplicationContextUtils.getWebApplicationContext(getServletContext()));
167       contextReloaded();
168    }
169 
170    /** @return The running instance of ContainerContextHandler */
171    public static ContainerContextHandler getInstance(){
172       if (me == null)
173          me = new ContainerContextHandler();
174       return me;
175    }
176 
177 
178    // Protected ----------------------------------------------------------------
179 
180    /** Publish a <code>ContextRefreshedEvent</code> on applicationContext */
181    protected void contextReloaded(){
182       // Refresh application context from servlet context.
183       setApplicationContext(WebApplicationContextUtils.getWebApplicationContext(servletContext));
184       // Publish event.
185       if (applicationContext != null)
186          applicationContext.publishEvent(new ContextRefreshedEvent(applicationContext));
187    }
188 }