/**
 * Copyright (C) 2014 Microsoft Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.microsoft.reef.webserver;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Parse HttpServletRequest
 */
public class RequestParser {
    private final HttpServletRequest request;
    private final String pathInfo;
    private final String method;
    private final String queryString;
    private final String requestUri;
    private final String serveletPath;
    private final Map<String, String> headers = new HashMap();
    private final byte[] inputStream;
    private final String targetSpecification;
    private final String targetEntity;
    private final Map<String, String> querieMap = new HashMap<>();

    /**
     * parse HttpServletRequest
     *
     * @param request
     * @throws IOException
     * @throws ServletException
     */
    public RequestParser(HttpServletRequest request) throws IOException, ServletException {
        this.request = request;

        pathInfo = request.getPathInfo();
        method = request.getMethod();
        queryString = request.getQueryString();
        requestUri = request.getRequestURI();
        serveletPath = request.getServletPath();

        Enumeration hn = request.getHeaderNames();
        while (hn.hasMoreElements()) {
            String s = (String) hn.nextElement();
            String header = request.getHeader(s);
            headers.put(s, header);
        }

        int len = request.getContentLength();
        if (len > 0) {
            inputStream = new byte[len];
            request.getInputStream().read(inputStream);
        } else {
            inputStream = null;
        }

        if (requestUri != null) {
            String[] parts = requestUri.split("/");

            if (parts != null && parts.length > 1) {
                targetSpecification = parts[1];
            } else {
                targetSpecification = null;
            }

            if (parts != null && parts.length > 2) {
                targetEntity = parts[2];
            } else {
                targetEntity = null;
            }
        } else {
            targetSpecification = null;
            targetEntity = null;
        }

        if (queryString != null) {
            final String[] questions = queryString.split("&");
            for (final String s : questions) {
                final String[] pair = s.split("=");
                if (pair != null && pair.length == 2) {
                    querieMap.put(pair[0], pair[1]);
                }
            }
        }
    }

    /**
     * get target to match specification like "Reef"
     *
     * @return specification
     */
    public String getTargetSpecification() {
        return targetSpecification;
    }

    /**
     * get query string like "id=12345"
     *
     * @return
     */
    public String getQueryString() {
        return queryString;
    }

    /**
     * get target target entity like "Evaluators"
     *
     * @return
     */
    public String getTargetEntity() {
        return targetEntity;
    }

    /**
     * get http request method like "Get"
     *
     * @return
     */
    public String getMethod() {
        return method;
    }

    /**
     * get input Stream
     *
     * @return
     */
    public byte[] getInputStream() {
        return inputStream;
    }

    /**
     * get request headers
     *
     * @return
     */
    public Map<String, String> getHeaders() {
        return headers;
    }

    public Map<String, String> getQueryMap() {
        return querieMap;
    }
}

@@ -751,32 +751,77 @@
 io.IOException;%0A
+import java.io.UnsupportedEncodingException;%0A
 import java.util
@@ -830,24 +830,24 @@
 numeration;%0A
-
 import java.
@@ -1137,16 +1137,53 @@
 estUri;%0A
+    private final String requestUrl;%0A
     priv
@@ -1747,16 +1747,31 @@
 hInfo = 
+getRequestData(
 request.
@@ -1783,16 +1783,17 @@
 thInfo()
+)
 ;%0A      
@@ -1803,16 +1803,31 @@
 ethod = 
+getRequestData(
 request.
@@ -1837,16 +1837,17 @@
 Method()
+)
 ;%0A      
@@ -1862,16 +1862,31 @@
 tring = 
+getRequestData(
 request.
@@ -1901,16 +1901,17 @@
 String()
+)
 ;%0A      
@@ -1925,16 +1925,31 @@
 stUri = 
+getRequestData(
 request.
@@ -1963,16 +1963,17 @@
 estURI()
+)
 ;%0A      
@@ -1989,16 +1989,31 @@
 tPath = 
+getRequestData(
 request.
@@ -2028,16 +2028,90 @@
 etPath()
+);%0A        requestUrl = getRequestData(request.getRequestURL().toString())
 ;%0A%0A     
@@ -3450,32 +3450,284 @@
        %7D%0A    %7D%0A%0A
+    private String getRequestData(String requestStr) throws UnsupportedEncodingException %7B%0A        if (requestStr != null) %7B%0A            return java.net.URLDecoder.decode(requestStr, %22UTF-8%22);%0A        %7D else %7B%0A            return null;%0A        %7D%0A    %7D%0A%0A
     /**%0A     * g
@@ -4676,24 +4676,24 @@
 ueryMap() %7B%0A
-
         retu
@@ -4711,11 +4711,81 @@
 p;%0A    %7D
+%0A%0A    public String getRequestUrl() %7B%0A        return requestUrl;%0A    %7D
 %0A%7D%0A

use URLDecoder to decode the request string