Kenmegne
7 days ago 23a46b4be35277e06ec89f48730eeb694e686be8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * 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;
        }
    }
 
}