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.
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.springlets.http.converter.json;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Jackson Serializer which generates a tree with binding and validation
* property errors stored on a {@link BindingResult} object.
*
* Error messages will be {@link FieldError#getDefaultMessage()} so, it is
* already translated to (current request) language (or supposed to).
*
* JSON generated for {@link List} binding errors:
*
*
* @author http://www.disid.com[DISID Corporation S.L.]
*/
public class BindingResultSerializer extends JsonSerializer {
@Override
public void serialize(BindingResult result, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonProcessingException {
// Create the errors map
Map allErrorsMessages = new HashMap();
// Get field errors
List fieldErrors = result.getFieldErrors();
if (fieldErrors.isEmpty()) {
// Nothing to do
jgen.writeNull();
return;
}
// Check if target type is an array or a bean
@SuppressWarnings("rawtypes")
Class targetClass = result.getTarget().getClass();
if (targetClass.isArray() || Collection.class.isAssignableFrom(targetClass)) {
loadListErrors(result.getFieldErrors(), allErrorsMessages);
} else {
loadObjectErrors(result.getFieldErrors(), allErrorsMessages);
}
// Create the result map
Map bindingResult = new HashMap();
bindingResult.put("target-resource", StringUtils.uncapitalize(result.getObjectName()));
bindingResult.put("error-count", result.getErrorCount());
bindingResult.put("errors", allErrorsMessages);
jgen.writeObject(bindingResult);
}
/**
* Iterate over object errors and load it on allErrorsMessages map.
*
* Delegates on {@link #loadObjectError(FieldError, String, Map)}
*
* @param fieldErrors
* @param allErrorsMessages
*/
private void loadObjectErrors(List fieldErrors,
Map allErrorsMessages) {
for (FieldError error : fieldErrors) {
loadObjectError(error, error.getField(), allErrorsMessages);
}
}
/**
* Iterate over list items errors and load it on allErrorsMessages map.
*
* Delegates on {@link #loadObjectError(FieldError, String, Map)}
*
* @param fieldErrors
* @param allErrorsMessages
*/
@SuppressWarnings("unchecked")
private void loadListErrors(List fieldErrors, Map allErrorsMessages) {
// Get prefix to unwrapping list:
// "list[0].employedSince"
String fieldNamePath = fieldErrors.get(0).getField();
String prefix = "";
if (fieldNamePath != null && fieldNamePath.contains("[")) {
// "list"
prefix = substringBefore(fieldNamePath, "[");
}
String index = "";
Map currentErrors;
// Iterate over errors
for (FieldError error : fieldErrors) {
fieldNamePath = error.getField();
if (fieldNamePath != null && fieldNamePath.contains("]")) {
// get property path without list prefix
// "[0].employedSince"
fieldNamePath = substringAfter(error.getField(), prefix);
// Get item's index:
// "[0].employedSince"
index = substringBefore(substringAfter(fieldNamePath, "["), "]");
// Remove index definition from field path
// "employedSince"
fieldNamePath = substringAfter(fieldNamePath, ".");
}
// Check if this item already has errors registered
currentErrors = (Map) allErrorsMessages.get(index);
if (currentErrors == null) {
// No errors registered: create map to contain this error
currentErrors = new HashMap();
allErrorsMessages.put(index, currentErrors);
}
// Load error on item's map
loadObjectError(error, fieldNamePath, currentErrors);
}
}
/**
* Loads an object field error in errors map.
*
* This method identifies if referred object property is an array, an object
* or a simple property to decide how to store the error message.
*
* @param error
* @param fieldNamePath
* @param objectErrors
*/
@SuppressWarnings("unchecked")
private void loadObjectError(FieldError error, String fieldNamePath,
Map objectErrors) {
String propertyName = fieldNamePath;
boolean isObject = false;
// Get this property name and if is a object property
if (fieldNamePath != null && fieldNamePath.contains(".")) {
isObject = true;
propertyName = substringBefore(fieldNamePath, ".");
}
// Check if property is an array or a list
boolean isList = propertyName != null && propertyName.contains("[");
// Process a list item property
if (isList) {
// Get property name
String listPropertyName = substringBefore(propertyName, "[");
// Get referred item index
String index = substringBefore(substringAfter(propertyName, "["), "]");
// Get item path
String itemPath = substringAfter(fieldNamePath, ".");
// Get container of list property errors
Map listErrors = (Map) objectErrors.get(listPropertyName);
if (listErrors == null) {
// property has no errors yet: create a container for it
listErrors = new HashMap();
objectErrors.put(listPropertyName, listErrors);
}
// Get current item errors
Map itemErrors = (Map) listErrors.get(index);
if (itemErrors == null) {
// item has no errors yet: create a container for it
itemErrors = new HashMap();
listErrors.put(index, itemErrors);
}
// Load error in item property path
loadObjectError(error, itemPath, itemErrors);
} else if (isObject) {
// It's not a list but it has properties in it value
// Get current property errors
Map propertyErrors = (Map) objectErrors.get(propertyName);
if (propertyErrors == null) {
// item has no errors yet: create a container for it
propertyErrors = new HashMap();
objectErrors.put(propertyName, propertyErrors);
}
// Get error sub path
String subFieldPath = substringAfter(fieldNamePath, ".");
// Load error in container
loadObjectError(error, subFieldPath, propertyErrors);
} else {
// standard property with no children value
// Store error message in container
objectErrors.put(propertyName, error.getDefaultMessage());
}
}
private String substringBefore(String text, String separator) {
if (StringUtils.isEmpty(text)) {
return text;
}
final int pos = text.indexOf(separator);
if (pos < 0) {
return text;
}
return text.substring(0, pos);
}
private String substringAfter(String text, final String separator) {
if (StringUtils.isEmpty(text)) {
return text;
}
int pos = text.indexOf(separator);
if (pos < 0) {
return "";
}
return text.substring(pos + separator.length());
}
}