Package com.sun.messaging.ums.core

Source Code of com.sun.messaging.ums.core.UMSServlet

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/

package com.sun.messaging.ums.core;

import com.sun.messaging.ums.simple.SimpleMessage;
import com.sun.messaging.ums.simple.SimpleMessageFactory;
import com.sun.messaging.ums.common.Constants;
import com.sun.messaging.ums.provider.openmq.ProviderDestinationService;
import com.sun.messaging.ums.resources.UMSResources;
import com.sun.messaging.ums.readonly.DefaultReadOnlyService;
import com.sun.messaging.ums.readonly.ReadOnlyMessageFactory;
import com.sun.messaging.ums.readonly.ReadOnlyRequestMessage;
import com.sun.messaging.ums.readonly.ReadOnlyResponseMessage;
import com.sun.messaging.ums.service.DestinationService;
import com.sun.messaging.ums.service.BrokerInfoService;
import com.sun.messaging.ums.service.SOAP2JMSService;
import com.sun.messaging.ums.service.UMSServiceImpl;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

//import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Enumeration;

import java.util.Hashtable;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;

//import javax.xml.messaging.ReqRespListener;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.MimeHeaders;
import javax.xml.soap.MimeHeader;
import javax.xml.soap.SOAPConstants;

/**
*
* The entry class for UMS services.
*
* The configurations are defined in web.xml for thi servlet.
*
* <servlet>
*   <servlet-name>UMS</servlet-name>
*   <servlet-class>
*       com.sun.messaging.ums.core.UMSServlet
*   </servlet-class>
*   <!-- set openmq broker address -->
*   <!--
*   <init-param>
*       <param-name>imqAddressList</param-name>
*       <param-value>localhost</param-value>
*   </init-param>
*   -->
*  
*  
*    <!-- provider registeration -->
*    <!-- mom.provider.num-->
*   
*    <!--
*    <init-param>
*       <param-name>mom.provider.1</param-name>
*       <param-value>jmsgrid</param-value>
*   </init-param>
*    -->
*   
*    <!--
*    <init-param>
*       <param-name>mom.provider.0</param-name>
*       <param-value>openmq</param-value>
*   </init-param>
*    -->
*   
*    <!-- provider factory class registration, not used in first release -->
*    <!--
*    <init-param>
*       <param-name>mom.jmsgrid.providerFactory</param-name>
*       <param-value>com.sun.messaging.ums.jmsgrid.ProviderFactory</param-value>
*   </init-param>
*   
*    <init-param>
*       <param-name>mom.openmq.providerFactory</param-name>
*       <param-value>com.sun.messaging.ums.openmq.ProviderFactory</param-value>
*   </init-param>
*    -->
*
*    <!-- jms grid daemon host configuration, not used in first release
*    <init-param>
*       <param-name>grid.host</param-name>
*       <param-value>niagra2</param-value>
*   </init-param>
*    -->
*   
*    <!-- authenticate with JMS server -->
*    <!-- applications must provide user/pass for JMS server if set to true -->
*    <init-param>
*       <param-name>ums.service.authenticate</param-name>
*       <param-value>false</param-value>
*   </init-param>
*   
*    <!-- applications must encode password with base64 encoding if set to true -->
*    <init-param>
*       <param-name>ums.service.authenticate.basic</param-name>
*       <param-value>false</param-value>
*   </init-param>
*   
*    <!-- user name for UMS to authenticate with JMS Server -->
*    <init-param>
*       <param-name>ums.user.name</param-name>
*       <param-value>guest</param-value>
*   </init-param>
*   
*    <!-- password for ums to authenticate with JMS server -->
*    <init-param>
*       <param-name>ums.password</param-name>
*       <param-value>guest</param-value>
*   </init-param>
*   
* </servlet>
*
* <!-- simple messaging service url -->
<servlet-mapping>
*   <servlet-name>UMS</servlet-name>
*   <url-pattern>/simple</url-pattern>
</servlet-mapping>
*
* <!-- xml messaging service url -->
* <servlet-mapping>
*   <servlet-name>UMS</servlet-name>
*   <url-pattern>/xml</url-pattern>
* </servlet-mapping>
*
* @author chiaming
*/
public class UMSServlet extends HttpServlet {

    /**
     * message factory to be used to construct soap message.
     */
    protected MessageFactory mfactory = null;

    private static Logger logger = UMSServiceImpl.logger;

    protected Properties props = null;

    /**
     * <p>define class name in the web.xml as follows:
     * <p> <init-param>
     * <p>  <param-name>mq.soap.service</param-name>
     * <p>  <param-value>MQSOAPService-CLASS-FULL-NAME</param-value>
     * <p> </init-param>
     *
     */
    //public static final String MQ_SERVICE_PARAM_NAME = "mq.soap.service";
   
    /**
     * default MQ SOAP service class name.
     */
    //public static final String MQ_SERVICE_DEFAULT_CLASSNAME =
    //        "com.sun.messaging.ums.jms.SOAP2JMSService";

    /**
     * MQ SERVICE class name.
     */
    //protected String mqServiceClassName = null;

    /**
     * MQ SERVICE instance.
     */
    protected UMSService mqService = null;

    /**
     * Service Context instance.
     */
    protected ServiceContext serviceContext = null;
   
    /**
     * MQ JMS Service
     */
    protected UMSServiceImpl JMSService = null;
   
    /**
     * receive timeout for HTTP/GET JMS service.
     */
    static protected long receiveTimeout = 7000;
   
    /**
     * topic/queue domain
     */
    private static final String TOPIC_DOMAIN = "topic";
   
    private static final String QUEUE_DOMAIN = "queue";
   
    /**
     * service field string used in HTTP/GET response message
     */
    private static final String SERVICE = "service=";
   
    /**
     * message field string used in HTTP/GET response message
     */
    private static final String MESSAGE = "text=";
   
    /**
     * destination field string used in HTTP/GET response message
     */
    private static final String DESTINATION = "destination=";
   
    /**
     * domain field string used in HTTP/GET response message
     */
    private static final String DOMAIN = "domain=";
   
    /**
     * UUID/SID/CLIENTID used in HTTP/GET response message
     */
    private static final String UUID = "sid=";
   
    /**
     * Content-Length
     */
    private static final String CONTENT_LENGTH = "Content-Length";
   
    /**
     * content-type
     */
    private static final String CONTENT_TYPE = "Content-Type";
   
    /**
     *
     */
    private static final String TEXT_XML = "text/xml";
    
    /**
     * authenticate
     */
    protected boolean shouldAuthenticate = false;
   
    /**
     * admin debug service.
     * this is sent from HTTP/GET with service=admin
     * and debug=true/false.
     */
    private static final String ADMIN_DEBUG = "debug";
   
    private static final String SIMPLE = "simple";
   
    /**
     * simple messaging response message header fields
     */
    private static final String UMS_SERVICE = "ums.service";
    private static final String UMS_MOM = "ums.mom";
    private static final String UMS_DESTINATION = "ums.destination";
    private static final String UMS_DOMAIN = "ums.domain";
    private static final String UMS_STATUS = "ums.status";
   
    /**
     * UTF-8
     */
    private static final String UTF8 = "UTF-8";
   
    /**
     * empty string
     */
    private static final String EMPTY_STRING = "";
   
    /**
     * utf-8 content type
     */
    private static final String PLAIN_TEXT_CONTENT_TYPE = "text/plain;charset=UTF-8";
   
    private static final String HTML_CONTENT_TYPE = "text/html;charset=UTF-8";
   
    private static final String XML_CONTENT_TYPE = "text/xml;charset=UTF-8";
   
    /**
     * read only service -- this is to be used to dispatch readonly request.
     */
    private DefaultReadOnlyService readOnlyService = null;
   
    /**
     * init message factory and soap intermediate object.
     */
    public void init(ServletConfig servletConfig) throws ServletException {
        super.init(servletConfig);

        /**
         * init logger.
         */
        initLogger();

        /**
         * init config params:
         * 1. get mq service class name.
         * 2. construct init properties object from servlet config object.
         */
        initParams (servletConfig);

        /**
         * init/construct message factory.
         */
        initMessageFactory();

        /**
         * construct/init/start mq service.
         */
        initService ();
       
    }

    /**
     * Init logger
     */
    protected void initLogger() {
       
        //logger = Logger.getLogger(UMSService.LOGGER_CAT_NAME);

        String msg = UMSResources.getResources().getKString(UMSResources.UMS_LOGGER_INIT, logger.getName());
        logger.info(msg);
       
        //logger.fine("**** servlet logger init: " + logger.getName() );
    }

    /**
     * 1. Get mq service class name.
     * 2. Convert servlet init parameters into Properties object.
     */
    protected void initParams (ServletConfig servletConfig) {

        /**
         * get MQ Service Class Name.
         */
        //mqServiceClassName =
        //servletConfig.getInitParameter(MQ_SERVICE_PARAM_NAME);
       
        //if (mqServiceClassName == null) {
        //    mqServiceClassName = MQ_SERVICE_DEFAULT_CLASSNAME;
        //}

        props = new Properties();
        Enumeration enum2 = servletConfig.getInitParameterNames();

        while ( enum2.hasMoreElements() ) {
            String pname = (String) enum2.nextElement();
            String pvalue = (String) servletConfig.getInitParameter(pname);

            props.put(pname, pvalue);
        }
       
        String msg = UMSResources.getResources().getKString(UMSResources.UMS_CONFIG_INIT);
        logger.info(msg);

    }

    /**
     * init message factory -- may be over ridden by sub class.
     */
    protected void
    initMessageFactory () throws ServletException {
        try {
            mfactory = MessageFactory.newInstance(SOAPConstants.DEFAULT_SOAP_PROTOCOL);
        } catch (Exception e) {
            throw new ServletException (e.getMessage(), e);
        }
    }

    /**
     * instantiate/init/start MQ SOAP Service.
     */
    protected void
    initService () throws ServletException {

        try {

            /**
             * construct mq service.
             */
            //mqService =
            //(UMSService) Class.forName(mqServiceClassName).newInstance();
           
            mqService = new SOAP2JMSService();
           
            /**
             * construct service context.
             */
            initServiceContext();

            /**
             * init mq service with service context.
             */
            this.mqService.init( serviceContext );

            /**
             * start mq service.
             */
            this.mqService.start();
           
            /**
             * JMSService for doGet
             */
            //if (mqService instanceof SOAP2JMSService) {
            this.JMSService = ((SOAP2JMSService) mqService).getJMSService();
            //}
           
            //make the JMSService available to ReadOnlyServices
            props.put(DefaultReadOnlyService.JMSSERVICE, this.JMSService);
           
            /**
             * receive timeout - default 7 seconds
             */
            String tmp = props.getProperty (Constants.IMQ_RECEIVE_TIMEOUT, Constants.IMQ_RECEIVE_TIMEOUT_DEFAULT_VALUE);
            if (tmp != null) {
                receiveTimeout = Long.parseLong(tmp);
            }
           
            String msg = UMSResources.getResources().getKString(UMSResources.UMS_DEFAULT_RECEIVE_TIMEOUT, receiveTimeout);
            logger.info(msg);
            //logger.info("default receive timeout=" + receiveTimeout + " milli seconds.");
           
            /**
             * authenticate
             */
            tmp = props.getProperty(Constants.JMS_AUTHENTICATE, "false");
            this.shouldAuthenticate = Boolean.valueOf(tmp).booleanValue();
           
            /**
             * destination service
             *
             */
            DestinationService.init(props);
           
            /**
             * broker info service
             *
             */
            BrokerInfoService.init(props);
           
            /**
             * init readonly service
             */
            readOnlyService = new DefaultReadOnlyService();
            readOnlyService.init(props);
           
            msg = UMSResources.getResources().getKString(UMSResources.UMS_SERVICE_STARTED);
            logger.info(msg);
           
        } catch (Exception e) {
            throw new ServletException (e.getMessage(), e);
        }
    }

    /**
     * init service context.  Sub class may over ride this method and
     * provide a customized service object.
     */
    protected void initServiceContext() throws ServletException {
        serviceContext = new UMSServiceContext (props);
    }
   
    public void
    doGet(HttpServletRequest req, HttpServletResponse resp)
                        throws ServletException, IOException {
        //this.doSimpleMessaging(req, resp);
        this.doReadOnlyService(req, resp);
    }
   
    /**
     * The features are not yet ready for public use yet.
     * XXX
     * @param req
     * @param resp
     * @throws javax.servlet.ServletException
     * @throws java.io.IOException
     */
    private void doReadOnlyService (HttpServletRequest req, HttpServletResponse resp)
                        throws ServletException, IOException {
       
        int status = resp.SC_BAD_REQUEST;
       
        String service = req.getParameter(Constants.SERVICE_NAME);
        //String user = req.getParameter(Constants.USER);
        //String pass = req.getParameter(Constants.PASSWORD);
       
        String respMsg = null;
       
        if (UMSServiceImpl.getDebug()) {
           
            String remoteHost = req.getRemoteHost();
            int remotePort = req.getRemotePort();
           
            String requestURL = req.getRequestURL().toString();
            logger.info("requestURL=" + requestURL + ", client=" + remoteHost + ":" + remotePort + ", request service=" + service);
        }
       
        Map map = this.getHeadersAsMap(req);
       
        //use string[] to be consistent
        String[] ru = new String[1];
        ru[0] = req.getRequestURL().toString();
        map.put(DefaultReadOnlyService.REQUEST_URL, ru);
       
        try {
           
          //respMsg = readOnlyService.request(map);
          ReadOnlyRequestMessage rom = ReadOnlyMessageFactory.createRequestMessage(map, req.getInputStream());
          ReadOnlyResponseMessage respm = readOnlyService.request(rom);
         
          respMsg = respm.getResponseMessage();
         
          //get status code from respm
          status = respm.getStatusCode();
         
          resp.setStatus(status);
 
          if (isHTML (respMsg)) {
              resp.setHeader(CONTENT_TYPE, HTML_CONTENT_TYPE);
          } else if (isXML (respMsg)) {
              resp.setHeader(CONTENT_TYPE, XML_CONTENT_TYPE);
          } else {
              resp.setHeader(CONTENT_TYPE, PLAIN_TEXT_CONTENT_TYPE);
          }
         
          byte[] data = null;
 
          if (respMsg != null) {
              data = respMsg.getBytes(UTF8);
          } else {
              data = EMPTY_STRING.getBytes(UTF8);
          }
 
          DataOutputStream dos = new DataOutputStream(resp.getOutputStream());
         
          resp.setContentLength(data.length);
 
          dos.write(data, 0, data.length);
 
          dos.flush();
          dos.close();
       
        } catch (Exception e) {

            logger.log(Level.WARNING, e.getMessage(), e);

            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.setHeader(CONTENT_TYPE, PLAIN_TEXT_CONTENT_TYPE);
          
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
           
            PrintStream ps = new PrintStream (baos);
            ps.println(e);

            // don't print a stack trace: too much information
            //e.printStackTrace(ps);
           
            byte[] data = baos.toString().getBytes(UTF8);
           
            DataOutputStream dos = new DataOutputStream(resp.getOutputStream());

            resp.setContentLength(data.length);

            dos.write(data, 0, data.length);

            dos.flush();
            dos.close();
            resp.flushBuffer();
       
        }
    }
   
    public void
    doPost(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
       
        String uri = req.getServletPath();
       
        if (UMSServiceImpl.debug) {
           
            String remoteHost = req.getRemoteHost();
            int remotePort = req.getRemotePort();
           
            String requestURL = req.getRequestURL().toString();
            logger.info("requestURL=" + requestURL + ", client=" + remoteHost + ":" + remotePort);
        }
       
        if ( uri != null && uri.indexOf(SIMPLE) > 0 ) {
            doSimpleMessaging (req, resp);
            //doTest(req, resp);   
        } else {
            doXmlMessaging (req, resp);
        }
       
    }
   
    /**
     * Send/Receive a simple text message.  Default domain is queue.  To specify
     * domain, add domain=queue/topic in the query string.
     *
     * Example:
     *
     * http://host:port/xmlprotocol/service?clientId=chiaming&service=receive&destination=testQ
     * http://host:port/xmlprotocol/service?clientId=chiaming&service=send&destination=testQ&text=myMessage
     *
     * @param req
     * @param resp
     * @throws javax.servlet.ServletException
     * @throws java.io.IOException
     */
    public void doSimpleMessaging(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        String respMsg = null;

        int status = resp.SC_BAD_REQUEST;

        boolean isSend = false;
        boolean isReceive = false;
        boolean isAdmin = false;
        boolean isLogin = false;
        boolean isClose = false;
        boolean isCommit = false;
        boolean isRollback = false;

        boolean isValidRequest = true;

        //String separator = ",";

        Map map = this.getHeadersAsMap(req);

        //String text = this.readHttpBody(req);
        InputStream in = req.getInputStream();

        SimpleMessage msg = SimpleMessageFactory.createMessage(map, in);

        in.close();

        //String text = msg.getText();

        String destName = msg.getMessageProperty(Constants.DESTINATION_NAME);
        boolean isTopic = msg.isTopicDomain();

        String clientId = msg.getMessageProperty(Constants.CLIENT_ID);

        if (UMSServiceImpl.debug) {
            logger.info("Simple messaging sid=" + clientId);
        }

        if (msg.isSendService()) {
            isSend = true;
        } else if (msg.isReceiveService()) {
            isReceive = true;
        } else if (msg.isLoginService()) {
            isLogin = true;
        } else if (msg.isCloseService()) {
            isClose = true;
        } else if (msg.isAdminService()) {
            isAdmin = true;
        } else if (msg.isCommitService()) {
            isCommit = true;
        } else if (msg.isRollbackService()) {
            isRollback = true;
        } else {
            isValidRequest = false;
        }

        try {

            //logger.info("request servlet path=" + req.getServletPath());

            if (isValidRequest == false) {

                status = resp.SC_BAD_REQUEST;
                //throw exception  
                respMsg = "Invalid query string., see http://host:port/<context>/";

            } else {

                if (isSend) {

                    //String text = req.getParameter(Constants.HTTP_GET_SEND_TEXT);

                    String text = msg.getText();

                    if (UMSServiceImpl.debug) {
                        logger.info("Simple messaging, sending text=" + text);
                    }

                    this.JMSService.sendText(clientId, isTopic, destName, text, map);

                    resp.setHeader(UMS_SERVICE, Constants.SERVICE_VALUE_SEND_MESSAGE_REPLY);
                    resp.setHeader(UMS_DESTINATION, destName);
                    resp.setHeader(UMS_DOMAIN, getDomain(isTopic));

                    resp.setHeader(UMS_MOM, JMSService.getProvider(map));
                    resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_OK);

                } else if (isReceive) {

                    long timeout = this.getServiceTimeout(msg);

                    //receive message
                    String text = this.JMSService.receiveText(clientId, destName, isTopic, timeout, map);

                    resp.setHeader(UMS_SERVICE, Constants.SERVICE_VALUE_RECEIVE_MESSAGE_REPLY);
                    resp.setHeader(UMS_DESTINATION, destName);
                    resp.setHeader(UMS_DOMAIN, getDomain(isTopic));

                    resp.setHeader(UMS_MOM, JMSService.getProvider(map));

                    respMsg = text;

                    if (respMsg == null) {
                        //respMsg = "null";
                        resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_NO_MESSAGE);
                    } else {
                        resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_OK);
                    }

                } else if (isLogin) {

                    String sid = this.JMSService.authenticate(map);

                    resp.setHeader(UMS_SERVICE, Constants.SERVICE_VALUE_LOGIN_REPLY);

                    resp.setHeader(UMS_MOM, JMSService.getProvider(map));
                    resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_OK);

                    respMsg = sid;
                } else if (isClose) {

                    String sid = this.JMSService.closeClient2(map);

                    resp.setHeader(UMS_SERVICE, Constants.SERVICE_VALUE_CLOSE_REPLY);

                    resp.setHeader(UMS_MOM, JMSService.getProvider(map));
                    resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_OK);

                } else if (isCommit) {

                    this.JMSService.commit(msg);

                    resp.setHeader(UMS_SERVICE, Constants.SERVICE_VALUE_COMMIT_REPLY);

                    resp.setHeader(UMS_MOM, JMSService.getProvider(map));
                    resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_OK);
                } else if (isRollback) {

                    this.JMSService.rollback(msg);

                    resp.setHeader(UMS_SERVICE, Constants.SERVICE_VALUE_ROLLBACK_REPLY);

                    resp.setHeader(UMS_MOM, JMSService.getProvider(map));

                    resp.setHeader(UMS_STATUS, Constants.SERVICE_STATUS_VALUE_OK);

                } else if (isAdmin) {

                    String user = req.getParameter(Constants.USER);
                    String pass = req.getParameter(Constants.PASSWORD);
                    ProviderDestinationService pds = DestinationService.getProviderDestinationService(null);

                    pds.authenticate(user, pass);

                    String flag = req.getParameter(ADMIN_DEBUG);

                    boolean debug = Boolean.valueOf(flag).booleanValue();

                    UMSServiceImpl.debug = debug;

                    respMsg = SERVICE + "admin, " + ADMIN_DEBUG + "=" + debug;
                }

                status = resp.SC_OK;
            }

            resp.setStatus(status);

            //resp.setHeader("Content-Type", "text/plain;charset=UTF-8");
            resp.setHeader(CONTENT_TYPE, PLAIN_TEXT_CONTENT_TYPE);
            //resp.setCharacterEncoding("UTF-8");

            byte[] data = null;

            if (respMsg != null) {
                data = respMsg.getBytes(UTF8);
            } else {
                //data = "".getBytes(UTF8);
                data = EMPTY_STRING.getBytes(UTF8);
            }

            DataOutputStream dos = new DataOutputStream(resp.getOutputStream());


            resp.setContentLength(data.length);

            dos.write(data, 0, data.length);

            //dos.writeUTF(respMsg);

            dos.flush();
            dos.close();

        } catch (Exception e) {

            logger.log(Level.WARNING, e.getMessage(), e);

            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            resp.setHeader(CONTENT_TYPE, PLAIN_TEXT_CONTENT_TYPE);
          
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
           
            PrintStream ps = new PrintStream (baos);
            e.printStackTrace(ps);
            byte[] data = baos.toString().getBytes(UTF8);
           
            DataOutputStream dos = new DataOutputStream(resp.getOutputStream());

            resp.setContentLength(data.length);

            dos.write(data, 0, data.length);

            dos.flush();
            dos.close();
            resp.flushBuffer();
        }

    }

    /**
    * Http request services.  HTTP requests are transformed into
    * SOAP messages and dispated to the appropriate services.
    */
   public void
   doXmlMessaging (HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {

       SOAPMessage msg = null;

       try {
           // Get all the headers from the HTTP request.
           MimeHeaders headers = getHeaders(req);

           // Get the body of the HTTP request.
           InputStream is = req.getInputStream();

           // Now internalize the contents of a HTTP request and
           // create a SOAPMessage
           msg = mfactory.createMessage(headers, is);

           SOAPMessage reply = null;

           /**
            * Dispatch message to mq soap service.
            */
           reply = onMessage (msg);
          
           //System.out.println ("@@@@@@ in doPost() \n");
           //reply.writeTo(System.out);
                  

           if ( reply != null ) {

               // Need to saveChanges 'cos we're going to use the
               // MimeHeaders to set HTTP response information. These
               // MimeHeaders are generated as part of the save.

               if (reply.saveRequired()) {
                   reply.saveChanges();
               }

               if ( isSOAPFault (reply) ) {
                   resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
               } else {
                   resp.setStatus(HttpServletResponse.SC_OK);
               }

               //remove content-length header field
               reply.getMimeHeaders().removeHeader(CONTENT_LENGTH);
              
               putHeaders (reply.getMimeHeaders(), resp);
              
               String[] sa = reply.getMimeHeaders().getHeader(CONTENT_TYPE);
               if ( sa == null || sa.length == 0 ) {
                 //XXX:
                 //int acount = reply.countAttachments();
                 resp.setHeader (CONTENT_TYPE, TEXT_XML);
               }
              
               // Write out the message on the response stream.
               OutputStream os = resp.getOutputStream();
               reply.writeTo(os);

               os.flush();

           } else {
               resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
           }
       } catch (Throwable ex) {
           /**
            * Log exception.
            */
           logger.log(Level.WARNING, ex.getMessage(), ex);

           resp.setStatus (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
       }
   }

   /**
     * Returns a <code>MimeHeaders</code> object that contains the headers
     * in the given <code>HttpServletRequest</code> object.
     *
     * @param req the <code>HttpServletRequest</code> object that a
     *        messaging provider sent to the servlet
     * @return a new <code>MimeHeaders</code> object containing the headers
     *         in the message sent to the servlet
     */
    protected static MimeHeaders getHeaders(HttpServletRequest req) {
        Enumeration enum2 = req.getHeaderNames();
        MimeHeaders headers = new MimeHeaders();

        while (enum2.hasMoreElements()) {
            String headerName = (String)enum2.nextElement();
            String headerValue = req.getHeader(headerName);

            StringTokenizer values = new StringTokenizer(headerValue, ",");
            while (values.hasMoreTokens())
                headers.addHeader(headerName, values.nextToken().trim());
        }

        return headers;
    }
   
   
    private void parseQueryString (Map map, String querystr) {
               
        String[] values = querystr.split("&");
       
        for (int i=0; i<values.length; i++) {
             
            //String[] keyValuePair = values[i].split("=");
           
            //String key = keyValuePair[0];
           
            //value as array -- to be consisitent with the rest of http headers
            //in the map.
            //String[] value = new String[1];
            //value[0] = keyValuePair[1];
           
            int index = values[i].indexOf('=');
            String key = values[i].substring(0, index);
           
            String[] value = new String[1];
            value[0] = values[i].substring(index+1);
           
            map.put(key, value);
           
            if (UMSServiceImpl.debug) {
                logger.info ("Adding query string param, " + key+"="+key + ", value[0]=" + value[0]);
            }
        }
               
    }
   
    protected Map getHeadersAsMap (HttpServletRequest req) {
       
        Hashtable<String, String[]> headers = new Hashtable <String, String[]> ();
       
        String querystr = req.getQueryString();
       
        if (querystr != null) {
            parseQueryString (headers, querystr);
        }
       
        Enumeration enum2 = req.getHeaderNames();
       

        while (enum2.hasMoreElements()) {
            String headerName = (String)enum2.nextElement();
            String headerValue = req.getHeader(headerName);

            ArrayList <String> alist = new ArrayList<String>();
           
            StringTokenizer values = new StringTokenizer(headerValue, ",");
            while (values.hasMoreTokens()) {
                //headers.addHeader(headerName, values.nextToken().trim());
                String hvtrim = values.nextToken().trim();
                alist.add(hvtrim);
               
                if (UMSServiceImpl.debug) {
                    logger.info ("Adding http header to map, " + headerName +"=" + hvtrim);
                }
            }
           
            String[] sarray = new String [alist.size()];
           
            alist.toArray(sarray);
           
            headers.put (headerName, sarray);
           
            //logger.info ("**** header in map, header=" + headerName + ", value=" + sarray);
        }

        return headers;
    }
   
     protected Map getRequestQueryAsMap_deprecated (HttpServletRequest req) {
        
         Hashtable <String, String> map = new Hashtable <String, String>();
        
         String qstr = req.getQueryString();
        
         StringTokenizer tokens = new StringTokenizer (qstr, " ");
        
         while (tokens.hasMoreTokens()) {
            
             String pair = tokens.nextToken();
           
         }
        
         return map;
     }
   
    protected String readHttpBody(HttpServletRequest req)
            throws ServletException, IOException {

        String text = null;

        InputStream in = req.getInputStream();
        DataInputStream din = new DataInputStream(in);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] bytes = new byte[1024];

        boolean more = true;
        int len = 0;

        while (more) {

            len = din.read(bytes);
           
            if (UMSServiceImpl.debug) {
                logger.info("Simple messaging, reading message body ... len=" + len);
            }
           
            if (len > 0) {
                baos.write(bytes, 0, len);
            } else if (len < 0) {
                more = false;
            }
        }

        byte[] body = baos.toByteArray();

        String enc = req.getCharacterEncoding();
        if (enc == null) {
            enc = UTF8;
        }
       
        baos.close();
        din.close();

        text = new String(body, enc);
        return text;
    }

    /**
     * Sets the given <code>HttpServletResponse</code> object with the
     * headers in the given <code>MimeHeaders</code> object.
     *
     * @param headers the <code>MimeHeaders</code> object containing the
     *        the headers in the message sent to the servlet
     * @param res the <code>HttpServletResponse</code> object to which the
     *        headers are to be written
     * @see #getHeaders
     */
    protected static void
    putHeaders(MimeHeaders headers, HttpServletResponse res) {
        
        Iterator it = headers.getAllHeaders();
       
        while (it.hasNext()) {
            MimeHeader header = (MimeHeader)it.next();

            String[] values = headers.getHeader(header.getName());
           
            if (values.length == 1) {
               
                res.setHeader(header.getName(), header.getValue());
            } else {
                StringBuffer concat = new StringBuffer();
                int i = 0;

                while (i < values.length) {
                    if (i != 0) {
                        concat.append(',');
                    }
                    concat.append(values[i++]);
                }
               
                res.setHeader(header.getName(), concat.toString());
                 
            }
        }
    }

    /**
     * check if this is a soap fault message.
     */
    protected boolean isSOAPFault (SOAPMessage message) throws SOAPException {
        SOAPBody body = message.getSOAPPart().getEnvelope().getBody();
        return body.hasFault();
    }

    /**
     * Message delivered from doPost().  Subclass can override this method
     * or define mq.soap.service property in web.xml file.
     */
    public SOAPMessage onMessage ( SOAPMessage message ) {
        SOAPMessage reply = null;

        try {
            reply = mqService.onMessage(message);
        } catch (Throwable e) {
            //this should not happen.  the exception is handled in onMessage()
            //and doPost().
            log (e.getMessage(), e);
        }

        return reply;
    }

    /**
     * destroy this servlet.
     */
    public void destroy() {
        mqService.close();
    }
   
    /**
     * Send/Receive a simple text message.  Default domain is queue.  To specify
     * domain, add domain=queue/topic in the query string.
     *
     * Example:
     *
     * http://host:port/xmlprotocol/service?clientId=chiaming&service=receive&destination=testQ
     * http://host:port/xmlprotocol/service?clientId=chiaming&service=send&destination=testQ&text=myMessage
     *
     * @param req
     * @param resp
     * @throws javax.servlet.ServletException
     * @throws java.io.IOException
     */
   
    /**
    public void
    doGetOld(HttpServletRequest req, HttpServletResponse resp)
                        throws ServletException, IOException {
       
        String respMsg = null;
       
        int status = resp.SC_BAD_REQUEST;
       
        boolean isSend = false;
        boolean isReceive = false;
        boolean isAdmin = false;
        boolean isLogin = false;
        boolean isClose = false;
       
        boolean isValidRequest = true;
       
        boolean isTopic = false;
       
        String separator = ",";
       
        //check the query string
        String clientId = req.getParameter(Constants.CLIENT_ID);
        String domain = req.getParameter(Constants.DOMAIN);
        if (Constants.TOPIC_DOMAIN.equals(domain)) {
            isTopic = true;
        }
       
        String destName = req.getParameter(Constants.DESTINATION_NAME);
       
        String service = req.getParameter(Constants.SERVICE_NAME);
       
        if (Constants.SERVICE_VALUE_SEND_MESSAGE.equals(service)) {
            isSend = true;
        } else if (Constants.SERVICE_VALUE_RECEIVE_MESSAGE.equals(service)) {
            isReceive = true;
        } else if (Constants.SERVICE_VALUE_LOGIN.equals(service)) {
            isLogin = true;
        } else if (Constants.SERVICE_VALUE_CLOSE.equals(service)) {
            isClose = true;
        } else if ("admin".equals(service)) {
            isAdmin = true;
        } else {
            isValidRequest = false;
        }
      
        try {
           
            //logger.info("request servlet path=" + req.getServletPath());
       
        if (isValidRequest == false) {
           
           status = resp.SC_BAD_REQUEST;
          //throw exception  
           respMsg = "Invalid query string., Usage: http://hostport/service?clientId=ID&destination=destName";
             
        } else {
           
            Map map = req.getParameterMap();
           
            separator = req.getParameter(Constants.HTTP_GET_RESPONSE_SEPARATOR);
            if (separator ==null) {
                separator = Constants.HTTP_GET_RESPONSE_SEPARATOR_DEFAULT_VALUE;
            }
       
            if (isSend) {
               
                String text = req.getParameter(Constants.HTTP_GET_SEND_TEXT);
               
                this.JMSService.sendText(clientId, isTopic, destName, text, map);
               
                respMsg = SERVICE + service + separator + DESTINATION +
                        destName + separator + DOMAIN + getDomain (isTopic) + separator + MESSAGE + text;
               
            } else if (isReceive) {
               
                long timeout = this.getServiceTimeout(req);
               
                //receive message
                String text = this.JMSService.receiveText(clientId, destName, isTopic, timeout, map);
               
                respMsg = SERVICE + service + separator + DESTINATION + destName +
                        separator + DOMAIN + getDomain (isTopic) + separator + MESSAGE + text;
               
            } else if (isLogin) {
               
                String uuid = this.JMSService.authenticate(map);
               
                respMsg = SERVICE + service + separator + UUID + uuid;
            } else if (isClose) {
               
                String sid = this.JMSService.closeClient2 (map);
               
                respMsg = SERVICE + service + separator + UUID + sid;
               
            } else if (isAdmin) {
               
                String flag = req.getParameter(ADMIN_DEBUG);
               
                boolean debug = Boolean.valueOf(flag).booleanValue();
               
                MQServiceImpl.debug = debug;
           
                respMsg = SERVICE + service + separator + ADMIN_DEBUG + "=" + debug;
            }
           
            status = resp.SC_OK;
        }
       
        } catch (Exception e) {
           
            throw new ServletException (e);
                 
        }
       
        resp.setStatus(status);
       
        resp.setHeader ("Content-Type", "text/plain");

        OutputStream os = resp.getOutputStream();
       
        PrintWriter pw = new PrintWriter (os);
          
        pw.println(respMsg);
       
        pw.close();
    }
    **/
   
    protected static long getServiceTimeout (SimpleMessage msg) {
       
        long timeout = receiveTimeout;
       
        try {
           
            String str = msg.getMessageProperty (Constants.RECEIVE_TIMEOUT);
           
            if (str != null) {
               
                timeout = Long.parseLong(str);
           
                if (timeout <=0 || timeout > 60000) {
                    timeout = receiveTimeout;
                }
            }
           
        } catch (Exception e) {
            logger.log(Level.WARNING, e.getMessage(), e);
        }
       
        return timeout;
    }
   
    private String getDomain (boolean isTopic) {
        if (isTopic) {
            return TOPIC_DOMAIN;
           
        } else {
            return QUEUE_DOMAIN;
        }
    }
   
    protected static boolean isHTML (String msg) {
        boolean flag = false;
       
        if (msg == null || msg.length()==0) {
            return false;
        }
       
        String prefix = msg.substring(0, 5);
        if ("<html".equalsIgnoreCase(prefix) == true) {
            flag = true;
        }
       
        return flag;
    }
   
    protected static boolean isXML (String msg) {
        boolean flag = false;
       
        if (msg == null || msg.length()==0) {
            return false;
        }
       
        String prefix = msg.substring(0, 5);
        if ("<?xml".equalsIgnoreCase(prefix) == true) {
            flag = true;
        }
       
        return flag;
    }

}
TOP

Related Classes of com.sun.messaging.ums.core.UMSServlet

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.