All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.droidlogix.dbflare.a2e.ApiCore Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
package com.droidlogix.dbflare.a2e;

import com.dbflare.core.models.IEndpoint;
import com.dbflare.core.models.IEndpointParameter;
import com.droidlogix.dbflare.datahandler.EntityRepository;
import com.droidlogix.dbflare.datahandler.IEntityRepository;
import com.droidlogix.dbflare.datahandler.PagingParameter;
import com.droidlogix.dbflare.datahandler.models.ResultInfo;
import com.droidlogix.dbflare.endpoint.core.IEndpointCore;
import com.droidlogix.dbflare.exceptions.DbFlareGenericException;
import com.droidlogix.dbflare.util.ApiUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;

/**
 * @author John Pili
 * @since 1.0.0
 */

public class ApiCore implements ApiCoreInterface
{
	private static final Logger logger = LoggerFactory.getLogger(ApiCore.class);

	private EntityManager entityManager;
	private IEndpointCore endpointCoreService;
	private ObjectMapper objectMapper;
	//private DbFlareResultCache dbFlareResultCache;

	private ObjectNode generateObjectNodeMapping(List mappingValues, Object result) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
	{
		ObjectNode objectNode = objectMapper.createObjectNode();
		for (MappingValue item : mappingValues)
		{
			if (item.getKeyVectorType().equalsIgnoreCase("java.lang.String")) // THIS IS ACCESS VIA METHOD OF ENTITY
			{
				Method method = result.getClass().getMethod(item.getKeyVector());
				objectNode.putPOJO(item.getJsonOutputName(), method.invoke(result));
			}
			else if (item.getKeyVectorType().equalsIgnoreCase("java.lang.Integer")) // THIS ACCESS THE POSITIONAL OF SQL RESULT
			{
				int position = Integer.parseInt(item.getKeyVector());
				objectNode.putPOJO(item.getJsonOutputName(), ((Object[]) result)[position]);
			}
		}
		return objectNode;
	}

	private String prettifierAndContainifier(boolean prettify, boolean container, JsonResult jsonResult)
	{
		try
		{
			if (!prettify)
			{
				if (container)
				{
					return objectMapper.writeValueAsString(jsonResult);
				}
				else
				{
					return objectMapper.writeValueAsString(jsonResult.getData());
				}
			}
			else
			{
				if (container)
				{
					return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonResult);
				}
				else
				{
					return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonResult.getData());
				}
			}
		}
		catch (JsonProcessingException jsonProcessingException)
		{
			logger.error(jsonProcessingException.getMessage());
			JsonResult parsingErrorJsonResult = new JsonResult(0, null, jsonProcessingException.getMessage());
			return prettifierAndContainifier(false, true, parsingErrorJsonResult);
		}
	}

	public ApiCore(EntityManager entityManager, IEndpointCore endpointCoreService, ObjectMapper objectMapper)
	{
		this.entityManager = entityManager;
		this.endpointCoreService = endpointCoreService;
		this.objectMapper = objectMapper;
	}

	public IEntityRepository.QUERY_STRING_TYPE getQueryStringType(IEndpoint apiEndPoint) throws DbFlareGenericException
	{
		if (!apiEndPoint.getQueryType().trim().isEmpty())
		{
			if (apiEndPoint.getQueryType().equalsIgnoreCase("JPQL_QUERY"))
			{
				return IEntityRepository.QUERY_STRING_TYPE.JPQL_QUERY;
			}
			else if (apiEndPoint.getQueryType().equalsIgnoreCase("NATIVE_QUERY"))
			{
				return IEntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY;
			}
			else if (apiEndPoint.getQueryType().equalsIgnoreCase("NAMED_QUERY"))
			{
				return IEntityRepository.QUERY_STRING_TYPE.NAMED_QUERY;
			}
			else if (apiEndPoint.getQueryType().equalsIgnoreCase("STORED_PROCEDURE"))
			{
				return IEntityRepository.QUERY_STRING_TYPE.STORED_PROCEDURE;
			}
			else
			{
				throw new DbFlareGenericException("Invalid Query Type");
			}
		}
		else
		{
			throw new DbFlareGenericException("Invalid Query Type");
		}
	}

	@Override
	public Map processIncomingURLParameters(IEndpoint apiEndPoint, Map urlParameters) throws DbFlareGenericException
	{
		try
		{
			Map namedParameters = new HashMap<>();
			Map positionalParameters = new HashMap<>();
			EntityRepository.QUERY_STRING_TYPE queryStringType = getQueryStringType(apiEndPoint);

			List apiEndPointParameterList = null;
			apiEndPointParameterList = this.endpointCoreService.getEndpointParametersByEndpoint(apiEndPoint.getIdEndpoint());

			if (queryStringType != null)
			{
				if (apiEndPointParameterList != null && !apiEndPointParameterList.isEmpty())
				{
					for (IEndpointParameter item : apiEndPointParameterList)
					{
						try
						{
							if (!item.getOutgoingParameterName().startsWith("{{") && !item.getOutgoingParameterName().endsWith("}}"))
							{
								Object incoming = urlParameters.get(item.getIncomingParameterName()); // This is always an Object[]
								String[] outgoing = (String[]) incoming; // Cast Object[] to String[]
								switch (queryStringType)
								{
									case JPQL_QUERY:
									case NAMED_QUERY:
									{
										if (item.getOutgoingParameterNameType().equalsIgnoreCase("java.lang.Integer"))
										{
											if (outgoing.length == 1)
											{
												if (!item.isNullableValue() && outgoing[0] != null)
												{
													namedParameters.put(item.getOutgoingParameterName(), Integer.parseInt(outgoing[0]));
												}
												else
												{
													if (outgoing[0] == null)
													{
														namedParameters.put(item.getOutgoingParameterName(), null);
													}
												}
											}
											else if (outgoing.length > 1)
											{
												List tmpList = new ArrayList<>();
												for (String o : outgoing)
												{
													tmpList.add(Integer.parseInt(o));
												}
												namedParameters.put(item.getOutgoingParameterName(), tmpList);
											}
										}
										else if (item.getOutgoingParameterNameType().equalsIgnoreCase("java.lang.Long"))
										{
											if (outgoing.length == 1)
											{
												if (!item.isNullableValue() && outgoing[0] != null)
												{
													namedParameters.put(item.getOutgoingParameterName(), Long.parseLong(outgoing[0]));
												}
												else
												{
													if (outgoing[0] == null)
													{
														namedParameters.put(item.getOutgoingParameterName(), null);
													}
												}
											}
											else if (outgoing.length > 1)
											{
												List tmpList = new ArrayList<>();
												for (String o : outgoing)
												{
													tmpList.add(Long.parseLong(o));
												}
												namedParameters.put(item.getOutgoingParameterName(), tmpList);
											}
										}
										else if (item.getOutgoingParameterNameType().equalsIgnoreCase("java.util.Date"))
										{
											if (outgoing.length == 1)
											{
												namedParameters.put(item.getOutgoingParameterName(), tryDateTimeParse(outgoing[0]));
											}
											else if (outgoing.length > 1)
											{
												List tmpList = new ArrayList<>();
												for (String o : outgoing)
												{
													tmpList.add(tryDateTimeParse(o));
												}
												namedParameters.put(item.getOutgoingParameterName(), tmpList);
											}
										}
										else if (item.getOutgoingParameterNameType().equalsIgnoreCase("java.lang.Boolean"))
										{
											namedParameters.put(item.getOutgoingParameterName(), Boolean.parseBoolean(outgoing[0]));
										}
										else
										{
											if (outgoing.length == 1)
											{
												namedParameters.put(item.getOutgoingParameterName(), outgoing[0]);
											}
											else if (outgoing.length > 1)
											{
												List tmpList = new ArrayList<>();
												for (String o : outgoing)
												{
													tmpList.add(o);
												}
												namedParameters.put(item.getOutgoingParameterName(), tmpList);
											}
										}
										break;
									}
									case NATIVE_QUERY:
									{
										if (item.getOutgoingParameterNameType().equalsIgnoreCase("java.util.Date"))
										{
											if (outgoing.length == 1)
											{
												positionalParameters.put(Integer.parseInt(item.getOutgoingParameterName()), tryDateTimeParse(outgoing[0]));
											}
											else if (outgoing.length > 1)
											{
												List tmpList = new ArrayList<>();
												for (String o : outgoing)
												{
													tmpList.add(tryDateTimeParse(o));
												}
												positionalParameters.put(Integer.parseInt(item.getOutgoingParameterName()), tmpList);
											}
										}
										else
										{
											if (outgoing.length == 1)
											{
												positionalParameters.put(Integer.parseInt(item.getOutgoingParameterName()), outgoing[0]);
											}
											else if (outgoing.length > 1)
											{
												List tmpList = new ArrayList<>();
												for (String o : outgoing)
												{
													tmpList.add(o);
												}
												positionalParameters.put(Integer.parseInt(item.getOutgoingParameterName()), tmpList);
											}
										}
										break;
									}
									default:
									{
										break;
									}
								}
							}
						}
						catch (Exception exception)
						{
							//logger.error(exception.getMessage());
							throw new DbFlareGenericException("Missing or Invalid Request Parameter: " + exception.getMessage());
						}
					}

					switch (queryStringType)
					{
						case JPQL_QUERY:
						case NAMED_QUERY:
						{
							return namedParameters;
						}
						case NATIVE_QUERY:
						{
							return positionalParameters;
						}
						default:
						{
							break;
						}
					}
				}
			}
		}
		catch(Exception exception)
		{
			throw new DbFlareGenericException(exception.getMessage(), exception.getCause());
		}
		return new HashMap();
	}

	@Override
	public String transposeQueryStringPlaceholders(IEndpoint endpoint, Map incomingURLParameters) throws DbFlareGenericException
	{
		try
		{
			List apiEndPointParameterList = null;
			apiEndPointParameterList = this.endpointCoreService.getEndpointParametersByEndpoint(endpoint.getIdEndpoint());

			StringBuilder stringBuilder = new StringBuilder(endpoint.getQueryString());
			if (apiEndPointParameterList != null && !apiEndPointParameterList.isEmpty())
			{
				for (IEndpointParameter item : apiEndPointParameterList)
				{
					try
					{
						StringBuilder csv = new StringBuilder();
						if (item.getOutgoingParameterName().startsWith("{{") && item.getOutgoingParameterName().endsWith("}}"))
						{
							Object[] incoming = incomingURLParameters.get(item.getIncomingParameterName()); // This is always an Object[] or empty Object[]
							String[] outgoing = (String[]) incoming; // Cast Object[] to String[]

							if (item.getOutgoingParameterNameType().equalsIgnoreCase("java.lang.Integer") || item.getOutgoingParameterNameType().equalsIgnoreCase("java.lang.Long"))
							{
								if (outgoing.length == 1)
								{
									stringBuilder = new StringBuilder(stringBuilder.toString().replace(item.getOutgoingParameterName(), outgoing[0]));
								}
								else if (outgoing.length > 1)
								{
									for (int i = 0; i < outgoing.length - 1; i++)
									{
										csv.append(outgoing[i]);
										if (i < outgoing.length - 1)
										{
											csv.append(",");
										}
									}
									stringBuilder = new StringBuilder(stringBuilder.toString().replace(item.getOutgoingParameterName(), csv));
								}
							}
							else
							{
								if (outgoing.length == 1)
								{
									stringBuilder = new StringBuilder(stringBuilder.toString().replace(item.getOutgoingParameterName(), "\"" + outgoing[0] + "\""));
								}
								else if (outgoing.length > 1)
								{
									for (int i = 0; i < outgoing.length; ++i)
									{
										csv.append("\"");
										csv.append(outgoing[i]);
										csv.append("\"");
										if (i < outgoing.length - 1)
										{
											csv.append(",");
										}
									}
									stringBuilder = new StringBuilder(stringBuilder.toString().replace(item.getOutgoingParameterName(), csv));
								}
							}
						}
					}
					catch (Exception exception)
					{
						logger.error(exception.getMessage());
						throw new Exception("Error processing placeholders");
					}
				}
			}
			stringBuilder = new StringBuilder(transposeQueryStringSort(stringBuilder.toString(), endpoint, incomingURLParameters));
			logger.info(stringBuilder.toString());
			return stringBuilder.toString();
		}
		catch(Exception exception)
		{
			throw new DbFlareGenericException(exception.getMessage(), exception.getCause());
		}
	}

	@Override
	public String transposeQueryStringSort(String queryString, IEndpoint endpoint, Map incomingURLParameters) throws DbFlareGenericException
	{
		try
		{
			StringBuilder stringBuilder = new StringBuilder(queryString.trim());
			if (endpoint != null)
			{
				if (endpoint.getMethod().equalsIgnoreCase("GET")) // This will transpose only GET API
				{
					if (endpoint.getQueryString() != null && !endpoint.getQueryString().trim().isEmpty()) // Check if queryString is null or empty
					{
						if (!endpoint.getQueryString().toUpperCase().contains("ORDER BY ")) // Check if the queryString already has ORDER BY
						{
							try
							{
								Object[] incoming = incomingURLParameters.get("sort"); // This is always an Object[] or empty Object[]
								String[] outgoing = (String[]) incoming; // Cast Object[] to String[]

								if (outgoing.length == 1)
								{
									stringBuilder.append(" ORDER BY ");
									String direction = outgoing[0].toLowerCase().endsWith("_desc") ? " DESC " : " ASC ";
									stringBuilder.append(ApiUtil.extractSortColumn(outgoing[0]));
									stringBuilder.append(direction);
								}
								else if (outgoing.length > 1)
								{
									stringBuilder.append(" ORDER BY ");
									StringBuilder csv = new StringBuilder();
									for (int i = 0; i < outgoing.length; ++i)
									{
										if (i < outgoing.length - 1)
										{
											String direction = outgoing[i].toLowerCase().endsWith("_desc") ? " DESC " : " ASC ";
											csv.append(stringBuilder.append(ApiUtil.extractSortColumn(outgoing[i])));
											csv.append(direction);
											if (i < outgoing.length - 1)
											{
												csv.append(", ");
											}
										}
									}
									stringBuilder.append(csv.toString());
								}
							}
							catch (Exception exception)
							{
							}
						}
					}
				}
			}
			return stringBuilder.toString();
		}
		catch(Exception exception)
		{
			throw new DbFlareGenericException(exception.getMessage(), exception.getCause());
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	public Object processBindingFromRequest(Class clazz, HttpServletRequest request) throws DbFlareGenericException
	{
		try
		{
			BufferedReader reader = request.getReader();
			GsonBuilder gsonBuilder = new GsonBuilder();
			gsonBuilder.registerTypeAdapter(Date.class, new DbFlareDateDeserializer());

			//CODE FROM or BASED: https://gist.github.com/orip/3635246
			gsonBuilder.registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64TypeAdapter()).create();
			Gson gson = gsonBuilder.create();
			return gson.fromJson(reader, clazz);
			//objectMapper.readValue(reader, clazz); // Jackson doesn't properly map this yet!
		}
		catch(Exception exception)
		{
			throw new DbFlareGenericException(exception.getMessage());
		}
	}

	@Override
	public List processBindingFromRequestToList(String className, HttpServletRequest request) throws DbFlareGenericException
	{
		try
		{
			BufferedReader reader = request.getReader();
			GsonBuilder gsonBuilder = new GsonBuilder();
			gsonBuilder.registerTypeAdapter(Date.class, new DbFlareDateDeserializer());

			//CODE FROM or BASED: https://gist.github.com/orip/3635246
			gsonBuilder.registerTypeHierarchyAdapter(byte[].class, new ByteArrayToBase64TypeAdapter()).create();
			Gson gson = gsonBuilder.create();
			return gson.fromJson(reader, TypeToken.getParameterized(ArrayList.class, Class.forName(className)).getType());
			//objectMapper.readValue(reader, clazz); // Jackson doesn't properly map this yet!
		}
		catch(Exception exception)
		{
			throw new DbFlareGenericException(exception.getMessage());
		}
	}

	@Override
	public JsonResult resultOutputProcessor(IEndpoint apiEndPoint, Object result) throws Exception // SINGLE RESULT
	{
		List mappingValues = new ArrayList<>();
		if (apiEndPoint.getMappingValue() != null && !apiEndPoint.getMappingValue().isEmpty())
		{
			mappingValues = extractMappingValues(apiEndPoint);
		}

		JsonResult jsonResult = new JsonResult();
		if (mappingValues != null)
		{
			if (mappingValues.isEmpty())
			{
				jsonResult.setData(result);
				jsonResult.setTotal(1);
			}
			else
			{
				jsonResult.setData(generateObjectNodeMapping(mappingValues, result));
				jsonResult.setTotal(1);
			}
		}
		return jsonResult;
	}

	@Override
	public JsonResult resultOutputProcessor(IEndpoint apiEndPoint, List resultList) throws
			Exception // MULTIPLE RESULT
	{
		List mappingValues = new ArrayList<>();
		if (apiEndPoint.getMappingValue() != null && !apiEndPoint.getMappingValue().isEmpty())
		{
			mappingValues = extractMappingValues(apiEndPoint);
		}
		else
		{
			//TODO: Next Feature
			mappingValues = autoGenerateMappingValues(apiEndPoint);
		}

		JsonResult jsonResult = new JsonResult();
		if (mappingValues != null)
		{
			if (mappingValues.isEmpty())
			{
				jsonResult.setData(resultList);
				jsonResult.setTotal(resultList.size());
			}
			else
			{
				ArrayNode arrayNode = objectMapper.createArrayNode();
				for (Object result : resultList)
				{
					arrayNode.add(generateObjectNodeMapping(mappingValues, result));
				}
				jsonResult.setData(arrayNode);
				jsonResult.setTotal(resultList.size());
			}
		}
		return jsonResult;
	}

	@Override
	public String execute(String api, boolean prettify, boolean container, PagingParameter
			pagingParameter, Map urlParameters) throws DbFlareGenericException
	{
		long delta1 = System.currentTimeMillis();
		try
		{
			IEndpoint apiEndPoint = endpointCoreService.getEndpointByApi(api);
			if (apiEndPoint != null)
			{
				Map parameters = processIncomingURLParameters(apiEndPoint, urlParameters); // CONVERT URL QUERY STRING INTO MAP
				if (apiEndPoint.getQueryResultType().equalsIgnoreCase(EntityRepository.QUERY_RESULT_TYPE.SINGLE.name())) // SINGLE RESULT
				{
					if (apiEndPoint.getQueryType().equalsIgnoreCase(EntityRepository.QUERY_STRING_TYPE.JPQL_QUERY.name()))
					{
						JsonResult jsonResult;
						ResultInfo resultInfo = new ResultInfo();
						Object object = new EntityRepository(entityManager).getSingle(apiEndPoint.getQueryString(), parameters, EntityRepository.QUERY_STRING_TYPE.JPQL_QUERY, resultInfo);
						jsonResult = resultOutputProcessor(apiEndPoint, object);
						jsonResult.setTotal(resultInfo.getTotal());
						jsonResult.setDbExecutionTime(resultInfo.getDbExecutionTime());
						return prettifierAndContainifier(prettify, container, jsonResult);
					}
					else if (apiEndPoint.getQueryType().equalsIgnoreCase(EntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY.name()))
					{
						JsonResult jsonResult;
						ResultInfo resultInfo = new ResultInfo();
						Object object = new EntityRepository(entityManager).getSingle(apiEndPoint.getQueryString(), parameters, EntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY, resultInfo);
						jsonResult = resultOutputProcessor(apiEndPoint, object);
						jsonResult.setTotal(resultInfo.getTotal());
						jsonResult.setDbExecutionTime(resultInfo.getDbExecutionTime());
						return prettifierAndContainifier(prettify, container, jsonResult);
					}
				}
				else if (apiEndPoint.getQueryResultType().equalsIgnoreCase(EntityRepository.QUERY_RESULT_TYPE.MULTIPLE.name())) // MULTIPLE RESULT
				{
					if (apiEndPoint.getQueryType().equalsIgnoreCase(EntityRepository.QUERY_STRING_TYPE.JPQL_QUERY.name()))
					{
						JsonResult jsonResult;
						ResultInfo resultInfo = new ResultInfo();
						if (pagingParameter == null)
						{
							List tmpList = new EntityRepository(entityManager).getList(apiEndPoint.getQueryString(), parameters, EntityRepository.QUERY_STRING_TYPE.JPQL_QUERY, resultInfo);
							jsonResult = resultOutputProcessor(apiEndPoint, tmpList);
							jsonResult.setTotal(resultInfo.getTotal());
							jsonResult.setDbExecutionTime(resultInfo.getDbExecutionTime());
						}
						else
						{
							List tmpList = new EntityRepository(entityManager).getList(apiEndPoint.getQueryString(), parameters, EntityRepository.QUERY_STRING_TYPE.JPQL_QUERY, resultInfo, pagingParameter);
							jsonResult = resultOutputProcessor(apiEndPoint, tmpList);
							jsonResult.setTotal(resultInfo.getTotal());
							jsonResult.setDbExecutionTime(resultInfo.getDbExecutionTime());
						}
						return prettifierAndContainifier(prettify, container, jsonResult);
					}
					else if (apiEndPoint.getQueryType().equalsIgnoreCase(EntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY.name()))
					{
						JsonResult jsonResult;
						ResultInfo resultInfo = new ResultInfo();
						if (pagingParameter == null)
						{
							List tmpList = new EntityRepository(entityManager).getList(transposeQueryStringPlaceholders(apiEndPoint, urlParameters), parameters, EntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY, resultInfo);
							jsonResult = resultOutputProcessor(apiEndPoint, tmpList);
							jsonResult.setTotal(resultInfo.getTotal());
							jsonResult.setDbExecutionTime(resultInfo.getDbExecutionTime());
						}
						else
						{
							List tmpList = new EntityRepository(entityManager).getList(transposeQueryStringPlaceholders(apiEndPoint, urlParameters), parameters, EntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY, resultInfo, pagingParameter);
							jsonResult = resultOutputProcessor(apiEndPoint, tmpList);
							jsonResult.setTotal(resultInfo.getTotal());
							jsonResult.setDbExecutionTime(resultInfo.getDbExecutionTime());
						}
						return prettifierAndContainifier(prettify, container, jsonResult);
					}
				}
			}
			throw new Exception("API not found");
		}
		catch (Exception exception)
		{
			logger.error(exception.getMessage());
			throw new DbFlareGenericException(exception.getMessage(), exception.getCause());
		}
	}

	@Override
	public String sqlQuery(String sqlQuery)
	{
		try
		{
			try
			{
				ResultInfo resultInfo = new ResultInfo();
				List tmpList = new EntityRepository(entityManager).getList(sqlQuery, null, EntityRepository.QUERY_STRING_TYPE.NATIVE_QUERY, resultInfo);
				return objectMapper.writeValueAsString(tmpList);
			}
			catch (Exception exception)
			{
				return objectMapper.writeValueAsString(exception.getMessage());
			}
		}
		catch (Exception exception)
		{
			logger.error(exception.getMessage());
		}
		return "[]";
	}

	@Override
	public String jpqlQuery(String jpqlQuery)
	{
		try
		{
			try
			{
				ResultInfo resultInfo = new ResultInfo();
				List tmpList = new EntityRepository(entityManager).getList(jpqlQuery, null, EntityRepository.QUERY_STRING_TYPE.JPQL_QUERY, resultInfo);
				return objectMapper.writeValueAsString(tmpList);
			}
			catch (Exception exception)
			{
				logger.error(exception.getMessage());
				return objectMapper.writeValueAsString(exception.getMessage());
			}
		}
		catch (Exception exception)
		{
			logger.error(exception.getMessage());

		}
		return "[]";
	}

	//CODE FROM or BASED: https://gist.github.com/orip/3635246
	private static class ByteArrayToBase64TypeAdapter implements JsonSerializer, JsonDeserializer
	{
		public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
		{
			return Base64.getDecoder().decode(json.getAsString());
		}

		public JsonElement serialize(byte[] src, Type typeOfSrc, JsonSerializationContext context)
		{
			return new JsonPrimitive(Base64.getEncoder().encodeToString(src));
		}

	}

	private Date tryDateTimeParse(String target) throws DbFlareGenericException
	{
		try
		{
			try
			{
				return new DateTime(Long.parseLong(target)).toDate();
			}
			catch (Exception exception)
			{
				return new DateTime(target).toDate();
			}
		}
		catch(Exception exception)
		{
			throw new DbFlareGenericException("Invalid date format in parameter (" + target + "): It should be in date format ISO 8601 or epoch integer");
		}
	}

	private List extractMappingValues(IEndpoint apiEndPoint)
	{
		try
		{
			return new Gson().fromJson(apiEndPoint.getMappingValue(), new TypeToken>()
			{
			}.getType());
		}
		catch (Exception exception)
		{
			logger.error(exception.getMessage());
		}
		return new ArrayList<>();
	}

	/***
	 * This will auto generate json mapping values if user not define any
	 * @param apiEndPoint
	 * @return
	 */
	private List autoGenerateMappingValues(IEndpoint apiEndPoint)
	{
		return new ArrayList<>();
	}
}