#700 Fixing enum constants and adding unit test.

This commit is contained in:
sjaakd 2016-08-28 22:43:29 +02:00
parent 824fb993b5
commit a5a82cf5f1
13 changed files with 242 additions and 22 deletions

View File

@ -35,6 +35,7 @@ import javax.lang.model.type.DeclaredType;
import org.mapstruct.ap.internal.model.assignment.AdderWrapper;
import org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper;
import org.mapstruct.ap.internal.model.assignment.Assignment;
import org.mapstruct.ap.internal.model.assignment.EnumConstantWrapper;
import org.mapstruct.ap.internal.model.assignment.EnumSetCopyWrapper;
import org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps;
import org.mapstruct.ap.internal.model.assignment.NewCollectionOrMapWrapper;
@ -686,7 +687,9 @@ public class PropertyMapping extends ModelElement {
String mappedElement = "constant '" + constantExpression + "'";
Type sourceType = ctx.getTypeFactory().getType( String.class );
Assignment assignment = ctx.getMappingResolver().getTargetAssignment(
Assignment assignment = null;
if ( !targetType.isEnumType() ) {
assignment = ctx.getMappingResolver().getTargetAssignment(
method,
mappedElement,
sourceType,
@ -697,6 +700,10 @@ public class PropertyMapping extends ModelElement {
constantExpression,
method.getMappingTargetParameter() != null
);
}
else {
assignment = getEnumAssignment();
}
if ( assignment != null ) {
@ -751,6 +758,26 @@ public class PropertyMapping extends ModelElement {
null
);
}
private Assignment getEnumAssignment() {
Assignment assignment = null;
// String String quotation marks.
String enumExpression = constantExpression.substring( 1, constantExpression.length() - 1 );
if ( targetType.getEnumConstants().contains( enumExpression ) ) {
assignment = AssignmentFactory.createDirect( enumExpression );
assignment = new EnumConstantWrapper( assignment, targetType );
}
else {
ctx.getMessager().printMessage( method.getExecutable(),
Message.CONSTANTMAPPING_NON_EXISTING_CONSTANT,
constantExpression,
targetType,
targetPropertyName
);
}
return assignment;
}
}
public static class JavaExpressionMappingBuilder extends MappingBuilderBase<JavaExpressionMappingBuilder> {

View File

@ -0,0 +1,50 @@
/**
* Copyright 2012-2016 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.internal.model.assignment;
import java.util.HashSet;
import java.util.Set;
import org.mapstruct.ap.internal.model.common.Type;
/**
*
* @author Sjaak Derksen
*/
public class EnumConstantWrapper extends AssignmentWrapper {
private final Type enumType;
public EnumConstantWrapper(Assignment decoratedAssignment, Type enumType ) {
super( decoratedAssignment );
this.enumType = enumType;
}
@Override
public Set<Type> getImportTypes() {
Set<Type> imported = new HashSet<Type>( getAssignment().getImportTypes() );
imported.add( enumType );
return imported;
}
@Override
public String toString() {
return enumType.getName() + "." + getAssignment();
}
}

View File

@ -56,6 +56,7 @@ public enum Message {
CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map \"%s %s\" to \"%s %s\"." ),
CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ),
CONSTANTMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s for property \"%s\"." ),
MAPMAPPING_KEY_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source key type to target key type." ),
MAPMAPPING_VALUE_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source value type to target value type." ),

View File

@ -0,0 +1,21 @@
<#--
Copyright 2012-2016 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.
-->
${ext.targetType.name}.${assignment}

View File

@ -0,0 +1,28 @@
/**
* Copyright 2012-2016 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.source.constants;
/**
*
* @author Sjaak Derksen
*/
public enum CountryEnum {
GERMANY, THE_NETHERLANDS, BELGIUM;
}

View File

@ -37,7 +37,8 @@ public interface ErroneousMapper1 {
@Mapping(source = "test", target = "integerConstant", constant = "14"),
@Mapping(target = "longWrapperConstant", constant = "3001"),
@Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"),
@Mapping(target = "nameConstants", constant = "jack-jill-tom")
@Mapping(target = "nameConstants", constant = "jack-jill-tom"),
@Mapping(target = "country", constant = "THE_NETHERLANDS")
})
Target sourceToTarget(Source s);
}

View File

@ -36,7 +36,8 @@ public interface ErroneousMapper2 {
@Mapping(target = "integerConstant"),
@Mapping(target = "longWrapperConstant", constant = "3001"),
@Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"),
@Mapping(target = "nameConstants", constant = "jack-jill-tom")
@Mapping(target = "nameConstants", constant = "jack-jill-tom"),
@Mapping(target = "country", constant = "THE_NETHERLANDS")
})
Target sourceToTarget(Source s);
}

View File

@ -37,7 +37,8 @@ public interface ErroneousMapper3 {
@Mapping(target = "integerConstant", expression = "java('test')", constant = "14"),
@Mapping(target = "longWrapperConstant", constant = "3001"),
@Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"),
@Mapping(target = "nameConstants", constant = "jack-jill-tom")
@Mapping(target = "nameConstants", constant = "jack-jill-tom"),
@Mapping(target = "country", constant = "THE_NETHERLANDS")
})
Target sourceToTarget(Source s);
}

View File

@ -37,7 +37,8 @@ public interface ErroneousMapper4 {
@Mapping(source = "test", target = "integerConstant", expression = "java('test')"),
@Mapping(target = "longWrapperConstant", constant = "3001"),
@Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"),
@Mapping(target = "nameConstants", constant = "jack-jill-tom")
@Mapping(target = "nameConstants", constant = "jack-jill-tom"),
@Mapping(target = "country", constant = "THE_NETHERLANDS")
})
Target sourceToTarget(Source s);
}

View File

@ -0,0 +1,46 @@
/**
* Copyright 2012-2016 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.source.constants;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
/**
* @author Sjaak Derksen
*/
@Mapper(uses = StringListMapper.class)
public interface ErroneousMapper5 {
ErroneousMapper5 INSTANCE = Mappers.getMapper( ErroneousMapper5.class );
@Mappings({
@Mapping(target = "stringConstant", constant = "stringConstant"),
@Mapping(target = "emptyStringConstant", constant = ""),
@Mapping(target = "integerConstant", constant = "14"),
@Mapping(target = "longWrapperConstant", constant = "3001"),
@Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"),
@Mapping(target = "nameConstants", constant = "jack-jill-tom"),
@Mapping(target = "country", constant = "DENMARK")
})
Target sourceToTarget(Source s);
Source targetToSource(Target t);
}

View File

@ -49,6 +49,7 @@ public class SourceConstantsTest {
Source.class,
Source2.class,
Target.class,
CountryEnum.class,
SourceTargetMapper.class,
StringListMapper.class
})
@ -66,6 +67,7 @@ public class SourceConstantsTest {
assertThat( target.getLongWrapperConstant() ).isEqualTo( new Long( 3001L ) );
assertThat( target.getDateConstant() ).isEqualTo( getDate( "dd-MM-yyyy", "09-01-2014" ) );
assertThat( target.getNameConstants() ).isEqualTo( Arrays.asList( "jack", "jill", "tom" ) );
assertThat( target.getCountry() ).isEqualTo( CountryEnum.THE_NETHERLANDS );
}
@Test
@ -73,6 +75,7 @@ public class SourceConstantsTest {
@WithClasses({
Source.class,
Target.class,
CountryEnum.class,
SourceTargetMapper.class,
StringListMapper.class
})
@ -91,6 +94,7 @@ public class SourceConstantsTest {
@WithClasses({
Source.class,
Target.class,
CountryEnum.class,
ErroneousMapper1.class,
StringListMapper.class
})
@ -99,12 +103,12 @@ public class SourceConstantsTest {
diagnostics = {
@Diagnostic(type = ErroneousMapper1.class,
kind = Kind.ERROR,
line = 42,
line = 43,
messageRegExp = "Source and constant are both defined in @Mapping, either define a source or a "
+ "constant"),
@Diagnostic(type = ErroneousMapper1.class,
kind = Kind.WARNING,
line = 42,
line = 43,
messageRegExp = "Unmapped target property: \"integerConstant\"")
}
)
@ -116,6 +120,7 @@ public class SourceConstantsTest {
@WithClasses({
Source.class,
Target.class,
CountryEnum.class,
ErroneousMapper3.class,
StringListMapper.class
})
@ -124,13 +129,13 @@ public class SourceConstantsTest {
diagnostics = {
@Diagnostic(type = ErroneousMapper3.class,
kind = Kind.ERROR,
line = 42,
line = 43,
messageRegExp =
"Expression and constant are both defined in @Mapping, either define an expression or a "
+ "constant"),
@Diagnostic(type = ErroneousMapper3.class,
kind = Kind.WARNING,
line = 42,
line = 43,
messageRegExp = "Unmapped target property: \"integerConstant\"")
}
)
@ -142,6 +147,7 @@ public class SourceConstantsTest {
@WithClasses({
Source.class,
Target.class,
CountryEnum.class,
ErroneousMapper4.class,
StringListMapper.class
})
@ -150,12 +156,12 @@ public class SourceConstantsTest {
diagnostics = {
@Diagnostic(type = ErroneousMapper4.class,
kind = Kind.ERROR,
line = 42,
line = 43,
messageRegExp = "Source and expression are both defined in @Mapping, either define a source or an "
+ "expression"),
@Diagnostic(type = ErroneousMapper4.class,
kind = Kind.WARNING,
line = 42,
line = 43,
messageRegExp = "Unmapped target property: \"integerConstant\"")
}
)
@ -184,6 +190,33 @@ public class SourceConstantsTest {
assertThat( target.getSomeConstant() ).isEqualTo( "stringConstant" );
}
@Test
@IssueKey("700")
@WithClasses({
Source.class,
Target.class,
CountryEnum.class,
ErroneousMapper5.class,
StringListMapper.class
})
@ExpectedCompilationOutcome(
value = CompilationResult.FAILED,
diagnostics = {
@Diagnostic(type = ErroneousMapper5.class,
kind = Kind.ERROR,
line = 43,
messageRegExp = "^Constant \"DENMARK\" doesn't exist in enum type org.mapstruct.ap.test.source."
+ "constants.CountryEnum for property \"country\".$"),
@Diagnostic(type = ErroneousMapper5.class,
kind = Kind.ERROR,
line = 43,
messageRegExp = "^Can't map \"java.lang.String \"DENMARK\"\" to \"org.mapstruct.ap.test.source."
+ "constants.CountryEnum country\".$")
}
)
public void errorOnNonExistingEnumConstant() throws ParseException {
}
private Date getDate(String format, String date) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat( format );
Date result = dateFormat.parse( date );

View File

@ -37,7 +37,8 @@ public interface SourceTargetMapper {
@Mapping(target = "integerConstant", constant = "14"),
@Mapping(target = "longWrapperConstant", constant = "3001"),
@Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"),
@Mapping(target = "nameConstants", constant = "jack-jill-tom")
@Mapping(target = "nameConstants", constant = "jack-jill-tom"),
@Mapping(target = "country", constant = "THE_NETHERLANDS")
})
Target sourceToTarget(Source s);

View File

@ -34,6 +34,7 @@ public class Target {
private Long longWrapperConstant;
private Date dateConstant;
private List<String> nameConstants = new ArrayList<String>();
private CountryEnum country;
public String getPropertyThatShouldBeMapped() {
return propertyThatShouldBeMapped;
@ -87,4 +88,12 @@ public class Target {
this.emptyStringConstant = emptyStringConstant;
}
public CountryEnum getCountry() {
return country;
}
public void setCountry(CountryEnum country) {
this.country = country;
}
}