001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.xbean.spring.jndi; 018 019 import java.util.concurrent.ConcurrentHashMap; 020 021 import org.apache.commons.logging.Log; 022 import org.apache.commons.logging.LogFactory; 023 import org.springframework.beans.factory.BeanFactory; 024 import org.springframework.core.io.ClassPathResource; 025 import org.springframework.core.io.Resource; 026 import org.springframework.core.io.ResourceEditor; 027 import org.apache.xbean.spring.context.impl.XBeanXmlBeanFactory; 028 029 import javax.naming.Context; 030 import javax.naming.NamingException; 031 import javax.naming.spi.InitialContextFactory; 032 033 import java.util.HashMap; 034 import java.util.Hashtable; 035 import java.util.Map; 036 037 /** 038 * A simple JNDI initial context which loads the JNDI namespace from a spring.xml configuration file. 039 * The spring.xml configuration file can be specified by the {@link Context#PROVIDER_URL} property 040 * which can be any spring resource string (classpath://foo.xml, or file://foo/bar.xml or a URL) 041 * otherwise the jndi.xml file is found on the classpath. 042 * 043 * @version $Revision: 657 $ 044 */ 045 public class SpringInitialContextFactory implements InitialContextFactory { 046 private static final transient Log log = LogFactory.getLog(SpringInitialContextFactory.class); 047 048 private static Map cache = new HashMap(); 049 050 private static Context singleton; 051 052 /** 053 * A factory method which can be used to initialise a singleton JNDI context from inside a Spring.xml 054 * such that future calls to new InitialContext() will reuse it 055 */ 056 public static Context makeInitialContext() { 057 singleton = new DefaultContext(); 058 return singleton; 059 } 060 061 public Context getInitialContext(Hashtable environment) throws NamingException { 062 if (singleton != null) { 063 return singleton; 064 } 065 Resource resource = null; 066 Object value = environment.get(Context.PROVIDER_URL); 067 String key = "jndi.xml"; 068 if (value == null) { 069 resource = new ClassPathResource(key); 070 } 071 else { 072 if (value instanceof Resource) { 073 resource = (Resource) value; 074 } 075 else { 076 ResourceEditor editor = new ResourceEditor(); 077 key = value.toString(); 078 editor.setAsText(key); 079 resource = (Resource) editor.getValue(); 080 } 081 } 082 BeanFactory context = loadContext(resource, key); 083 Context answer = (Context) context.getBean("jndi"); 084 if (answer == null) { 085 log.warn("No JNDI context available in JNDI resource: " + resource); 086 answer = new DefaultContext(environment, new ConcurrentHashMap()); 087 } 088 return answer; 089 } 090 091 protected BeanFactory loadContext(Resource resource, String key) { 092 synchronized (cache) { 093 BeanFactory answer = (BeanFactory) cache.get(key); 094 if (answer == null) { 095 answer = createContext(resource); 096 cache.put(key, answer); 097 } 098 return answer; 099 } 100 } 101 102 protected BeanFactory createContext(Resource resource) { 103 log.info("Loading JNDI context from: " + resource); 104 return new XBeanXmlBeanFactory(resource); 105 } 106 }