/*
 * Copyright 2002-2011 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.jndi;

import java.util.Properties;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.springframework.core.env.PropertySource;

/**
 * {@link PropertySource} implementation that reads properties from
 * a JNDI {@link Context}.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 * @see Context#lookup(String)
 * @see org.springframework.web.context.support.StandardServletEnvironment
 */
public class JndiPropertySource extends PropertySource<Context> {

	/** JNDI context property source name: {@value} */
	public static final String JNDI_PROPERTY_SOURCE_NAME = "jndiPropertySource";

	/**
	 * Name of property used to determine if a {@link JndiPropertySource}
	 * should be registered by default: {@value}
	 */
	public static final String JNDI_PROPERTY_SOURCE_ENABLED_FLAG = "jndiPropertySourceEnabled";

	/**
	 * Create a new {@code JndiPropertySource} with the default name
	 * {@value #JNDI_PROPERTY_SOURCE_NAME} and create a new {@link InitialContext}
	 * as the source object.
	 * @throws JndiLookupFailureException if a new {@link InitialContext}
	 * cannot be created.
	 */
	public JndiPropertySource() throws JndiLookupFailureException {
		this(JNDI_PROPERTY_SOURCE_NAME, createInitialContext(null));
	}

	/**
	 * Create a new {@code JndiPropertySource} with the given name and
	 * create a new {@link InitialContext} as the source object.
	 * @throws JndiLookupFailureException if a new {@link InitialContext}
	 * cannot be created.
	 */
	public JndiPropertySource(String name) throws JndiLookupFailureException {
		this(name, createInitialContext(null));
	}

	/**
	 * Create a new {@code JndiPropertySource} with the given name and
	 * use the given jndiEnvironment properties to create a new
	 * {@link InitialContext} as the source object.
	 * @throws JndiLookupFailureException if a new {@link InitialContext}
	 * cannot be created.
	 */
	public JndiPropertySource(String name, Properties jndiEnvironment) throws JndiLookupFailureException {
		this(name, createInitialContext(jndiEnvironment));
	}

	/**
	 * Create a new {@code JndiPropertySource} with the given name and
	 * JNDI {@link Context}.
	 */
	public JndiPropertySource(String name, Context source) {
		super(name, source);
	}

	/**
	 * Look up and return the given name from the source JNDI {@link Context}.
	 */
	@Override
	public Object getProperty(String name) throws JndiLookupFailureException {
		try {
			return this.source.lookup(name);
		} catch (NamingException ex) {
			throw new JndiLookupFailureException("unable to look up name" + name, ex);
		}
	}

	private static Context createInitialContext(Properties jndiEnvironment) {
		try {
			return new InitialContext(jndiEnvironment);
		} catch (NamingException ex) {
			throw new JndiLookupFailureException("unable to create InitialContext", ex);
		}
	}

}

@@ -911,18 +911,18 @@
 from
-%0A *
  a JNDI
+%0A *
  %7B@l
@@ -934,16 +934,281 @@
 ontext%7D.
+ All properties retrieved through %7B@link #getProperty(String)%7D will%0A * automatically be prefixed with %22java:comp/env/%22 when executing the actual%0A * %7B@link Context#lookup(String)%7D call. This default can be overridden using%0A * %7B@link #setJndiPrefix(String)%7D property.
 %0A *%0A * @
@@ -3201,20 +3201,62 @@
 /**%0A%09 * 
-L
+%7B@inheritDoc%7D%0A%09 * %3Cp%3EThis implementation l
 ook
+s
  up and 
@@ -3261,16 +3261,17 @@
 d return
+s
  the giv
@@ -3294,24 +3294,28 @@
  source JNDI
+%0A%09 *
  %7B@link Cont
@@ -3323,254 +3323,547 @@
 xt%7D.
-%0A%09 */%0A%09@Override%0A%09public Object getProperty(String name) throws JndiLookupFailureException %7B%0A%09%09try %7B%0A%09%09%09return this.source.lookup(name);%0A%09%09%7D catch (NamingException ex) %7B%0A%09%09%09throw new JndiLookupFailureException(%22unable to look up name%22 + name, ex)
+ If a %7B@link NamingException%7D is thrown during the call to%0A%09 * %7B@link Context#lookup(String)%7D, returns %7B@code null%7D and issue a DEBUG-level log%0A%09 * statement with the exception message.%0A%09 */%0A%09@Override%0A%09public Object getProperty(String name) %7B%0A%09%09try %7B%0A%09%09%09Object value = this.source.lookup(name);%0A%09%09%09logger.debug(%22Context#lookup(%22 + name + %22) returned: %5B%22 + value + %22%5D%22);%0A%09%09%09return value;%0A%09%09%7D catch (NamingException ex) %7B%0A%09%09%09logger.debug(%22Context#lookup(%22 + name + %22) threw NamingException with message: %22 + ex.getMessage());%0A%09%09%09return null
 ;%0A%09%09

Return null from JndiPropertySource on lookup failure