001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.jndi; 018 019import javax.naming.NamingException; 020 021import org.springframework.lang.Nullable; 022import org.springframework.util.Assert; 023 024/** 025 * Convenient superclass for classes that can locate any number of JNDI objects. 026 * Derives from JndiAccessor to inherit the "jndiTemplate" and "jndiEnvironment" 027 * bean properties. 028 * 029 * <p>JNDI names may or may not include the "java:comp/env/" prefix expected 030 * by Java EE applications when accessing a locally mapped (ENC - Environmental 031 * Naming Context) resource. If it doesn't, the "java:comp/env/" prefix will 032 * be prepended if the "resourceRef" property is true (the default is 033 * <strong>false</strong>) and no other scheme (e.g. "java:") is given. 034 * 035 * @author Juergen Hoeller 036 * @since 1.1 037 * @see #setJndiTemplate 038 * @see #setJndiEnvironment 039 * @see #setResourceRef 040 */ 041public abstract class JndiLocatorSupport extends JndiAccessor { 042 043 /** JNDI prefix used in a Java EE container. */ 044 public static final String CONTAINER_PREFIX = "java:comp/env/"; 045 046 047 private boolean resourceRef = false; 048 049 050 /** 051 * Set whether the lookup occurs in a Java EE container, i.e. if the prefix 052 * "java:comp/env/" needs to be added if the JNDI name doesn't already 053 * contain it. Default is "false". 054 * <p>Note: Will only get applied if no other scheme (e.g. "java:") is given. 055 */ 056 public void setResourceRef(boolean resourceRef) { 057 this.resourceRef = resourceRef; 058 } 059 060 /** 061 * Return whether the lookup occurs in a Java EE container. 062 */ 063 public boolean isResourceRef() { 064 return this.resourceRef; 065 } 066 067 068 /** 069 * Perform an actual JNDI lookup for the given name via the JndiTemplate. 070 * <p>If the name doesn't begin with "java:comp/env/", this prefix is added 071 * if "resourceRef" is set to "true". 072 * @param jndiName the JNDI name to look up 073 * @return the obtained object 074 * @throws NamingException if the JNDI lookup failed 075 * @see #setResourceRef 076 */ 077 protected Object lookup(String jndiName) throws NamingException { 078 return lookup(jndiName, null); 079 } 080 081 /** 082 * Perform an actual JNDI lookup for the given name via the JndiTemplate. 083 * <p>If the name doesn't begin with "java:comp/env/", this prefix is added 084 * if "resourceRef" is set to "true". 085 * @param jndiName the JNDI name to look up 086 * @param requiredType the required type of the object 087 * @return the obtained object 088 * @throws NamingException if the JNDI lookup failed 089 * @see #setResourceRef 090 */ 091 protected <T> T lookup(String jndiName, @Nullable Class<T> requiredType) throws NamingException { 092 Assert.notNull(jndiName, "'jndiName' must not be null"); 093 String convertedName = convertJndiName(jndiName); 094 T jndiObject; 095 try { 096 jndiObject = getJndiTemplate().lookup(convertedName, requiredType); 097 } 098 catch (NamingException ex) { 099 if (!convertedName.equals(jndiName)) { 100 // Try fallback to originally specified name... 101 if (logger.isDebugEnabled()) { 102 logger.debug("Converted JNDI name [" + convertedName + 103 "] not found - trying original name [" + jndiName + "]. " + ex); 104 } 105 jndiObject = getJndiTemplate().lookup(jndiName, requiredType); 106 } 107 else { 108 throw ex; 109 } 110 } 111 if (logger.isDebugEnabled()) { 112 logger.debug("Located object with JNDI name [" + convertedName + "]"); 113 } 114 return jndiObject; 115 } 116 117 /** 118 * Convert the given JNDI name into the actual JNDI name to use. 119 * <p>The default implementation applies the "java:comp/env/" prefix if 120 * "resourceRef" is "true" and no other scheme (e.g. "java:") is given. 121 * @param jndiName the original JNDI name 122 * @return the JNDI name to use 123 * @see #CONTAINER_PREFIX 124 * @see #setResourceRef 125 */ 126 protected String convertJndiName(String jndiName) { 127 // Prepend container prefix if not already specified and no other scheme given. 128 if (isResourceRef() && !jndiName.startsWith(CONTAINER_PREFIX) && jndiName.indexOf(':') == -1) { 129 jndiName = CONTAINER_PREFIX + jndiName; 130 } 131 return jndiName; 132 } 133 134}