org.openapitools.codegen.languages.PostmanCollectionCodegen Maven / Gradle / Ivy
package org.openapitools.codegen.languages;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.examples.Example;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.servers.ServerVariable;
import lombok.Getter;
import lombok.Setter;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* OpenAPI generator for Postman Collection format v2.1
*/
public class PostmanCollectionCodegen extends DefaultCodegen implements CodegenConfig {
private final Logger LOGGER = LoggerFactory.getLogger(PostmanCollectionCodegen.class);
protected String apiVersion = "1.0.0";
// Select whether to create folders according to the spec’s paths or tags. Values: Paths | Tags
public static final String FOLDER_STRATEGY = "folderStrategy";
public static final String FOLDER_STRATEGY_DEFAULT_VALUE = "Tags";
// Select whether to create Postman variables for path templates
public static final String PATH_PARAMS_AS_VARIABLES = "pathParamsAsVariables";
public static final Boolean PATH_PARAMS_AS_VARIABLES_DEFAULT_VALUE = false;
public static final String POSTMAN_FILE_DEFAULT_VALUE = "postman.json";
// create Postman variables from placeholders ie {{VAR_1}}
public static final String POSTMAN_VARIABLES = "postmanVariables";
protected Boolean postmanVariables = true;
// replace placeholder `UNIQUE_REFERENCE` with Postman {{$guid}}
public static final String POSTMAN_GUID = "postmanGuid";
protected Boolean postmanGuid = true;
// default guid placeholder name
public static final String POSTMAN_GUID_PLACEHOLDER_NAME = "postmanGuidPlaceholderName";
protected static final String POSTMAN_GUID_PLACEHOLDER_NAME_DEFAULT_VALUE = "UNIQUE_REFERENCE";
protected static String postmanGuidPlaceholderName = POSTMAN_GUID_PLACEHOLDER_NAME_DEFAULT_VALUE;
// replace placeholder `ISO_TIMESTAMP` with Postman {{isoTimestamp}}
protected Boolean postmanIsoTimestamp = true;
public static final String POSTMAN_ISO_TIMESTAMP = "postmanIsoTimestamp";
public static final String POSTMAN_ISO_TIMESTAMP_PLACEHOLDER_NAME = "postmanIsoTimestampPlaceholderName";
public static final String POSTMAN_ISO_TIMESTAMP_PLACEHOLDER_NAME_DEFAULT_VALUE = "ISO_TIMESTAMP";
protected static String postmanIsoTimestampPlaceholderName = POSTMAN_ISO_TIMESTAMP_PLACEHOLDER_NAME_DEFAULT_VALUE;
public static final String REQUEST_PARAMETER_GENERATION = "requestParameterGeneration";
public static final String REQUEST_PARAMETER_GENERATION_DEFAULT_VALUE = "Example";
public String folderStrategy = FOLDER_STRATEGY_DEFAULT_VALUE; // values: Paths | Tags
protected Boolean pathParamsAsVariables = PATH_PARAMS_AS_VARIABLES_DEFAULT_VALUE; // values: true | false
// Output file
public String postmanFile = POSTMAN_FILE_DEFAULT_VALUE;
// Select whether to generate requests/responses from Example or Schema
protected String requestParameterGeneration = REQUEST_PARAMETER_GENERATION_DEFAULT_VALUE; // values: Example, Schema
public Set variables = new HashSet<>();
public static final String JSON_ESCAPE_DOUBLE_QUOTE = "\\\"";
public static final String JSON_ESCAPE_NEW_LINE = "\\n";
// operations grouped by tag
public Map> codegenOperationsByTag = new HashMap<>();
// list of operations
public List codegenOperationsList = new ArrayList<>();
/**
* Configures the type of generator.
*
* @return the CodegenType for this generator
* @see org.openapitools.codegen.CodegenType
*/
@Override
public CodegenType getTag() {
return CodegenType.SCHEMA;
}
@Override
public GeneratorLanguage generatorLanguage() {
return null;
}
/**
* Configures a friendly name for the generator. This will be used by the generator
* to select the library with the -g flag.
*
* @return the friendly name for the generator
*/
@Override
public String getName() {
return "postman-collection";
}
public PostmanCollectionCodegen() {
super();
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.BETA)
.build();
embeddedTemplateDir = templateDir = "postman-collection";
supportingFiles.add(
new SupportingFile("postman.mustache", "", postmanFile)
);
cliOptions.clear();
cliOptions.add(CliOption.newString(FOLDER_STRATEGY, "whether to create folders according to the spec’s paths or tags"));
cliOptions.add(CliOption.newBoolean(PATH_PARAMS_AS_VARIABLES, "whether to create Postman variables for path parameters"));
cliOptions.add(CliOption.newString(POSTMAN_VARIABLES, "whether to convert placeholders (i.e. {{VAR_1}}) into Postman variables"));
cliOptions.add(CliOption.newString(POSTMAN_GUID, "whether to convert placeholders (i.e. {{UNIQUE_REFERENCE}}) into Postman formula {{$guid}}"));
cliOptions.add(CliOption.newString(POSTMAN_GUID_PLACEHOLDER_NAME, "name of the placeholder (i.e. {{UNIQUE_REFERENCE}}) to replace with Postman formula {{$guid}}"));
cliOptions.add(CliOption.newString(POSTMAN_ISO_TIMESTAMP, "whether to convert placeholders (i.e. {{ISO_TIMESTAMP}}) into Postman formula {{$isoTimestamp}}"));
cliOptions.add(CliOption.newString(POSTMAN_ISO_TIMESTAMP_PLACEHOLDER_NAME, "name of the placeholder (i.e. {{ISO_TIMESTAMP}}) to replace with Postman formula {{$isoTimestamp}}"));
cliOptions.add(CliOption.newString(REQUEST_PARAMETER_GENERATION, "whether to generate the request parameters based on the schema or the examples"));
}
@Override
public void postProcessParameter(CodegenParameter parameter) {
// create Postman variable from every path parameter
if(pathParamsAsVariables && parameter.isPathParam) {
variables.add(new PostmanVariable()
.addName(parameter.paramName)
.addType(mapToPostmanType(parameter.dataType))
.addeDefaultValue(parameter.defaultValue));
}
}
@Override
public void preprocessOpenAPI(OpenAPI openAPI) {
super.preprocessOpenAPI(openAPI);
this.additionalProperties().put("formattedDescription", formatDescription(openAPI.getInfo().getDescription()));
}
@Override
public List fromServerVariables(Map variables) {
if(variables != null){
variables.entrySet().stream().forEach(serverVariableEntry -> this.variables.add(new PostmanVariable()
.addName(serverVariableEntry.getKey())
.addType("string")
.addeDefaultValue(serverVariableEntry.getValue().getDefault())));
}
return super.fromServerVariables(variables);
}
@Override
public void processOpts() {
super.processOpts();
if(additionalProperties().containsKey(FOLDER_STRATEGY)) {
folderStrategy = additionalProperties().get(FOLDER_STRATEGY).toString();
}
if (additionalProperties.containsKey(PATH_PARAMS_AS_VARIABLES)) {
pathParamsAsVariables = Boolean.parseBoolean(additionalProperties.get(PATH_PARAMS_AS_VARIABLES).toString());
}
if(additionalProperties().containsKey(REQUEST_PARAMETER_GENERATION)) {
requestParameterGeneration = additionalProperties().get(REQUEST_PARAMETER_GENERATION).toString();
}
if(additionalProperties().containsKey(POSTMAN_VARIABLES)) {
postmanVariables = Boolean.parseBoolean(additionalProperties.get(POSTMAN_VARIABLES).toString());
}
if(additionalProperties().containsKey(POSTMAN_GUID)) {
postmanGuid = Boolean.parseBoolean(additionalProperties.get(POSTMAN_GUID).toString());
}
if(additionalProperties().containsKey(POSTMAN_GUID_PLACEHOLDER_NAME)) {
postmanGuidPlaceholderName = additionalProperties.get(POSTMAN_GUID_PLACEHOLDER_NAME).toString();
}
if(additionalProperties().containsKey(POSTMAN_ISO_TIMESTAMP)) {
postmanIsoTimestamp = Boolean.parseBoolean(additionalProperties.get(POSTMAN_ISO_TIMESTAMP).toString());
}
if(additionalProperties().containsKey(POSTMAN_ISO_TIMESTAMP_PLACEHOLDER_NAME)) {
postmanIsoTimestampPlaceholderName = additionalProperties.get(POSTMAN_ISO_TIMESTAMP_PLACEHOLDER_NAME).toString();
}
super.vendorExtensions().put("variables", variables);
if(folderStrategy.equalsIgnoreCase("tags")) {
this.additionalProperties().put("codegenOperationsByTag", codegenOperationsByTag);
} else {
this.additionalProperties().put("codegenOperationsList", codegenOperationsList);
}
}
/**
* Process and modify operations before generating code
*/
@Override
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List allModels) {
OperationsMap results = super.postProcessOperationsWithModels(objs, allModels);
OperationMap ops = results.getOperations();
List opList = ops.getOperation();
for(CodegenOperation codegenOperation : opList) {
// use Postman notation for path parameter
codegenOperation.path = replacesBracesInPath(codegenOperation.path);
if(pathParamsAsVariables) {
// set value of path parameter with corresponding env variable
for(CodegenParameter codegenParameter : codegenOperation.pathParams) {
codegenParameter.defaultValue = "{{" + codegenParameter.paramName + "}}";
}
}
codegenOperation.summary = getSummary(codegenOperation);
// request headers
if(codegenOperation.produces != null && codegenOperation.produces.get(0) != null) {
// produces mediaType as `Accept` header (use first mediaType only)
String mediaType = codegenOperation.produces.get(0).get("mediaType");
CodegenParameter acceptHeader = new CodegenParameter();
acceptHeader.baseName = "Accept";
acceptHeader.paramName = "Accept";
CodegenProperty schema = new CodegenProperty();
schema.defaultValue = mediaType;
acceptHeader.setSchema(schema);
codegenOperation.headerParams.add(0, acceptHeader);
}
if(codegenOperation.consumes != null && codegenOperation.consumes.get(0) != null) {
// consumes mediaType as `Content-Type` header (use first mediaType only)
String mediaType = codegenOperation.consumes.get(0).get("mediaType");
CodegenParameter contentTypeHeader = new CodegenParameter();
contentTypeHeader.baseName = "Content-Type";
contentTypeHeader.paramName = "Content-Type";
CodegenProperty schema = new CodegenProperty();
schema.defaultValue = mediaType;
contentTypeHeader.setSchema(schema);
codegenOperation.headerParams.add(0, contentTypeHeader);
}
// build pathSegments
String[] pathSegments = codegenOperation.path.substring(1).split("/");
codegenOperation.vendorExtensions.put("pathSegments", pathSegments);
codegenOperation.responses.stream().forEach(r -> r.vendorExtensions.put("pathSegments", pathSegments));
List postmanRequests = getPostmanRequests(codegenOperation);
if(postmanRequests != null) {
if(postmanVariables) {
postmanRequests = createPostmanVariables(postmanRequests);
}
if(postmanGuid) {
postmanRequests = setPostmanGuid(postmanRequests);
}
if(postmanIsoTimestamp) {
postmanRequests = setPostmanIsoTimestamp(postmanRequests);
}
codegenOperation.vendorExtensions.put("postmanRequests", postmanRequests);
}
// set all available responses
for(CodegenResponse codegenResponse : codegenOperation.responses) {
codegenResponse.vendorExtensions.put("status", getStatus(codegenResponse));
// TODO: set response for each request
// if(postmanRequests != null) {
// // re-use request body for each response
// codegenResponse.vendorExtensions.put("requestBody", postmanRequests);
// }
// String responseBody = getResponseBody(codegenResponse);
// if(responseBody != null) {
// codegenResponse.vendorExtensions.put("responseBody", responseBody);
// codegenResponse.vendorExtensions.put("hasResponseBody", true);
// } else {
// codegenResponse.vendorExtensions.put("hasResponseBody", false);
// }
}
if(folderStrategy.equalsIgnoreCase("tags")) {
addToMap(codegenOperation);
} else {
addToList(codegenOperation);
}
}
return results;
}
/**
* Add the CodegenOperation to the map that is passed to the Mustache templates
* The map groups the CodegenOperations by tag as defined in the OpenAPI spec
* @param codegenOperation Codegen operation instance
*/
public void addToMap(CodegenOperation codegenOperation){
String key = null;
if(codegenOperation.tags == null || codegenOperation.tags.isEmpty()) {
key = "default";
} else {
key = codegenOperation.tags.get(0).getName();
}
List list = codegenOperationsByTag.get(key);
if(list == null) {
list = new ArrayList<>();
}
list.add(codegenOperation);
codegenOperationsByTag.put(key, list);
// sort requests by path
Collections.sort(list, Comparator.comparing(obj -> obj.path));
}
public void addToList(CodegenOperation codegenOperation) {
codegenOperationsList.add(codegenOperation);
// sort requests by path
Collections.sort(codegenOperationsList, Comparator.comparing(obj -> obj.path));
}
String getResponseBody(CodegenResponse codegenResponse) {
String responseBody = "";
if(codegenResponse.getContent() != null && codegenResponse.getContent().get("application/json") != null &&
codegenResponse.getContent().get("application/json").getExamples() != null) {
// find in components/examples
String exampleRef = codegenResponse.getContent().get("application/json").getExamples()
.values().iterator().next().get$ref();
if(exampleRef != null) {
Example example = this.openAPI.getComponents().getExamples().get(extractExampleByName(exampleRef));
responseBody = getJsonFromExample(example);
}
} else if(codegenResponse.getContent() != null) {
// find in context examples
Map maxExamples = codegenResponse.getContent().get("application/json").getExamples();
if(maxExamples != null && maxExamples.values().iterator().hasNext()) {
responseBody = getJsonFromExample(maxExamples.values().iterator().next());
}
}
return responseBody;
}
// from OpenAPI operation to n Postman requests
List getPostmanRequests(CodegenOperation codegenOperation) {
List items = new ArrayList<>();
if(codegenOperation.getHasBodyParam()) {
// operation with bodyParam
if (requestParameterGeneration.equalsIgnoreCase("Schema")) {
// get from schema
items.add(new PostmanRequestItem(codegenOperation.summary, getJsonFromSchema(codegenOperation.bodyParam)));
} else {
// get from examples
if (codegenOperation.bodyParam.getContent().get("application/json") != null &&
codegenOperation.bodyParam.getContent().get("application/json").getExamples() != null) {
for (Map.Entry entry : codegenOperation.bodyParam.getContent().get("application/json").getExamples().entrySet()) {
if(entry.getValue().get$ref() != null) {
// find in components/examples
String exampleRef = entry.getValue().get$ref();
Example example = this.openAPI.getComponents().getExamples().get(extractExampleByName(exampleRef));
String exampleAsString = getJsonFromExample(example);
items.add(new PostmanRequestItem(example.getSummary(), exampleAsString));
} else if (entry.getValue().getValue() != null && entry.getValue().getValue() instanceof ObjectNode) {
// find inline
String exampleAsString = convertToJson((ObjectNode) entry.getValue().getValue());
items.add(new PostmanRequestItem(entry.getKey(), exampleAsString));
}
}
} else if (codegenOperation.bodyParam.example != null) {
// find in bodyParam example
items.add(new PostmanRequestItem(codegenOperation.summary, formatJson(codegenOperation.bodyParam.example)));
} else if (codegenOperation.bodyParam.getSchema() != null) {
// find in schema example
String exampleAsString = formatJson(codegenOperation.bodyParam.getSchema().getExample());
items.add(new PostmanRequestItem(codegenOperation.summary, exampleAsString));
} else {
// example not found
// get from schema
items.add(new PostmanRequestItem(codegenOperation.summary, getJsonFromSchema(codegenOperation.bodyParam)));
}
}
} else {
// operation without bodyParam
items.add(new PostmanRequestItem(codegenOperation.summary, ""));
}
return items;
}
// from placeholders (ie {{VAR_1}}) create Postman variables
public List createPostmanVariables(List postmanRequests) {
for(PostmanRequestItem requestItem : postmanRequests) {
for(String var: extractPlaceholders(requestItem.getBody())) {
variables.add(new PostmanVariable()
.addName(var)
.addType("string")
.addeDefaultValue(""));
}
}
return postmanRequests;
}
// replace postmanGuid placeholder (ie {{UNIQUE_REFERENCE}}) with Postman formula {{$guid}}
List setPostmanGuid(List postmanRequests) {
for(PostmanRequestItem requestItem : postmanRequests) {
requestItem.setBody(requestItem.getBody().replace("{{" + postmanGuidPlaceholderName + "}}", "{{$guid}}"));
}
return postmanRequests;
}
// replace postman placeholder (ie {{ISO_TIMESTAMP}}) with Postman formula {{$isoTimestamp}}
List setPostmanIsoTimestamp(List postmanRequests) {
for(PostmanRequestItem requestItem : postmanRequests) {
requestItem.setBody(requestItem.getBody().replace("{{" + postmanIsoTimestampPlaceholderName + "}}", "{{$isoTimestamp}}"));
}
return postmanRequests;
}
/**
* Returns human-friendly help for the generator. Provide the consumer with help
* tips, parameters here
*
* @return A string value for the help message
*/
@Override
public String getHelp() {
return "Generates a Postman collection (format v2.1.0) JSON file";
}
/**
* Escapes a reserved word as defined in the `reservedWords` array. Handle escaping
* those terms here. This logic is only called if a variable matches the reserved words
*
* @return the escaped term
*/
@Override
public String escapeReservedWord(String name) {
return "_" + name; // add an underscore to the name
}
/**
* override with any special text escaping logic to handle unsafe
* characters so as to avoid code injection
*
* @param input String to be cleaned up
* @return string with unsafe characters removed or escaped
*/
@Override
public String escapeUnsafeCharacters(String input) {
//TODO: check that this logic is safe to escape unsafe characters to avoid code injection
return input;
}
/**
* Return the default value of the property
*
* Return null when the default is not defined
*
* @param schema Property schema
* @return string presentation of the default value of the property
*/
@SuppressWarnings("static-method")
@Override
public String toDefaultValue(Schema schema) {
if (schema.getDefault() != null) {
return schema.getDefault().toString();
}
return null;
}
/**
* Escape single and/or double quote to avoid code injection
*
* @param input String to be cleaned up
* @return string with quotation mark removed or escaped
*/
@Override
public String escapeQuotationMark(String input) {
//TODO: check that this logic is safe to escape quotation mark to avoid code injection
return input.replace("\"", "\\\"");
}
// convert path from /users/{id} to /users/:id
String replacesBracesInPath(String path) {
String s = path.replace("{", ":");
s = s.replace("}", "");
return s;
}
public String extractExampleByName(String ref) {
return ref.substring(ref.lastIndexOf("/") + 1);
}
public String mapToPostmanType(String openApiDataType) {
String ret = "any"; // default value
if(openApiDataType.equalsIgnoreCase("string")) {
ret = "string";
} else if(openApiDataType.equalsIgnoreCase("number") ||
openApiDataType.equalsIgnoreCase("integer")) {
ret = "number";
} else if(openApiDataType.equalsIgnoreCase("boolean")) {
ret = "boolean";
}
return ret;
}
/**
* get HTTP Status Code as text
* @param codegenResponse
* @return
*/
String getStatus(CodegenResponse codegenResponse) {
String ret = "";
if (codegenResponse.is2xx) {
if (codegenResponse.code.equalsIgnoreCase("200")) {
ret = "OK";
} else if (codegenResponse.code.equalsIgnoreCase("201")) {
ret = "Created";
} else {
ret = "Success";
}
} else if (codegenResponse.is3xx) {
ret = "Redirection";
}
if (codegenResponse.is4xx) {
if (codegenResponse.code.equalsIgnoreCase("400")) {
ret = "Bad Request";
} else if (codegenResponse.code.equalsIgnoreCase("401")) {
ret = "Unauthorized";
} else if (codegenResponse.code.equalsIgnoreCase("403")) {
ret = "Forbidden";
} else if (codegenResponse.code.equalsIgnoreCase("404")) {
ret = "Not Found";
} else if (codegenResponse.code.equalsIgnoreCase("409")) {
ret = "Conflict";
} else {
ret = "Client Error";
}
}
if (codegenResponse.is5xx) {
if (codegenResponse.code.equalsIgnoreCase("500")) {
ret = "Internal Server Error";
} else if (codegenResponse.code.equalsIgnoreCase("501")) {
ret = "Not Implemented";
} else {
ret = "Server Error";
}
}
return ret;
}
// make sure operation name is always set
String getSummary(CodegenOperation codegenOperation) {
String ret = null;
if(codegenOperation.summary != null) {
ret = codegenOperation.summary;
} else if (codegenOperation.operationId != null) {
ret = codegenOperation.operationId;
} else {
ret = codegenOperation.httpMethod;
}
return ret;
}
/**
* Format text to include in JSON file
* @param description Text to format
* @return Formatted text
*/
public String formatDescription(String description) {
if (description != null) {
description = description.replace("\n", JSON_ESCAPE_NEW_LINE);
description = description.replace("\"", JSON_ESCAPE_DOUBLE_QUOTE);
}
return description;
}
/**
* Extract all placeholders (string delimited by curly braces ie {{PLACEHOLDER}}) from the input string
* @param input String containing the placeholders
* @return Set of placeholders found in the string
*/
public Set extractPlaceholders(String input) {
Set variables = new HashSet<>();
Pattern pattern = Pattern.compile("\\{\\{([^}]*)\\}\\}");
Matcher matcher = pattern.matcher(input);
while(matcher.find()) {
if(postmanGuidPlaceholderName.equalsIgnoreCase(matcher.group(1))) {
// skip if it is postmanGuid placeholder
break;
}
if(postmanIsoTimestampPlaceholderName.equalsIgnoreCase(matcher.group(1))) {
// skip if it is postmanIsoTimestamp placeholder
break;
}
if(isPostmanDynamicVariable(matcher.group(1))) {
// skip if it is reserved words
break;
}
variables.add(matcher.group(1));
}
return variables;
}
public boolean isPostmanDynamicVariable(String value) {
boolean ret = false;
if(value.equals("$guid") || value.equals("$timestamp")) {
ret = true;
}
return ret;
}
// Supporting helpers
public String getJsonFromSchema(CodegenParameter codegenParameter) {
String ret = "{" + JSON_ESCAPE_NEW_LINE + " ";
int numVars = codegenParameter.vars.size();
int counter = 1;
for (CodegenProperty codegenProperty : codegenParameter.vars) {
ret = ret + JSON_ESCAPE_DOUBLE_QUOTE + codegenProperty.baseName + JSON_ESCAPE_DOUBLE_QUOTE + ": " +
JSON_ESCAPE_DOUBLE_QUOTE + "<" + getPostmanType(codegenProperty) + ">" + JSON_ESCAPE_DOUBLE_QUOTE;
if(counter < numVars) {
// add comma unless last attribute
ret = ret + "," + JSON_ESCAPE_NEW_LINE + " ";
}
counter++;
}
ret = ret + JSON_ESCAPE_NEW_LINE + "}";
return ret;
}
public String getJsonFromExample(Example example) {
String ret = "";
if(example == null) {
return ret;
}
if(example.getValue() instanceof ObjectNode) {
ret = convertToJson((ObjectNode)example.getValue());
} else if(example.getValue() instanceof LinkedHashMap) {
ret = convertToJson((LinkedHashMap)example.getValue());
}
return ret;
}
// array of attributes from JSON payload (ignore commas within quotes)
public String[] getAttributes(String json) {
return json.split(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", -1);
}
public String convertToJson(ObjectNode objectNode) {
return formatJson(objectNode.toString());
}
// convert to JSON (string) escaping and formatting
public String convertToJson(LinkedHashMap linkedHashMap) {
String ret = "";
return traverseMap(linkedHashMap, ret);
}
public String formatJson(String json) {
ObjectMapper objectMapper = new ObjectMapper();
try {
// convert to JSON object and prettify
JsonNode actualObj = objectMapper.readTree(json);
json = Json.pretty(actualObj);
json = json.replace("\"", JSON_ESCAPE_DOUBLE_QUOTE);
json = json.replace("\r\n", JSON_ESCAPE_NEW_LINE);
json = json.replace("\r", JSON_ESCAPE_NEW_LINE);
json = json.replace("\n", JSON_ESCAPE_NEW_LINE);
} catch (JsonProcessingException e) {
LOGGER.warn("Error formatting JSON", e);
json = "";
}
return json;
}
// traverse recursively
private String traverseMap(LinkedHashMap linkedHashMap, String ret) {
ret = ret + "{" + JSON_ESCAPE_NEW_LINE + " ";
int numVars = linkedHashMap.entrySet().size();
int counter = 1;
for (Map.Entry mapElement : linkedHashMap.entrySet()) {
String key = mapElement.getKey();
Object value = mapElement.getValue();
if(value instanceof String) {
// unescape double quotes already escaped
value = ((String)value).replace("\\\"", "\"");
ret = ret + JSON_ESCAPE_DOUBLE_QUOTE + key + JSON_ESCAPE_DOUBLE_QUOTE + ": " +
JSON_ESCAPE_DOUBLE_QUOTE + value + JSON_ESCAPE_DOUBLE_QUOTE;
} else if (value instanceof Integer) {
ret = ret + JSON_ESCAPE_DOUBLE_QUOTE + key + JSON_ESCAPE_DOUBLE_QUOTE + ": " +
value;
} else if (value instanceof Boolean) {
ret = ret + JSON_ESCAPE_DOUBLE_QUOTE + key + JSON_ESCAPE_DOUBLE_QUOTE + ": " +
value;
} else if (value instanceof LinkedHashMap) {
String in = ret + JSON_ESCAPE_DOUBLE_QUOTE + key + JSON_ESCAPE_DOUBLE_QUOTE + ": ";
ret = traverseMap(((LinkedHashMap) value), in);
} else if (value instanceof ArrayList>) {
ret = ret + JSON_ESCAPE_DOUBLE_QUOTE + key + JSON_ESCAPE_DOUBLE_QUOTE + ": " + getJsonArray((ArrayList