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 }