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