/*
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
|
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
|
*/
|
package com.megatim.fdxcommons.core.impl.interceptor;
|
|
import com.google.gson.Gson;
|
import com.google.gson.internal.LinkedTreeMap;
|
import com.megatim.fdxcommons.core.ifaces.interceptor.LoggingInterceptorBinding;
|
import com.megatim.fdxcommons.core.ifaces.interceptor.InterceptorHandler;
|
import java.lang.reflect.Field;
|
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.Method;
|
import java.lang.reflect.Parameter;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.Collection;
|
import java.util.List;
|
import java.util.Optional;
|
import java.util.regex.Matcher;
|
import java.util.regex.Pattern;
|
import java.util.stream.Collectors;
|
import javax.enterprise.context.Dependent;
|
import javax.ws.rs.core.MultivaluedMap;
|
|
/**
|
* {} : Les paramètres de requête sont entre accolades () : La valeur de retour
|
* entre les parenthèses [] : L'entité de requête est entre les crochets
|
*
|
* @author ASUS
|
*/
|
@Dependent
|
public class InterceptorHandlerImpl implements InterceptorHandler {
|
|
@Override
|
public String finalMessage(LoggingInterceptorBinding interceptorBinding, Parameter[] parameters, MultivaluedMap<String, String> queryParams, Object requestEntity, Object responseEntity) throws Exception {
|
//Recherche des références au paramètres de la requête
|
String message = infoFromPathParameters(interceptorBinding.message(), queryParams);
|
|
//Recherche des références aux éléments du tableau de paramètres
|
message = infoFromParameters(message, parameters, requestEntity);
|
|
//Recherche des références à la valeur de retour
|
return infoFromReturnValue(message, interceptorBinding.classe(), responseEntity);
|
}
|
|
private String infoFromPathParameters(String message, MultivaluedMap<String, String> queryParams) throws Exception {
|
if (!queryParams.isEmpty()) {
|
Pattern pattern = Pattern.compile("\\{\\S{1,}\\}");
|
Matcher matcher = pattern.matcher(message);
|
|
while (matcher.find()) {
|
String group = matcher.group();
|
String fieldName = group.substring(1, group.length() - 1);
|
|
if (queryParams.containsKey(fieldName)) {
|
message = message.replace(group, queryParams.getFirst(fieldName));
|
}
|
}
|
}
|
return message;
|
}
|
|
private String infoFromReturnValue(String message, Class<?> classe, Object dataToProcess) throws Exception {
|
Pattern pattern = Pattern.compile("\\(\\S{1,}\\)");
|
Matcher matcher = pattern.matcher(message);
|
|
while (matcher.find()) {
|
String group = matcher.group();
|
String fieldName = group.substring(1, group.length() - 1);
|
String[] fieldPath = fieldName.split("\\.");
|
String fieldValue = value(fieldPath, classe, dataToProcess);
|
message = message.replace(group, fieldValue);
|
}
|
|
return message;
|
}
|
|
private String infoFromParameters(String message, Parameter[] parameters, Object requestEntity) throws Exception {
|
if (parameters.length > 0) {
|
Pattern pattern = Pattern.compile("\\[\\d{1,}\\S*\\]");
|
Matcher matcher = pattern.matcher(message);
|
|
while (matcher.find()) {
|
String group = matcher.group();
|
String fieldName = group.substring(1, group.length() - 1);
|
String[] fieldPath = fieldName.split("\\.");
|
int index = Integer.parseInt(fieldPath[0]);
|
|
if (requestEntity != null && index < parameters.length) {
|
Object obj = new Gson().fromJson(requestEntity.toString(), parameters[index].getType());
|
String value = "";
|
|
if (fieldPath.length == 1) {
|
value = value(fieldPath, parameters[index].getType(), obj);
|
} else {
|
value = value(Arrays.copyOfRange(fieldPath, 1, fieldPath.length),
|
parameters[index].getType(), obj);
|
}
|
|
message = message.replace(group, value);
|
}
|
}
|
}
|
return message;
|
}
|
|
private String value(String[] fieldPath, Class<?> classe, Object dataToProcess) throws Exception {
|
|
if (dataToProcess instanceof Collection) {
|
return valueFromCollection(fieldPath, classe, (Collection) dataToProcess);
|
|
} else {
|
return valueFromField(fieldPath, classe, dataToProcess);
|
}
|
}
|
|
private String valueFromCollection(String[] fieldPath, Class<?> classe, Collection collection) throws Exception {
|
List<String> values = new ArrayList<>();
|
for (Object obj : collection) {
|
values.add(valueFromField(fieldPath, classe, obj));
|
}
|
return "[" + values.stream().collect(Collectors.joining(",")) + "]";
|
}
|
|
private String valueFromLinkedTreeMap(LinkedTreeMap dataToProcess, String field) {
|
return dataToProcess.get(field).toString();
|
}
|
|
private String valueFromField(String[] fieldPath, Class<?> classe, Object dataToProcess) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
if (dataToProcess instanceof LinkedTreeMap) {
|
return valueFromLinkedTreeMap((LinkedTreeMap) dataToProcess, fieldPath[0]);
|
} else {
|
String methodName = "get" + (fieldPath[0].charAt(0) + "").toUpperCase() + fieldPath[0].substring(1);
|
Method method = classe.getMethod(methodName);
|
Object obj = method.invoke(classe.cast(dataToProcess));
|
|
if (fieldPath.length == 1) {
|
return obj.toString();
|
|
} else {
|
Class<?> classToParse = fieldType(fieldPath[0], classe);
|
return valueFromField(Arrays.copyOfRange(fieldPath, 1, fieldPath.length), classToParse, obj);
|
}
|
}
|
}
|
|
private Class<?> fieldType(String fieldName, Class<?> classe) {
|
Optional<Field> optionalField = Arrays.asList(classe.getDeclaredFields()).stream().filter(f -> f.getName().equals(fieldName)).findFirst();
|
|
if (optionalField.isPresent()) {
|
return optionalField.get().getType();
|
} else {
|
return null;
|
}
|
}
|
|
}
|