001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  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    package org.apache.activemq.web;
018    
019    import java.io.IOException;
020    import java.io.PrintWriter;
021    import java.util.Enumeration;
022    import java.util.HashMap;
023    import java.util.Map;
024    
025    import javax.jms.JMSException;
026    import javax.jms.Message;
027    import javax.jms.Queue;
028    import javax.jms.QueueBrowser;
029    import javax.jms.Session;
030    import javax.servlet.ServletException;
031    import javax.servlet.http.HttpServlet;
032    import javax.servlet.http.HttpServletRequest;
033    import javax.servlet.http.HttpServletResponse;
034    
035    import org.apache.activemq.util.FactoryFinder;
036    import org.apache.activemq.util.IntrospectionSupport;
037    import org.apache.activemq.web.view.MessageRenderer;
038    import org.apache.activemq.web.view.XmlMessageRenderer;
039    
040    /**
041     * Renders the contents of a queue using some kind of view. The URI is assumed
042     * to be the queue. The following parameters can be used
043     * <p/>
044     * <ul>
045     * <li>view - specifies the type of the view such as simple, xml, rss</li>
046     * <li>selector - specifies the SQL 92 selector to apply to the queue</li>
047     * </ul>
048     *
049     * 
050     */
051    public class QueueBrowseServlet extends HttpServlet {
052        private static FactoryFinder factoryFinder = new FactoryFinder("META-INF/services/org/apache/activemq/web/view/");
053    
054        // Implementation methods
055        // -------------------------------------------------------------------------
056        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
057            try {
058                WebClient client = WebClient.getWebClient(request);
059                Session session = client.getSession();
060                Queue queue = getQueue(request, session);
061                if (queue == null) {
062                    throw new ServletException("No queue URI specified");
063                }
064    
065                String msgId = request.getParameter("msgId");
066                if (msgId == null) {
067                    MessageRenderer renderer = getMessageRenderer(request);
068                    configureRenderer(request, renderer);
069    
070                    String selector = getSelector(request);
071                    QueueBrowser browser = session.createBrowser(queue, selector);
072                    renderer.renderMessages(request, response, browser);
073                }
074                else {
075                    XmlMessageRenderer renderer = new XmlMessageRenderer();
076                    QueueBrowser browser = session.createBrowser(queue, "JMSMessageID='" + msgId + "'");
077                    if (!browser.getEnumeration().hasMoreElements()) {
078                        response.sendError(HttpServletResponse.SC_NOT_FOUND);
079                        return;
080                    }
081                    Message message = (Message) browser.getEnumeration().nextElement();
082    
083                    PrintWriter writer = response.getWriter();
084                    renderer.renderMessage(writer, request, response, browser, message);
085                    writer.flush();
086                }
087            }
088            catch (JMSException e) {
089                throw new ServletException(e);
090            }
091        }
092    
093        protected MessageRenderer getMessageRenderer(HttpServletRequest request) throws IOException, ServletException {
094            String style = request.getParameter("view");
095            if (style == null) {
096                style = "simple";
097            }
098            try {
099                return (MessageRenderer) factoryFinder.newInstance(style);
100            }
101            catch (IllegalAccessException e) {
102                throw new NoSuchViewStyleException(style, e);
103            }
104            catch (InstantiationException e) {
105                throw new NoSuchViewStyleException(style, e);
106            }
107            catch (ClassNotFoundException e) {
108                throw new NoSuchViewStyleException(style, e);
109            }
110        }
111    
112        @SuppressWarnings("unchecked")
113        protected void configureRenderer(HttpServletRequest request, MessageRenderer renderer) {
114            Map<String, String> properties = new HashMap<String, String>();
115            for (Enumeration<String> iter = request.getParameterNames(); iter.hasMoreElements();) {
116                String name = (String) iter.nextElement();
117                properties.put(name, request.getParameter(name));
118            }
119            IntrospectionSupport.setProperties(renderer, properties);
120        }
121    
122        protected String getSelector(HttpServletRequest request) {
123            return request.getParameter("selector");
124        }
125    
126        protected Queue getQueue(HttpServletRequest request, Session session) throws JMSException {
127            String uri = request.getPathInfo();
128            if (uri == null) {
129                return null;
130            }
131    
132            // replace URI separator with JMS destination separator
133            if (uri.startsWith("/")) {
134                uri = uri.substring(1);
135                if (uri.length() == 0) {
136                    return null;
137                }
138            }
139            uri = uri.replace('/', '.');
140    
141            return session.createQueue(uri);
142        }
143    }