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 package fr.paris.lutece.plugins.identitystore.service.attribute;
35
36 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.AttributeChangeStatus;
37 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.AttributeStatus;
38 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.common.IdentityDto;
39 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.crud.IdentityChangeRequest;
40 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.merge.IdentityMergeRequest;
41 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.IdentitySearchRequest;
42 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.SearchAttribute;
43 import fr.paris.lutece.plugins.identitystore.v3.web.rs.dto.search.SearchDto;
44 import fr.paris.lutece.plugins.identitystore.v3.web.rs.util.Constants;
45 import org.apache.commons.lang3.StringUtils;
46
47 import java.util.*;
48 import java.util.stream.Collectors;
49
50
51
52
53 public class IdentityAttributeFormatterService
54 {
55
56 private static IdentityAttributeFormatterService _instance;
57 private static final List<String> PHONE_ATTR_KEYS = Arrays.asList( "mobile_phone", "fixed_phone" );
58 private static final List<String> DATE_ATTR_KEYS = Collections.singletonList( "birthdate" );
59 private static final List<String> FIRSTNAME_ATTR_KEYS = Collections.singletonList( "first_name" );
60 private static final List<String> UPPERCASE_ATTR_KEYS = Arrays.asList( "birthcountry", "family_name", "preferred_username" );
61 private static final List<String> LOWERCASE_ATTR_KEYS = Arrays.asList( "login", "email" );
62
63 public static IdentityAttributeFormatterService instance( )
64 {
65 if ( _instance == null )
66 {
67 _instance = new IdentityAttributeFormatterService( );
68 }
69 return _instance;
70 }
71
72
73
74
75
76
77
78
79 public List<AttributeStatus> formatIdentityChangeRequestAttributeValues( final IdentityChangeRequest request )
80 {
81 final IdentityDto identity = request.getIdentity( );
82 final List<AttributeStatus> statuses = this.formatIdentityAttributeValues( identity );
83 request.setIdentity( identity );
84 return statuses;
85 }
86
87
88
89
90
91
92
93
94 public List<AttributeStatus> formatIdentityMergeRequestAttributeValues( final IdentityMergeRequest request )
95 {
96 final List<AttributeStatus> statuses = new ArrayList<>( );
97 final IdentityDto identity = request.getIdentity( );
98 if ( identity != null )
99 {
100 statuses.addAll( this.formatIdentityAttributeValues( identity ) );
101 request.setIdentity( identity );
102 }
103 return statuses;
104 }
105
106
107
108
109
110
111
112
113 public List<AttributeStatus> formatIdentitySearchRequestAttributeValues( final IdentitySearchRequest request )
114 {
115 final List<AttributeStatus> statuses = new ArrayList<>( );
116 final SearchDto search = request.getSearch( );
117 if ( search != null )
118 {
119 search.getAttributes( ).stream( ).filter( attributeDto -> StringUtils.isNotBlank( attributeDto.getValue( ) ) )
120 .forEach(attribute -> attribute.setValue( this.formatAttribute( attribute.getKey(), attribute.getValue(), statuses ) ));
121 }
122 return statuses;
123 }
124
125
126
127
128
129
130
131
132 public List<AttributeStatus> formatDuplicateSearchRequestAttributeValues( final Map<String, String> attributes )
133 {
134 final List<AttributeStatus> statuses = new ArrayList<>( );
135 if ( attributes != null )
136 {
137 attributes.entrySet().stream( ).filter( attributeDto -> StringUtils.isNotBlank( attributeDto.getValue( ) ) )
138 .forEach(attribute -> attribute.setValue( this.formatAttribute( attribute.getKey(), attribute.getValue(), statuses ) ));
139 }
140 return statuses;
141 }
142
143
144
145
146
147
148
149
150
151 private List<AttributeStatus> formatIdentityAttributeValues( final IdentityDto identity )
152 {
153 final List<AttributeStatus> statuses = new ArrayList<>( );
154 identity.getAttributes( ).stream( ).filter( attributeDto -> StringUtils.isNotBlank( attributeDto.getValue( ) ) ).forEach( attribute -> {
155 attribute.setValue( this.formatAttribute( attribute.getKey(), attribute.getValue(), statuses ) );
156 } );
157 return statuses;
158 }
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200 private String formatAttribute( final String key, final String value, final List<AttributeStatus> statuses )
201 {
202
203
204 String formattedValue = value.trim( ).replaceAll( "\\s+", " " );
205
206 if ( PHONE_ATTR_KEYS.contains( key ) )
207 {
208 formattedValue = formatPhoneValue( formattedValue );
209 }
210 if ( DATE_ATTR_KEYS.contains( key ) )
211 {
212 formattedValue = formatDateValue( formattedValue );
213 }
214 if ( FIRSTNAME_ATTR_KEYS.contains( key ) )
215 {
216 formattedValue = formatFirstnameValue( formattedValue );
217 }
218 if ( UPPERCASE_ATTR_KEYS.contains( key ) )
219 {
220 formattedValue = StringUtils.upperCase( formattedValue );
221 }
222 if ( LOWERCASE_ATTR_KEYS.contains( key ) )
223 {
224 formattedValue = StringUtils.lowerCase( formattedValue );
225 }
226
227
228 if ( !formattedValue.equals( value ) )
229 {
230 statuses.add( buildAttributeValueFormattedStatus( key, value, formattedValue ) );
231 }
232
233 return formattedValue;
234 }
235
236
237
238
239
240
241
242
243
244
245
246 private String formatPhoneValue( final String value )
247 {
248
249 String formattedValue = value.replaceAll( "\\s", "" ).replace( ".", "" ).replace( "-", "" ).replace( "(", "" ).replace( ")", "" );
250
251 formattedValue = formattedValue.replaceAll( "^(0{2}|\\+)3{2}", "0" );
252
253 return formattedValue;
254 }
255
256
257
258
259
260
261
262
263 public String formatDateValue( final String value )
264 {
265 final StringBuilder sb = new StringBuilder( );
266 final String [ ] splittedDate = value.split( "/" );
267 if ( splittedDate.length == 3 )
268 {
269 final String day = splittedDate [0];
270 if ( day.length( ) == 1 )
271 {
272 sb.append( "0" );
273 }
274 sb.append( day ).append( "/" );
275
276 final String month = splittedDate [1];
277 if ( month.length( ) == 1 )
278 {
279 sb.append( "0" );
280 }
281 sb.append( month ).append( "/" ).append( splittedDate [2] );
282
283 return sb.toString( );
284 }
285 else
286 {
287 return value;
288 }
289 }
290
291
292
293
294
295
296
297
298
299
300
301 private String formatFirstnameValue( final String value )
302 {
303 if ( StringUtils.isBlank( value ) )
304 {
305 return value;
306 }
307 return Arrays.stream( value.replace( ",", " " ).trim( ).split( " " ) ).filter( StringUtils::isNotBlank ).map( String::trim )
308 .map( firstname -> {
309 if( firstname.contains("-") )
310 {
311 return Arrays.stream(firstname.split("-")).map( this::toFirstLetterUpperCased ).map( String::trim ).collect(Collectors.joining("-"));
312 }
313 else
314 {
315 return this.toFirstLetterUpperCased( firstname );
316 }
317 } ).collect( Collectors.joining( " " ) );
318 }
319
320 private String toFirstLetterUpperCased ( final String value )
321 {
322 return !value.isEmpty() ? value.substring( 0, 1 ).toUpperCase( ) + value.substring( 1 ).toLowerCase( ) : value;
323 }
324
325
326
327
328
329
330
331
332 public AttributeStatus buildAttributeValueFormattedStatus( final String attrStrKey, final String oldValue, final String newValue )
333 {
334 final AttributeStatus status = new AttributeStatus( );
335 status.setKey( attrStrKey );
336 status.setStatus( AttributeChangeStatus.FORMATTED_VALUE );
337 status.setMessage( "[" + oldValue + "] -> [" + newValue + "]" );
338 status.setMessageKey( Constants.PROPERTY_ATTRIBUTE_STATUS_FORMATTED_VALUE );
339 return status;
340 }
341
342 }