View Javadoc

    1   /***
    2    *
    3    * Copyright 2004 Protique Ltd
    4    *
    5    * Licensed under the Apache License, Version 2.0 (the "License");
    6    * you may not use this file except in compliance with the License.
    7    * You may obtain a copy of the License at
    8    *
    9    * http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   **/
    18
    19  package org.codehaus.activemq.web;
    20
    21  import org.apache.commons.logging.Log;
    22  import org.apache.commons.logging.LogFactory;
    23  import org.codehaus.activemq.ActiveMQConnection;
    24  import org.codehaus.activemq.ActiveMQConnectionFactory;
    25  import org.codehaus.activemq.ActiveMQSession;
    26
    27  import javax.jms.ConnectionFactory;
    28  import javax.jms.Destination;
    29  import javax.jms.JMSException;
    30  import javax.jms.Message;
    31  import javax.jms.MessageConsumer;
    32  import javax.jms.MessageProducer;
    33  import javax.jms.Session;
    34  import javax.servlet.ServletContext;
    35  import javax.servlet.http.HttpSession;
    36  import javax.servlet.http.HttpSessionActivationListener;
    37  import javax.servlet.http.HttpSessionEvent;
    38  import java.io.Externalizable;
    39  import java.io.IOException;
    40  import java.io.ObjectInput;
    41  import java.io.ObjectOutput;
    42  import java.util.HashMap;
    43  import java.util.Map;
    44
    45  /***
    46   * Represents a messaging client used from inside a web container
    47   * typically stored inside a HttpSession
    48   *
    49   * @version $Revision: 1.11 $
    50   */
    51  public class WebClient implements HttpSessionActivationListener, Externalizable {
    52      public static final String webClientAttribute = "org.codehaus.activemq.webclient";
    53      public static final String connectionFactoryAttribute = "org.codehaus.activemq.connectionFactory";
    54      public static final String brokerUrlInitParam = "org.codehaus.activemq.brokerURL";
    55      public static final String embeddedBrokerInitParam = "org.codehaus.activemq.embeddedBroker";
    56
    57      private static final Log log = LogFactory.getLog(WebClient.class);
    58
    59
    60      private transient ServletContext context;
    61      private static transient ConnectionFactory factory;
    62      private transient ActiveMQConnection connection;
    63      private transient ActiveMQSession session;
    64      private transient MessageProducer producer;
    65      private transient Map consumers = new HashMap();
    66
    67
    68      /***
    69       * @return the web client for the current HTTP session or null if there is not a web client created yet
    70       */
    71      public static WebClient getWebClient(HttpSession session) {
    72          return (WebClient) session.getAttribute(webClientAttribute);
    73      }
    74
    75      /***
    76       * Only called by serialization
    77       */
    78      public WebClient() {
    79      }
    80
    81      public WebClient(ServletContext context) {
    82          this.context = context;
    83          setupConnectionFactory(context);
    84      }
    85
    86      public void start() throws JMSException {
    87      }
    88
    89      public void stop() throws JMSException {
    90          try {
    91              connection.close();
    92          }
    93          finally {
    94              producer = null;
    95              session = null;
    96              connection = null;
    97              consumers.clear();
    98          }
    99      }
    100
    101     public void writeExternal(ObjectOutput out) throws IOException {
    102     }
    103
    104     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    105         consumers = new HashMap();
    106     }
    107
    108     public void send(Destination destination, Message message) throws JMSException {
    109         if (producer == null) {
    110             producer = getSession().createProducer(null);
    111         }
    112         log.info("Sending to destination: " + destination);
    113         producer.send(destination, message);
    114         log.info("Sent! message: " + message);
    115     }
    116
    117     public Session getSession() throws JMSException {
    118         if (session == null) {
    119             session = (ActiveMQSession) getConnection().createSession(false, Session.AUTO_ACKNOWLEDGE);
    120         }
    121         return session;
    122     }
    123
    124     public ActiveMQConnection getConnection() throws JMSException {
    125         if (connection == null) {
    126             connection = (ActiveMQConnection) factory.createConnection();
    127             connection.start();
    128         }
    129         return connection;
    130     }
    131
    132     public void sessionWillPassivate(HttpSessionEvent event) {
    133         try {
    134             stop();
    135         }
    136         catch (JMSException e) {
    137             log.warn("Could not close connection: " + e, e);
    138         }
    139     }
    140
    141     public void sessionDidActivate(HttpSessionEvent event) {
    142         // lets update the connection factory from the servlet context
    143         context = event.getSession().getServletContext();
    144         setupConnectionFactory(context);
    145     }
    146
    147     private static synchronized void setupConnectionFactory(ServletContext context) {
    148         factory = initConnectionFactory(context);
    149         if (factory == null) {
    150             log.warn("No ConnectionFactory available in the ServletContext for: " + connectionFactoryAttribute);
    151             factory = new ActiveMQConnectionFactory("vm://localhost");
    152             context.setAttribute(connectionFactoryAttribute, factory);
    153         }
    154     }
    155
    156     public static ConnectionFactory initConnectionFactory(ServletContext servletContext) {
    157         ConnectionFactory connectionFactory = (ConnectionFactory) servletContext.getAttribute(connectionFactoryAttribute);
    158         if (connectionFactory == null) {
    159             String brokerURL = (String) servletContext.getInitParameter(brokerUrlInitParam);
    160
    161             servletContext.log("Value of: " + brokerUrlInitParam + " is: " + brokerURL);
    162
    163             if (brokerURL == null) {
    164                 brokerURL = "vm://localhost";
    165             }
    166
    167             boolean embeddedBroker = MessageServletSupport.asBoolean(servletContext.getInitParameter(embeddedBrokerInitParam));
    168             servletContext.log("Use embedded broker: " + embeddedBroker);
    169
    170             ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory(brokerURL);
    171             factory.setUseEmbeddedBroker(embeddedBroker);
    172
    173             connectionFactory = factory;
    174             servletContext.setAttribute(connectionFactoryAttribute, connectionFactory);
    175         }
    176         return connectionFactory;
    177     }
    178
    179     public synchronized MessageConsumer getConsumer(Destination destination) throws JMSException {
    180         MessageConsumer consumer = (MessageConsumer) consumers.get(destination);
    181         if (consumer == null) {
    182             consumer = session.createConsumer(destination);
    183             consumers.put(destination, consumer);
    184         }
    185         return consumer;
    186     }
    187
    188 }