DATACMNS-546 - PropertyPath has better exception messages now.
PropertyPath now exposes the complete property named the resolution failed for in case it can't resolve a source String. It will expose the part of the Path from the deepest successful resolution result. Changed the resolution algorithm to use a List instead of a Stack and a fresh instance of the former so that the nested recursion steps keep track of the correct resolution depths.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2011-2013 the original author or authors.
|
||||
* Copyright 2011-2014 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.
|
||||
@@ -63,7 +63,7 @@ public class PropertyPath implements Iterable<PropertyPath> {
|
||||
* @param owningType must not be {@literal null}.
|
||||
* @param base the {@link PropertyPath} previously found.
|
||||
*/
|
||||
PropertyPath(String name, TypeInformation<?> owningType, Stack<PropertyPath> base) {
|
||||
PropertyPath(String name, TypeInformation<?> owningType, List<PropertyPath> base) {
|
||||
|
||||
Assert.hasText(name);
|
||||
Assert.notNull(owningType);
|
||||
@@ -303,7 +303,7 @@ public class PropertyPath implements Iterable<PropertyPath> {
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
private static PropertyPath create(String source, TypeInformation<?> type, Stack<PropertyPath> base) {
|
||||
private static PropertyPath create(String source, TypeInformation<?> type, List<PropertyPath> base) {
|
||||
return create(source, type, "", base);
|
||||
}
|
||||
|
||||
@@ -317,7 +317,7 @@ public class PropertyPath implements Iterable<PropertyPath> {
|
||||
* @param addTail
|
||||
* @return
|
||||
*/
|
||||
private static PropertyPath create(String source, TypeInformation<?> type, String addTail, Stack<PropertyPath> base) {
|
||||
private static PropertyPath create(String source, TypeInformation<?> type, String addTail, List<PropertyPath> base) {
|
||||
|
||||
PropertyReferenceException exception = null;
|
||||
PropertyPath current = null;
|
||||
@@ -327,13 +327,14 @@ public class PropertyPath implements Iterable<PropertyPath> {
|
||||
current = new PropertyPath(source, type, base);
|
||||
|
||||
if (!base.isEmpty()) {
|
||||
base.peek().next = current;
|
||||
base.get(base.size() - 1).next = current;
|
||||
}
|
||||
|
||||
base.push(current);
|
||||
List<PropertyPath> newBase = new ArrayList<PropertyPath>(base);
|
||||
newBase.add(current);
|
||||
|
||||
if (StringUtils.hasText(addTail)) {
|
||||
current.next = create(addTail, current.type, base);
|
||||
current.next = create(addTail, current.type, newBase);
|
||||
}
|
||||
|
||||
return current;
|
||||
@@ -356,7 +357,11 @@ public class PropertyPath implements Iterable<PropertyPath> {
|
||||
String head = source.substring(0, position);
|
||||
String tail = source.substring(position);
|
||||
|
||||
return create(head, type, tail + addTail, base);
|
||||
try {
|
||||
return create(head, type, tail + addTail, base);
|
||||
} catch (PropertyReferenceException e) {
|
||||
throw e.hasDeeperResolutionDepthThan(exception) ? e : exception;
|
||||
}
|
||||
}
|
||||
|
||||
throw exception;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012 the original author or authors.
|
||||
* Copyright 2012-2014 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.
|
||||
@@ -15,7 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mapping;
|
||||
|
||||
import java.util.Stack;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,23 +32,23 @@ public class PropertyReferenceException extends RuntimeException {
|
||||
|
||||
private final String propertyName;
|
||||
private final TypeInformation<?> type;
|
||||
private final Stack<PropertyPath> base;
|
||||
private final List<PropertyPath> alreadyResolvedPath;
|
||||
|
||||
/**
|
||||
* Creates a new {@link PropertyReferenceException}.
|
||||
*
|
||||
* @param propertyName the name of the property not found on the given type.
|
||||
* @param type the type the property could not be found on.
|
||||
* @param base the previously calculated {@link PropertyPath}s.
|
||||
* @param alreadyResolvedPah the previously calculated {@link PropertyPath}s.
|
||||
*/
|
||||
public PropertyReferenceException(String propertyName, TypeInformation<?> type, Stack<PropertyPath> base) {
|
||||
public PropertyReferenceException(String propertyName, TypeInformation<?> type, List<PropertyPath> alreadyResolvedPah) {
|
||||
|
||||
Assert.hasText(propertyName);
|
||||
Assert.notNull(type);
|
||||
|
||||
this.propertyName = propertyName;
|
||||
this.type = type;
|
||||
this.base = base;
|
||||
this.alreadyResolvedPath = alreadyResolvedPah;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,8 +79,8 @@ public class PropertyReferenceException extends RuntimeException {
|
||||
StringBuilder builder = new StringBuilder(String.format(ERROR_TEMPLATE, propertyName, type.getType()
|
||||
.getSimpleName()));
|
||||
|
||||
if (!base.isEmpty()) {
|
||||
builder.append(" Traversed path: ").append(base.get(0).toString()).append(".");
|
||||
if (!alreadyResolvedPath.isEmpty()) {
|
||||
builder.append(" Traversed path: ").append(alreadyResolvedPath.get(0).toString()).append(".");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
@@ -92,6 +92,17 @@ public class PropertyReferenceException extends RuntimeException {
|
||||
* @return
|
||||
*/
|
||||
public PropertyPath getBaseProperty() {
|
||||
return base.isEmpty() ? null : base.peek();
|
||||
return alreadyResolvedPath.isEmpty() ? null : alreadyResolvedPath.get(alreadyResolvedPath.size() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link PropertyReferenceException} has a deeper resolution depth (i.e. a longer path of
|
||||
* already resolved properties) than the current exception.
|
||||
*
|
||||
* @param exception
|
||||
* @return
|
||||
*/
|
||||
public boolean hasDeeperResolutionDepthThan(PropertyReferenceException exception) {
|
||||
return this.alreadyResolvedPath.size() > exception.alreadyResolvedPath.size();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user