/*
* Copyright 2002-2007 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 javax.jms.MessageListener;
import javax.resource.ResourceException;
import org.springframework.jca.endpoint.GenericMessageEndpointManager;
import org.springframework.jms.support.destination.DestinationResolver;
/**
* Extension of the generic JCA 1.5
* {@link org.springframework.jca.endpoint.GenericMessageEndpointManager},
* adding JMS-specific support for ActivationSpec configuration.
*
* <p>Allows for defining a common {@link JmsActivationSpecConfig} object
* that gets converted into a provider-specific JCA 1.5 ActivationSpec
* object for activating the endpoint.
*
* <p><b>NOTE:</b> This JCA-based endpoint manager supports standard JMS
* {@link javax.jms.MessageListener} endpoints only. It does <i>not</i> support
* Spring's {@link org.springframework.jms.listener.SessionAwareMessageListener}
* variant, simply because the JCA endpoint management contract does not allow
* for obtaining the current JMS {@link javax.jms.Session}.
*
* @author Juergen Hoeller
* @since 2.5
* @see javax.jms.MessageListener
* @see #setActivationSpecConfig
* @see JmsActivationSpecConfig
* @see JmsActivationSpecFactory
* @see JmsMessageEndpointFactory
*/
public class JmsMessageEndpointManager extends GenericMessageEndpointManager {
private final JmsMessageEndpointFactory endpointFactory = new JmsMessageEndpointFactory();
private boolean messageListenerSet = false;
private JmsActivationSpecFactory activationSpecFactory = new DefaultJmsActivationSpecFactory();
private JmsActivationSpecConfig activationSpecConfig;
/**
* Set the JMS MessageListener for this endpoint.
* <p>This is a shortcut for configuring a dedicated JmsMessageEndpointFactory.
* @see JmsMessageEndpointFactory#setMessageListener
*/
public void setMessageListener(MessageListener messageListener) {
this.endpointFactory.setMessageListener(messageListener);
this.messageListenerSet = true;
}
/**
* Set the XA transaction manager to use for wrapping endpoint
* invocations, enlisting the endpoint resource in each such transaction.
* <p>The passed-in object may be a transaction manager which implements
* Spring's {@link org.springframework.transaction.jta.TransactionFactory}
* interface, or a plain {@link javax.transaction.TransactionManager}.
* <p>If no transaction manager is specified, the endpoint invocation
* will simply not be wrapped in an XA transaction. Consult your
* resource provider's ActivationSpec documentation for the local
* transaction options of your particular provider.
* <p>This is a shortcut for configuring a dedicated JmsMessageEndpointFactory.
* @see JmsMessageEndpointFactory#setTransactionManager
*/
public void setTransactionManager(Object transactionManager) {
this.endpointFactory.setTransactionManager(transactionManager);
}
/**
* Set the factory for concrete JCA 1.5 ActivationSpec objects,
* creating JCA ActivationSpecs based on
* {@link #setActivationSpecConfig JmsActivationSpecConfig} objects.
* <p>This factory is dependent on the concrete JMS provider, e.g. on ActiveMQ.
* The default implementation simply guesses the ActivationSpec class name
* from the provider's class name (e.g. "ActiveMQResourceAdapter" ->
* "ActiveMQActivationSpec" in the same package), and populates the
* ActivationSpec properties as suggested by the JCA 1.5 specification
* (plus a couple of autodetected vendor-specific properties).
* @see DefaultJmsActivationSpecFactory
*/
public void setActivationSpecFactory(JmsActivationSpecFactory activationSpecFactory) {
this.activationSpecFactory =
(activationSpecFactory != null ? activationSpecFactory : new DefaultJmsActivationSpecFactory());
}
/**
* Set the DestinationResolver to use for resolving destination names
* into the JCA 1.5 ActivationSpec "destination" property.
* <p>If not specified, destination names will simply be passed in as Strings.
* If specified, destination names will be resolved into Destination objects first.
* <p>Note that a DestinationResolver is usually specified on the JmsActivationSpecFactory
* (see {@link StandardJmsActivationSpecFactory#setDestinationResolver}). This is simply
* a shortcut for parameterizing the default JmsActivationSpecFactory; it will replace
* any custom JmsActivationSpecFactory that might have been set before.
* @see StandardJmsActivationSpecFactory#setDestinationResolver
*/
public void setDestinationResolver(DestinationResolver destinationResolver) {
DefaultJmsActivationSpecFactory factory = new DefaultJmsActivationSpecFactory();
factory.setDestinationResolver(destinationResolver);
this.activationSpecFactory = factory;
}
/**
* Specify the {@link JmsActivationSpecConfig} object that this endpoint manager
* should use for activating its listener.
* <p>This config object will be turned into a concrete JCA 1.5 ActivationSpec
* object through a {@link #setActivationSpecFactory JmsActivationSpecFactory}.
*/
public void setActivationSpecConfig(JmsActivationSpecConfig activationSpecConfig) {
this.activationSpecConfig = activationSpecConfig;
}
public void afterPropertiesSet() throws ResourceException {
if (this.messageListenerSet) {
setMessageEndpointFactory(this.endpointFactory);
}
if (this.activationSpecConfig != null) {
setActivationSpec(
this.activationSpecFactory.createActivationSpec(getResourceAdapter(), this.activationSpecConfig));
}
super.afterPropertiesSet();
}
}
|