org.rest.client.request.RequestPayloadParser.java Source code

Java tutorial

Introduction

Here is the source code for org.rest.client.request.RequestPayloadParser.java

Source

/*******************************************************************************
 * Copyright 2012 Pawe Pszty
 * 
 * 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 org.rest.client.request;

import java.util.ArrayList;

import com.google.gwt.http.client.URL;
import com.google.gwt.regexp.shared.RegExp;

public class RequestPayloadParser {

    /**
     * Parse list of Payload form values {@link FormPayloadData} to Payload string
     * @param input
     * @param encode if true params will be encoded
     * @return
     */
    public static String parseData(ArrayList<FormPayloadData> input, boolean encode, boolean useBoundary,
            String currentBoundary) {
        if (useBoundary) {
            return parseDataBoundary(input, encode, currentBoundary);
        }
        return parseDataMultipart(input, encode);
    }

    private static String parseDataMultipart(ArrayList<FormPayloadData> input, boolean encode) {
        if (input == null || input.size() == 0)
            return "";
        String result = "";

        for (FormPayloadData item : input) {
            if (!result.isEmpty()) {
                result += "&";
            }
            String key = item.getKey();
            String value = item.getValue();
            if (!(key.trim().equals("") && value.trim().equals(""))) {
                if (encode)
                    result += URL.encodeQueryString(key.trim());
                else
                    result += key.trim();
                result += "=";
                if (encode)
                    result += URL.encodeQueryString(value.trim());
                else
                    result += value.trim();
            }
        }
        return result;
    }

    public static String recognizeBoundary(String input) {
        if (input == null || input.isEmpty()) {
            return null;
        }
        String[] body = input.split("\n");
        int lines = body.length;
        if (lines == 0) {
            return null;
        }

        for (int i = 0; i < lines; i++) {
            String line = body[i];
            if (line.startsWith("--")) {
                if (line.endsWith("--")) { //it should not happen
                    return null;
                }
                return line.substring(2);
            }
        }

        return null;
    }

    private static String parseDataBoundary(ArrayList<FormPayloadData> input, final boolean encode,
            String currentBoundary) {
        if (input == null || input.size() == 0)
            return "";

        StringBuilder sb = new StringBuilder();

        final String boundary = currentBoundary == null ? "--ARCFormBoundary" + generateBoundary()
                : "--" + currentBoundary;

        for (FormPayloadData item : input) {
            String key = item.getKey();
            String value = item.getValue();
            if (key.trim().equals("") && value.trim().equals("")) {
                continue;
            }

            if (encode) {
                key = URL.encodeQueryString(key.trim());
                value = URL.encodeQueryString(value.trim());
            } else {
                key = key.trim();
                value = value.trim();
            }

            sb.append(boundary).append("\n");
            sb.append("Content-Disposition: form-data; name=\"").append(key).append("\"").append("\n");
            sb.append("\n");
            sb.append(value).append("\n");

        }
        sb.append(boundary).append("--").append("\n");
        return sb.toString();
    }

    private static final native String generateBoundary() /*-{ return Math.random().toString(36).substring(3); }-*/;

    /**
     * Old bodyToListValues method
     * @param input
     * @return
     */
    public static ArrayList<FormPayloadData> payloadToList(String input) {
        ArrayList<FormPayloadData> result = new ArrayList<FormPayloadData>();
        if (input == null) {
            return result;
        }
        String[] dataList = input.split("[\r\n]");
        int len = dataList.length;
        for (int i = 0; i < len; i++) {
            result.addAll(stringToFormArrayList(dataList[i]));
        }
        return result;
    }

    /**
     * Parse application/x-www-form-urlencoded form entity body to {@link FormPayloadData} object
     * 
     * Old parseBodyData method
     * 
     * @param input
     * @return
     */
    public static ArrayList<FormPayloadData> stringToFormArrayList(String input) {
        return stringToFormArrayList(input, false, false);
    }

    /**
     * Parse application/x-www-form-urlencoded form entity body to {@link FormPayloadData} object
     * 
     * Old parseBodyData method
     * 
     * @param input
     * @return
     */
    public static ArrayList<FormPayloadData> stringToFormArrayList(String input, boolean decode,
            boolean useBoundary) {
        if (useBoundary) {
            return stringToFormArrayListBoundary(input, decode);
        }
        return stringToFormArrayListMultipart(input, decode);
    }

    public static ArrayList<FormPayloadData> stringToFormArrayListBoundary(String input, boolean decode) {
        ArrayList<FormPayloadData> result = new ArrayList<FormPayloadData>();
        if (input == null || input.isEmpty()) {
            return result;
        }
        String[] body = input.split("\n");
        int lines = body.length;
        if (lines == 0) {
            return result;
        }

        FormPayloadData current = null;
        String currentValue = "";
        for (int i = 0; i < lines; i++) {
            String line = body[i];
            if (line.startsWith("--")) {

                if (current != null) {
                    current.setValue(currentValue);
                    result.add(current);
                    current = new FormPayloadData();
                    currentValue = "";
                }

                if (line.endsWith("--")) { //end of body
                    break;
                }
                //begin part of body
                //just move to the next line
            } else if (line.toLowerCase().contains("content-disposition")) {
                String fieldName = extractNameFromBoundaryLine(line);

                if (decode) {
                    fieldName = URL.decodeQueryString(fieldName.trim());
                }

                if (current == null) {
                    current = new FormPayloadData();
                }
                current.setKey(fieldName);
                i++;
                line = body[i];
                //next line should be empty, but check for misspelling 
                if (!line.isEmpty()) {
                    currentValue = line;
                }
            } else {

                if (!currentValue.isEmpty()) {
                    currentValue += "\n";
                }
                currentValue += line;
            }
        }
        return result;
    }

    private static final native String extractNameFromBoundaryLine(String line) /*-{
                                                                                var r = /\sname="(.*?)"/gim
                                                                                var result = "[unknown]";
                                                                                try{
                                                                                var m = r.exec(line);
                                                                                if(m && m.length > 1){
                                                                                result = m[1]; 
                                                                                }
                                                                                } catch(e){}
                                                                                    
                                                                                return result;
                                                                                }-*/;

    public static ArrayList<FormPayloadData> stringToFormArrayListMultipart(String input, boolean decode) {
        ArrayList<FormPayloadData> result = new ArrayList<FormPayloadData>();
        if (input == null || input.isEmpty()) {
            return result;
        }
        /*
          * Chrome inspector has FormData output like:
          * key:value
          * key:value
          * and so on.
          * When copying from inspector parse data to create proper form data.
          * 
          * But first check if it is not regular form data input.
          * 
          * @TODO: check other inputs that contain ":" in it.
          */
        RegExp htmlInputCheck = RegExp.compile("^([^\\=]{1,})=(.*)$", "m");
        if (!htmlInputCheck.test(input)) {
            RegExp r = RegExp.compile("^([^\\:]{1,}):(.*)$", "gm");
            input = r.replace(input, "$1=$2&");
            if (input.endsWith("&")) {
                input = input.substring(0, input.length() - 1);
            }
        }
        String[] list = input.split("&");
        for (String param : list) {
            String[] _tmp = param.split("=", 2);
            if (_tmp.length != 2) {
                continue;
            }

            try {
                String name = decode ? URL.decodeQueryString(_tmp[0].trim()) : _tmp[0].trim();
                String value = decode ? URL.decodeQueryString(_tmp[1].trim()) : _tmp[1].trim();
                FormPayloadData fpd = new FormPayloadData();
                fpd.setKey(name);
                fpd.setValue(value);
                result.add(fpd);
            } catch (Exception e) {
            }
        }
        return result;
    }

    /**
     * Parse raw body data to decoded entity body string for application/x-www-form-urlencoded encoding.
     * Old parseUrlencodedEntiti method
     * @param data
     * @return
     */
    public static String parseUrlEncodedEntity(String data) {
        if (data == null || data.equals(""))
            return "";

        ArrayList<FormPayloadData> list = new ArrayList<FormPayloadData>();
        String[] spl = data.split("&");
        int len = spl.length;
        for (int i = 0; i < len; i++) {
            list.addAll(stringToFormArrayList(spl[i]));
        }
        String result = "";
        for (FormPayloadData item : list) {
            String key = item.getKey();
            String value = item.getValue();
            if (!result.isEmpty()) {
                result += "&";
            }
            if (!(key.trim().equals("") && value.trim().equals(""))) {
                result += URL.decodeQueryString(key.trim());
                result += "=";
                result += URL.decodeQueryString(value.trim());
            }
        }
        return result;
    }
}