
com.wedeploy.api.sdk.ErrorData Maven / Gradle / Ivy
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Liferay, Inc. nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.wedeploy.api.sdk;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
public abstract class ErrorData {
/**
* Creates body string.
*/
public String errorBody() {
StringBuilder errorBody = new StringBuilder();
errorBody.append("{\n\t\"code\": ");
errorBody.append(statusCode);
errorBody.append(",\n");
errorBody.append("\t\"message\": \"");
errorBody.append(encodeString(statusMessage));
errorBody.append("\"");
if (!subErrors.isEmpty()) {
errorBody.append(",\n");
errorBody.append("\t\"errors\": [\n");
for (int i = 0; i < subErrors.size(); i++) {
String[] subError = subErrors.get(i);
if (i != 0) {
errorBody.append(",\n");
}
errorBody.append("\t\t{\n");
errorBody.append("\t\t\t\"reason\": \"");
errorBody.append(encodeString(subError[0]));
if (subError.length >= 2) {
errorBody.append("\",\n");
errorBody.append("\t\t\t\"message\": \"");
errorBody.append(encodeString(subError[1]));
errorBody.append("\"");
if (subError.length >= 3 && subError[2] != null) {
errorBody.append(",\n");
errorBody.append("\t\t\t\"details\": \"");
errorBody.append(encodeString(subError[2]));
errorBody.append("\"\n");
}
}
errorBody.append("\t\t}");
}
errorBody.append("\n\t]\n");
} else {
errorBody.append("\n");
}
errorBody.append("}");
return errorBody.toString();
}
public void headers(BiConsumer consumer) {
headers.forEach(consumer);
}
/**
* Returns status code.
*/
public int statusCode() {
return statusCode;
}
/**
* Returns status message.
*/
public String statusMessage() {
return statusMessage;
}
/**
* Adds error reason and a message.
*
* @see #add(String, String, Throwable)
*/
protected void add(String reason, String message) {
subErrors.add(new String[]{reason, message});
}
/**
* Adds error reason, message and throwable details.
*
* @see #add(String, String)
*/
protected void add(String reason, String message, Throwable throwable) {
subErrors.add(new String[]{reason, message, throwableToString(throwable)});
}
protected List getSubErrors() {
return subErrors;
}
protected void header(String name, String value) {
headers.put(name, value);
}
/**
* Writes the response into the target.
*/
protected abstract T into(T targetConsumer);
protected void set(
int statusCode, String statusMessage, String defaultMessage) {
this.statusCode = statusCode;
if (statusMessage == null) {
statusMessage = defaultMessage;
}
this.statusMessage = statusMessage;
}
/**
* Encodes input to JSON-safe string.
*/
private String encodeString(String value) {
StringBuilder sb = new StringBuilder();
int len = value.length();
for (int i = 0; i < len; i++) {
char c = value.charAt(i);
switch (c) {
case '"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '/':
sb.append("\\/");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
sb.append(c);
}
}
return sb.toString();
}
protected static String throwableToString(Throwable throwable) {
if (throwable == null) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append(throwable.toString());
sb.append("\n");
while (throwable != null) {
sb.append("---\n");
StackTraceElement[] stackTraceElements = throwable.getStackTrace();
int len = stackTraceElements.length >= 3 ? 3 : stackTraceElements.length;
for (int i = 0; i < len; i++) {
sb.append(stackTraceElements[i].toString());
sb.append("\n");
}
if (stackTraceElements.length > 3) {
sb.append("...\n");
}
throwable = throwable.getCause();
}
return sb.toString();
}
private final Map headers = new HashMap<>();
private int statusCode;
private String statusMessage;
private final LinkedList subErrors = new LinkedList<>();
}