You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by di...@apache.org on 2005/12/05 22:38:38 UTC

svn commit: r354198 [2/3] - /webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSEndpoint.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSEndpoint.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSEndpoint.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSEndpoint.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,149 @@
+/*
+ * 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.axis2.transport.jms;
+
+import javax.jms.Destination;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import java.util.HashMap;
+
+/**
+ * JMSEndpoint encapsulates interactions w/ a JMS destination.
+ */
+public abstract class JMSEndpoint {
+    private JMSConnector m_connector;
+
+    protected JMSEndpoint(JMSConnector connector) {
+        m_connector = connector;
+    }
+
+    abstract Destination getDestination(Session session)
+            throws Exception;
+
+    /**
+     * Send a message and wait for a response.
+     *
+     * @param message
+     * @param timeout
+     * @return
+     * @throws javax.jms.JMSException
+     */
+    public byte[] call(byte[] message, long timeout) throws Exception {
+        return m_connector.getSendConnection().call(this, message, timeout, null);
+    }
+
+    /**
+     * Send a message and wait for a response.
+     *
+     * @param message
+     * @param timeout
+     * @param properties
+     * @return
+     * @throws javax.jms.JMSException
+     */
+    public byte[] call(byte[] message, long timeout, HashMap properties)
+            throws Exception {
+        if (properties != null)
+            properties = (HashMap) properties.clone();
+        return m_connector.getSendConnection().call(this, message, timeout, properties);
+    }
+
+    /**
+     * Send a message w/o waiting for a response.
+     *
+     * @param message
+     * @throws javax.jms.JMSException
+     */
+    public void send(byte[] message) throws Exception {
+        m_connector.getSendConnection().send(this, message, null);
+    }
+
+    /**
+     * Send a message w/o waiting for a response.
+     *
+     * @param message
+     * @param properties
+     * @throws javax.jms.JMSException
+     */
+    public void send(byte[] message, HashMap properties)
+            throws Exception {
+        if (properties != null)
+            properties = (HashMap) properties.clone();
+        m_connector.getSendConnection().send(this, message, properties);
+    }
+
+    /**
+     * Register a MessageListener.
+     *
+     * @param listener
+     * @throws javax.jms.JMSException
+     */
+    public void registerListener(MessageListener listener)
+            throws Exception {
+        m_connector.getReceiveConnection().subscribe(createSubscription(listener, null));
+    }
+
+    /**
+     * Register a MessageListener.
+     *
+     * @param listener
+     * @param properties
+     * @throws javax.jms.JMSException
+     */
+    public void registerListener(MessageListener listener, HashMap properties)
+            throws Exception {
+        if (properties != null)
+            properties = (HashMap) properties.clone();
+        m_connector.getReceiveConnection().subscribe(createSubscription(listener, properties));
+    }
+
+    /**
+     * Unregister a message listener.
+     *
+     * @param listener
+     */
+    public void unregisterListener(MessageListener listener) {
+        m_connector.getReceiveConnection().unsubscribe(createSubscription(listener, null));
+    }
+
+    /**
+     * Unregister a message listener.
+     *
+     * @param listener
+     * @param properties
+     */
+    public void unregisterListener(MessageListener listener, HashMap properties) {
+        if (properties != null)
+            properties = (HashMap) properties.clone();
+        m_connector.getReceiveConnection().unsubscribe(createSubscription(listener, properties));
+    }
+
+    protected Subscription createSubscription(MessageListener listener,
+                                              HashMap properties) {
+        return new Subscription(listener, this, properties);
+    }
+
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    public boolean equals(Object object) {
+        if (object == null || !(object instanceof JMSEndpoint))
+            return false;
+        return true;
+    }
+}

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSSender.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSSender.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSSender.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSSender.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,204 @@
+/*
+ * 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.axis2.transport.jms;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.i18n.Messages;
+import org.apache.axis2.om.OMElement;
+import org.apache.axis2.om.OMOutputFormat;
+import org.apache.axis2.soap.SOAPEnvelope;
+import org.apache.axis2.description.TransportOutDescription;
+import org.apache.axis2.description.HandlerDescription;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.addressing.EndpointReference;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.transport.AbstractTransportSender;
+import org.apache.axis2.transport.TransportSender;
+
+import javax.jms.Destination;
+import javax.xml.namespace.QName;
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * This is meant to be used on a SOAP Client to call a SOAP server.
+ */
+public class JMSSender implements TransportSender {
+    public JMSSender() {
+    }
+
+    public void init(HandlerDescription handlerdesc) {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void init(ConfigurationContext confContext, TransportOutDescription transportOut) throws AxisFault {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    /**
+     * invoke() creates an endpoint, sends the request SOAP message, and then
+     * either reads the response SOAP message or simply returns.
+     *
+     * @param msgContext
+     * @throws AxisFault
+     */
+    public void invoke(MessageContext msgContext) throws AxisFault {
+        JMSConnector connector = null;
+        try {
+            Object destination = msgContext.getProperty(JMSConstants.DESTINATION);
+            if (destination == null)
+                throw new AxisFault("noDestination");
+
+            connector = (JMSConnector) msgContext.getProperty(JMSConstants.CONNECTOR);
+
+            JMSEndpoint endpoint = null;
+            if (destination instanceof String)
+                endpoint = connector.createEndpoint((String) destination);
+            else
+                endpoint = connector.createEndpoint((Destination) destination);
+
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            writeMessage(msgContext, out);
+
+            HashMap props = createSendProperties(msgContext);
+
+// TODO: How do we fix Attachments?            
+//            // If the request message contains attachments, set
+//            // a contentType property to go in the outgoing message header
+//            String ret = null;
+//            Message message = msgContext.getRequestMessage();
+//            Attachments mAttachments = message.getAttachmentsImpl();
+//            if (mAttachments != null && 0 != mAttachments.getAttachmentCount()) {
+//                String contentType = mAttachments.getContentType();
+//                if (contentType != null && !contentType.trim().equals("")) {
+//                    props.put("contentType", contentType);
+//                }
+//            }
+
+            boolean waitForResponse = true;
+            if (msgContext.getProperty(JMSConstants.WAIT_FOR_RESPONSE).equals(Boolean.TRUE))
+                waitForResponse =
+                        ((Boolean) msgContext.getProperty(
+                                JMSConstants.WAIT_FOR_RESPONSE)).booleanValue();
+            if (waitForResponse) {
+                long timeout = ((Long) msgContext.getProperty(JMSConstants._TIMEOUT_TIME)).longValue();
+                byte[] response = endpoint.call(out.toByteArray(), timeout, props);
+                InputStream in = new ByteArrayInputStream(response);
+                msgContext.setProperty(MessageContext.TRANSPORT_IN, in);
+            } else {
+                endpoint.send(out.toByteArray(), props);
+            }
+        }
+        catch (Exception e) {
+            throw new AxisFault("failedSend", e);
+        }
+        finally {
+            if (connector != null)
+                JMSConnectorManager.getInstance().release(connector);
+        }
+    }
+
+    private HashMap createSendProperties(MessageContext context) {
+        //I'm not sure why this helper method is private, but 
+        //we need to delegate to factory method that can build the
+        //application-specific map of properties so make a change to
+        //delegate here. 
+        HashMap props = createApplicationProperties(context);
+
+        if (context.getProperty(JMSConstants.PRIORITY) != null)
+            props.put(JMSConstants.PRIORITY,
+                    context.getProperty(JMSConstants.PRIORITY));
+        if (context.getProperty(JMSConstants.DELIVERY_MODE) != null)
+            props.put(JMSConstants.DELIVERY_MODE,
+                    context.getProperty(JMSConstants.DELIVERY_MODE));
+        if (context.getProperty(JMSConstants.TIME_TO_LIVE) != null)
+            props.put(JMSConstants.TIME_TO_LIVE,
+                    context.getProperty(JMSConstants.TIME_TO_LIVE));
+        if (context.getProperty(JMSConstants.JMS_CORRELATION_ID) != null)
+            props.put(JMSConstants.JMS_CORRELATION_ID,
+                    context.getProperty(JMSConstants.JMS_CORRELATION_ID));
+        return props;
+    }
+
+    /**
+     * Return a map of properties that makeup the application-specific
+     * for the JMS Messages.
+     */
+    protected HashMap createApplicationProperties(MessageContext context) {
+        HashMap props = null;
+        if (context.getProperty(
+                JMSConstants.JMS_APPLICATION_MSG_PROPS) != null) {
+            props = new HashMap();
+            props.putAll((Map) context.getProperty(
+                    JMSConstants.JMS_APPLICATION_MSG_PROPS));
+        }
+        return props;
+    }
+
+    public QName getName() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public Parameter getParameter(String name) {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void cleanup() throws AxisFault {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public HandlerDescription getHandlerDesc() {
+        return null;  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void cleanUp(MessageContext msgContext) throws AxisFault {
+        //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    public void writeMessage(MessageContext msgContext, OutputStream out)
+            throws AxisFault {
+        SOAPEnvelope envelope = msgContext.getEnvelope();
+        OMElement outputMessage = envelope;
+
+        if (envelope != null && msgContext.isDoingREST()) {
+            outputMessage = envelope.getBody().getFirstElement();
+        }
+
+        if (outputMessage != null) {
+            try {
+                OMOutputFormat format = new OMOutputFormat();
+                //Pick the char set encoding from the msgContext
+                String charSetEnc = (String) msgContext
+						.getProperty(MessageContext.CHARACTER_SET_ENCODING);
+                format.setDoOptimize(msgContext.isDoingMTOM());
+                format.setCharSetEncoding(charSetEnc);
+				outputMessage.serializeAndConsume(out, format);
+                out.flush();
+            } catch (Exception e) {
+                throw new AxisFault(e);
+            }
+        } else {
+            throw new AxisFault(Messages.getMessage("outMessageNull"));
+        }
+    }
+
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSTransport.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSTransport.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSTransport.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSTransport.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,232 @@
+/*
+ * 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.axis2.transport.jms;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.context.MessageContext;
+import org.apache.axis2.i18n.Messages;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+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.
+ * <p/>
+ * There are two
+ * Connector and connection factory
+ * properties are passed in during instantiation and are in turn passed through
+ * when creating a connector.
+ */
+public class JMSTransport {
+    protected static Log log =
+            LogFactory.getLog(JMSTransport.class.getName());
+
+    private static HashMap vendorConnectorPools = new HashMap();
+
+    private HashMap defaultConnectorProps;
+    private HashMap defaultConnectionFactoryProps;
+    private String transportName;
+
+    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
+     * @throws AxisFault if service cannot be found
+     */
+    public void setupMessageContextImpl(MessageContext context)
+            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
+        // TODO: Fill username password from context
+        String username = "";
+        String password = "";
+
+        // the presence of an endpoint address indicates whether the client application
+        //  is instantiating the JMSTransport directly (deprecated) or indirectly via JMS URL
+        String endpointAddr = context.getTo().getAddress();
+        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
+            try {
+                vendorAdapter = JMSVendorAdapterFactory.getJMSVendorAdapter();
+            } catch (Exception e) {
+                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, 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");
+        }
+    }
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLConnection.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLConnection.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLConnection.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLConnection.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,31 @@
+/*
+ * 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.axis2.transport.jms;
+
+import java.net.URL;
+
+/**
+ * URLConnection for the "jms" protocol
+ */
+public class JMSURLConnection extends java.net.URLConnection {
+    public JMSURLConnection(URL url) {
+        super(url);
+    }
+
+    public void connect() {
+    }
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLHelper.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLHelper.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLHelper.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSURLHelper.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,219 @@
+/*
+ * 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.axis2.transport.jms;
+
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+/**
+ * JMSURLHelper provides access to properties in the URL.
+ * The URL must be of the form: "jms:/<destination>?[<property>=<key>&]*"
+ */
+public class JMSURLHelper {
+    private URL url;
+
+    // the only property not in the query string
+    private String destination;
+
+    // vendor-specific properties
+    private HashMap properties;
+
+    // required properties
+    private Vector requiredProperties;
+
+    //application-specific JMS message properties
+    private Vector appProperties;
+
+    public JMSURLHelper(java.net.URL url) throws java.net.MalformedURLException {
+        this(url, null);
+    }
+
+    public JMSURLHelper(java.net.URL url, String[] requiredProperties) throws java.net.MalformedURLException {
+        this.url = url;
+        properties = new HashMap();
+        appProperties = new Vector();
+
+        // the path should be something like '/SampleQ1'
+        // clip the leading '/' if there is one
+        destination = url.getPath();
+        if (destination.startsWith("/"))
+            destination = destination.substring(1);
+
+        if ((destination == null) || (destination.trim().length() < 1))
+            throw new java.net.MalformedURLException("Missing destination in URL");
+
+        // parse the query string and populate the properties table
+        String query = url.getQuery();
+        StringTokenizer st = new StringTokenizer(query, "&;");
+        while (st.hasMoreTokens()) {
+            String keyValue = st.nextToken();
+            int eqIndex = keyValue.indexOf("=");
+            if (eqIndex > 0) {
+                String key = keyValue.substring(0, eqIndex);
+                String value = keyValue.substring(eqIndex + 1);
+                if (key.startsWith(JMSConstants._MSG_PROP_PREFIX)) {
+                    key = key.substring(
+                            JMSConstants._MSG_PROP_PREFIX.length());
+                    addApplicationProperty(key);
+                }
+                properties.put(key, value);
+            }
+        }
+
+        // set required properties
+        addRequiredProperties(requiredProperties);
+        validateURL();
+    }
+
+    public String getDestination() {
+        return destination;
+    }
+
+    public void setDestination(String destination) {
+        this.destination = destination;
+    }
+
+    public String getVendor() {
+        return getPropertyValue(JMSConstants._VENDOR);
+    }
+
+    public String getDomain() {
+        return getPropertyValue(JMSConstants._DOMAIN);
+    }
+
+    public HashMap getProperties() {
+        return properties;
+    }
+
+    public String getPropertyValue(String property) {
+        return (String) properties.get(property);
+    }
+
+    public void addRequiredProperties(String[] properties) {
+        if (properties == null)
+            return;
+
+        for (int i = 0; i < properties.length; i++) {
+            addRequiredProperty(properties[i]);
+        }
+    }
+
+    public void addRequiredProperty(String property) {
+        if (property == null)
+            return;
+
+        if (requiredProperties == null)
+            requiredProperties = new Vector();
+
+        requiredProperties.addElement(property);
+    }
+
+    public Vector getRequiredProperties() {
+        return requiredProperties;
+    }
+
+    /**
+     * Adds the name of a property from the url properties that should
+     * be added to the JMS message.
+     */
+    public void addApplicationProperty(String property) {
+        if (property == null)
+            return;
+
+        if (appProperties == null)
+            appProperties = new Vector();
+
+        appProperties.addElement(property);
+    }
+
+    /**
+     * Adds the name and value od the application property to the
+     * JMS URL.
+     */
+    public void addApplicationProperty(String property, String value) {
+        if (property == null)
+            return;
+
+        if (appProperties == null)
+            appProperties = new Vector();
+
+        properties.put(property, value);
+        appProperties.addElement(property);
+    }
+
+    /**
+     * Returns a collection of properties that are defined within the
+     * JMS URL to be added directly to the JMS messages.
+     *
+     * @return collection or null depending on presence of elements
+     */
+    public Vector getApplicationProperties() {
+        return appProperties;
+    }
+
+
+    /**
+     * Returns a URL formatted String. The properties of the URL may not
+     * end up in the same order as the JMS URL that was originally used to
+     * create this object.
+     */
+    public String getURLString() {
+        StringBuffer text = new StringBuffer("jms:/");
+        text.append(getDestination());
+        text.append("?");
+        Map props = (Map) properties.clone();
+        boolean firstEntry = true;
+        for (Iterator itr = properties.keySet().iterator(); itr.hasNext();) {
+            String key = (String) itr.next();
+            if (!firstEntry) {
+                text.append("&");
+            }
+            if (appProperties.contains(key)) {
+                text.append(JMSConstants._MSG_PROP_PREFIX);
+            }
+            text.append(key);
+            text.append("=");
+            text.append(props.get(key));
+            firstEntry = false;
+        }
+        return text.toString();
+    }
+
+    /**
+     * Returns a formatted URL String with the assigned properties
+     */
+    public String toString() {
+        return getURLString();
+    }
+
+    private void validateURL()
+            throws java.net.MalformedURLException {
+        Vector required = getRequiredProperties();
+        if (required == null)
+            return;
+
+        for (int i = 0; i < required.size(); i++) {
+            String key = (String) required.elementAt(i);
+            if (properties.get(key) == null)
+                throw new java.net.MalformedURLException();
+        }
+    }
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapter.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapter.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapter.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapter.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,256 @@
+/*
+ * 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.axis2.transport.jms;
+
+import org.apache.axis2.context.MessageContext;
+
+import javax.jms.InvalidDestinationException;
+import javax.jms.JMSException;
+import javax.jms.JMSSecurityException;
+import javax.jms.Message;
+import javax.jms.Queue;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSession;
+import javax.jms.Topic;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicSession;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+
+/**
+ * SPI Interface that all JMSVendorAdaptors must implement.  Allows for
+ * ConnectionFactory creation and Destination lookup
+ */
+public abstract class JMSVendorAdapter {
+    public static final int SEND_ACTION = 0;
+    public static final int CONNECT_ACTION = 1;
+    public static final int SUBSCRIBE_ACTION = 2;
+    public static final int RECEIVE_ACTION = 3;
+    public static final int ON_EXCEPTION_ACTION = 4;
+
+    public abstract QueueConnectionFactory getQueueConnectionFactory(HashMap cfProps)
+            throws Exception;
+
+    public abstract TopicConnectionFactory getTopicConnectionFactory(HashMap cfProps)
+            throws Exception;
+
+    // let adapters add vendor-specific properties or override standard ones
+    public abstract void addVendorConnectionFactoryProperties(JMSURLHelper jmsurl, HashMap cfProps);
+
+    // let adapters match connectors using vendor-specific connection factory properties
+    public abstract boolean isMatchingConnectionFactory(javax.jms.ConnectionFactory cf, JMSURLHelper jmsurl, HashMap cfProps);
+
+    // returns <adapter> in 'org.apache.axis2.transport.jms.<adapter>VendorAdapter'
+    public String getVendorId() {
+        String name = this.getClass().getName();
+
+        // cut off the trailing 'VendorAdapter'
+        if (name.endsWith(JMSConstants.ADAPTER_POSTFIX)) {
+            int index = name.lastIndexOf(JMSConstants.ADAPTER_POSTFIX);
+            name = name.substring(0, index);
+        }
+
+        // cut off the leading 'org.apache.axis2.transport.jms.'
+        int index = name.lastIndexOf(".");
+        if (index > 0)
+            name = name.substring(index + 1);
+
+        return name;
+    }
+
+    /**
+     * Creates a JMS connector property table using values supplied in
+     * the endpoint address.  Properties are translated from the short form
+     * in the endpoint address to the long form (prefixed by "transport.jms.")
+     *
+     * @param jmsurl the endpoint address
+     * @return the set of properties to be used for instantiating the JMS connector
+     */
+    public HashMap getJMSConnectorProperties(JMSURLHelper jmsurl) {
+        HashMap connectorProps = new HashMap();
+
+        // the JMS URL may be useful when matching connectors
+        connectorProps.put(JMSConstants.JMS_URL, jmsurl);
+
+        // JMSConstants.CLIENT_ID,
+        String clientID = jmsurl.getPropertyValue(JMSConstants._CLIENT_ID);
+        if (clientID != null)
+            connectorProps.put(JMSConstants.CLIENT_ID, clientID);
+
+        // JMSConstants.CONNECT_RETRY_INTERVAL,
+        String connectRetryInterval = jmsurl.getPropertyValue(JMSConstants._CONNECT_RETRY_INTERVAL);
+        if (connectRetryInterval != null)
+            connectorProps.put(JMSConstants.CONNECT_RETRY_INTERVAL, connectRetryInterval);
+
+        // JMSConstants.INTERACT_RETRY_INTERVAL,
+        String interactRetryInterval = jmsurl.getPropertyValue(JMSConstants._INTERACT_RETRY_INTERVAL);
+        if (interactRetryInterval != null)
+            connectorProps.put(JMSConstants.INTERACT_RETRY_INTERVAL, interactRetryInterval);
+
+        // JMSConstants.DOMAIN
+        String domain = jmsurl.getPropertyValue(JMSConstants._DOMAIN);
+        if (domain != null)
+            connectorProps.put(JMSConstants.DOMAIN, domain);
+
+        // JMSConstants.NUM_RETRIES
+        String numRetries = jmsurl.getPropertyValue(JMSConstants._NUM_RETRIES);
+        if (numRetries != null)
+            connectorProps.put(JMSConstants.NUM_RETRIES, numRetries);
+
+        // JMSConstants.NUM_SESSIONS
+        String numSessions = jmsurl.getPropertyValue(JMSConstants._NUM_SESSIONS);
+        if (numSessions != null)
+            connectorProps.put(JMSConstants.NUM_SESSIONS, numSessions);
+
+        // JMSConstants.TIMEOUT_TIME,
+        String timeoutTime = jmsurl.getPropertyValue(JMSConstants._TIMEOUT_TIME);
+        if (timeoutTime != null)
+            connectorProps.put(JMSConstants.TIMEOUT_TIME, timeoutTime);
+
+        return connectorProps;
+    }
+
+    /**
+     * Creates a connection factory property table using values supplied in
+     * the endpoint address
+     *
+     * @param jmsurl the endpoint address
+     * @return the set of properties to be used for instantiating the connection factory
+     */
+    public HashMap getJMSConnectionFactoryProperties(JMSURLHelper jmsurl) {
+        HashMap cfProps = new HashMap();
+
+        // hold on to the original address (this will be useful when the JNDI vendor adapter
+        // matches connectors)
+        cfProps.put(JMSConstants.JMS_URL, jmsurl);
+
+        // JMSConstants.DOMAIN
+        String domain = jmsurl.getPropertyValue(JMSConstants._DOMAIN);
+        if (domain != null)
+            cfProps.put(JMSConstants.DOMAIN, domain);
+
+        // allow vendors to customize the cf properties table
+        addVendorConnectionFactoryProperties(jmsurl, cfProps);
+
+        return cfProps;
+    }
+
+    public Queue getQueue(QueueSession session, String name)
+            throws Exception {
+        return session.createQueue(name);
+    }
+
+    public Topic getTopic(TopicSession session, String name)
+            throws Exception {
+        return session.createTopic(name);
+    }
+
+    public boolean isRecoverable(Throwable thrown, int action) {
+        if (thrown instanceof RuntimeException ||
+                thrown instanceof Error ||
+                thrown instanceof JMSSecurityException ||
+                thrown instanceof InvalidDestinationException)
+            return false;
+        if (action == ON_EXCEPTION_ACTION)
+            return false;
+        return true;
+    }
+
+    public void setProperties(Message message, HashMap props)
+            throws JMSException {
+        Iterator iter = props.keySet().iterator();
+        while (iter.hasNext()) {
+            String key = (String) iter.next();
+            String value = (String) props.get(key);
+
+            message.setStringProperty(key, value);
+        }
+    }
+
+    /**
+     * Set JMS properties in the message context.
+     * <p/>
+     * TODO: just copy all properties that are not used for the JMS connector
+     * or connection factory
+     */
+    public void setupMessageContext(MessageContext context,
+                                    JMSURLHelper jmsurl) {
+        Object tmp = null;
+
+        String jmsurlDestination = null;
+        if (jmsurl != null)
+            jmsurlDestination = jmsurl.getDestination();
+        if (jmsurlDestination != null)
+            context.setProperty(JMSConstants.DESTINATION, jmsurlDestination);
+
+        String delivMode = null;
+        if (jmsurl != null)
+            delivMode = jmsurl.getPropertyValue(JMSConstants._DELIVERY_MODE);
+        if (delivMode != null) {
+            int mode = JMSConstants.DEFAULT_DELIVERY_MODE;
+            if (delivMode.equalsIgnoreCase(JMSConstants.DELIVERY_MODE_PERSISTENT))
+                mode = javax.jms.DeliveryMode.PERSISTENT;
+            else if (delivMode.equalsIgnoreCase(JMSConstants.DELIVERY_MODE_NONPERSISTENT))
+                mode = javax.jms.DeliveryMode.NON_PERSISTENT;
+            context.setProperty(JMSConstants.DELIVERY_MODE, new Integer(mode));
+        }
+            
+        String prio = null;
+        if (jmsurl != null)
+            prio = jmsurl.getPropertyValue(JMSConstants._PRIORITY);
+        if (prio != null)
+            context.setProperty(JMSConstants.PRIORITY, Integer.valueOf(prio));
+
+        String ttl = null;
+        if (jmsurl != null)
+            ttl = jmsurl.getPropertyValue(JMSConstants._TIME_TO_LIVE);
+        if (ttl != null)
+            context.setProperty(JMSConstants.TIME_TO_LIVE, Long.valueOf(ttl));
+
+        String wait = null;
+        if (jmsurl != null)
+            wait = jmsurl.getPropertyValue(JMSConstants._WAIT_FOR_RESPONSE);
+        if (wait != null)
+            context.setProperty(JMSConstants.WAIT_FOR_RESPONSE, Boolean.valueOf(wait));
+        setupApplicationProperties(context, jmsurl);
+    }
+
+    public void setupApplicationProperties(MessageContext context,
+                                           JMSURLHelper jmsurl) {
+        //start with application properties from the URL
+        Map appProps = new HashMap();
+        if (jmsurl != null && jmsurl.getApplicationProperties() != null) {
+            for (Iterator itr = jmsurl.getApplicationProperties().iterator();
+                 itr.hasNext();) {
+                String name = (String) itr.next();
+                appProps.put(name, jmsurl.getPropertyValue(name));
+            }
+        }
+
+        //next add application properties from the message context
+        Map ctxProps =
+                (Map) context.getProperty(JMSConstants.JMS_APPLICATION_MSG_PROPS);
+        if (ctxProps != null) {
+            appProps.putAll(ctxProps);
+        }
+
+        //now tore these properties within the context
+        context.setProperty(JMSConstants.JMS_APPLICATION_MSG_PROPS, appProps);
+    }
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapterFactory.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapterFactory.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapterFactory.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JMSVendorAdapterFactory.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,76 @@
+/*
+ * 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.axis2.transport.jms;
+
+import org.apache.axis2.util.Loader;
+
+import java.util.HashMap;
+
+/**
+ * Discovery class used to locate vendor adapters.  Switch the default
+ * JNDI-based implementation by using the
+ * org.apache.axis2.transport.jms.JMSVendorAdapter system property
+ */
+public class JMSVendorAdapterFactory {
+    private static HashMap s_adapters = new HashMap();
+    private final static String VENDOR_PKG = "org.apache.axis2.transport.jms";
+    private static Loader loader = new Loader();
+
+    static {
+//        AxisProperties.setClassDefault(JMSVendorAdapter.class,
+//                VENDOR_PKG + ".JNDIVendorAdapter");
+    }
+
+    public static final JMSVendorAdapter getJMSVendorAdapter() throws Exception {
+//        return (JMSVendorAdapter) AxisProperties.newInstance(JMSVendorAdapter.class);
+        return (JMSVendorAdapter) Loader.loadClass(VENDOR_PKG + ".JNDIVendorAdapter").newInstance();
+    }
+
+    public static final JMSVendorAdapter getJMSVendorAdapter(String vendorId) {
+        // check to see if the adapter has already been instantiated
+        if (s_adapters.containsKey(vendorId))
+            return (JMSVendorAdapter) s_adapters.get(vendorId);
+
+        // create a new instance
+        JMSVendorAdapter adapter = null;
+        try {
+            Class vendorClass = Class.forName(getVendorAdapterClassname(vendorId));
+            adapter = (JMSVendorAdapter) vendorClass.newInstance();
+        }
+        catch (Exception e) {
+            return null;
+        }
+
+        synchronized (s_adapters) {
+            if (s_adapters.containsKey(vendorId))
+                return (JMSVendorAdapter) s_adapters.get(vendorId);
+
+            if (adapter != null)
+                s_adapters.put(vendorId, adapter);
+        }
+
+        return adapter;
+    }
+
+    private static String getVendorAdapterClassname(String vendorId) {
+        StringBuffer sb = new StringBuffer(VENDOR_PKG).append(".");
+        sb.append(vendorId);
+        sb.append("VendorAdapter");
+
+        return sb.toString();
+    }
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JNDIVendorAdapter.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JNDIVendorAdapter.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JNDIVendorAdapter.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/JNDIVendorAdapter.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,137 @@
+/*
+ * 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.axis2.transport.jms;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Queue;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueSession;
+import javax.jms.Topic;
+import javax.jms.TopicConnectionFactory;
+import javax.jms.TopicSession;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import java.util.HashMap;
+import java.util.Hashtable;
+
+/**
+ * Uses JNDI to locate ConnectionFactory and Destinations
+ */
+public class JNDIVendorAdapter extends JMSVendorAdapter {
+    public final static String CONTEXT_FACTORY = "java.naming.factory.initial";
+    public final static String PROVIDER_URL = "java.naming.provider.url";
+
+    public final static String _CONNECTION_FACTORY_JNDI_NAME = "ConnectionFactoryJNDIName";
+    public final static String CONNECTION_FACTORY_JNDI_NAME = JMSConstants.JMS_PROPERTY_PREFIX +
+            _CONNECTION_FACTORY_JNDI_NAME;
+
+    private Context context;
+
+    public QueueConnectionFactory getQueueConnectionFactory(HashMap cfConfig)
+            throws Exception {
+        return (QueueConnectionFactory) getConnectionFactory(cfConfig);
+    }
+
+    public TopicConnectionFactory getTopicConnectionFactory(HashMap cfConfig)
+            throws Exception {
+        return (TopicConnectionFactory) getConnectionFactory(cfConfig);
+    }
+
+    private ConnectionFactory getConnectionFactory(HashMap cfProps)
+            throws Exception {
+        if (cfProps == null)
+            throw new IllegalArgumentException("noCFProps");
+        String jndiName = (String) cfProps.get(CONNECTION_FACTORY_JNDI_NAME);
+        if (jndiName == null || jndiName.trim().length() == 0)
+            throw new IllegalArgumentException("noCFName");
+
+        Hashtable environment = new Hashtable(cfProps);
+
+        // set the context factory if provided in the JMS URL
+        String ctxFactory = (String) cfProps.get(CONTEXT_FACTORY);
+        if (ctxFactory != null)
+            environment.put(CONTEXT_FACTORY, ctxFactory);
+
+        // set the provider url if provided in the JMS URL
+        String providerURL = (String) cfProps.get(PROVIDER_URL);
+        if (providerURL != null)
+            environment.put(PROVIDER_URL, providerURL);
+
+        context = new InitialContext(environment);
+
+        return (ConnectionFactory) context.lookup(jndiName);
+    }
+
+    /**
+     * Populates the connection factory config table with properties from
+     * the JMS URL query string
+     *
+     * @param jmsurl   The target endpoint address of the Axis call
+     * @param cfConfig The set of properties necessary to create/configure the connection factory
+     */
+    public void addVendorConnectionFactoryProperties(JMSURLHelper jmsurl,
+                                                     HashMap cfConfig) {
+        // add the connection factory jndi name
+        String cfJNDIName = jmsurl.getPropertyValue(_CONNECTION_FACTORY_JNDI_NAME);
+        if (cfJNDIName != null)
+            cfConfig.put(CONNECTION_FACTORY_JNDI_NAME, cfJNDIName);
+
+        // add the initial ctx factory
+        String ctxFactory = jmsurl.getPropertyValue(CONTEXT_FACTORY);
+        if (ctxFactory != null)
+            cfConfig.put(CONTEXT_FACTORY, ctxFactory);
+
+        // add the provider url
+        String providerURL = jmsurl.getPropertyValue(PROVIDER_URL);
+        if (providerURL != null)
+            cfConfig.put(PROVIDER_URL, providerURL);
+    }
+
+    /**
+     * Check that the attributes of the candidate connection factory match the
+     * requested connection factory properties.
+     *
+     * @param cf             the candidate connection factory
+     * @param originalJMSURL the URL which was used to create the connection factory
+     * @param cfProps        the set of properties that should be used to determine the match
+     * @return true or false to indicate whether a match has been found
+     */
+    public boolean isMatchingConnectionFactory(ConnectionFactory cf,
+                                               JMSURLHelper originalJMSURL,
+                                               HashMap cfProps) {
+        JMSURLHelper jmsurl = (JMSURLHelper) cfProps.get(JMSConstants.JMS_URL);
+
+        // just check the connection factory jndi name
+        String cfJndiName = jmsurl.getPropertyValue(_CONNECTION_FACTORY_JNDI_NAME);
+        String originalCfJndiName = originalJMSURL.getPropertyValue(_CONNECTION_FACTORY_JNDI_NAME);
+
+        if (cfJndiName.equalsIgnoreCase(originalCfJndiName))
+            return true;
+
+        return false;
+    }
+
+    public Queue getQueue(QueueSession session, String name)
+            throws Exception {
+        return (Queue) context.lookup(name);
+    }
+
+    public Topic getTopic(TopicSession session, String name)
+            throws Exception {
+        return (Topic) context.lookup(name);
+    }
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/MapUtils.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/MapUtils.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/MapUtils.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/MapUtils.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,116 @@
+/*
+ * 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.axis2.transport.jms;
+
+import java.util.Map;
+
+/**
+ * MapUtils provides convenience methods for accessing a java.util.Map
+ */
+public class MapUtils {
+    /**
+     * Returns an int property from a Map and removes it.
+     *
+     * @param properties
+     * @param key
+     * @param defaultValue
+     * @return old value
+     */
+    public static int removeIntProperty(Map properties, String key, int defaultValue) {
+        int value = defaultValue;
+        if (properties != null && properties.containsKey(key)) {
+            try {
+                value = ((Integer) properties.remove(key)).intValue();
+            } catch (Exception ignore) {
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Returns a long property from a Map and removes it.
+     *
+     * @param properties
+     * @param key
+     * @param defaultValue
+     * @return old value
+     */
+    public static long removeLongProperty(Map properties, String key, long defaultValue) {
+        long value = defaultValue;
+        if (properties != null && properties.containsKey(key)) {
+            try {
+                value = ((Long) properties.remove(key)).longValue();
+            } catch (Exception ignore) {
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Returns a String property from a Map and removes it.
+     *
+     * @param properties
+     * @param key
+     * @param defaultValue
+     * @return old value
+     */
+    public static String removeStringProperty(Map properties, String key, String defaultValue) {
+        String value = defaultValue;
+        if (properties != null && properties.containsKey(key)) {
+            try {
+                value = (String) properties.remove(key);
+            } catch (Exception ignore) {
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Returns a boolean property from a Map and removes it.
+     *
+     * @param properties
+     * @param key
+     * @param defaultValue
+     * @return old value
+     */
+    public static boolean removeBooleanProperty(Map properties, String key, boolean defaultValue) {
+        boolean value = defaultValue;
+        if (properties != null && properties.containsKey(key)) {
+            try {
+                value = ((Boolean) properties.remove(key)).booleanValue();
+            } catch (Exception ignore) {
+            }
+        }
+        return value;
+    }
+
+    /**
+     * Returns an Object property from a Map and removes it.
+     *
+     * @param properties
+     * @param key
+     * @param defaultValue
+     * @return old value
+     */
+    public static Object removeObjectProperty(Map properties, String key, Object defaultValue) {
+        Object value = defaultValue;
+        if (properties != null && properties.containsKey(key)) {
+            value = properties.remove(key);
+        }
+        return value;
+    }
+}

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/QueueConnector.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/QueueConnector.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/QueueConnector.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/QueueConnector.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,257 @@
+/*
+ * 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.axis2.transport.jms;
+
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.QueueConnection;
+import javax.jms.QueueConnectionFactory;
+import javax.jms.QueueReceiver;
+import javax.jms.QueueSender;
+import javax.jms.QueueSession;
+import javax.jms.Session;
+import javax.jms.TemporaryQueue;
+
+/**
+ * QueueConnector is a concrete JMSConnector subclass that specifically handles
+ * connections to queues (ptp domain).
+ */
+public class QueueConnector extends JMSConnector {
+
+    public QueueConnector(ConnectionFactory factory,
+                          int numRetries,
+                          int numSessions,
+                          long connectRetryInterval,
+                          long interactRetryInterval,
+                          long timeoutTime,
+                          boolean allowReceive,
+                          String clientID,
+                          String username,
+                          String password,
+                          JMSVendorAdapter adapter,
+                          JMSURLHelper jmsurl)
+            throws JMSException {
+        super(factory, numRetries, numSessions, connectRetryInterval,
+                interactRetryInterval, timeoutTime, allowReceive, clientID,
+                username, password, adapter, jmsurl);
+    }
+
+    public JMSEndpoint createEndpoint(String destination) {
+        return new QueueEndpoint(destination);
+    }
+
+    /**
+     * Create an endpoint for a queue destination.
+     *
+     * @param destination
+     * @return
+     * @throws JMSException
+     */
+    public JMSEndpoint createEndpoint(Destination destination)
+            throws JMSException {
+        if (!(destination instanceof Queue))
+            throw new IllegalArgumentException("The input must be a queue for this connector");
+        return new QueueDestinationEndpoint((Queue) destination);
+    }
+
+    protected javax.jms.Connection internalConnect(ConnectionFactory connectionFactory,
+                                                   String username,
+                                                   String password)
+            throws JMSException {
+        QueueConnectionFactory qcf = (QueueConnectionFactory) connectionFactory;
+        if (username == null)
+            return qcf.createQueueConnection();
+
+        return qcf.createQueueConnection(username, password);
+    }
+
+
+    protected SyncConnection createSyncConnection(ConnectionFactory factory,
+                                                  javax.jms.Connection connection,
+                                                  int numSessions,
+                                                  String threadName,
+                                                  String clientID,
+                                                  String username,
+                                                  String password)
+
+            throws JMSException {
+        return new QueueSyncConnection((QueueConnectionFactory) factory,
+                (QueueConnection) connection, numSessions,
+                threadName, clientID, username, password);
+    }
+
+    private QueueSession createQueueSession(QueueConnection connection, int ackMode)
+            throws JMSException {
+        return connection.createQueueSession(false, ackMode);
+    }
+
+    private Queue createQueue(QueueSession session, String subject)
+            throws Exception {
+        return m_adapter.getQueue(session, subject);
+    }
+
+    private QueueReceiver createReceiver(QueueSession session,
+                                         Queue queue,
+                                         String messageSelector)
+            throws JMSException {
+        return session.createReceiver(queue, messageSelector);
+    }
+
+    private final class QueueSyncConnection extends SyncConnection {
+        QueueSyncConnection(QueueConnectionFactory connectionFactory,
+                            QueueConnection connection,
+                            int numSessions,
+                            String threadName,
+                            String clientID,
+                            String username,
+                            String password)
+                throws JMSException {
+            super(connectionFactory, connection, numSessions, threadName,
+                    clientID, username, password);
+        }
+
+        protected SendSession createSendSession(javax.jms.Connection connection)
+                throws JMSException {
+            QueueSession session = createQueueSession((QueueConnection) connection,
+                    JMSConstants.DEFAULT_ACKNOWLEDGE_MODE);
+            QueueSender sender = session.createSender(null);
+            return new QueueSendSession(session, sender);
+        }
+
+        private final class QueueSendSession extends SendSession {
+            QueueSendSession(QueueSession session,
+                             QueueSender sender)
+                    throws JMSException {
+                super(session, sender);
+            }
+
+            protected MessageConsumer createConsumer(Destination destination)
+                    throws JMSException {
+                return createReceiver((QueueSession) m_session, (Queue) destination, null);
+            }
+
+
+            protected Destination createTemporaryDestination()
+                    throws JMSException {
+                return ((QueueSession) m_session).createTemporaryQueue();
+            }
+
+            protected void deleteTemporaryDestination(Destination destination)
+                    throws JMSException {
+                ((TemporaryQueue) destination).delete();
+            }
+
+            protected void send(Destination destination, Message message,
+                                int deliveryMode, int priority, long timeToLive)
+                    throws JMSException {
+                ((QueueSender) m_producer).send((Queue) destination, message,
+                        deliveryMode, priority, timeToLive);
+            }
+
+        }
+    }
+
+    private class QueueEndpoint
+            extends JMSEndpoint {
+        String m_queueName;
+
+        QueueEndpoint(String queueName) {
+            super(QueueConnector.this);
+            m_queueName = queueName;
+        }
+
+        Destination getDestination(Session session)
+                throws Exception {
+            return createQueue((QueueSession) session, m_queueName);
+        }
+
+        public String toString() {
+            StringBuffer buffer = new StringBuffer("QueueEndpoint:");
+            buffer.append(m_queueName);
+            return buffer.toString();
+        }
+
+        public boolean equals(Object object) {
+            if (!super.equals(object))
+                return false;
+
+            if (!(object instanceof QueueEndpoint))
+                return false;
+
+            return m_queueName.equals(((QueueEndpoint) object).m_queueName);
+        }
+    }
+
+
+    private final class QueueDestinationEndpoint
+            extends QueueEndpoint {
+        Queue m_queue;
+
+        QueueDestinationEndpoint(Queue queue)
+                throws JMSException {
+            super(queue.getQueueName());
+            m_queue = queue;
+        }
+
+        Destination getDestination(Session session) {
+            return m_queue;
+        }
+
+    }
+
+    protected AsyncConnection createAsyncConnection(ConnectionFactory factory,
+                                                    javax.jms.Connection connection,
+                                                    String threadName,
+                                                    String clientID,
+                                                    String username,
+                                                    String password)
+            throws JMSException {
+        return new QueueAsyncConnection((QueueConnectionFactory) factory,
+                (QueueConnection) connection, threadName,
+                clientID, username, password);
+    }
+
+    private final class QueueAsyncConnection extends AsyncConnection {
+
+        QueueAsyncConnection(QueueConnectionFactory connectionFactory,
+                             QueueConnection connection,
+                             String threadName,
+                             String clientID,
+                             String username,
+                             String password)
+                throws JMSException {
+            super(connectionFactory, connection, threadName, clientID, username, password);
+        }
+
+        protected ListenerSession createListenerSession(javax.jms.Connection connection,
+                                                        Subscription subscription)
+                throws Exception {
+            QueueSession session = createQueueSession((QueueConnection) connection,
+                    subscription.m_ackMode);
+            QueueReceiver receiver = createReceiver(session,
+                    (Queue) subscription.m_endpoint.getDestination(session),
+                    subscription.m_messageSelector);
+            return new ListenerSession(session, receiver, subscription);
+        }
+
+    }
+
+}
\ No newline at end of file

Added: webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/SimpleJMSListener.java
URL: http://svn.apache.org/viewcvs/webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/SimpleJMSListener.java?rev=354198&view=auto
==============================================================================
--- webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/SimpleJMSListener.java (added)
+++ webservices/axis2/trunk/java/modules/core/src/org/apache/axis2/transport/jms/SimpleJMSListener.java Mon Dec  5 13:38:30 2005
@@ -0,0 +1,181 @@
+/*
+ * 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.axis2.transport.jms;
+
+import org.apache.axis2.i18n.Messages;
+import org.apache.axis2.util.OptionsParser;
+import org.apache.axis2.context.ConfigurationContext;
+import org.apache.axis2.context.ConfigurationContextFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.jms.BytesMessage;
+import javax.jms.MessageListener;
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Properties;
+
+
+/**
+ * SimpleJMSListener implements the javax.jms.MessageListener interface. Its
+ * basic purpose is listen asynchronously for messages and to pass them off
+ * to SimpleJMSWorker for processing.
+ * <p/>
+ * Note: This is a simple JMS listener that does not pool worker threads and
+ * is not otherwise tuned for performance. As such, its intended use is not
+ * for production code, but for demos, debugging, and performance profiling.
+ */
+public class SimpleJMSListener implements MessageListener {
+    protected static Log log =
+            LogFactory.getLog(SimpleJMSListener.class.getName());
+
+    // Do we use (multiple) threads to process incoming messages?
+    private static boolean doThreads;
+
+    private JMSConnector connector;
+    private JMSEndpoint endpoint;
+    private HashMap connectorProps;
+    protected ConfigurationContext configurationContext;
+
+    public SimpleJMSListener(String repositoryDirectory, HashMap connectorMap, HashMap cfMap,
+                             String destination, String username,
+                             String password, boolean doThreads)
+            throws Exception {
+        ConfigurationContextFactory erfac = new ConfigurationContextFactory();
+        this.configurationContext = erfac.buildConfigurationContext(repositoryDirectory);
+
+        SimpleJMSListener.doThreads = doThreads;
+
+        try {
+            // create a JMS connector using the default vendor adapter
+            JMSVendorAdapter adapter = JMSVendorAdapterFactory.getJMSVendorAdapter();
+            connector = JMSConnectorFactory.createServerConnector(connectorMap,
+                    cfMap,
+                    username,
+                    password,
+                    adapter);
+            connectorProps = connectorMap;
+        } catch (Exception e) {
+            log.error(Messages.getMessage("exception00"), e);
+            throw e;
+        }
+
+        // create the appropriate endpoint for the indicated destination
+        endpoint = connector.createEndpoint(destination);
+    }
+
+    protected JMSConnector getConnector() {
+        return connector;
+    }
+
+    /**
+     * This method is called asynchronously whenever a message arrives.
+     *
+     * @param message
+     */
+    public void onMessage(javax.jms.Message message) {
+        try {
+            // pass off the message to a worker as a BytesMessage
+            SimpleJMSWorker worker = new SimpleJMSWorker(configurationContext, this, (BytesMessage) message);
+
+            // do we allow multi-threaded workers?
+            if (doThreads) {
+                Thread t = new Thread(worker);
+                t.start();
+            } else {
+                worker.run();
+            }
+        }
+        catch (ClassCastException cce) {
+            log.error(Messages.getMessage("exception00"), cce);
+            cce.printStackTrace();
+            return;
+        }
+    }
+
+    public void start()
+            throws Exception {
+        endpoint.registerListener(this, connectorProps);
+        connector.start();
+    }
+
+    public void shutdown()
+            throws Exception {
+        endpoint.unregisterListener(this);
+        connector.stop();
+        connector.shutdown();
+    }
+
+    public static final HashMap createConnectorMap(org.apache.axis2.util.OptionsParser optionsParser) {
+        HashMap connectorMap = new HashMap();
+        if (optionsParser.isFlagSet('t') > 0) {
+            //queue is default so only setup map if topic domain is required
+            connectorMap.put(JMSConstants.DOMAIN, JMSConstants.DOMAIN_TOPIC);
+        }
+        return connectorMap;
+    }
+
+    public static final HashMap createCFMap(OptionsParser optionsParser)
+            throws IOException {
+        String cfFile = optionsParser.isValueSet('c');
+        if (cfFile == null)
+            return null;
+
+        Properties cfProps = new Properties();
+        cfProps.load(new BufferedInputStream(new FileInputStream(cfFile)));
+        HashMap cfMap = new HashMap(cfProps);
+        return cfMap;
+    }
+
+    public static void main(String[] args) throws Exception {
+        OptionsParser optionsParser = new OptionsParser(args);
+
+        // first check if we should print usage
+        if ((optionsParser.isFlagSet('?') > 0) || (optionsParser.isFlagSet('h') > 0))
+            printUsage();
+
+        SimpleJMSListener listener = new SimpleJMSListener(
+                optionsParser.isValueSet('r'),
+                createConnectorMap(optionsParser),
+                createCFMap(optionsParser),
+                optionsParser.isValueSet('d'),
+                optionsParser.getUser(),
+                optionsParser.getPassword(),
+                optionsParser.isFlagSet('s') > 0);
+        listener.start();
+    }
+
+    public static void printUsage() {
+        System.out.println("Usage: SimpleJMSListener [options]");
+        System.out.println(" Opts: -? this message");
+        System.out.println();
+        System.out.println("       -r repository directory location");
+        System.out.println("       -c connection factory properties filename");
+        System.out.println("       -d destination");
+        System.out.println("       -t topic [absence of -t indicates queue]");
+        System.out.println();
+        System.out.println("       -u username");
+        System.out.println("       -w password");
+        System.out.println();
+        System.out.println("       -s single-threaded listener");
+        System.out.println("          [absence of option => multithreaded]");
+
+        System.exit(1);
+    }
+}