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
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 }