001/* 002 * Copyright 2002-2017 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.jms.config; 018 019import javax.jms.MessageListener; 020 021import org.springframework.jms.listener.AbstractMessageListenerContainer; 022import org.springframework.jms.listener.MessageListenerContainer; 023import org.springframework.jms.listener.endpoint.JmsActivationSpecConfig; 024import org.springframework.jms.listener.endpoint.JmsMessageEndpointManager; 025 026/** 027 * Base model for a JMS listener endpoint 028 * 029 * @author Stephane Nicoll 030 * @author Juergen Hoeller 031 * @since 4.1 032 * @see MethodJmsListenerEndpoint 033 * @see SimpleJmsListenerEndpoint 034 */ 035public abstract class AbstractJmsListenerEndpoint implements JmsListenerEndpoint { 036 037 private String id; 038 039 private String destination; 040 041 private String subscription; 042 043 private String selector; 044 045 private String concurrency; 046 047 048 public void setId(String id) { 049 this.id = id; 050 } 051 052 @Override 053 public String getId() { 054 return this.id; 055 } 056 057 /** 058 * Set the name of the destination for this endpoint. 059 */ 060 public void setDestination(String destination) { 061 this.destination = destination; 062 } 063 064 /** 065 * Return the name of the destination for this endpoint. 066 */ 067 public String getDestination() { 068 return this.destination; 069 } 070 071 /** 072 * Set the name for the durable subscription. 073 */ 074 public void setSubscription(String subscription) { 075 this.subscription = subscription; 076 } 077 078 /** 079 * Return the name for the durable subscription, if any. 080 */ 081 public String getSubscription() { 082 return this.subscription; 083 } 084 085 /** 086 * Set the JMS message selector expression. 087 * <p>See the JMS specification for a detailed definition of selector expressions. 088 */ 089 public void setSelector(String selector) { 090 this.selector = selector; 091 } 092 093 /** 094 * Return the JMS message selector expression, if any. 095 */ 096 public String getSelector() { 097 return this.selector; 098 } 099 100 /** 101 * Set a concurrency for the listener, if any. 102 * <p>The concurrency limits can be a "lower-upper" String, e.g. "5-10", or a simple 103 * upper limit String, e.g. "10" (the lower limit will be 1 in this case). 104 * <p>The underlying container may or may not support all features. For instance, it 105 * may not be able to scale: in that case only the upper value is used. 106 */ 107 public void setConcurrency(String concurrency) { 108 this.concurrency = concurrency; 109 } 110 111 /** 112 * Return the concurrency for the listener, if any. 113 */ 114 public String getConcurrency() { 115 return this.concurrency; 116 } 117 118 119 @Override 120 public void setupListenerContainer(MessageListenerContainer listenerContainer) { 121 if (listenerContainer instanceof AbstractMessageListenerContainer) { 122 setupJmsListenerContainer((AbstractMessageListenerContainer) listenerContainer); 123 } 124 else { 125 new JcaEndpointConfigurer().configureEndpoint(listenerContainer); 126 } 127 } 128 129 private void setupJmsListenerContainer(AbstractMessageListenerContainer listenerContainer) { 130 if (getDestination() != null) { 131 listenerContainer.setDestinationName(getDestination()); 132 } 133 if (getSubscription() != null) { 134 listenerContainer.setSubscriptionName(getSubscription()); 135 } 136 if (getSelector() != null) { 137 listenerContainer.setMessageSelector(getSelector()); 138 } 139 if (getConcurrency() != null) { 140 listenerContainer.setConcurrency(getConcurrency()); 141 } 142 setupMessageListener(listenerContainer); 143 } 144 145 /** 146 * Create a {@link MessageListener} that is able to serve this endpoint for the 147 * specified container. 148 */ 149 protected abstract MessageListener createMessageListener(MessageListenerContainer container); 150 151 private void setupMessageListener(MessageListenerContainer container) { 152 MessageListener messageListener = createMessageListener(container); 153 if (messageListener == null) { 154 throw new IllegalStateException("Endpoint [" + this + "] must provide a non-null message listener"); 155 } 156 container.setupMessageListener(messageListener); 157 } 158 159 /** 160 * Return a description for this endpoint. 161 * <p>Available to subclasses, for inclusion in their {@code toString()} result. 162 */ 163 protected StringBuilder getEndpointDescription() { 164 StringBuilder result = new StringBuilder(); 165 return result.append(getClass().getSimpleName()).append("[").append(this.id).append("] destination="). 166 append(this.destination).append("' | subscription='").append(this.subscription). 167 append(" | selector='").append(this.selector).append("'"); 168 } 169 170 @Override 171 public String toString() { 172 return getEndpointDescription().toString(); 173 } 174 175 176 /** 177 * Inner class to avoid a hard dependency on the JCA API. 178 */ 179 private class JcaEndpointConfigurer { 180 181 public void configureEndpoint(Object listenerContainer) { 182 if (listenerContainer instanceof JmsMessageEndpointManager) { 183 setupJcaMessageContainer((JmsMessageEndpointManager) listenerContainer); 184 } 185 else { 186 throw new IllegalArgumentException("Could not configure endpoint with the specified container '" + 187 listenerContainer + "' Only JMS (" + AbstractMessageListenerContainer.class.getName() + 188 " subclass) or JCA (" + JmsMessageEndpointManager.class.getName() + ") are supported."); 189 } 190 } 191 192 private void setupJcaMessageContainer(JmsMessageEndpointManager container) { 193 JmsActivationSpecConfig activationSpecConfig = container.getActivationSpecConfig(); 194 if (activationSpecConfig == null) { 195 activationSpecConfig = new JmsActivationSpecConfig(); 196 container.setActivationSpecConfig(activationSpecConfig); 197 } 198 if (getDestination() != null) { 199 activationSpecConfig.setDestinationName(getDestination()); 200 } 201 if (getSubscription() != null) { 202 activationSpecConfig.setSubscriptionName(getSubscription()); 203 } 204 if (getSelector() != null) { 205 activationSpecConfig.setMessageSelector(getSelector()); 206 } 207 if (getConcurrency() != null) { 208 activationSpecConfig.setConcurrency(getConcurrency()); 209 } 210 setupMessageListener(container); 211 } 212 } 213 214}