001/* 002 * Copyright 2012-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 * http://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.boot.autoconfigure.jms; 018 019import java.util.Arrays; 020 021import javax.jms.ConnectionFactory; 022import javax.naming.NamingException; 023 024import org.springframework.boot.autoconfigure.AutoConfigureBefore; 025import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 026import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 027import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 028import org.springframework.boot.autoconfigure.condition.ConditionalOnJndi; 029import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 030import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 031import org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration.JndiOrPropertyCondition; 032import org.springframework.boot.context.properties.EnableConfigurationProperties; 033import org.springframework.context.annotation.Bean; 034import org.springframework.context.annotation.Conditional; 035import org.springframework.context.annotation.Configuration; 036import org.springframework.jms.core.JmsTemplate; 037import org.springframework.jndi.JndiLocatorDelegate; 038import org.springframework.util.StringUtils; 039 040/** 041 * {@link EnableAutoConfiguration Auto-configuration} for JMS provided from JNDI. 042 * 043 * @author Phillip Webb 044 * @since 1.2.0 045 */ 046@Configuration 047@AutoConfigureBefore(JmsAutoConfiguration.class) 048@ConditionalOnClass(JmsTemplate.class) 049@ConditionalOnMissingBean(ConnectionFactory.class) 050@Conditional(JndiOrPropertyCondition.class) 051@EnableConfigurationProperties(JmsProperties.class) 052public class JndiConnectionFactoryAutoConfiguration { 053 054 // Keep these in sync with the condition below 055 private static final String[] JNDI_LOCATIONS = { "java:/JmsXA", 056 "java:/XAConnectionFactory" }; 057 058 private final JmsProperties properties; 059 060 private final JndiLocatorDelegate jndiLocatorDelegate; 061 062 public JndiConnectionFactoryAutoConfiguration(JmsProperties properties) { 063 this.properties = properties; 064 this.jndiLocatorDelegate = JndiLocatorDelegate.createDefaultResourceRefLocator(); 065 } 066 067 @Bean 068 public ConnectionFactory connectionFactory() throws NamingException { 069 if (StringUtils.hasLength(this.properties.getJndiName())) { 070 return this.jndiLocatorDelegate.lookup(this.properties.getJndiName(), 071 ConnectionFactory.class); 072 } 073 return findJndiConnectionFactory(); 074 } 075 076 private ConnectionFactory findJndiConnectionFactory() { 077 for (String name : JNDI_LOCATIONS) { 078 try { 079 return this.jndiLocatorDelegate.lookup(name, ConnectionFactory.class); 080 } 081 catch (NamingException ex) { 082 // Swallow and continue 083 } 084 } 085 throw new IllegalStateException( 086 "Unable to find ConnectionFactory in JNDI locations " 087 + Arrays.asList(JNDI_LOCATIONS)); 088 } 089 090 /** 091 * Condition for JNDI name or a specific property. 092 */ 093 static class JndiOrPropertyCondition extends AnyNestedCondition { 094 095 JndiOrPropertyCondition() { 096 super(ConfigurationPhase.PARSE_CONFIGURATION); 097 } 098 099 @ConditionalOnJndi({ "java:/JmsXA", "java:/XAConnectionFactory" }) 100 static class Jndi { 101 102 } 103 104 @ConditionalOnProperty(prefix = "spring.jms", name = "jndi-name") 105 static class Property { 106 107 } 108 109 } 110 111}