Skip to content

DATACMNS-703 - PropertyReferenceExceptions now exposes potential matches. #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
Expand All @@ -15,10 +15,14 @@
*/
package org.springframework.data.mapping;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.PropertyMatches;
import org.springframework.data.util.TypeInformation;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
* Exception being thrown when creating {@link PropertyPath} instances.
Expand All @@ -29,10 +33,12 @@ public class PropertyReferenceException extends RuntimeException {

private static final long serialVersionUID = -5254424051438976570L;
private static final String ERROR_TEMPLATE = "No property %s found for type %s!";
private static final String HINTS_TEMPLATE = " Did you mean %s?";

private final String propertyName;
private final TypeInformation<?> type;
private final List<PropertyPath> alreadyResolvedPath;
private final List<String> propertyMatches;

/**
* Creates a new {@link PropertyReferenceException}.
Expand All @@ -41,14 +47,16 @@ public class PropertyReferenceException extends RuntimeException {
* @param type the type the property could not be found on.
* @param alreadyResolvedPah the previously calculated {@link PropertyPath}s.
*/
public PropertyReferenceException(String propertyName, TypeInformation<?> type, List<PropertyPath> alreadyResolvedPah) {
public PropertyReferenceException(String propertyName, TypeInformation<?> type,
List<PropertyPath> alreadyResolvedPah) {

Assert.hasText(propertyName);
Assert.notNull(type);

this.propertyName = propertyName;
this.type = type;
this.alreadyResolvedPath = alreadyResolvedPah;
this.propertyMatches = detectPotentialMatches(propertyName, type.getType());
}

/**
Expand Down Expand Up @@ -76,11 +84,18 @@ public TypeInformation<?> getType() {
@Override
public String getMessage() {

StringBuilder builder = new StringBuilder(String.format(ERROR_TEMPLATE, propertyName, type.getType()
.getSimpleName()));
StringBuilder builder = new StringBuilder(
String.format(ERROR_TEMPLATE, propertyName, type.getType().getSimpleName()));

if (!propertyMatches.isEmpty()) {
String matches = StringUtils.collectionToDelimitedString(propertyMatches, ",", "'", "'");
builder.append(String.format(HINTS_TEMPLATE, matches));
}

if (!alreadyResolvedPath.isEmpty()) {
builder.append(" Traversed path: ").append(alreadyResolvedPath.get(0).toString()).append(".");
builder.append(" Traversed path: ");
builder.append(alreadyResolvedPath.get(0).toString());
builder.append(".");
}

return builder.toString();
Expand All @@ -105,4 +120,20 @@ public PropertyPath getBaseProperty() {
public boolean hasDeeperResolutionDepthThan(PropertyReferenceException exception) {
return this.alreadyResolvedPath.size() > exception.alreadyResolvedPath.size();
}

/**
* Detects all potential matches for the given property name and type.
*
* @param propertyName must not be {@literal null} or empty.
* @param type must not be {@literal null}.
* @return
*/
private static List<String> detectPotentialMatches(String propertyName, Class<?> type) {

List<String> result = new ArrayList<String>();
result.addAll(Arrays.asList(PropertyMatches.forField(propertyName, type).getPossibleMatches()));
result.addAll(Arrays.asList(PropertyMatches.forProperty(propertyName, type).getPossibleMatches()));

return result;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2014 the original author or authors.
* Copyright 2011-2015 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.
Expand Down Expand Up @@ -353,6 +353,9 @@ public void rejectsNullTypeInformation() {
from("foo", (TypeInformation<?>) null);
}

/**
* @see DATACMNS-546
*/
@Test
public void returnsCompletePathIfResolutionFailedCompletely() {

Expand All @@ -362,8 +365,11 @@ public void returnsCompletePathIfResolutionFailedCompletely() {
from("somethingDifferent", Foo.class);
}

/**
* @see DATACMNS-546
*/
@Test
public void foobar() {
public void includesResolvedPathInExceptionMessage() {

exception.expect(PropertyReferenceException.class);
exception.expectMessage("fooName");
Expand All @@ -373,6 +379,18 @@ public void foobar() {
from("userFooName", Bar.class);
}

/**
* @see DATACMNS-
*/
@Test
public void includesPropertyHintsOnTypos() {

exception.expect(PropertyReferenceException.class);
exception.expectMessage("userName");

from("userAme", Foo.class);
}

private class Foo {

String userName;
Expand Down

This file was deleted.