Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.plenigo.sdk.internal.util.SdkUtils Maven / Gradle / Ivy
package com.plenigo.sdk.internal.util;
import com.plenigo.sdk.PlenigoException;
import com.plenigo.sdk.internal.ApiResults;
import com.plenigo.sdk.models.ErrorDetail;
import org.json.simple.parser.ContainerFactory;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* This class contains general SDK utilities that are required.
*
*
* IMPORTANT: This class is part of the internal API, please do not use it, because it can
* be removed in future versions of the SDK or access to such elements could
* be changed from 'public' to 'default' or less.
*
*
* Thread safety: This class is thread safe and can be injected.
*
*/
public final class SdkUtils {
private static final Logger LOGGER = Logger.getLogger(SdkUtils.class.getName());
/**
* The default entry separator used between key value pairs.
*/
private static final String ENTRY_SEPARATOR = "&";
/**
* The default separator between key and value.
*/
private static final String KEY_VALUE_SEPARATOR = "=>";
/**
* The default separator used for URL query strings.
*/
private static final String URL_QUERY_STRING_ENTRY_SEPARATOR = "&";
/**
* The default separator used for URL query strings.
*/
private static final String URL_QUERY_STRING_KEY_VALUE_SEPARATOR = "=";
/**
* The container factory used through all the json parsing.
*/
private static final ContainerFactory CONTAINER_FACTORY = new DefaultContainerFactory();
/**
* The JSON container factory.
*/
private static class DefaultContainerFactory implements ContainerFactory {
@Override
public Map createObjectContainer() {
return new LinkedHashMap();
}
@Override
public List> creatArrayContainer() {
return new LinkedList>();
}
}
/**
* Default constructor.
*/
private SdkUtils() {
}
/**
* This method converts a Map into a query string of key-value pairs with
* the format that plenigo's API accepts.
*
* @param keyValuePairs The map to convert
*
* @return a String of key value pairs
*/
public static String getStringFromMap(final Map keyValuePairs) {
return buildQueryString(keyValuePairs, ENTRY_SEPARATOR, KEY_VALUE_SEPARATOR, true);
}
/**
* This builds an encoded query string.
*
* @param map The map that contains all the key-value pairs.
*
* @return The query string
*/
public static String buildUrlQueryString(final Map map) {
return buildQueryString(map, URL_QUERY_STRING_ENTRY_SEPARATOR, URL_QUERY_STRING_KEY_VALUE_SEPARATOR, true);
}
/**
* This builds query string with the given entry separator
* and key value separator,
* e.g: key1{keyValueSeparator}value1{entrySeparator}key2{keyValueSeparator}value2 .
*
* @param map The key value map
* @param entrySeparator The separator used per key-value pair
* @param keyValueSeparator The separator used to delimit the key and value
* @param useEncoding Boolean that specifies if the keys and values should be encoded with the default charset
*
* @return A query string
*/
private static String buildQueryString(Map map, String entrySeparator, String keyValueSeparator, Boolean useEncoding) {
StringBuilder stringBuilder = new StringBuilder();
for (Map.Entry key : map.entrySet()) {
if (stringBuilder.length() > 0) {
stringBuilder.append(entrySeparator);
}
Object mapValue = key.getValue();
String value = null;
if (mapValue != null) {
value = mapValue.toString();
}
if (mapValue instanceof Collection) {
Collection values = (Collection) mapValue;
for (Object collVal : values) {
if (collVal != null) {
value = collVal.toString();
}
appendQueryStringValue(keyValueSeparator, useEncoding, stringBuilder, key, value);
}
} else {
appendQueryStringValue(keyValueSeparator, useEncoding, stringBuilder, key, value);
}
}
return stringBuilder.toString();
}
/**
* Append a query string value to the specified string builder.
*
* @param keyValueSeparator The separator of the key and value
* @param useEncoding true if encoding is required
* @param stringBuilder The string builder to append to
* @param key The key to be used
* @param value The value to be used
*/
private static void appendQueryStringValue(String keyValueSeparator, Boolean useEncoding, StringBuilder stringBuilder, Map.Entry key,
String value) {
try {
if (key.getKey() != null) {
String keyStr;
if (useEncoding) {
keyStr = URLEncoder.encode(key.getKey(), Charset.DEFAULT);
} else {
keyStr = key.getKey();
}
stringBuilder.append(keyStr);
}
stringBuilder.append(keyValueSeparator);
if (value != null) {
String valueStr;
if (useEncoding) {
valueStr = URLEncoder.encode(value, Charset.DEFAULT);
} else {
valueStr = value;
}
stringBuilder.append(valueStr);
}
} catch (UnsupportedEncodingException e) {
throw new IllegalStateException("The encoding is not supported", e);
}
}
/**
* This method parses a string with the format
* that plenigo's API accepts, into a map.
*
* @param data The data to parse
*
* @return a {@link java.util.Map}
*/
public static Map getMapFromString(final String data) {
Map map = new HashMap();
for (String pairs : data.split(ENTRY_SEPARATOR)) {
String[] entry = pairs.split(KEY_VALUE_SEPARATOR);
if (entry.length < 2) {
LOGGER.log(Level.FINEST, "Could not split entry data [{0}], exiting mapping...", data);
break;
}
map.put(entry[0], entry[1]);
}
LOGGER.log(Level.FINEST, "Map data to return {0}", map);
return map;
}
/**
* This method is used to evaluate if a value
* is null, in that case, it will not put
* the key-value pair into the map.
*
* @param map The map to use
* @param key The key
* @param value The value to evaluate
*/
public static void addIfNotNull(final Map map,
final String key, final Object value) {
if (value != null) {
LOGGER.log(Level.FINEST, "Formatted value of key: {0} has the value of {1} , adding to map", new Object[]{key, value});
map.put(key, value);
} else {
LOGGER.log(Level.FINEST, "Value of key {0} is null, not adding to map", key);
}
}
/**
* This method parses a JSON as a Map or List depending
* on the input stream.
*
* @param in Input stream representing the JSON
*
* @return A {@link java.util.List} or {@link java.util.Map} representing
* the json.
*
* @throws org.json.simple.parser.ParseException When there was an error parsing the JSON
* @throws java.io.IOException When there was a read error.
*/
private static Object parseJSON(final Reader in)
throws ParseException, IOException {
JSONParser parser = new JSONParser();
return parser.parse(in, CONTAINER_FACTORY);
}
/**
* Returns the array value if it exists, otherwise it returns null.
*
* @param indexPosition The index position of the value
* @param array The array
* @param outputClass The output class
* @param The output class placeholder
*
* @return The output class value
*
* @throws PlenigoException If a conversion error occurs
*/
public static O getArrayValueIfExistsOrNull(int indexPosition, String[] array, Class outputClass) throws PlenigoException {
O output = null;
if (LOGGER.isLoggable(Level.FINEST)) {
String arrayStr = null;
if (array != null) {
arrayStr = Arrays.toString(array);
}
LOGGER.log(Level.FINEST, "Attempting to retrieve the following array data: index position: {0}, array {1}, output class: {2}",
new Object[]{indexPosition, arrayStr, outputClass});
}
if (indexPosition >= 0 && array != null && array.length > indexPosition && array[indexPosition] != null) {
/*
* Converts an input type class to the specified output class using a 1 arg constructor, this is useful for wrapper classes mostly.
*/
String input = array[indexPosition];
output = convert(outputClass, input);
}
return output;
}
/**
* Converts the input into the given output class using a one parameter constructor strategy.
*
* @param outputClass the output class to use
* @param input the input information
* @param the type of the output class
*
* @return the converted instance
*
* @throws PlenigoException if an error happens during conversion
*/
private static O convert(Class outputClass, String input) throws PlenigoException {
O output = null;
try {
if (!(input == null || input.equals(""))) {
output = outputClass.getConstructor(
String.class).newInstance(input);
}
} catch (IllegalArgumentException e) {
LOGGER.log(Level.SEVERE, SdkUtils.getConversionErrMsg(input, outputClass), e);
throw new PlenigoException(SdkUtils.getConversionErrMsg(input, outputClass), e);
} catch (SecurityException e) {
LOGGER.log(Level.SEVERE, SdkUtils.getConversionErrMsg(input, outputClass), e);
throw new PlenigoException(SdkUtils.getConversionErrMsg(input, outputClass), e);
} catch (InstantiationException e) {
LOGGER.log(Level.SEVERE, SdkUtils.getConversionErrMsg(input, outputClass), e);
throw new PlenigoException(SdkUtils.getConversionErrMsg(input, outputClass), e);
} catch (IllegalAccessException e) {
LOGGER.log(Level.SEVERE, SdkUtils.getConversionErrMsg(input, outputClass), e);
throw new PlenigoException(SdkUtils.getConversionErrMsg(input, outputClass), e);
} catch (InvocationTargetException e) {
LOGGER.log(Level.SEVERE, SdkUtils.getConversionErrMsg(input, outputClass), e);
throw new PlenigoException(getConversionErrMsg(input, outputClass), e);
} catch (NoSuchMethodException e) {
LOGGER.log(Level.SEVERE, SdkUtils.getConversionErrMsg(input, outputClass), e);
throw new PlenigoException(SdkUtils.getConversionErrMsg(input, outputClass), e);
}
return output;
}
/**
* Returns the value if it exists, otherwise it returns null.
*
* @param value The value to convert
* @param outputClass The output class
* @param type of the output class
*
* @return The output class value
*
* @throws PlenigoException If a conversion error occurs
*/
public static O getValueIfExistsOrNull(Object value, Class outputClass) throws PlenigoException {
if (value == null) {
return null;
}
String val = value.toString();
return convert(outputClass, val);
}
/**
* Returns a conversion error msg.
*
* @param input The input data
* @param output The output class
*
* @return The error message
*/
private static String getConversionErrMsg(Object input, Object output) {
return "Error occured while converting from input " + input
+ " to type " + output;
}
/**
* This method parses a JSON as a Map.
*
* @param in Input stream representing the JSON
*
* @return A {@link java.util.Map} representing the json.
*
* @throws org.json.simple.parser.ParseException When there was an error parsing the JSON
* @throws java.io.IOException When there was a read error.
*/
@SuppressWarnings("unchecked")
public static Map parseJSONObject(final Reader in)
throws ParseException, IOException {
return (Map) parseJSON(in);
}
/**
* This join builds a query string separated by the ampersand sign.
*
* @param stringsToJoin The strings to delimit by the ampersand sign
*
* @return The joined string
*/
public static String join(String... stringsToJoin) {
StringBuilder builder = new StringBuilder(stringsToJoin[0]);
for (int i = 1; i < stringsToJoin.length; i++) {
builder.append(URL_QUERY_STRING_ENTRY_SEPARATOR).append(stringsToJoin[i]);
}
return builder.toString();
}
/**
* Parses invalid parameters from a Map, this is usually used when
* the API responds with a BAD_REQUEST parameter.
*
* @param parameters The mapped information
*
* @return a list of all the invalid parameters.
*/
@SuppressWarnings("unchecked")
public static List parseInvalidParamsErrors(Map parameters) {
List errorDetails = new LinkedList();
for (Map.Entry entry : parameters.entrySet()) {
String name = entry.getKey();
String errorMsg = null;
if (entry.getValue() instanceof Map) {
//noinspection unchecked
Map errorDetail = (Map) entry.getValue();
errorMsg = errorDetail.get(ApiResults.ERROR_MSG);
}
errorDetails.add(new ErrorDetail(name, errorMsg));
}
return errorDetails;
}
/**
* This method parses a URL query string into a Map.
*
* @param queryString The URL Query string
*
* @return The map of key-value pairs
*
* @throws java.io.UnsupportedEncodingException If The Charset is not supported
*/
public static Map parseQueryStringToMap(String queryString) throws UnsupportedEncodingException {
String decodedQueryString = URLDecoder.decode(queryString, Charset.DEFAULT);
Map params = new LinkedHashMap();
String[] pairs = decodedQueryString.split(URL_QUERY_STRING_ENTRY_SEPARATOR);
for (String pair : pairs) {
int idx = pair.indexOf("=");
params.put(pair.substring(0, idx), pair.substring(idx + 1));
}
return params;
}
/**
* This converts an input stream into a String.
*
* @param is The input stream to convert
*
* @return The string retrieved from the input stream
*/
public static String toString(java.io.InputStream is) {
String streamContent = "";
if (is == null) {
return streamContent;
}
Scanner scanner = null;
try {
scanner = new Scanner(is, Charset.DEFAULT).useDelimiter("\\A");
if (scanner.hasNext()) {
streamContent = scanner.next();
}
} finally {
if (scanner != null) {
scanner.close();
}
}
return streamContent;
}
/**
* Returns an empty string if the value is not null, if it is null it will return an empty string.
*
* @param map The map to get the key value from
* @param key The key to be used to get the value
*
* @return The corresponding value
*/
public static String getValueIfNotNull(Map map, String key) {
Object value = map.get(key);
if (value == null) {
return "";
}
return value.toString();
}
}