View Javadoc

1   /*
2    * $Id: SpringInitialContextFactory.java 21939 2011-05-18 13:32:09Z aperepel $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.config.spring.jndi;
12  
13  import java.util.HashMap;
14  import java.util.Hashtable;
15  import java.util.Map;
16  import java.util.concurrent.ConcurrentHashMap;
17  
18  import javax.naming.Context;
19  import javax.naming.NamingException;
20  import javax.naming.spi.InitialContextFactory;
21  
22  import org.apache.commons.logging.Log;
23  import org.apache.commons.logging.LogFactory;
24  import org.springframework.beans.factory.BeanFactory;
25  import org.springframework.context.support.AbstractXmlApplicationContext;
26  import org.springframework.core.io.ClassPathResource;
27  import org.springframework.core.io.Resource;
28  import org.springframework.core.io.ResourceEditor;
29  
30  /**
31   * TODO
32   */
33  public class SpringInitialContextFactory implements InitialContextFactory
34  {
35      private static final transient Log log = LogFactory.getLog(SpringInitialContextFactory.class);
36  
37      private static Map cache = new HashMap();
38  
39      private static Context singleton;
40  
41      /**
42       * A factory method which can be used to initialise a singleton JNDI context from
43       * inside a Spring.xml such that future calls to new InitialContext() will reuse
44       * it
45       */
46      public static Context makeInitialContext()
47      {
48          singleton = new DefaultSpringJndiContext();
49          return singleton;
50      }
51  
52      public Context getInitialContext(Hashtable environment) throws NamingException
53      {
54          if (singleton != null)
55          {
56              return singleton;
57          }
58          Resource resource = null;
59          Object value = environment.get(Context.PROVIDER_URL);
60          String key = "jndi.xml";
61          if (value == null)
62          {
63              resource = new ClassPathResource(key);
64          }
65          else
66          {
67              if (value instanceof Resource)
68              {
69                  resource = (Resource) value;
70              }
71              else
72              {
73                  ResourceEditor editor = new ResourceEditor();
74                  key = value.toString();
75                  editor.setAsText(key);
76                  resource = (Resource) editor.getValue();
77              }
78          }
79          BeanFactory context = loadContext(resource, key);
80          Context answer = (Context) context.getBean("jndi");
81          if (answer == null)
82          {
83              log.warn("No JNDI context available in JNDI resource: " + resource);
84              answer = new DefaultSpringJndiContext(environment, new ConcurrentHashMap());
85          }
86          return answer;
87      }
88  
89      protected BeanFactory loadContext(Resource resource, String key)
90      {
91          synchronized (cache)
92          {
93              BeanFactory answer = (BeanFactory) cache.get(key);
94              if (answer == null)
95              {
96                  answer = createContext(resource);
97                  cache.put(key, answer);
98              }
99              return answer;
100         }
101     }
102 
103     protected BeanFactory createContext(Resource resource)
104     {
105         log.info("Loading JNDI context from: " + resource);
106         return new SpringInitialContextApplicationContext(new Resource[]{resource});
107     }
108 
109     /**
110      * Simple implementation of AbstractXmlApplicationContext that allows
111      * {@link Resource} to be used in the constructor
112      */
113     class SpringInitialContextApplicationContext extends AbstractXmlApplicationContext
114     {
115         private Resource[] configResources;
116 
117         public SpringInitialContextApplicationContext(Resource[] resources)
118         {
119             super();
120             configResources = resources;
121             refresh();
122         }
123 
124         protected Resource[] getConfigResources()
125         {
126             return configResources;
127         }
128     }
129 
130 }