/*
* Copyright 2001, 2002,2004 The Apache Software Foundation.
*
* 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.apache.axis.transport.jms;
import org.apache.axis.AxisEngine;
import org.apache.axis.AxisFault;
import org.apache.axis.MessageContext;
import org.apache.axis.client.Call;
import org.apache.axis.client.Transport;
import org.apache.axis.components.jms.JMSVendorAdapter;
import org.apache.axis.components.jms.JMSVendorAdapterFactory;
import org.apache.axis.components.logger.LogFactory;
import org.apache.axis.utils.Messages;
import org.apache.commons.logging.Log;
import java.util.HashMap;
/**
* JMSTransport is the JMS-specific implemenation of org.apache.axis.client.Transport.
* It implements the setupMessageContextImpl() function to set JMS-specific message
* context fields and transport chains.
*
* There are two
* Connector and connection factory
* properties are passed in during instantiation and are in turn passed through
* when creating a connector.
*
* @author Jaime Meritt (jmeritt@sonicsoftware.com)
* @author Richard Chung (rchung@sonicsoftware.com)
* @author Dave Chappell (chappell@sonicsoftware.com)
* @author Ray Chun (rchun@sonicsoftware.com)
*/
public class JMSTransport extends Transport
{
protected static Log log =
LogFactory.getLog(JMSTransport.class.getName());
private static HashMap vendorConnectorPools = new HashMap();
private HashMap defaultConnectorProps;
private HashMap defaultConnectionFactoryProps;
static
{
// add a shutdown hook to close JMS connections
Runtime.getRuntime().addShutdownHook(
new Thread()
{
public void run()
{
JMSTransport.closeAllConnectors();
}
}
);
}
public JMSTransport()
{
transportName = "JMSTransport";
}
// this cons is provided for clients that instantiate the JMSTransport directly
public JMSTransport(HashMap connectorProps,
HashMap connectionFactoryProps)
{
this();
defaultConnectorProps = connectorProps;
defaultConnectionFactoryProps = connectionFactoryProps;
}
/**
* Set up any transport-specific derived properties in the message context.
* @param context the context to set up
* @param message the client service instance
* @param engine the engine containing the registries
* @throws AxisFault if service cannot be found
*/
public void setupMessageContextImpl(MessageContext context,
Call message,
AxisEngine engine)
throws AxisFault
{
if (log.isDebugEnabled()) {
log.debug("Enter: JMSTransport::setupMessageContextImpl");
}
JMSConnector connector = null;
HashMap connectorProperties = null;
HashMap connectionFactoryProperties = null;
JMSVendorAdapter vendorAdapter = null;
JMSURLHelper jmsurl = null;
// a security context is required to create/use JMSConnectors
String username = message.getUsername();
String password = message.getPassword();
// the presence of an endpoint address indicates whether the client application
// is instantiating the JMSTransport directly (deprecated) or indirectly via JMS URL
String endpointAddr = message.getTargetEndpointAddress();
if (endpointAddr != null)
{
try
{
// performs minimal validation ('jms:/destination?...')
jmsurl = new JMSURLHelper(new java.net.URL(endpointAddr));
// lookup the appropriate vendor adapter
String vendorId = jmsurl.getVendor();
if (vendorId == null)
vendorId = JMSConstants.JNDI_VENDOR_ID;
if (log.isDebugEnabled())
log.debug("JMSTransport.setupMessageContextImpl(): endpt=" + endpointAddr +
", vendor=" + vendorId);
vendorAdapter = JMSVendorAdapterFactory.getJMSVendorAdapter(vendorId);
if (vendorAdapter == null)
{
throw new AxisFault("cannotLoadAdapterClass:" + vendorId);
}
// populate the connector and connection factory properties tables
connectorProperties = vendorAdapter.getJMSConnectorProperties(jmsurl);
connectionFactoryProperties = vendorAdapter.getJMSConnectionFactoryProperties(jmsurl);
}
catch (java.net.MalformedURLException e)
{
log.error(Messages.getMessage("malformedURLException00"), e);
throw new AxisFault(Messages.getMessage("malformedURLException00"), e);
}
}
else
{
// the JMSTransport was instantiated directly, use the default adapter
vendorAdapter = JMSVendorAdapterFactory.getJMSVendorAdapter();
if (vendorAdapter == null)
{
throw new AxisFault("cannotLoadAdapterClass");
}
// use the properties passed in to the constructor
connectorProperties = defaultConnectorProps;
connectionFactoryProperties = defaultConnectionFactoryProps;
}
try
{
connector = JMSConnectorManager.getInstance().getConnector(connectorProperties, connectionFactoryProperties,
username, password, vendorAdapter);
}
catch (Exception e)
{
log.error(Messages.getMessage("cannotConnectError"), e);
if(e instanceof AxisFault)
throw (AxisFault)e;
throw new AxisFault("cannotConnect", e);
}
// store these in the context for later use
context.setProperty(JMSConstants.CONNECTOR, connector);
context.setProperty(JMSConstants.VENDOR_ADAPTER, vendorAdapter);
// vendors may populate the message context
vendorAdapter.setupMessageContext(context, message, jmsurl);
if (log.isDebugEnabled()) {
log.debug("Exit: JMSTransport::setupMessageContextImpl");
}
}
/**
* Shuts down the connectors managed by this JMSTransport.
*/
public void shutdown()
{
if (log.isDebugEnabled()) {
log.debug("Enter: JMSTransport::shutdown");
}
closeAllConnectors();
if (log.isDebugEnabled()) {
log.debug("Exit: JMSTransport::shutdown");
}
}
/**
* Closes all JMS connectors
*/
public static void closeAllConnectors()
{
if (log.isDebugEnabled()) {
log.debug("Enter: JMSTransport::closeAllConnectors");
}
JMSConnectorManager.getInstance().closeAllConnectors();
if (log.isDebugEnabled()) {
log.debug("Exit: JMSTransport::closeAllConnectors");
}
}
/**
* Closes JMS connectors that match the specified endpoint address
*
* @param endpointAddr the JMS endpoint address
* @param username
* @param password
*/
public static void closeMatchingJMSConnectors(String endpointAddr, String username, String password)
{
if (log.isDebugEnabled()) {
log.debug("Enter: JMSTransport::closeMatchingJMSConnectors");
}
try
{
JMSURLHelper jmsurl = new JMSURLHelper(new java.net.URL(endpointAddr));
String vendorId = jmsurl.getVendor();
JMSVendorAdapter vendorAdapter = null;
if (vendorId == null)
vendorId = JMSConstants.JNDI_VENDOR_ID;
vendorAdapter = JMSVendorAdapterFactory.getJMSVendorAdapter(vendorId);
// the vendor adapter may not exist
if (vendorAdapter == null)
return;
// determine the set of properties to be used for matching the connection
HashMap connectorProps = vendorAdapter.getJMSConnectorProperties(jmsurl);
HashMap cfProps = vendorAdapter.getJMSConnectionFactoryProperties(jmsurl);
JMSConnectorManager.getInstance().closeMatchingJMSConnectors(connectorProps, cfProps,
username, password,
vendorAdapter);
}
catch (java.net.MalformedURLException e)
{
log.warn(Messages.getMessage("malformedURLException00"), e);
}
if (log.isDebugEnabled()) {
log.debug("Exit: JMSTransport::closeMatchingJMSConnectors");
}
}
} |