View Javadoc

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