001/* 002 * Copyright 2002-2010 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.util.Assert; 022 023/** 024 * Convenient superclass for classes that can locate any number of JNDI objects. 025 * Derives from JndiAccessor to inherit the "jndiTemplate" and "jndiEnvironment" 026 * bean properties. 027 * 028 * <p>JNDI names may or may not include the "java:comp/env/" prefix expected 029 * by J2EE applications when accessing a locally mapped (ENC - Environmental 030 * Naming Context) resource. If it doesn't, the "java:comp/env/" prefix will 031 * be prepended if the "resourceRef" property is true (the default is 032 * <strong>false</strong>) and no other scheme (e.g. "java:") is given. 033 * 034 * @author Juergen Hoeller 035 * @since 1.1 036 * @see #setJndiTemplate 037 * @see #setJndiEnvironment 038 * @see #setResourceRef 039 */ 040public abstract class JndiLocatorSupport extends JndiAccessor { 041 042 /** JNDI prefix used in a J2EE container */ 043 public static final String CONTAINER_PREFIX = "java:comp/env/"; 044 045 046 private boolean resourceRef = false; 047 048 049 /** 050 * Set whether the lookup occurs in a J2EE container, i.e. if the prefix 051 * "java:comp/env/" needs to be added if the JNDI name doesn't already 052 * contain it. Default is "false". 053 * <p>Note: Will only get applied if no other scheme (e.g. "java:") is given. 054 */ 055 public void setResourceRef(boolean resourceRef) { 056 this.resourceRef = resourceRef; 057 } 058 059 /** 060 * Return whether the lookup occurs in a J2EE container. 061 */ 062 public boolean isResourceRef() { 063 return this.resourceRef; 064 } 065 066 067 /** 068 * Perform an actual JNDI lookup for the given name via the JndiTemplate. 069 * <p>If the name doesn't begin with "java:comp/env/", this prefix is added 070 * if "resourceRef" is set to "true". 071 * @param jndiName the JNDI name to look up 072 * @return the obtained object 073 * @throws NamingException if the JNDI lookup failed 074 * @see #setResourceRef 075 */ 076 protected Object lookup(String jndiName) throws NamingException { 077 return lookup(jndiName, null); 078 } 079 080 /** 081 * Perform an actual JNDI lookup for the given name via the JndiTemplate. 082 * <p>If the name doesn't begin with "java:comp/env/", this prefix is added 083 * if "resourceRef" is set to "true". 084 * @param jndiName the JNDI name to look up 085 * @param requiredType the required type of the object 086 * @return the obtained object 087 * @throws NamingException if the JNDI lookup failed 088 * @see #setResourceRef 089 */ 090 protected <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException { 091 Assert.notNull(jndiName, "'jndiName' must not be null"); 092 String convertedName = convertJndiName(jndiName); 093 T jndiObject; 094 try { 095 jndiObject = getJndiTemplate().lookup(convertedName, requiredType); 096 } 097 catch (NamingException ex) { 098 if (!convertedName.equals(jndiName)) { 099 // Try fallback to originally specified name... 100 if (logger.isDebugEnabled()) { 101 logger.debug("Converted JNDI name [" + convertedName + 102 "] not found - trying original name [" + jndiName + "]. " + ex); 103 } 104 jndiObject = getJndiTemplate().lookup(jndiName, requiredType); 105 } 106 else { 107 throw ex; 108 } 109 } 110 if (logger.isDebugEnabled()) { 111 logger.debug("Located object with JNDI name [" + convertedName + "]"); 112 } 113 return jndiObject; 114 } 115 116 /** 117 * Convert the given JNDI name into the actual JNDI name to use. 118 * <p>The default implementation applies the "java:comp/env/" prefix if 119 * "resourceRef" is "true" and no other scheme (e.g. "java:") is given. 120 * @param jndiName the original JNDI name 121 * @return the JNDI name to use 122 * @see #CONTAINER_PREFIX 123 * @see #setResourceRef 124 */ 125 protected String convertJndiName(String jndiName) { 126 // Prepend container prefix if not already specified and no other scheme given. 127 if (isResourceRef() && !jndiName.startsWith(CONTAINER_PREFIX) && jndiName.indexOf(':') == -1) { 128 jndiName = CONTAINER_PREFIX + jndiName; 129 } 130 return jndiName; 131 } 132 133}