001/*
002 * Copyright 2002-2020 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.listener.endpoint;
018
019import javax.jms.Session;
020
021import org.springframework.core.Constants;
022import org.springframework.jms.support.QosSettings;
023import org.springframework.jms.support.converter.MessageConverter;
024import org.springframework.lang.Nullable;
025
026/**
027 * Common configuration object for activating a JMS message endpoint.
028 * Gets converted into a provider-specific JCA 1.5 ActivationSpec
029 * object for activating the endpoint.
030 *
031 * <p>Typically used in combination with {@link JmsMessageEndpointManager},
032 * but not tied to it.
033 *
034 * @author Juergen Hoeller
035 * @author Stephane Nicoll
036 * @since 2.5
037 * @see JmsActivationSpecFactory
038 * @see JmsMessageEndpointManager#setActivationSpecConfig
039 * @see javax.resource.spi.ResourceAdapter#endpointActivation
040 */
041public class JmsActivationSpecConfig {
042
043        /** Constants instance for {@code javax.jms.Session}. */
044        private static final Constants sessionConstants = new Constants(Session.class);
045
046
047        @Nullable
048        private String destinationName;
049
050        private boolean pubSubDomain = false;
051
052        @Nullable
053        private Boolean replyPubSubDomain;
054
055        @Nullable
056        private QosSettings replyQosSettings;
057
058        private boolean subscriptionDurable = false;
059
060        private boolean subscriptionShared = false;
061
062        @Nullable
063        private String subscriptionName;
064
065        @Nullable
066        private String clientId;
067
068        @Nullable
069        private String messageSelector;
070
071        private int acknowledgeMode = Session.AUTO_ACKNOWLEDGE;
072
073        private int maxConcurrency = -1;
074
075        private int prefetchSize = -1;
076
077        @Nullable
078        private MessageConverter messageConverter;
079
080
081        public void setDestinationName(@Nullable String destinationName) {
082                this.destinationName = destinationName;
083        }
084
085        @Nullable
086        public String getDestinationName() {
087                return this.destinationName;
088        }
089
090        public void setPubSubDomain(boolean pubSubDomain) {
091                this.pubSubDomain = pubSubDomain;
092        }
093
094        public boolean isPubSubDomain() {
095                return this.pubSubDomain;
096        }
097
098        public void setReplyPubSubDomain(boolean replyPubSubDomain) {
099                this.replyPubSubDomain = replyPubSubDomain;
100        }
101
102        public boolean isReplyPubSubDomain() {
103                if (this.replyPubSubDomain != null) {
104                        return this.replyPubSubDomain;
105                }
106                else {
107                        return isPubSubDomain();
108                }
109        }
110
111        public void setReplyQosSettings(@Nullable QosSettings replyQosSettings) {
112                this.replyQosSettings = replyQosSettings;
113        }
114
115        @Nullable
116        public QosSettings getReplyQosSettings() {
117                return this.replyQosSettings;
118        }
119
120        public void setSubscriptionDurable(boolean subscriptionDurable) {
121                this.subscriptionDurable = subscriptionDurable;
122                if (subscriptionDurable) {
123                        this.pubSubDomain = true;
124                }
125        }
126
127        public boolean isSubscriptionDurable() {
128                return this.subscriptionDurable;
129        }
130
131        public void setSubscriptionShared(boolean subscriptionShared) {
132                this.subscriptionShared = subscriptionShared;
133                if (subscriptionShared) {
134                        this.pubSubDomain = true;
135                }
136        }
137
138        public boolean isSubscriptionShared() {
139                return this.subscriptionShared;
140        }
141
142        public void setSubscriptionName(@Nullable String subscriptionName) {
143                this.subscriptionName = subscriptionName;
144        }
145
146        @Nullable
147        public String getSubscriptionName() {
148                return this.subscriptionName;
149        }
150
151        public void setDurableSubscriptionName(@Nullable String durableSubscriptionName) {
152                this.subscriptionName = durableSubscriptionName;
153                this.subscriptionDurable = (durableSubscriptionName != null);
154        }
155
156        @Nullable
157        public String getDurableSubscriptionName() {
158                return (this.subscriptionDurable ? this.subscriptionName : null);
159        }
160
161        public void setClientId(@Nullable String clientId) {
162                this.clientId = clientId;
163        }
164
165        @Nullable
166        public String getClientId() {
167                return this.clientId;
168        }
169
170        public void setMessageSelector(@Nullable String messageSelector) {
171                this.messageSelector = messageSelector;
172        }
173
174        @Nullable
175        public String getMessageSelector() {
176                return this.messageSelector;
177        }
178
179        /**
180         * Set the JMS acknowledgement mode by the name of the corresponding constant
181         * in the JMS {@link Session} interface, e.g. "CLIENT_ACKNOWLEDGE".
182         * <p>Note that JCA resource adapters generally only support auto and dups-ok
183         * (see Spring's {@link StandardJmsActivationSpecFactory}). ActiveMQ also
184         * supports "SESSION_TRANSACTED" in the form of RA-managed transactions
185         * (automatically translated by Spring's {@link DefaultJmsActivationSpecFactory}.
186         * @param constantName the name of the {@link Session} acknowledge mode constant
187         * @see javax.jms.Session#AUTO_ACKNOWLEDGE
188         * @see javax.jms.Session#CLIENT_ACKNOWLEDGE
189         * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE
190         * @see javax.jms.Session#SESSION_TRANSACTED
191         * @see StandardJmsActivationSpecFactory
192         * @see DefaultJmsActivationSpecFactory
193         */
194        public void setAcknowledgeModeName(String constantName) {
195                setAcknowledgeMode(sessionConstants.asNumber(constantName).intValue());
196        }
197
198        /**
199         * Set the JMS acknowledgement mode to use.
200         * @see javax.jms.Session#AUTO_ACKNOWLEDGE
201         * @see javax.jms.Session#CLIENT_ACKNOWLEDGE
202         * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE
203         * @see javax.jms.Session#SESSION_TRANSACTED
204         */
205        public void setAcknowledgeMode(int acknowledgeMode) {
206                this.acknowledgeMode = acknowledgeMode;
207        }
208
209        /**
210         * Return the JMS acknowledgement mode to use.
211         */
212        public int getAcknowledgeMode() {
213                return this.acknowledgeMode;
214        }
215
216        /**
217         * Specify concurrency limits via a "lower-upper" String, e.g. "5-10", or a simple
218         * upper limit String, e.g. "10".
219         * <p>JCA listener containers will always scale from zero to the given upper limit.
220         * A specified lower limit will effectively be ignored.
221         * <p>This property is primarily supported for configuration compatibility with
222         * {@link org.springframework.jms.listener.DefaultMessageListenerContainer}.
223         * For this activation config, generally use {@link #setMaxConcurrency} instead.
224         */
225        public void setConcurrency(String concurrency) {
226                try {
227                        int separatorIndex = concurrency.indexOf('-');
228                        if (separatorIndex != -1) {
229                                setMaxConcurrency(Integer.parseInt(concurrency.substring(separatorIndex + 1)));
230                        }
231                        else {
232                                setMaxConcurrency(Integer.parseInt(concurrency));
233                        }
234                }
235                catch (NumberFormatException ex) {
236                        throw new IllegalArgumentException("Invalid concurrency value [" + concurrency + "]: only " +
237                                        "single maximum integer (e.g. \"5\") and minimum-maximum combo (e.g. \"3-5\") supported. " +
238                                        "Note that JmsActivationSpecConfig will effectively ignore the minimum value and " +
239                                        "scale from zero up to the number of consumers according to the maximum value.");
240                }
241        }
242
243        /**
244         * Specify the maximum number of consumers/sessions to use, effectively
245         * controlling the number of concurrent invocations on the target listener.
246         */
247        public void setMaxConcurrency(int maxConcurrency) {
248                this.maxConcurrency = maxConcurrency;
249        }
250
251        /**
252         * Return the maximum number of consumers/sessions to use.
253         */
254        public int getMaxConcurrency() {
255                return this.maxConcurrency;
256        }
257
258        /**
259         * Specify the maximum number of messages to load into a session
260         * (a kind of batch size).
261         */
262        public void setPrefetchSize(int prefetchSize) {
263                this.prefetchSize = prefetchSize;
264        }
265
266        /**
267         * Return the maximum number of messages to load into a session.
268         */
269        public int getPrefetchSize() {
270                return this.prefetchSize;
271        }
272
273        /**
274         * Set the {@link MessageConverter} strategy for converting JMS Messages.
275         * @param messageConverter the message converter to use
276         */
277        public void setMessageConverter(@Nullable MessageConverter messageConverter) {
278                this.messageConverter = messageConverter;
279        }
280
281        /**
282         * Return the {@link MessageConverter} to use, if any.
283         */
284        @Nullable
285        public MessageConverter getMessageConverter() {
286                return this.messageConverter;
287        }
288
289}