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