org.wso2.carbon.apimgt.swagger.migration.utils.ResourceUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.wso2.carbon.apimgt.swagger.migration.utils.ResourceUtil.java

Source

/*
 * Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
 * 
 * WSO2 Inc. licenses this file to you 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.wso2.carbon.apimgt.swagger.migration.utils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.registry.core.Registry;
import org.wso2.carbon.registry.core.RegistryConstants;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.exceptions.RegistryException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ResourceUtil {

    private static final Log log = LogFactory.getLog(ResourceUtil.class);

    /**
     * Get all the parameters related to each resource. The parameter array is
     * an array which is part of the operations object inside each resource.
     * 
     * @param resource
     *            api-doc which contains swagger 1.1 info
     * @return map of parameter array related to all the http methods for each
     *         resource. the key for
     *         the map is resourcepath_httpmethod
     */
    public static Map<String, JSONArray> getAllParametersForResources(JSONObject resource) {
        Map<String, JSONArray> parameters = new HashMap<String, JSONArray>();

        String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
        String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
        String resourcePathPrefix = resourcePath + "/" + apiVersion;

        String key = null;

        JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
        for (int i = 0; i < apis.size(); i++) {

            JSONObject apiInfo = (JSONObject) apis.get(i);
            String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
            JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);

            for (int j = 0; j < operations.size(); j++) {
                JSONObject operation = (JSONObject) operations.get(j);
                String httpMethod = (String) operation.get(Constants.API_DOC_11_METHOD);
                JSONArray parameterArray = (JSONArray) operation.get(Constants.API_DOC_11_PARAMETERS);

                // get the key by removing the "apiVersion" and "resourcePath"
                // from the "path" variable
                // and concat the http method
                String keyPrefix = path.substring(resourcePathPrefix.length());
                if (keyPrefix.isEmpty()) {
                    keyPrefix = "/*";
                }
                key = keyPrefix + "_" + httpMethod.toLowerCase();

                parameters.put(key, parameterArray);
            }
        }

        return parameters;

    }

    /**
     * Get all the operation object related to each resource. Method is inside the operation object
     * this object contains the nickname, description related to that resource method
     * @param resource
     *            api-doc which contains swagger 1.1 info
     * @return map of operations array related to all the http methods for each
     *         resource. the key for
     *         the map is resourcepath_httpmethod
     */
    private static Map<String, JSONObject> getAllOperationsForResources(JSONObject resource) {
        Map<String, JSONObject> parameters = new HashMap<String, JSONObject>();

        String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
        String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
        String resourcePathPrefix = resourcePath + "/" + apiVersion;

        String key = null;

        JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
        for (int i = 0; i < apis.size(); i++) {

            JSONObject apiInfo = (JSONObject) apis.get(i);
            String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
            JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);

            for (int j = 0; j < operations.size(); j++) {
                JSONObject operation = (JSONObject) operations.get(j);
                String httpMethod = (String) operation.get(Constants.API_DOC_11_METHOD);
                JSONArray parameterArray = (JSONArray) operation.get(Constants.API_DOC_11_PARAMETERS);

                // get the key by removing the "apiVersion" and "resourcePath"
                // from the "path" variable
                // and concat the http method
                String keyPrefix = path.substring(resourcePathPrefix.length());
                if (keyPrefix.isEmpty()) {
                    keyPrefix = "/*";
                }
                key = keyPrefix + "_" + httpMethod.toLowerCase();

                parameters.put(key, operation);
            }
        }

        return parameters;
    }

    /**
     * Get all the apis as a map. key for map is the full resource path for that api. key is created
     * using 'basepath + apis[i].path' values in the api-doc.json file (swagger 1.1 doc) 
     * 
     * @param resource
     *            api-doc which contains swagger 1.1 info
     * @return map of apis in the swagger 1.1 doc. key is the full resource path for that resource
     */
    public static Map<String, JSONObject> getAllAPIsByResourcePath(JSONObject resource) {
        Map<String, JSONObject> parameters = new HashMap<String, JSONObject>();

        String basePath = (String) resource.get(Constants.API_DOC_11_BASE_PATH);
        String key = null;

        JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
        for (int i = 0; i < apis.size(); i++) {

            JSONObject apiInfo = (JSONObject) apis.get(i);
            String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
            key = basePath + path;
            parameters.put(key, apiInfo);
        }

        return parameters;

    }

    private static JSONArray getDefaultParameters() {
        JSONParser parser = new JSONParser();
        JSONArray defaultParam = new JSONArray();
        try {
            defaultParam = (JSONArray) parser.parse(Constants.DEFAULT_PARAM_ARRAY);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return defaultParam;

    }

    /**
     * Modify the resource in registry location '1.2' to be compatible with the
     * AM 1.8. add the
     * parameters to operations element, add 'nickname' variable and the
     * 'basePath' variable
     * 
     * @param resource
     *            resource inside the 1.2 location
     * @param allParameters
     *            map containing all the parameters extracted from api-doc
     *            containing
     *            resources for swagger 1.1
     * @param allOperations 
     * @param basePath
     *            base path for the resource
     * @return modified resource for the api
     */
    public static String getUpdatedSwagger12Resource(JSONObject resource, Map<String, JSONArray> allParameters,
            Map<String, JSONObject> allOperations, String basePath) {

        JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_12_APIS);
        for (int i = 0; i < apis.size(); i++) {
            JSONObject apiInfo = (JSONObject) apis.get(i);
            String path = (String) apiInfo.get(Constants.API_DOC_12_PATH);
            JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_12_OPERATIONS);

            for (int j = 0; j < operations.size(); j++) {
                JSONObject operation = (JSONObject) operations.get(j);
                String method = (String) operation.get(Constants.API_DOC_12_METHOD);

                // nickname is method name + "_" + path without starting "/"
                // symbol
                String nickname = method.toLowerCase() + "_" + path.substring(1);
                // add nickname variable
                operation.put(Constants.API_DOC_12_NICKNAME, nickname);
                String key = path + "_" + method.toLowerCase();

                JSONArray parameters = new JSONArray();
                if (allParameters.containsKey(key)) {
                    parameters = allParameters.get(key);

                    //setting the 'type' to 'string' if this variable is missing
                    for (int m = 0; m < parameters.size(); m++) {
                        JSONObject para = (JSONObject) parameters.get(m);
                        if (!para.containsKey("type")) {
                            para.put("type", "string");
                        }
                    }

                } else {
                    parameters = getDefaultParameters();

                }
                //if there are parameters already in this 
                JSONArray existingParams = (JSONArray) operation.get(Constants.API_DOC_12_PARAMETERS);
                if (existingParams.isEmpty()) {
                    JSONParser parser = new JSONParser();
                    if (path.contains("{")) {
                        List<String> urlParams = ResourceUtil.getURLTempateParams(path);
                        for (String p : urlParams) {
                            try {
                                JSONObject paramObj = (JSONObject) parser
                                        .parse(Constants.DEFAULT_PARAM_FOR_URL_TEMPLATE);
                                paramObj.put("name", p);
                                parameters.add(paramObj);
                            } catch (ParseException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    }
                    // add parameters array
                    operation.put(Constants.API_DOC_12_PARAMETERS, parameters);
                } else {
                    for (int k = 0; k < existingParams.size(); k++) {
                        parameters.add(existingParams.get(k));
                    }
                    operation.put(Constants.API_DOC_12_PARAMETERS, parameters);
                }

                //updating the resource description and nickname using values in the swagger 1.1 doc
                if (allOperations.containsKey(key)) {

                    //update info related to object
                    JSONObject operationObj11 = allOperations.get(key);
                    //add summery
                    if (operationObj11.containsKey("summary")) {
                        operation.put("summary", (String) operationObj11.get("summery"));
                    }

                }
            }
        }

        // add basePath variable
        resource.put(Constants.API_DOC_12_BASE_PATH, basePath);

        return resource.toJSONString();
    }

    /**
     * location for the swagger 1.2 resources
     * @param apiName
     * @param apiVersion
     * @param apiProvider
     * @return
     */
    public static String getSwagger12ResourceLocation(String apiName, String apiVersion, String apiProvider) {
        String resourcePath = APIConstants.API_DOC_LOCATION + RegistryConstants.PATH_SEPARATOR + apiName + "-"
                + apiVersion + "-" + apiProvider + RegistryConstants.PATH_SEPARATOR
                + APIConstants.API_DOC_1_2_LOCATION;

        return resourcePath;
    }

    /**
    * update all the the swagger document in the registry related to an api
    * @param apiDocJson
    * @param docResourcePaths
    * @param re
    * @throws org.json.simple.parser.ParseException
    * @throws org.wso2.carbon.registry.core.exceptions.RegistryException
    */
    public static void updateAPISwaggerDocs(String apiDocJson, String[] docResourcePaths, Registry re)
            throws ParseException, RegistryException {

        JSONParser parser = new JSONParser();
        JSONObject apiDoc11 = (JSONObject) parser.parse(apiDocJson);

        Map<String, JSONArray> allParameters = ResourceUtil.getAllParametersForResources(apiDoc11);

        Map<String, JSONObject> allOperations = ResourceUtil.getAllOperationsForResources(apiDoc11);

        Map<String, JSONObject> apisByPath = ResourceUtil.getAllAPIsByResourcePath(apiDoc11);

        //this collection holds description given for each resource against the resource name.
        //descriptions added resources in an api in AM 1.7 are stored in api-doc 1.1. this desciption
        //is showed in am 1.7 api console in the store applicatoin. AM 1.8 uses descriptions in
        // api-doc in 1.2 resource folder. following map collects this value from api-doc 1.1 and
        // store it to add to api-doc 1.2
        Map<String, String> descriptionsForResource = new HashMap<String, String>();

        String basePath = (String) apiDoc11.get(Constants.API_DOC_11_BASE_PATH);
        String resourcePath = (String) apiDoc11.get(Constants.API_DOC_11_RESOURCE_PATH);
        String apiVersion = (String) apiDoc11.get(Constants.API_DOC_11_API_VERSION);

        resourcePath = resourcePath.endsWith("/") ? resourcePath : resourcePath + "/";
        String basePathForResource = basePath + resourcePath + apiVersion;

        String apidoc12path = "";

        //update each resource in the 1.2 folder except the api-doc resource
        for (String docResourcePath : docResourcePaths) {
            String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));

            if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
                //store api-doc in 1.2 folder for future use
                apidoc12path = docResourcePath;
                continue;
            }

            Resource resource = re.get(docResourcePath);
            JSONObject apiDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent()));

            String description = "";
            //generate the key to query the descriptionsForResource map
            JSONArray apisInResource = (JSONArray) apiDoc.get(Constants.API_DOC_12_APIS);
            JSONObject apiTemp = (JSONObject) apisInResource.get(0);
            String path = (String) apiTemp.get(Constants.API_DOC_12_PATH);

            String key = "";
            if (path.equals("/*")) {
                key = basePathForResource;
            } else {
                key = basePathForResource + path;
            }

            //get the description for that resource. query the api list generated using api-doc 1.1
            if (apisByPath.containsKey(key)) {
                JSONObject apiInfo = (JSONObject) apisByPath.get(key);
                description = (String) apiInfo.get("description");
                descriptionsForResource.put(resourceName, description);
            }

            String updatedJson = ResourceUtil.getUpdatedSwagger12Resource(apiDoc, allParameters, allOperations,
                    basePathForResource);
            log.info("\t update " + resourceName.substring(1));
            Resource res = re.get(docResourcePath);
            res.setContent(updatedJson);
            //update the registry
            re.put(docResourcePath, res);

        }

        //update the api-doc. add the descriptions to each api resource
        ResourceUtil.updateSwagger12APIdoc(apidoc12path, descriptionsForResource, re, parser);

    }

    /**
     * update the swagger 1.2 api-doc. This method updates the descriptions
     * @param apidoc12path
     * @param descriptionsForResource
     * @param re
     * @param parser
     * @throws org.wso2.carbon.registry.core.exceptions.RegistryException
     * @throws org.json.simple.parser.ParseException
     */
    private static void updateSwagger12APIdoc(String apidoc12path, Map<String, String> descriptionsForResource,
            Registry re, JSONParser parser) throws RegistryException, ParseException {
        Resource res = re.get(apidoc12path);
        JSONObject api12Doc = (JSONObject) parser.parse(new String((byte[]) res.getContent()));
        JSONArray apis = (JSONArray) api12Doc.get(Constants.API_DOC_12_APIS);
        for (int j = 0; j < apis.size(); j++) {
            JSONObject api = (JSONObject) apis.get(j);

            // get the resource name for each api in api-doc 1.2
            String resPathName = (String) api.get(Constants.API_DOC_12_PATH);
            if (descriptionsForResource.containsKey(resPathName)) {
                // if the descrption is available for that resource update it
                api.put("description", descriptionsForResource.get(resPathName));
            }
        }
        log.info("\t update api-doc");
        res.setContent(api12Doc.toJSONString());
        // update the registry
        re.put(apidoc12path, res);
    }

    /**
     * remove header and body parameters
     * @param docResourcePaths
     * @param registry
     * @throws org.wso2.carbon.registry.core.exceptions.RegistryException
     * @throws org.json.simple.parser.ParseException
     */
    public static void updateSwagger12ResourcesForAM18(String[] docResourcePaths, Registry registry)
            throws RegistryException, ParseException {
        JSONParser parser = new JSONParser();
        for (String docResourcePath : docResourcePaths) {

            String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));

            //modify this if api-doc resource needed to be changed
            if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
                continue;
            }

            Resource resource = registry.get(docResourcePath);
            JSONObject resourceDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent()));
            JSONArray apis = (JSONArray) resourceDoc.get(Constants.API_DOC_12_APIS);
            for (int j = 0; j < apis.size(); j++) {
                JSONObject api = (JSONObject) apis.get(j);
                JSONArray operations = (JSONArray) api.get("operations");

                for (int k = 0; k < operations.size(); k++) {
                    JSONObject operation = (JSONObject) operations.get(k);
                    JSONArray parameters = (JSONArray) operation.get("parameters");
                    String method = (String) operation.get("method");
                    JSONArray parametersNew = new JSONArray();
                    //remove header and body parameters
                    for (int l = 0; l < parameters.size(); l++) {
                        JSONObject parameter = (JSONObject) parameters.get(l);
                        /*
                        if(parameter.get("paramType").equals("header") ||
                              parameter.get("paramType").equals("body")){
                           continue;
                        } */
                        if (parameter.get("paramType").equals("header")) {
                            continue;
                        }
                        if (parameter.get("paramType").equals("body")) {

                            //only remove body of a GET and DELETE
                            if ("GET".equalsIgnoreCase(method) || "DELETE".equalsIgnoreCase(method)) {
                                continue;
                            }
                        }
                        parametersNew.add(parameter);
                    }
                    operation.put("parameters", parametersNew);
                }

            }

            resource.setContent(resourceDoc.toJSONString());
            //update the registry
            registry.put(docResourcePath, resource);
        }

    }

    /**
     * Update the API definition in Swagger 1.1
     * @param api11Path
     *          path of API 1.1 definition
     * @param api11DocJson
     *          api 1.1 definition
     * @param docResourcePaths
     *          path for API resources in 1.2 folder
     * @param registry
     *          registry
     * @throws org.json.simple.parser.ParseException
     * @throws org.wso2.carbon.registry.core.exceptions.RegistryException
     */
    public static void updateSwagger11APIDoc(String api11Path, String api11DocJson, String[] docResourcePaths,
            Registry registry) throws ParseException, RegistryException {
        JSONParser parser = new JSONParser();
        JSONObject apiDoc11 = (JSONObject) parser.parse(api11DocJson);

        //update each resource in the 1.2 folder except the api-doc resource
        for (String docResourcePath : docResourcePaths) {
            String resourceName = docResourcePath.substring(docResourcePath.lastIndexOf("/"));

            if (resourceName.equals(APIConstants.API_DOC_1_2_RESOURCE_NAME)) {
                //skip api-doc in 1.2 folder
                continue;
            }

            log.info("swagger 1.1 doc path : " + api11Path + "\n\n");

            log.info("swagger 1.1 doc json : " + apiDoc11.toJSONString() + "\n\n");
            log.info("Resource path : " + docResourcePath);
            Resource resource = registry.get(docResourcePath);
            JSONObject apiDoc = (JSONObject) parser.parse(new String((byte[]) resource.getContent()));

            log.info("API doc json : " + apiDoc.toJSONString() + "\n\n");

            Map<String, JSONArray> allParameters12 = ResourceUtil.getAllParametersForResources12(apiDoc);

            String updatedJson = ResourceUtil.getUpdatedSwagger11Resource(apiDoc11, allParameters12);

            log.info("updated json 1.2 : " + updatedJson + "\n\n");

            Resource res = registry.get(api11Path);
            res.setContent(updatedJson);
            //update the registry
            registry.put(api11Path, res);

        }

    }

    /**
     * @param resource        api-doc related to 1.1 definition
     * @param allParameters12 map containing all the parameters extracted
     *                        from each resource of swagger 1.2
     * @return JSON string of the updated Swagger 1.1 definition
     */
    public static String getUpdatedSwagger11Resource(JSONObject resource, Map<String, JSONArray> allParameters12) {

        log.info("===================== getUpdatedSwagger11Resource =========================");

        String resourcePath = (String) resource.get(Constants.API_DOC_11_RESOURCE_PATH);
        String apiVersion = (String) resource.get(Constants.API_DOC_11_API_VERSION);
        String resourcePathPrefix = resourcePath + "/" + apiVersion;

        log.info("resourcePath for 1.1 : " + resourcePath);
        log.info("apiVersion : " + apiVersion);
        log.info("resourcePathPrefix : " + resourcePathPrefix);

        JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_11_APIS);
        for (Object api : apis) {
            JSONObject apiInfo = (JSONObject) api;
            log.info("\n\napiInfo : " + apiInfo.toJSONString());

            String path = (String) apiInfo.get(Constants.API_DOC_11_PATH);
            path = path.substring(resourcePathPrefix.length());
            JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_11_OPERATIONS);

            log.info("\n\noperations : " + operations.toJSONString());

            for (Object operation1 : operations) {
                JSONObject operation = (JSONObject) operation1;
                log.info("\n\noperation : " + operation);
                String method = (String) operation.get(Constants.API_DOC_11_METHOD);

                String key = path + "_" + method.toLowerCase();

                log.info("\nkey : " + key);

                //if there are parameters already in this
                JSONArray existingParams = (JSONArray) operation.get(Constants.API_DOC_11_PARAMETERS);

                log.info("\nexistingParams : " + existingParams);
                //maintain the list of original parameters to avoid duplicates
                JSONArray originalParams = existingParams;

                JSONArray parameters;
                if (allParameters12.containsKey(key)) {
                    log.info("\nallParameters12.containsKey(key) : " + key);
                    parameters = allParameters12.get(key);
                    log.info("\nparameters : " + parameters.toJSONString());

                    //setting the 'type' to 'string' if this variable is missing
                    for (int m = 0; m < parameters.size(); m++) {
                        JSONObject para = (JSONObject) parameters.get(m);
                        log.info("\n\npara : " + para.toJSONString());
                        if (noSuchParameter(originalParams, (String) para.get(Constants.API_DOC_11_PARAM_NAME),
                                (String) para.get(Constants.API_DOC_11_PARAM_TYPE))) {
                            log.info("\nnoSuchParameter");
                            String dataType = "";
                            if (para.containsKey(Constants.API_DOC_12_DATA_TYPE)) {
                                log.info("\npara.containsKey(Constants.API_DOC_12_DATA_TYPE)");
                                dataType = (String) para.get(Constants.API_DOC_12_DATA_TYPE);
                            }

                            log.info("\ndataType : " + dataType);
                            para.put(Constants.API_DOC_11_DATA_TYPE, dataType);
                            para.remove(Constants.API_DOC_12_DATA_TYPE);
                            existingParams.add(existingParams.size(), para);
                        }
                    }
                }

                log.info("\nexistingParams after loop : " + existingParams);
                operation.put(Constants.API_DOC_12_PARAMETERS, existingParams);
            }
        }

        return resource.toJSONString();
    }

    /**
     * Get all the parameters related to each resource. The parameter array is
     * an array which is part of the operations object inside each resource.
     *
     * @param resource resource doc which contains swagger 1.2 info for one resource of the API
     * @return map of parameter array related to all the http methods for each
     *         resource. the key for
     *         the map is resourcepath_httpmethod
     */
    public static Map<String, JSONArray> getAllParametersForResources12(JSONObject resource) {
        Map<String, JSONArray> parameters = new HashMap<String, JSONArray>();

        log.info("\ngetAllParametersForResources12");
        String key;

        JSONArray apis = (JSONArray) resource.get(Constants.API_DOC_12_APIS);
        log.info("\napis : " + apis.toJSONString());
        for (Object api : apis) {

            JSONObject apiInfo = (JSONObject) api;
            String path = (String) apiInfo.get(Constants.API_DOC_12_PATH);
            JSONArray operations = (JSONArray) apiInfo.get(Constants.API_DOC_12_OPERATIONS);

            for (Object operation1 : operations) {
                JSONObject operation = (JSONObject) operation1;
                String httpMethod = (String) operation.get(Constants.API_DOC_12_METHOD);
                JSONArray parameterArray = (JSONArray) operation.get(Constants.API_DOC_12_PARAMETERS);

                // get the key by removing the "apiVersion" and "resourcePath"
                // from the "path" variable
                // and concat the http method
                String keyPrefix = path;
                if (keyPrefix.isEmpty()) {
                    keyPrefix = "/*";
                }
                key = keyPrefix + "_" + httpMethod.toLowerCase();

                log.info("\nkey : " + key);
                log.info("\nparameterArray : " + parameterArray.toJSONString());

                parameters.put(key, parameterArray);
            }
        }

        return parameters;

    }

    /**
     * Check if a given parameter already exists in the 1.1 definition
     *
     * @param originalParams parameters that was originally in 1.1 definition
     * @param paramName      name of the parameter to look for
     * @param paramType      type of the parameter to look for (path, query etc.)
     * @return whether the given parameter exists in 1.1 definition already
     */
    public static boolean noSuchParameter(JSONArray originalParams, String paramName, String paramType) {
        boolean notFound = true;
        for (Object originalParam : originalParams) {
            JSONObject para = (JSONObject) originalParam;
            String name = (String) para.get(Constants.API_DOC_11_PARAM_NAME);
            String type = (String) para.get(Constants.API_DOC_11_PARAM_TYPE);
            if (name.equals(paramName)) {
                if (type.equals(paramType)) {
                    notFound = false;
                    continue;
                }
            }
        }
        return notFound;
    }

    /**
     * extract the parameters from the url tempate.
     * @param url
     * @return
     */
    public static List<String> getURLTempateParams(String url) {
        boolean endVal = false;

        List<String> params = new ArrayList<String>();
        if (url.contains("{")) {

            int start = 0;
            int end = 0;
            for (int i = 0; i < url.length(); i++) {
                if (url.charAt(i) == '{')
                    start = i;
                else if (url.charAt(i) == '}') {
                    end = i;
                    endVal = true;
                }

                if (endVal) {
                    params.add(url.substring(start + 1, end));
                    endVal = false;
                }
            }

        }
        return params;
    }

    /**
     * print stack trace
     * @param throwable
     * @return
     */
    public static String getStackTrace(final Throwable throwable) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter printWriter = new PrintWriter(stringWriter, true);
        throwable.printStackTrace(printWriter);
        return stringWriter.getBuffer().toString();
    }
}