diff --git a/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java b/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java new file mode 100644 index 00000000000..907b63df20b --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/jndi/JndiLocatorDelegate.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002-2010 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 javax.naming.NamingException; + +/** + * {@link JndiLocatorSupport} subclass with public lookup methods, + * for convenient use as a delegate. + * + * @author Juergen Hoeller + * @since 3.0.1 + */ +public class JndiLocatorDelegate extends JndiLocatorSupport { + + @Override + public Object lookup(String jndiName) throws NamingException { + return super.lookup(jndiName); + } + + @Override + public T lookup(String jndiName, Class requiredType) throws NamingException { + return super.lookup(jndiName, requiredType); + } + +} diff --git a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index 6a062fc5a88..d03801fe41c 100644 --- a/org.springframework.orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/org.springframework.orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 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. @@ -27,7 +27,6 @@ import java.util.LinkedList; import java.util.Map; import java.util.Properties; import java.util.concurrent.ConcurrentHashMap; -import javax.naming.NamingException; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.PersistenceContext; @@ -52,7 +51,8 @@ import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcess import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.core.Ordered; import org.springframework.core.PriorityOrdered; -import org.springframework.jndi.JndiLocatorSupport; +import org.springframework.jndi.JndiLocatorDelegate; +import org.springframework.jndi.JndiTemplate; import org.springframework.orm.jpa.EntityManagerFactoryInfo; import org.springframework.orm.jpa.EntityManagerFactoryUtils; import org.springframework.orm.jpa.EntityManagerProxy; @@ -159,10 +159,14 @@ import org.springframework.util.ObjectUtils; * @see javax.persistence.PersistenceUnit * @see javax.persistence.PersistenceContext */ -public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport +public class PersistenceAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware, Serializable { + private Object jndiEnvironment; + + private boolean resourceRef = true; + private transient Map persistenceUnits; private transient Map persistenceContexts; @@ -182,10 +186,31 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport new ConcurrentHashMap(); - public PersistenceAnnotationBeanPostProcessor() { - setResourceRef(true); + /** + * Set the JNDI template to use for JNDI lookups. + * @see org.springframework.jndi.JndiAccessor#setJndiTemplate + */ + public void setJndiTemplate(Object jndiTemplate) { + this.jndiEnvironment = jndiTemplate; } + /** + * Set the JNDI environment to use for JNDI lookups. + * @see org.springframework.jndi.JndiAccessor#setJndiEnvironment + */ + public void setJndiEnvironment(Properties jndiEnvironment) { + this.jndiEnvironment = jndiEnvironment; + } + + /** + * Set whether the lookup occurs in a J2EE container, i.e. if the prefix + * "java:comp/env/" needs to be added if the JNDI name doesn't already + * contain it. PersistenceAnnotationBeanPostProcessor's default is "true". + * @see org.springframework.jndi.JndiLocatorSupport#setResourceRef + */ + public void setResourceRef(boolean resourceRef) { + this.resourceRef = resourceRef; + } /** * Specify the persistence units for EntityManagerFactory lookups, @@ -404,7 +429,7 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport try { return lookup(jndiName, EntityManagerFactory.class); } - catch (NamingException ex) { + catch (Exception ex) { throw new IllegalStateException("Could not obtain EntityManagerFactory [" + jndiName + "] from JNDI", ex); } } @@ -436,7 +461,7 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport try { return lookup(jndiName, EntityManager.class); } - catch (NamingException ex) { + catch (Exception ex) { throw new IllegalStateException("Could not obtain EntityManager [" + jndiName + "] from JNDI", ex); } } @@ -513,6 +538,42 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport } } + /** + * Perform a JNDI lookup for the given resource by name. + *

Called for EntityManagerFactory and EntityManager lookup + * when JNDI names are mapped for specific persistence units. + * @param jndiName the JNDI name to look up + * @param requiredType the required type of the object + * @return the obtained object + * @throws Exception if the JNDI lookup failed + */ + protected T lookup(String jndiName, Class requiredType) throws Exception { + return new LocatorDelegate().lookup(jndiName, requiredType); + } + + + /** + * Separate inner class to isolate the JNDI API dependency + * (for compatibility with Google App Engine's API white list). + */ + private class LocatorDelegate { + + public T lookup(String jndiName, Class requiredType) throws Exception { + JndiLocatorDelegate locator = new JndiLocatorDelegate(); + if (jndiEnvironment instanceof JndiTemplate) { + locator.setJndiTemplate((JndiTemplate) jndiEnvironment); + } + else if (jndiEnvironment instanceof Properties) { + locator.setJndiEnvironment((Properties) jndiEnvironment); + } + else if (jndiEnvironment != null) { + throw new IllegalStateException("Illegal 'jndiEnvironment' type: " + jndiEnvironment.getClass()); + } + locator.setResourceRef(resourceRef); + return locator.lookup(jndiName, requiredType); + } + } + /** * Class representing injection information about an annotated field