001    /** 
002     * 
003     * Copyright 2004 Protique Ltd
004     * 
005     * Licensed under the Apache License, Version 2.0 (the "License"); 
006     * you may not use this file except in compliance with the License. 
007     * You may obtain a copy of the License at 
008     * 
009     * http://www.apache.org/licenses/LICENSE-2.0
010     * 
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS, 
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
014     * See the License for the specific language governing permissions and 
015     * limitations under the License. 
016     * 
017     **/
018    
019    package org.activemq.web;
020    
021    import org.activemq.message.ActiveMQQueue;
022    import org.activemq.message.ActiveMQTopic;
023    
024    import javax.jms.Destination;
025    import javax.jms.JMSException;
026    import javax.jms.TextMessage;
027    import javax.servlet.ServletConfig;
028    import javax.servlet.ServletException;
029    import javax.servlet.http.HttpServlet;
030    import javax.servlet.http.HttpServletRequest;
031    import javax.servlet.http.HttpSession;
032    import java.io.BufferedReader;
033    import java.io.IOException;
034    import java.util.Iterator;
035    import java.util.Map;
036    
037    /**
038     * A useful base class for any JMS related servlet;
039     * there are various ways to map JMS operations to web requests
040     * so we put most of the common behaviour in a reusable base class.
041     *
042     * @version $Revision: 1.1.1.1 $
043     */
044    public abstract class MessageServletSupport extends HttpServlet {
045    
046        private boolean defaultTopicFlag = true;
047        private Destination defaultDestination;
048        private String destinationParameter = "destination";
049        private String topicParameter = "topic";
050        private String bodyParameter = "body";
051    
052    
053        public void init(ServletConfig servletConfig) throws ServletException {
054            super.init(servletConfig);
055    
056            String name = servletConfig.getInitParameter("topic");
057            if (name != null) {
058                defaultTopicFlag = asBoolean(name);
059            }
060    
061            log("Defaulting to use topics: " + defaultTopicFlag);
062    
063            name = servletConfig.getInitParameter("destination");
064            if (name != null) {
065                if (defaultTopicFlag) {
066                    defaultDestination = new ActiveMQTopic(name);
067                }
068                else {
069                    defaultDestination = new ActiveMQQueue(name);
070                }
071            }
072    
073            // lets check to see if there's a connection factory set
074            WebClient.initContext(getServletContext());
075        }
076    
077        protected WebClient createWebClient(HttpServletRequest request) {
078            return new WebClient(getServletContext());
079        }
080    
081        public static boolean asBoolean(String param) {
082            return asBoolean(param, false);
083        }
084        
085        public static boolean asBoolean(String param, boolean defaultValue) {
086            if (param == null) {
087                return defaultValue;
088            }
089            else {
090                return param.equalsIgnoreCase("true");
091            }
092        }
093    
094        /**
095         * Helper method to get the client for the current session
096         *
097         * @param request is the current HTTP request
098         * @return the current client or a newly creates
099         */
100        protected WebClient getWebClient(HttpServletRequest request) {
101            HttpSession session = request.getSession(true);
102            WebClient client = WebClient.getWebClient(session);
103            if (client == null) {
104                client = createWebClient(request);
105                session.setAttribute(WebClient.webClientAttribute, client);
106            }
107            return client;
108        }
109    
110    
111        protected void appendParametersToMessage(HttpServletRequest request, TextMessage message) throws JMSException {
112            for (Iterator iter = request.getParameterMap().entrySet().iterator(); iter.hasNext();) {
113                Map.Entry entry = (Map.Entry) iter.next();
114                String name = (String) entry.getKey();
115                if (!destinationParameter.equals(name) && !topicParameter.equals(name) && !bodyParameter.equals(name)) {
116                    Object value = entry.getValue();
117                    if (value instanceof Object[]) {
118                        Object[] array = (Object[]) value;
119                        if (array.length == 1) {
120                            value = array[0];
121                        }
122                        else {
123                            log("Can't use property: " + name + " which is of type: " + value.getClass().getName() + " value");
124                            value = null;
125                            for (int i = 0, size = array.length; i < size; i++) {
126                                log("value[" + i + "] = " + array[i]);
127                            }
128                        }
129                    }
130                    if (value != null) {
131                        message.setObjectProperty(name, value);
132                    }
133                }
134            }
135        }
136    
137        /**
138         * @return the destination to use for the current request
139         */
140        protected Destination getDestination(WebClient client, HttpServletRequest request) throws JMSException, NoDestinationSuppliedException {
141            String destinationName = request.getParameter(destinationParameter);
142            if (destinationName == null) {
143                if (defaultDestination == null) {
144                    return getDestinationFromURI(client, request);
145                }
146                else {
147                    return defaultDestination;
148                }
149            }
150    
151            return getDestination(client, request, destinationName);
152        }
153    
154        /**
155         * @return the destination to use for the current request using the relative URI from
156         *         where this servlet was invoked as the destination name
157         */
158        protected Destination getDestinationFromURI(WebClient client, HttpServletRequest request) throws NoDestinationSuppliedException, JMSException {
159            String uri = request.getPathInfo();
160            if (uri == null) {
161                throw new NoDestinationSuppliedException();
162            }
163            // replace URI separator with JMS destination separator
164            if (uri.startsWith("/")) {
165                uri = uri.substring(1);
166            }
167            uri = uri.replace('/', '.');
168            return getDestination(client, request, uri);
169        }
170    
171        /**
172         * @return the Destination object for the given destination name
173         */
174        protected Destination getDestination(WebClient client, HttpServletRequest request, String destinationName) throws JMSException {
175            if (isTopic(request)) {
176                return client.getSession().createTopic(destinationName);
177            }
178            else {
179                return client.getSession().createQueue(destinationName);
180            }
181        }
182    
183        /**
184         * @return true if the current request is for a topic destination, else false if its for a queue
185         */
186        protected boolean isTopic
187                (HttpServletRequest
188                request) {
189            boolean aTopic = defaultTopicFlag;
190            String aTopicText = request.getParameter(topicParameter);
191            if (aTopicText != null) {
192                aTopic = asBoolean(aTopicText);
193            }
194            return aTopic;
195        }
196    
197        protected long asLong(String name) {
198            return Long.parseLong(name);
199        }
200    
201        /**
202         * @return the text that was posted to the servlet which is used as the body
203         *         of the message to be sent
204         */
205        protected String getPostedMessageBody(HttpServletRequest request) throws IOException {
206            String answer = request.getParameter(bodyParameter);
207            if (answer == null) {
208                // lets read the message body instead
209                BufferedReader reader = request.getReader();
210                StringBuffer buffer = new StringBuffer();
211                while (true) {
212                    String line = reader.readLine();
213                    if (line == null) {
214                        break;
215                    }
216                    buffer.append(line);
217                    buffer.append("\n");
218                }
219                return buffer.toString();
220            }
221            return answer;
222        }
223    }