mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#122 Suggest property name in error message when referring to a non-existent property
This commit is contained in:
parent
9415bb0999
commit
5dd0097cc9
@ -164,7 +164,29 @@ public class SourceReference {
|
||||
Strings.join( Arrays.asList( sourcePropertyNames ), "." ) );
|
||||
}
|
||||
else {
|
||||
reportMappingError( Message.PROPERTYMAPPING_INVALID_PROPERTY_NAME, mapping.getSourceName() );
|
||||
int notFoundPropertyIndex;
|
||||
Type sourceType;
|
||||
if ( entries.isEmpty() ) {
|
||||
notFoundPropertyIndex = 0;
|
||||
sourceType = method.getParameters().get( 0 ).getType();
|
||||
}
|
||||
else {
|
||||
int lastFoundEntryIndex = entries.size() - 1;
|
||||
notFoundPropertyIndex = lastFoundEntryIndex + 1;
|
||||
sourceType = entries.get( lastFoundEntryIndex ).getType();
|
||||
}
|
||||
String mostSimilarWord = Strings.getMostSimilarWord(
|
||||
sourcePropertyNames[notFoundPropertyIndex],
|
||||
sourceType.getPropertyReadAccessors().keySet()
|
||||
);
|
||||
String prefix = "";
|
||||
for ( int i = 0; i < notFoundPropertyIndex; i++ ) {
|
||||
prefix += sourcePropertyNames[i] + ".";
|
||||
}
|
||||
reportMappingError(
|
||||
Message.PROPERTYMAPPING_INVALID_PROPERTY_NAME, mapping.getSourceName(),
|
||||
prefix + mostSimilarWord
|
||||
);
|
||||
}
|
||||
isValid = false;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ package org.mapstruct.ap.internal.model.source;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.lang.model.type.DeclaredType;
|
||||
|
||||
@ -32,6 +33,7 @@ import org.mapstruct.ap.internal.util.Executables;
|
||||
import org.mapstruct.ap.internal.util.FormattingMessager;
|
||||
import org.mapstruct.ap.internal.util.Message;
|
||||
|
||||
import org.mapstruct.ap.internal.util.Strings;
|
||||
import org.mapstruct.ap.internal.util.accessor.Accessor;
|
||||
|
||||
/**
|
||||
@ -95,7 +97,7 @@ public class TargetReference {
|
||||
* that multiple times because the first entry can also be the name of the parameter. Therefore we keep
|
||||
* the error message until the end when we can report it.
|
||||
*/
|
||||
private Message errorMessage;
|
||||
private MappingErrorMessage errorMessage;
|
||||
|
||||
public BuilderFromTargetMapping messager(FormattingMessager messager) {
|
||||
this.messager = messager;
|
||||
@ -159,7 +161,7 @@ public class TargetReference {
|
||||
|
||||
if ( !foundEntryMatch && errorMessage != null) {
|
||||
// This is called only for reporting errors
|
||||
reportMappingError( errorMessage, mapping.getTargetName() );
|
||||
errorMessage.report();
|
||||
}
|
||||
|
||||
// foundEntryMatch = isValid, errors are handled here, and the BeanMapping uses that to ignore
|
||||
@ -187,7 +189,7 @@ public class TargetReference {
|
||||
|| ( isNotLast && targetReadAccessor == null ) ) {
|
||||
// there should always be a write accessor (except for the last when the mapping is ignored and
|
||||
// there is a read accessor) and there should be read accessor mandatory for all but the last
|
||||
setErrorMessage( targetWriteAccessor, targetReadAccessor );
|
||||
setErrorMessage( targetWriteAccessor, targetReadAccessor, entryNames, i, nextType );
|
||||
break;
|
||||
}
|
||||
|
||||
@ -237,20 +239,16 @@ public class TargetReference {
|
||||
return nextType;
|
||||
}
|
||||
|
||||
private void setErrorMessage(Accessor targetWriteAccessor, Accessor targetReadAccessor) {
|
||||
private void setErrorMessage(Accessor targetWriteAccessor, Accessor targetReadAccessor, String[] entryNames,
|
||||
int index, Type nextType) {
|
||||
if ( targetWriteAccessor == null && targetReadAccessor == null ) {
|
||||
errorMessage = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE;
|
||||
errorMessage = new NoPropertyErrorMessage( mapping, method, messager, entryNames, index, nextType );
|
||||
}
|
||||
else if ( targetWriteAccessor == null ) {
|
||||
errorMessage = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE;
|
||||
errorMessage = new NoWriteAccessorErrorMessage( mapping, method, messager );
|
||||
}
|
||||
}
|
||||
|
||||
private void reportMappingError(Message msg, Object... objects) {
|
||||
messager.printMessage( method.getExecutable(), mapping.getMirror(), mapping.getSourceAnnotationValue(),
|
||||
msg, objects );
|
||||
}
|
||||
|
||||
/**
|
||||
* A write accessor is not valid if it is {@code null} and it is not last. i.e. for nested target mappings
|
||||
* there must be a write accessor for all entries except the last one.
|
||||
@ -354,4 +352,72 @@ public class TargetReference {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private abstract static class MappingErrorMessage {
|
||||
private final Mapping mapping;
|
||||
private final SourceMethod method;
|
||||
private final FormattingMessager messager;
|
||||
|
||||
private MappingErrorMessage(Mapping mapping, SourceMethod method, FormattingMessager messager) {
|
||||
this.mapping = mapping;
|
||||
this.method = method;
|
||||
this.messager = messager;
|
||||
}
|
||||
|
||||
abstract void report();
|
||||
|
||||
protected void printErrorMessage(Message message, Object... args) {
|
||||
Object[] errorArgs = new Object[args.length + 1];
|
||||
errorArgs[0] = mapping.getTargetName();
|
||||
System.arraycopy( args, 0, errorArgs, 1, args.length );
|
||||
messager.printMessage( method.getExecutable(), mapping.getMirror(), mapping.getSourceAnnotationValue(),
|
||||
message, errorArgs
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static class NoWriteAccessorErrorMessage extends MappingErrorMessage {
|
||||
|
||||
private NoWriteAccessorErrorMessage(Mapping mapping, SourceMethod method, FormattingMessager messager) {
|
||||
super( mapping, method, messager );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report() {
|
||||
printErrorMessage( Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE );
|
||||
}
|
||||
}
|
||||
|
||||
private static class NoPropertyErrorMessage extends MappingErrorMessage {
|
||||
|
||||
private final String[] entryNames;
|
||||
private final int index;
|
||||
private final Type nextType;
|
||||
|
||||
private NoPropertyErrorMessage(Mapping mapping, SourceMethod method, FormattingMessager messager,
|
||||
String[] entryNames, int index, Type nextType) {
|
||||
super( mapping, method, messager );
|
||||
this.entryNames = entryNames;
|
||||
this.index = index;
|
||||
this.nextType = nextType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report() {
|
||||
|
||||
Set<String> readAccessors = nextType.getPropertyReadAccessors().keySet();
|
||||
String mostSimilarProperty = Strings.getMostSimilarWord(
|
||||
entryNames[index],
|
||||
readAccessors
|
||||
);
|
||||
|
||||
String prefix = "";
|
||||
for ( int i = 0; i < index; i++ ) {
|
||||
prefix += entryNames[i] + ".";
|
||||
}
|
||||
|
||||
printErrorMessage( Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE, prefix + mostSimilarProperty );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public enum Message {
|
||||
BEANMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy', 'resultType' and 'qualifiedBy' are undefined in @BeanMapping, define at least one of them." ),
|
||||
BEANMAPPING_NOT_ASSIGNABLE( "%s not assignable to: %s." ),
|
||||
BEANMAPPING_ABSTRACT( "The result type %s may not be an abstract class nor interface." ),
|
||||
BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE( "Unknown property \"%s\" in return type." ),
|
||||
BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE( "Unknown property \"%s\" in return type. Did you mean \"%s\"?" ),
|
||||
BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE( "Property \"%s\" has no write accessor." ),
|
||||
BEANMAPPING_SEVERAL_POSSIBLE_SOURCES( "Several possible source properties for target property \"%s\"." ),
|
||||
BEANMAPPING_SEVERAL_POSSIBLE_TARGET_ACCESSORS( "Found several matching getters for property \"%s\"." ),
|
||||
@ -54,7 +54,7 @@ public enum Message {
|
||||
PROPERTYMAPPING_INVALID_EXPRESSION( "Value must be given in the form \"java(<EXPRESSION>)\"." ),
|
||||
PROPERTYMAPPING_INVALID_PARAMETER_NAME( "Method has no parameter named \"%s\"." ),
|
||||
PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER( "The type of parameter \"%s\" has no property named \"%s\"." ),
|
||||
PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s)." ),
|
||||
PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s). Did you mean \"%s\"?" ),
|
||||
PROPERTYMAPPING_NO_PRESENCE_CHECKER_FOR_SOURCE_TYPE( "Using custom source value presence checking strategy, but no presence checker found for %s in source type." ),
|
||||
PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
|
||||
PROPERTYMAPPING_NO_WRITE_ACCESSOR_FOR_TARGET_TYPE( "No write accessor found for property \"%s\" in target type." ),
|
||||
|
@ -199,4 +199,49 @@ public class Strings {
|
||||
static Iterable<String> extractParts(String name) {
|
||||
return Arrays.asList( name.split( "\\." ) );
|
||||
}
|
||||
|
||||
public static String getMostSimilarWord(String word, Collection<String> similarWords) {
|
||||
int minLevenstein = Integer.MAX_VALUE;
|
||||
String mostSimilarWord = null;
|
||||
for ( String similarWord : similarWords ) {
|
||||
int levensteinDistance = levenshteinDistance( similarWord, word );
|
||||
if ( levensteinDistance < minLevenstein ) {
|
||||
minLevenstein = levensteinDistance;
|
||||
mostSimilarWord = similarWord;
|
||||
}
|
||||
}
|
||||
return mostSimilarWord;
|
||||
}
|
||||
|
||||
private static int levenshteinDistance(String s, String t) {
|
||||
int sLength = s.length() + 1;
|
||||
int tLength = t.length() + 1;
|
||||
|
||||
int[][] distances = new int[tLength][];
|
||||
for ( int i = 0; i < tLength; i++ ) {
|
||||
distances[i] = new int[sLength];
|
||||
}
|
||||
|
||||
for ( int i = 0; i < tLength; i++ ) {
|
||||
distances[i][0] = i;
|
||||
}
|
||||
for ( int i = 0; i < sLength; i++ ) {
|
||||
distances[0][i] = i;
|
||||
}
|
||||
|
||||
for ( int i = 1; i < tLength; i++ ) {
|
||||
for ( int j = 1; j < sLength; j++ ) {
|
||||
int cost = s.charAt( j - 1 ) == t.charAt( i - 1 ) ? 0 : 1;
|
||||
distances[i][j] = Math.min(
|
||||
Math.min(
|
||||
distances[i - 1][j] + 1,
|
||||
distances[i][j - 1] + 1
|
||||
),
|
||||
distances[i - 1][j - 1] + cost
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return distances[tLength - 1][sLength - 1];
|
||||
}
|
||||
}
|
||||
|
@ -102,4 +102,13 @@ public class StringsTest {
|
||||
assertThat( Strings.sanitizeIdentifierName( "int[]" ) ).isEqualTo( "intArray" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findMostSimilarWord() throws Exception {
|
||||
String mostSimilarWord = Strings.getMostSimilarWord(
|
||||
"fulName",
|
||||
Arrays.asList( "fullAge", "fullName", "address", "status" )
|
||||
);
|
||||
assertThat( mostSimilarWord ).isEqualTo( "fullName" );
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,7 +44,8 @@ public interface ErroneousIssue1029Mapper {
|
||||
*/
|
||||
@Mappings({
|
||||
@Mapping(target = "outdated", ignore = true),
|
||||
@Mapping(target = "computedMapping", ignore = true)
|
||||
@Mapping(target = "computedMapping", ignore = true),
|
||||
@Mapping(target = "knownProp", ignore = true)
|
||||
})
|
||||
Deck toDeckWithSomeIgnores(DeckForm form);
|
||||
|
||||
@ -71,6 +72,8 @@ public interface ErroneousIssue1029Mapper {
|
||||
|
||||
private LocalDateTime lastUpdated;
|
||||
|
||||
private String knownProp;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@ -79,6 +82,14 @@ public interface ErroneousIssue1029Mapper {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getKnownProp() {
|
||||
return knownProp;
|
||||
}
|
||||
|
||||
public void setKnownProp(String knownProp) {
|
||||
this.knownProp = knownProp;
|
||||
}
|
||||
|
||||
public LocalDateTime getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
|
@ -42,11 +42,11 @@ public class Issue1029Test {
|
||||
@Test
|
||||
@ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = {
|
||||
@Diagnostic(kind = Kind.WARNING, line = 39, type = ErroneousIssue1029Mapper.class,
|
||||
messageRegExp = "Unmapped target properties: \"lastUpdated, computedMapping\"\\."),
|
||||
@Diagnostic(kind = Kind.WARNING, line = 49, type = ErroneousIssue1029Mapper.class,
|
||||
messageRegExp = "Unmapped target properties: \"knownProp, lastUpdated, computedMapping\"\\."),
|
||||
@Diagnostic(kind = Kind.WARNING, line = 50, type = ErroneousIssue1029Mapper.class,
|
||||
messageRegExp = "Unmapped target property: \"lastUpdated\"\\."),
|
||||
@Diagnostic(kind = Kind.ERROR, line = 54, type = ErroneousIssue1029Mapper.class,
|
||||
messageRegExp = "Unknown property \"unknownProp\" in return type\\.")
|
||||
@Diagnostic(kind = Kind.ERROR, line = 55, type = ErroneousIssue1029Mapper.class,
|
||||
messageRegExp = "Unknown property \"unknownProp\" in return type\\. Did you mean \"knownProp\"?")
|
||||
})
|
||||
public void reportsProperWarningsAndError() {
|
||||
}
|
||||
|
@ -48,7 +48,8 @@ public class Issue1153Test {
|
||||
@Diagnostic(type = ErroneousIssue1153Mapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 36,
|
||||
messageRegExp = "Unknown property \"nestedTarget2.writable2\" in return type\\.")
|
||||
messageRegExp = "Unknown property \"nestedTarget2.writable2\" in return type\\. " +
|
||||
"Did you mean \"nestedTarget2\\.writable\"")
|
||||
})
|
||||
@Test
|
||||
public void shouldReportErrorsCorrectly() {
|
||||
|
@ -47,15 +47,17 @@ public class ErroneousMappingsTest {
|
||||
@Diagnostic(type = ErroneousMapper.class,
|
||||
kind = Kind.ERROR,
|
||||
line = 29,
|
||||
messageRegExp = "No property named \"bar\" exists in source parameter\\(s\\)"),
|
||||
messageRegExp = "No property named \"bar\" exists in source parameter\\(s\\)\\. " +
|
||||
"Did you mean \"foo\"?"),
|
||||
@Diagnostic(type = ErroneousMapper.class,
|
||||
kind = Kind.ERROR,
|
||||
line = 30,
|
||||
messageRegExp = "No property named \"source1.foo\" exists in source parameter\\(s\\)"),
|
||||
messageRegExp = "No property named \"source1.foo\" exists in source parameter\\(s\\)\\. " +
|
||||
"Did you mean \"foo\"?"),
|
||||
@Diagnostic(type = ErroneousMapper.class,
|
||||
kind = Kind.ERROR,
|
||||
line = 31,
|
||||
messageRegExp = "Unknown property \"bar\" in return type"),
|
||||
messageRegExp = "Unknown property \"bar\" in return type. Did you mean \"foo\"?"),
|
||||
@Diagnostic(type = ErroneousMapper.class,
|
||||
kind = Kind.ERROR,
|
||||
line = 33,
|
||||
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
public class ColorRgb {
|
||||
|
||||
private String rgb;
|
||||
|
||||
public String getRgb() {
|
||||
return rgb;
|
||||
}
|
||||
|
||||
public void setRgb(String rgb) {
|
||||
this.rgb = rgb;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
public class ColorRgbDto {
|
||||
|
||||
private String rgb;
|
||||
|
||||
public String getRgb() {
|
||||
return rgb;
|
||||
}
|
||||
|
||||
public void setRgb(String rgb) {
|
||||
this.rgb = rgb;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
public class Garage {
|
||||
|
||||
private ColorRgb color;
|
||||
|
||||
public ColorRgb getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(ColorRgb color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
public class GarageDto {
|
||||
|
||||
private ColorRgbDto color;
|
||||
|
||||
public ColorRgbDto getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(ColorRgbDto color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
public class Person {
|
||||
|
||||
private String fullName;
|
||||
|
||||
private int fullAge;
|
||||
|
||||
private Garage garage;
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public int getFullAge() {
|
||||
return fullAge;
|
||||
}
|
||||
|
||||
public void setFullAge(int fullAge) {
|
||||
this.fullAge = fullAge;
|
||||
}
|
||||
|
||||
public Garage getGarage() {
|
||||
return garage;
|
||||
}
|
||||
|
||||
public void setGarage(Garage garage) {
|
||||
this.garage = garage;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
public class PersonDto {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private GarageDto garage;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public GarageDto getGarage() {
|
||||
return garage;
|
||||
}
|
||||
|
||||
public void setGarage(GarageDto garage) {
|
||||
this.garage = garage;
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mapstruct.ap.test.namesuggestion.erroneous.PersonAgeMapper;
|
||||
import org.mapstruct.ap.test.namesuggestion.erroneous.PersonGarageWrongSourceMapper;
|
||||
import org.mapstruct.ap.test.namesuggestion.erroneous.PersonGarageWrongTargetMapper;
|
||||
import org.mapstruct.ap.test.namesuggestion.erroneous.PersonNameMapper;
|
||||
import org.mapstruct.ap.testutil.WithClasses;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic;
|
||||
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
|
||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||
|
||||
@RunWith(AnnotationProcessorTestRunner.class)
|
||||
@WithClasses({
|
||||
Person.class, PersonDto.class, Garage.class, GarageDto.class, ColorRgb.class, ColorRgbDto.class
|
||||
})
|
||||
public class SuggestMostSimilarNameTest {
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
PersonAgeMapper.class
|
||||
})
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic(type = PersonAgeMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 32,
|
||||
messageRegExp = ".*Did you mean \"age\"\\?")
|
||||
}
|
||||
)
|
||||
public void testAgeSuggestion() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
PersonNameMapper.class
|
||||
})
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic(type = PersonNameMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 32,
|
||||
messageRegExp = ".*Did you mean \"fullName\"\\?")
|
||||
}
|
||||
)
|
||||
public void testNameSuggestion() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
PersonGarageWrongTargetMapper.class
|
||||
})
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic(type = PersonGarageWrongTargetMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 32,
|
||||
messageRegExp = "Unknown property \"garage\\.colour\\.rgb\".*Did you mean \"garage\\.color\"\\?"),
|
||||
@Diagnostic(type = PersonGarageWrongTargetMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 35,
|
||||
messageRegExp = "Unknown property \"garage\\.colour\".*Did you mean \"garage\\.color\"\\?")
|
||||
}
|
||||
)
|
||||
public void testGarageTargetSuggestion() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithClasses({
|
||||
PersonGarageWrongSourceMapper.class
|
||||
})
|
||||
@ExpectedCompilationOutcome(
|
||||
value = CompilationResult.FAILED,
|
||||
diagnostics = {
|
||||
@Diagnostic(type = PersonGarageWrongSourceMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 32,
|
||||
messageRegExp = "No property named \"garage\\.colour\\.rgb\".*Did you mean \"garage\\.color\"\\?"),
|
||||
@Diagnostic(type = PersonGarageWrongSourceMapper.class,
|
||||
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||
line = 35,
|
||||
messageRegExp = "No property named \"garage\\.colour\".*Did you mean \"garage\\.color\"\\?")
|
||||
}
|
||||
)
|
||||
public void testGarageSourceSuggestion() {
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion.erroneous;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ap.test.namesuggestion.Person;
|
||||
import org.mapstruct.ap.test.namesuggestion.PersonDto;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface PersonAgeMapper {
|
||||
|
||||
PersonAgeMapper MAPPER = Mappers.getMapper( PersonAgeMapper.class );
|
||||
|
||||
@Mapping(source = "agee", target = "fullAge")
|
||||
Person mapPerson(PersonDto dto);
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion.erroneous;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ap.test.namesuggestion.Person;
|
||||
import org.mapstruct.ap.test.namesuggestion.PersonDto;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface PersonGarageWrongSourceMapper {
|
||||
|
||||
PersonGarageWrongSourceMapper MAPPER = Mappers.getMapper( PersonGarageWrongSourceMapper.class );
|
||||
|
||||
@Mapping(source = "garage.colour.rgb", target = "garage.color.rgb")
|
||||
Person mapPerson(PersonDto dto);
|
||||
|
||||
@Mapping(source = "garage.colour", target = "garage.color")
|
||||
Person mapPersonGarage(PersonDto dto);
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion.erroneous;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ap.test.namesuggestion.Person;
|
||||
import org.mapstruct.ap.test.namesuggestion.PersonDto;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface PersonGarageWrongTargetMapper {
|
||||
|
||||
PersonGarageWrongTargetMapper MAPPER = Mappers.getMapper( PersonGarageWrongTargetMapper.class );
|
||||
|
||||
@Mapping(source = "garage.color.rgb", target = "garage.colour.rgb")
|
||||
Person mapPerson(PersonDto dto);
|
||||
|
||||
@Mapping(source = "garage.color", target = "garage.colour")
|
||||
Person mapPersonGarage(PersonDto dto);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/)
|
||||
* and/or other contributors as indicated by the @authors tag. See the
|
||||
* copyright.txt file in the distribution for a full listing of all
|
||||
* contributors.
|
||||
*
|
||||
* 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 org.mapstruct.ap.test.namesuggestion.erroneous;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.ap.test.namesuggestion.Person;
|
||||
import org.mapstruct.ap.test.namesuggestion.PersonDto;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
@Mapper
|
||||
public interface PersonNameMapper {
|
||||
|
||||
PersonNameMapper MAPPER = Mappers.getMapper( PersonNameMapper.class );
|
||||
|
||||
@Mapping(source = "name", target = "fulName")
|
||||
Person mapPerson(PersonDto dto);
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user