All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.jms.listener.endpoint.StandardJmsActivationSpecFactory Maven / Gradle / Ivy

There is a newer version: 5.3.34
Show newest version
/*
 * Copyright 2002-2008 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.jms.listener.endpoint;

import java.util.Properties;

import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.Topic;
import javax.resource.spi.ActivationSpec;
import javax.resource.spi.ResourceAdapter;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.jms.support.destination.DestinationResolutionException;
import org.springframework.jms.support.destination.DestinationResolver;

/**
 * Standard implementation of the {@link JmsActivationSpecFactory} interface.
 * Supports the standard JMS properties as defined by the JMS 1.5 specification
 * (Appendix B); ignores Spring's "maxConcurrency" and "prefetchSize" settings.
 *
 * 

The 'activationSpecClass' property is required, explicitly defining * the fully-qualified class name of the provider's ActivationSpec class * (e.g. "org.apache.activemq.ra.ActiveMQActivationSpec"). * *

Check out {@link DefaultJmsActivationSpecFactory} for an extended variant * of this class, supporting some further default conventions beyond the plain * JMS 1.5 specification. * * @author Juergen Hoeller * @since 2.5 * @see #setActivationSpecClass * @see DefaultJmsActivationSpecFactory */ public class StandardJmsActivationSpecFactory implements JmsActivationSpecFactory { private Class activationSpecClass; private Properties defaultProperties; private DestinationResolver destinationResolver; /** * Specify the fully-qualified ActivationSpec class name for the target * provider (e.g. "org.apache.activemq.ra.ActiveMQActivationSpec"). */ public void setActivationSpecClass(Class activationSpecClass) { this.activationSpecClass = activationSpecClass; } /** * Specify custom default properties, with String keys and String values. *

Applied to each ActivationSpec object before it gets populated with * listener-specific settings. Allows for configuring vendor-specific properties * beyond the Spring-defined settings in {@link JmsActivationSpecConfig}. */ public void setDefaultProperties(Properties defaultProperties) { this.defaultProperties = defaultProperties; } /** * Set the DestinationResolver to use for resolving destination names * into the JCA 1.5 ActivationSpec "destination" property. *

If not specified, destination names will simply be passed in as Strings. * If specified, destination names will be resolved into Destination objects first. *

Note that a DestinationResolver for use with this factory must be * able to work without an active JMS Session: e.g. * {@link org.springframework.jms.support.destination.JndiDestinationResolver} * or {@link org.springframework.jms.support.destination.BeanFactoryDestinationResolver} * but not {@link org.springframework.jms.support.destination.DynamicDestinationResolver}. */ public void setDestinationResolver(DestinationResolver destinationResolver) { this.destinationResolver = destinationResolver; } public ActivationSpec createActivationSpec(ResourceAdapter adapter, JmsActivationSpecConfig config) { Class activationSpecClassToUse = this.activationSpecClass; if (activationSpecClassToUse == null) { activationSpecClassToUse = determineActivationSpecClass(adapter); if (activationSpecClassToUse == null) { throw new IllegalStateException("Property 'activationSpecClass' is required"); } } ActivationSpec spec = (ActivationSpec) BeanUtils.instantiateClass(activationSpecClassToUse); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(spec); if (this.defaultProperties != null) { bw.setPropertyValues(this.defaultProperties); } populateActivationSpecProperties(bw, config); return spec; } /** * Determine the ActivationSpec class for the given ResourceAdapter, * if possible. Called if no 'activationSpecClass' has been set explicitly * @param adapter the ResourceAdapter to check * @return the corresponding ActivationSpec class, or null * if not determinable * @see #setActivationSpecClass */ protected Class determineActivationSpecClass(ResourceAdapter adapter) { return null; } /** * Populate the given ApplicationSpec object with the settings * defined in the given configuration object. *

This implementation applies all standard JMS settings, but ignores * "maxConcurrency" and "prefetchSize" - not supported in standard JCA 1.5. * @param bw the BeanWrapper wrapping the ActivationSpec object * @param config the configured object holding common JMS settings */ protected void populateActivationSpecProperties(BeanWrapper bw, JmsActivationSpecConfig config) { String destinationName = config.getDestinationName(); boolean pubSubDomain = config.isPubSubDomain(); Object destination = destinationName; if (this.destinationResolver != null) { try { destination = this.destinationResolver.resolveDestinationName(null, destinationName, pubSubDomain); } catch (JMSException ex) { throw new DestinationResolutionException("Cannot resolve destination name [" + destinationName + "]", ex); } } bw.setPropertyValue("destination", destination); bw.setPropertyValue("destinationType", pubSubDomain ? Topic.class.getName() : Queue.class.getName()); if (bw.isWritableProperty("subscriptionDurability")) { bw.setPropertyValue("subscriptionDurability", config.isSubscriptionDurable() ? "Durable" : "NonDurable"); } else if (config.isSubscriptionDurable()) { // Standard JCA 1.5 "subscriptionDurability" apparently not supported... throw new IllegalArgumentException( "Durable subscriptions not supported by underlying provider: " + this.activationSpecClass.getName()); } if (config.getDurableSubscriptionName() != null) { bw.setPropertyValue("subscriptionName", config.getDurableSubscriptionName()); } if (config.getClientId() != null) { bw.setPropertyValue("clientId", config.getClientId()); } if (config.getMessageSelector() != null) { bw.setPropertyValue("messageSelector", config.getMessageSelector()); } applyAcknowledgeMode(bw, config.getAcknowledgeMode()); } /** * Apply the specified acknowledge mode to the ActivationSpec object. *

This implementation applies the standard JCA 1.5 acknowledge modes * "Auto-acknowledge" and "Dups-ok-acknowledge". It throws an exception in * case of CLIENT_ACKNOWLEDGE or SESSION_TRANSACTED * having been requested. * @param bw the BeanWrapper wrapping the ActivationSpec object * @param ackMode the configured acknowledge mode * (according to the constants in {@link javax.jms.Session} * @see javax.jms.Session#AUTO_ACKNOWLEDGE * @see javax.jms.Session#DUPS_OK_ACKNOWLEDGE * @see javax.jms.Session#CLIENT_ACKNOWLEDGE * @see javax.jms.Session#SESSION_TRANSACTED */ protected void applyAcknowledgeMode(BeanWrapper bw, int ackMode) { if (ackMode == Session.SESSION_TRANSACTED) { throw new IllegalArgumentException("No support for SESSION_TRANSACTED: Only \"Auto-acknowledge\" " + "and \"Dups-ok-acknowledge\" supported in standard JCA 1.5"); } else if (ackMode == Session.CLIENT_ACKNOWLEDGE) { throw new IllegalArgumentException("No support for CLIENT_ACKNOWLEDGE: Only \"Auto-acknowledge\" " + "and \"Dups-ok-acknowledge\" supported in standard JCA 1.5"); } else if (bw.isWritableProperty("acknowledgeMode")) { bw.setPropertyValue("acknowledgeMode", ackMode == Session.DUPS_OK_ACKNOWLEDGE ? "Dups-ok-acknowledge" : "Auto-acknowledge"); } else if (ackMode == Session.DUPS_OK_ACKNOWLEDGE) { // Standard JCA 1.5 "acknowledgeMode" apparently not supported (e.g. WebSphere MQ 6.0.2.1) throw new IllegalArgumentException( "Dups-ok-acknowledge not supported by underlying provider: " + this.activationSpecClass.getName()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy