mirror of
https://github.com/mapstruct/mapstruct.git
synced 2025-07-12 00:00:08 +08:00
#2339 Support throwing an exception as an Enum Mapping option
This commit is contained in:
parent
228660c74f
commit
c4135e68ed
@ -36,6 +36,14 @@ public final class MappingConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String ANY_UNMAPPED = "<ANY_UNMAPPED>";
|
public static final String ANY_UNMAPPED = "<ANY_UNMAPPED>";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In an {@link ValueMapping} this represents any target that will be mapped to an
|
||||||
|
* {@link java.lang.IllegalArgumentException} which will be thrown at runtime.
|
||||||
|
* <p>
|
||||||
|
* NOTE: The value is only applicable to {@link ValueMapping#target()} and not to {@link ValueMapping#source()}.
|
||||||
|
*/
|
||||||
|
public static final String THROW_EXCEPTION = "<THROW_EXCEPTION>";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In an {@link EnumMapping} this represent the enum transformation strategy that adds a suffix to the source enum.
|
* In an {@link EnumMapping} this represent the enum transformation strategy that adds a suffix to the source enum.
|
||||||
*
|
*
|
||||||
|
@ -23,7 +23,8 @@ import java.lang.annotation.Target;
|
|||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>
|
* <code>
|
||||||
* public enum OrderType { RETAIL, B2B, EXTRA, STANDARD, NORMAL }
|
*
|
||||||
|
* public enum OrderType { RETAIL, B2B, C2C, EXTRA, STANDARD, NORMAL }
|
||||||
*
|
*
|
||||||
* public enum ExternalOrderType { RETAIL, B2B, SPECIAL, DEFAULT }
|
* public enum ExternalOrderType { RETAIL, B2B, SPECIAL, DEFAULT }
|
||||||
*
|
*
|
||||||
@ -45,13 +46,12 @@ import java.lang.annotation.Target;
|
|||||||
* +---------------------+----------------------------+
|
* +---------------------+----------------------------+
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* MapStruct will <B>WARN</B> on incomplete mappings. However, if for some reason no match is found an
|
|
||||||
* {@link java.lang.IllegalStateException} will be thrown.
|
|
||||||
* <p>
|
* <p>
|
||||||
* <B>Example 2:</B>
|
* <B>Example 2:</B>
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* <code>
|
* <code>
|
||||||
|
*
|
||||||
* @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ),
|
* @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ),
|
||||||
* @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ),
|
* @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ),
|
||||||
* @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" )
|
* @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" )
|
||||||
@ -70,6 +70,26 @@ import java.lang.annotation.Target;
|
|||||||
* +---------------------+----------------------------+
|
* +---------------------+----------------------------+
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
|
* <p>
|
||||||
|
* <B>Example 3:</B>
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <p></p>MapStruct will <B>WARN</B> on incomplete mappings. However, if for some reason no match is found, an
|
||||||
|
* {@link java.lang.IllegalStateException} will be thrown. This compile-time error can be avoided by
|
||||||
|
* using {@link MappingConstants#THROW_EXCEPTION} for {@link ValueMapping#target()}. It will result an
|
||||||
|
* {@link java.lang.IllegalArgumentException} at runtime.
|
||||||
|
* <pre>
|
||||||
|
* <code>
|
||||||
|
*
|
||||||
|
* @ValueMapping( source = "STANDARD", target = "DEFAULT" ),
|
||||||
|
* @ValueMapping( source = "C2C", target = MappingConstants.THROW_EXCEPTION )
|
||||||
|
* ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
|
||||||
|
* </code>
|
||||||
|
* Mapping result:
|
||||||
|
* {@link java.lang.IllegalArgumentException} with the error message:
|
||||||
|
* Unexpected enum constant: C2C
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
* @author Sjaak Derksen
|
* @author Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
@Repeatable(ValueMappings.class)
|
@Repeatable(ValueMappings.class)
|
||||||
@ -104,6 +124,7 @@ public @interface ValueMapping {
|
|||||||
* <ol>
|
* <ol>
|
||||||
* <li>enum constant name</li>
|
* <li>enum constant name</li>
|
||||||
* <li>{@link MappingConstants#NULL}</li>
|
* <li>{@link MappingConstants#NULL}</li>
|
||||||
|
* <li>{@link MappingConstants#THROW_EXCEPTION}</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* @return The target value.
|
* @return The target value.
|
||||||
|
@ -21,6 +21,8 @@ public final class MappingConstantsGem {
|
|||||||
|
|
||||||
public static final String ANY_UNMAPPED = "<ANY_UNMAPPED>";
|
public static final String ANY_UNMAPPED = "<ANY_UNMAPPED>";
|
||||||
|
|
||||||
|
public static final String THROW_EXCEPTION = "<THROW_EXCEPTION>";
|
||||||
|
|
||||||
public static final String SUFFIX_TRANSFORMATION = "suffix";
|
public static final String SUFFIX_TRANSFORMATION = "suffix";
|
||||||
|
|
||||||
public static final String STRIP_SUFFIX_TRANSFORMATION = "stripSuffix";
|
public static final String STRIP_SUFFIX_TRANSFORMATION = "stripSuffix";
|
||||||
|
@ -14,7 +14,6 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.lang.model.element.TypeElement;
|
import javax.lang.model.element.TypeElement;
|
||||||
import javax.lang.model.type.TypeMirror;
|
import javax.lang.model.type.TypeMirror;
|
||||||
import org.mapstruct.ap.internal.util.TypeUtils;
|
|
||||||
|
|
||||||
import org.mapstruct.ap.internal.gem.BeanMappingGem;
|
import org.mapstruct.ap.internal.gem.BeanMappingGem;
|
||||||
import org.mapstruct.ap.internal.model.common.Parameter;
|
import org.mapstruct.ap.internal.model.common.Parameter;
|
||||||
@ -25,11 +24,13 @@ import org.mapstruct.ap.internal.model.source.SelectionParameters;
|
|||||||
import org.mapstruct.ap.internal.model.source.ValueMappingOptions;
|
import org.mapstruct.ap.internal.model.source.ValueMappingOptions;
|
||||||
import org.mapstruct.ap.internal.util.Message;
|
import org.mapstruct.ap.internal.util.Message;
|
||||||
import org.mapstruct.ap.internal.util.Strings;
|
import org.mapstruct.ap.internal.util.Strings;
|
||||||
|
import org.mapstruct.ap.internal.util.TypeUtils;
|
||||||
import org.mapstruct.ap.spi.EnumTransformationStrategy;
|
import org.mapstruct.ap.spi.EnumTransformationStrategy;
|
||||||
|
|
||||||
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_REMAINING;
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_REMAINING;
|
||||||
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_UNMAPPED;
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_UNMAPPED;
|
||||||
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.NULL;
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.NULL;
|
||||||
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.THROW_EXCEPTION;
|
||||||
import static org.mapstruct.ap.internal.util.Collections.first;
|
import static org.mapstruct.ap.internal.util.Collections.first;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,6 +44,8 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
private final List<MappingEntry> valueMappings;
|
private final List<MappingEntry> valueMappings;
|
||||||
private final String defaultTarget;
|
private final String defaultTarget;
|
||||||
private final String nullTarget;
|
private final String nullTarget;
|
||||||
|
private boolean nullAsException;
|
||||||
|
private boolean defaultAsException;
|
||||||
|
|
||||||
private final Type unexpectedValueMappingException;
|
private final Type unexpectedValueMappingException;
|
||||||
|
|
||||||
@ -119,10 +122,12 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
return new ValueMappingMethod( method,
|
return new ValueMappingMethod( method,
|
||||||
mappingEntries,
|
mappingEntries,
|
||||||
valueMappings.nullValueTarget,
|
valueMappings.nullValueTarget,
|
||||||
|
valueMappings.hasNullValueAsException,
|
||||||
valueMappings.defaultTargetValue,
|
valueMappings.defaultTargetValue,
|
||||||
determineUnexpectedValueMappingException(),
|
determineUnexpectedValueMappingException(),
|
||||||
beforeMappingMethods,
|
beforeMappingMethods,
|
||||||
afterMappingMethods
|
afterMappingMethods,
|
||||||
|
determineExceptionMappingForDefaultCase()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +318,17 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
for ( ValueMappingOptions mappedConstant : valueMappings.regularValueMappings ) {
|
for ( ValueMappingOptions mappedConstant : valueMappings.regularValueMappings ) {
|
||||||
|
|
||||||
if ( !sourceEnumConstants.contains( mappedConstant.getSource() ) ) {
|
if ( !enumMapping.isInverse() && THROW_EXCEPTION.equals( mappedConstant.getSource() ) ) {
|
||||||
|
ctx.getMessager().printMessage(
|
||||||
|
method.getExecutable(),
|
||||||
|
mappedConstant.getMirror(),
|
||||||
|
mappedConstant.getSourceAnnotationValue(),
|
||||||
|
Message.VALUEMAPPING_THROW_EXCEPTION_SOURCE
|
||||||
|
);
|
||||||
|
foundIncorrectMapping = true;
|
||||||
|
}
|
||||||
|
else if ( !sourceEnumConstants.contains( mappedConstant.getSource() ) ) {
|
||||||
|
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
mappedConstant.getMirror(),
|
mappedConstant.getMirror(),
|
||||||
@ -361,6 +376,7 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
for ( ValueMappingOptions mappedConstant : valueMappings.regularValueMappings ) {
|
for ( ValueMappingOptions mappedConstant : valueMappings.regularValueMappings ) {
|
||||||
if ( !NULL.equals( mappedConstant.getTarget() )
|
if ( !NULL.equals( mappedConstant.getTarget() )
|
||||||
|
&& !THROW_EXCEPTION.equals( mappedConstant.getTarget() )
|
||||||
&& !targetEnumConstants.contains( mappedConstant.getTarget() ) ) {
|
&& !targetEnumConstants.contains( mappedConstant.getTarget() ) ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
@ -374,7 +390,9 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( valueMappings.defaultTarget != null && !NULL.equals( valueMappings.defaultTarget.getTarget() )
|
if ( valueMappings.defaultTarget != null
|
||||||
|
&& !THROW_EXCEPTION.equals( valueMappings.defaultTarget.getTarget() )
|
||||||
|
&& !NULL.equals( valueMappings.defaultTarget.getTarget() )
|
||||||
&& !targetEnumConstants.contains( valueMappings.defaultTarget.getTarget() ) ) {
|
&& !targetEnumConstants.contains( valueMappings.defaultTarget.getTarget() ) ) {
|
||||||
ctx.getMessager().printMessage(
|
ctx.getMessager().printMessage(
|
||||||
method.getExecutable(),
|
method.getExecutable(),
|
||||||
@ -415,7 +433,9 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Type determineUnexpectedValueMappingException() {
|
private Type determineUnexpectedValueMappingException() {
|
||||||
if ( !valueMappings.hasDefaultValue ) {
|
boolean noDefaultValueForSwitchCase = !valueMappings.hasDefaultValue;
|
||||||
|
if ( noDefaultValueForSwitchCase || valueMappings.hasAtLeastOneExceptionValue
|
||||||
|
|| valueMappings.hasNullValueAsException ) {
|
||||||
TypeMirror unexpectedValueMappingException = enumMapping.getUnexpectedValueMappingException();
|
TypeMirror unexpectedValueMappingException = enumMapping.getUnexpectedValueMappingException();
|
||||||
if ( unexpectedValueMappingException != null ) {
|
if ( unexpectedValueMappingException != null ) {
|
||||||
return ctx.getTypeFactory().getType( unexpectedValueMappingException );
|
return ctx.getTypeFactory().getType( unexpectedValueMappingException );
|
||||||
@ -427,6 +447,15 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean determineExceptionMappingForDefaultCase() {
|
||||||
|
if ( valueMappings.hasDefaultValue ) {
|
||||||
|
return THROW_EXCEPTION.equals( valueMappings.defaultTargetValue );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class EnumTransformationStrategyInvoker {
|
private static class EnumTransformationStrategyInvoker {
|
||||||
@ -464,7 +493,8 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
boolean hasMapAnyUnmapped = false;
|
boolean hasMapAnyUnmapped = false;
|
||||||
boolean hasMapAnyRemaining = false;
|
boolean hasMapAnyRemaining = false;
|
||||||
boolean hasDefaultValue = false;
|
boolean hasDefaultValue = false;
|
||||||
boolean hasNullValue = false;
|
boolean hasNullValueAsException = false;
|
||||||
|
boolean hasAtLeastOneExceptionValue = false;
|
||||||
|
|
||||||
ValueMappings(List<ValueMappingOptions> valueMappings) {
|
ValueMappings(List<ValueMappingOptions> valueMappings) {
|
||||||
|
|
||||||
@ -484,11 +514,17 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
else if ( NULL.equals( valueMapping.getSource() ) ) {
|
else if ( NULL.equals( valueMapping.getSource() ) ) {
|
||||||
nullTarget = valueMapping;
|
nullTarget = valueMapping;
|
||||||
nullValueTarget = getValue( nullTarget );
|
nullValueTarget = getValue( nullTarget );
|
||||||
hasNullValue = true;
|
if ( THROW_EXCEPTION.equals( nullValueTarget ) ) {
|
||||||
|
hasNullValueAsException = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
regularValueMappings.add( valueMapping );
|
regularValueMappings.add( valueMapping );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( THROW_EXCEPTION.equals( valueMapping.getTarget() ) ) {
|
||||||
|
hasAtLeastOneExceptionValue = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,14 +533,20 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueMappingMethod(Method method, List<MappingEntry> enumMappings, String nullTarget, String defaultTarget,
|
private ValueMappingMethod(Method method,
|
||||||
|
List<MappingEntry> enumMappings,
|
||||||
|
String nullTarget,
|
||||||
|
boolean hasNullTargetAsException,
|
||||||
|
String defaultTarget,
|
||||||
Type unexpectedValueMappingException,
|
Type unexpectedValueMappingException,
|
||||||
List<LifecycleCallbackMethodReference> beforeMappingMethods,
|
List<LifecycleCallbackMethodReference> beforeMappingMethods,
|
||||||
List<LifecycleCallbackMethodReference> afterMappingMethods) {
|
List<LifecycleCallbackMethodReference> afterMappingMethods, boolean defaultAsException) {
|
||||||
super( method, beforeMappingMethods, afterMappingMethods );
|
super( method, beforeMappingMethods, afterMappingMethods );
|
||||||
this.valueMappings = enumMappings;
|
this.valueMappings = enumMappings;
|
||||||
this.nullTarget = nullTarget;
|
this.nullTarget = nullTarget;
|
||||||
|
this.nullAsException = hasNullTargetAsException;
|
||||||
this.defaultTarget = defaultTarget;
|
this.defaultTarget = defaultTarget;
|
||||||
|
this.defaultAsException = defaultAsException;
|
||||||
this.unexpectedValueMappingException = unexpectedValueMappingException;
|
this.unexpectedValueMappingException = unexpectedValueMappingException;
|
||||||
this.overridden = method.overridesMethod();
|
this.overridden = method.overridesMethod();
|
||||||
}
|
}
|
||||||
@ -532,10 +574,18 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
return nullTarget;
|
return nullTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNullAsException() {
|
||||||
|
return nullAsException;
|
||||||
|
}
|
||||||
|
|
||||||
public Type getUnexpectedValueMappingException() {
|
public Type getUnexpectedValueMappingException() {
|
||||||
return unexpectedValueMappingException;
|
return unexpectedValueMappingException;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDefaultAsException() {
|
||||||
|
return defaultAsException;
|
||||||
|
}
|
||||||
|
|
||||||
public Parameter getSourceParameter() {
|
public Parameter getSourceParameter() {
|
||||||
return first( getSourceParameters() );
|
return first( getSourceParameters() );
|
||||||
}
|
}
|
||||||
@ -547,17 +597,25 @@ public class ValueMappingMethod extends MappingMethod {
|
|||||||
public static class MappingEntry {
|
public static class MappingEntry {
|
||||||
private final String source;
|
private final String source;
|
||||||
private final String target;
|
private final String target;
|
||||||
|
private boolean targetAsException = false;
|
||||||
|
|
||||||
MappingEntry(String source, String target) {
|
MappingEntry(String source, String target) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
if ( !NULL.equals( target ) ) {
|
if ( !NULL.equals( target ) ) {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
|
if ( THROW_EXCEPTION.equals( target ) ) {
|
||||||
|
this.targetAsException = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.target = null;
|
this.target = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTargetAsException() {
|
||||||
|
return targetAsException;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSource() {
|
public String getSource() {
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import org.mapstruct.ap.internal.util.Message;
|
|||||||
|
|
||||||
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_REMAINING;
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_REMAINING;
|
||||||
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_UNMAPPED;
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_UNMAPPED;
|
||||||
|
import static org.mapstruct.ap.internal.gem.MappingConstantsGem.THROW_EXCEPTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the mapping between one value constant and another.
|
* Represents the mapping between one value constant and another.
|
||||||
@ -112,7 +113,7 @@ public class ValueMappingOptions {
|
|||||||
|
|
||||||
public ValueMappingOptions inverse() {
|
public ValueMappingOptions inverse() {
|
||||||
ValueMappingOptions result;
|
ValueMappingOptions result;
|
||||||
if ( !(ANY_REMAINING.equals( source ) || ANY_UNMAPPED.equals( source ) ) ) {
|
if ( !(ANY_REMAINING.equals( source ) || ANY_UNMAPPED.equals( source ) || THROW_EXCEPTION.equals( target ) ) ) {
|
||||||
result = new ValueMappingOptions(
|
result = new ValueMappingOptions(
|
||||||
target,
|
target,
|
||||||
source,
|
source,
|
||||||
|
@ -175,7 +175,8 @@ public enum Message {
|
|||||||
VALUEMAPPING_ANY_REMAINING_FOR_NON_ENUM( "Source = \"<ANY_REMAINING>\" can only be used on targets of type enum and not for %s." ),
|
VALUEMAPPING_ANY_REMAINING_FOR_NON_ENUM( "Source = \"<ANY_REMAINING>\" can only be used on targets of type enum and not for %s." ),
|
||||||
VALUEMAPPING_ANY_REMAINING_OR_UNMAPPED_MISSING( "Source = \"<ANY_REMAINING>\" or \"<ANY_UNMAPPED>\" is advisable for mapping of type String to an enum type.", Diagnostic.Kind.WARNING ),
|
VALUEMAPPING_ANY_REMAINING_OR_UNMAPPED_MISSING( "Source = \"<ANY_REMAINING>\" or \"<ANY_UNMAPPED>\" is advisable for mapping of type String to an enum type.", Diagnostic.Kind.WARNING ),
|
||||||
VALUEMAPPING_NON_EXISTING_CONSTANT_FROM_SPI( "Constant %s doesn't exist in enum type %s. Constant was returned from EnumMappingStrategy: %s"),
|
VALUEMAPPING_NON_EXISTING_CONSTANT_FROM_SPI( "Constant %s doesn't exist in enum type %s. Constant was returned from EnumMappingStrategy: %s"),
|
||||||
VALUEMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s." );
|
VALUEMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s." ),
|
||||||
|
VALUEMAPPING_THROW_EXCEPTION_SOURCE( "Source = \"<THROW_EXCEPTION>\" is not allowed. Target = \"<THROW_EXCEPTION>\" can only be used." );
|
||||||
// CHECKSTYLE:ON
|
// CHECKSTYLE:ON
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,17 +15,17 @@
|
|||||||
</#if>
|
</#if>
|
||||||
</#list>
|
</#list>
|
||||||
if ( ${sourceParameter.name} == null ) {
|
if ( ${sourceParameter.name} == null ) {
|
||||||
return <@writeTarget target=nullTarget/>;
|
<#if nullAsException >throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} );<#else>return <@writeTarget target=nullTarget/>;</#if>
|
||||||
}
|
}
|
||||||
|
|
||||||
<@includeModel object=resultType/> ${resultName};
|
<@includeModel object=resultType/> ${resultName};
|
||||||
|
|
||||||
switch ( ${sourceParameter.name} ) {
|
switch ( ${sourceParameter.name} ) {
|
||||||
<#list valueMappings as valueMapping>
|
<#list valueMappings as valueMapping>
|
||||||
case <@writeSource source=valueMapping.source/>: ${resultName} = <@writeTarget target=valueMapping.target/>;
|
case <@writeSource source=valueMapping.source/>: <#if valueMapping.targetAsException >throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} );<#else>${resultName} = <@writeTarget target=valueMapping.target/>;
|
||||||
break;
|
break;</#if>
|
||||||
</#list>
|
</#list>
|
||||||
default: <#if unexpectedValueMappingException??>throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} )<#else>${resultName} = <@writeTarget target=defaultTarget/></#if>;
|
default: <#if defaultAsException >throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} )<#else>${resultName} = <@writeTarget target=defaultTarget/></#if>;
|
||||||
}
|
}
|
||||||
<#list beforeMappingReferencesWithMappingTarget as callback>
|
<#list beforeMappingReferencesWithMappingTarget as callback>
|
||||||
<#if callback_index = 0>
|
<#if callback_index = 0>
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.value.enum2enum;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingConstants;
|
||||||
|
import org.mapstruct.Named;
|
||||||
|
import org.mapstruct.ValueMapping;
|
||||||
|
import org.mapstruct.ap.test.value.ExternalOrderType;
|
||||||
|
import org.mapstruct.ap.test.value.OrderType;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jude Niroshan
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface DefaultOrderThrowExceptionMapper {
|
||||||
|
DefaultOrderThrowExceptionMapper INSTANCE = Mappers.getMapper( DefaultOrderThrowExceptionMapper.class );
|
||||||
|
|
||||||
|
@Named("orderTypeToExternalOrderTypeAnyUnmappedToException")
|
||||||
|
@ValueMapping(source = MappingConstants.ANY_UNMAPPED, target = MappingConstants.THROW_EXCEPTION)
|
||||||
|
ExternalOrderType orderTypeToExternalOrderTypeAnyUnmappedToException(OrderType orderType);
|
||||||
|
}
|
@ -5,8 +5,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.mapstruct.ap.test.value.enum2enum;
|
package org.mapstruct.ap.test.value.enum2enum;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
|
|
||||||
import javax.tools.Diagnostic.Kind;
|
import javax.tools.Diagnostic.Kind;
|
||||||
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
@ -22,14 +20,18 @@ import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutco
|
|||||||
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
|
||||||
import org.mapstruct.ap.testutil.runner.GeneratedSource;
|
import org.mapstruct.ap.testutil.runner.GeneratedSource;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test for the generation and invocation of enum mapping methods.
|
* Test for the generation and invocation of enum mapping methods.
|
||||||
*
|
*
|
||||||
* @author Gunnar Morling, Sjaak Derksen
|
* @author Gunnar Morling, Sjaak Derksen
|
||||||
*/
|
*/
|
||||||
@IssueKey("128")
|
@IssueKey("128")
|
||||||
@WithClasses({ OrderMapper.class, SpecialOrderMapper.class, DefaultOrderMapper.class, OrderEntity.class,
|
@WithClasses({
|
||||||
OrderType.class, OrderDto.class, ExternalOrderType.class })
|
OrderMapper.class, SpecialOrderMapper.class, DefaultOrderMapper.class, OrderEntity.class,
|
||||||
|
OrderType.class, OrderDto.class, ExternalOrderType.class
|
||||||
|
})
|
||||||
@RunWith(AnnotationProcessorTestRunner.class)
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
public class EnumToEnumMappingTest {
|
public class EnumToEnumMappingTest {
|
||||||
|
|
||||||
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.value.enum2enum;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mapstruct.ap.test.value.ExternalOrderType;
|
||||||
|
import org.mapstruct.ap.test.value.OrderType;
|
||||||
|
import org.mapstruct.ap.testutil.IssueKey;
|
||||||
|
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;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jude Niroshan
|
||||||
|
*/
|
||||||
|
@IssueKey("2339")
|
||||||
|
@WithClasses({
|
||||||
|
OrderEntity.class,
|
||||||
|
OrderType.class, ExternalOrderType.class
|
||||||
|
})
|
||||||
|
@RunWith(AnnotationProcessorTestRunner.class)
|
||||||
|
public class EnumToEnumThrowExceptionMappingTest {
|
||||||
|
|
||||||
|
@IssueKey("2339")
|
||||||
|
@Test
|
||||||
|
@WithClasses(DefaultOrderThrowExceptionMapper.class)
|
||||||
|
public void shouldBeAbleToMapAnyUnmappedToThrowException() {
|
||||||
|
|
||||||
|
assertThatThrownBy( () ->
|
||||||
|
DefaultOrderThrowExceptionMapper.INSTANCE
|
||||||
|
.orderTypeToExternalOrderTypeAnyUnmappedToException( OrderType.EXTRA ) )
|
||||||
|
.isInstanceOf( IllegalArgumentException.class )
|
||||||
|
.hasMessage( "Unexpected enum constant: EXTRA" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@IssueKey("2339")
|
||||||
|
@Test
|
||||||
|
@WithClasses({ DefaultOrderThrowExceptionMapper.class, ErroneousOrderMapperThrowExceptionAsSourceType.class })
|
||||||
|
@ExpectedCompilationOutcome(
|
||||||
|
value = CompilationResult.FAILED,
|
||||||
|
diagnostics = {
|
||||||
|
@Diagnostic(type = ErroneousOrderMapperThrowExceptionAsSourceType.class,
|
||||||
|
kind = javax.tools.Diagnostic.Kind.ERROR,
|
||||||
|
line = 29,
|
||||||
|
message = "Source = \"<THROW_EXCEPTION>\" is not allowed. " +
|
||||||
|
"Target = \"<THROW_EXCEPTION>\" can only be used.")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
public void shouldRaiseErrorWhenThrowExceptionUsedAsSourceType() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@IssueKey("2339")
|
||||||
|
@Test
|
||||||
|
@WithClasses({OrderThrowExceptionMapper.class, OrderDto.class})
|
||||||
|
public void shouldIgnoreThrowExceptionWhenInverseValueMappings() {
|
||||||
|
|
||||||
|
OrderType target = OrderThrowExceptionMapper.INSTANCE.externalOrderTypeToOrderType( ExternalOrderType.B2B );
|
||||||
|
assertThat( target ).isEqualTo( OrderType.B2B );
|
||||||
|
}
|
||||||
|
|
||||||
|
@IssueKey("2339")
|
||||||
|
@Test
|
||||||
|
@WithClasses({SpecialThrowExceptionMapper.class, OrderDto.class})
|
||||||
|
public void shouldBeAbleToMapAnyRemainingToThrowException() {
|
||||||
|
|
||||||
|
assertThatThrownBy( () ->
|
||||||
|
SpecialThrowExceptionMapper.INSTANCE
|
||||||
|
.orderTypeToExternalOrderType( OrderType.EXTRA ) )
|
||||||
|
.isInstanceOf( IllegalArgumentException.class )
|
||||||
|
.hasMessage( "Unexpected enum constant: EXTRA" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@IssueKey("2339")
|
||||||
|
@Test
|
||||||
|
@WithClasses({SpecialThrowExceptionMapper.class, OrderDto.class})
|
||||||
|
public void shouldBeAbleToMapNullToThrowException() {
|
||||||
|
|
||||||
|
assertThatThrownBy( () ->
|
||||||
|
SpecialThrowExceptionMapper.INSTANCE
|
||||||
|
.anyRemainingToNullToException( null ) )
|
||||||
|
.isInstanceOf( IllegalArgumentException.class )
|
||||||
|
.hasMessage( "Unexpected enum constant: null" );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.value.enum2enum;
|
||||||
|
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.ValueMapping;
|
||||||
|
import org.mapstruct.ValueMappings;
|
||||||
|
import org.mapstruct.ap.test.value.ExternalOrderType;
|
||||||
|
import org.mapstruct.ap.test.value.OrderType;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jude Niroshan
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ErroneousOrderMapperThrowExceptionAsSourceType {
|
||||||
|
|
||||||
|
ErroneousOrderMapperThrowExceptionAsSourceType INSTANCE = Mappers.getMapper(
|
||||||
|
ErroneousOrderMapperThrowExceptionAsSourceType.class );
|
||||||
|
|
||||||
|
@ValueMappings({
|
||||||
|
@ValueMapping(source = "EXTRA", target = "SPECIAL"),
|
||||||
|
@ValueMapping(source = "STANDARD", target = "DEFAULT"),
|
||||||
|
@ValueMapping(source = "NORMAL", target = "DEFAULT"),
|
||||||
|
@ValueMapping(source = "<ANY_REMAINING>", target = "DEFAULT"),
|
||||||
|
@ValueMapping(source = "<THROW_EXCEPTION>", target = "DEFAULT")
|
||||||
|
})
|
||||||
|
ExternalOrderType orderTypeToExternalOrderTypeWithErroneousSourceMapping(OrderType orderType);
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.value.enum2enum;
|
||||||
|
|
||||||
|
import org.mapstruct.InheritInverseConfiguration;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.MappingConstants;
|
||||||
|
import org.mapstruct.ValueMapping;
|
||||||
|
import org.mapstruct.ValueMappings;
|
||||||
|
import org.mapstruct.ap.test.value.ExternalOrderType;
|
||||||
|
import org.mapstruct.ap.test.value.OrderType;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jude Niroshan
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface OrderThrowExceptionMapper {
|
||||||
|
OrderThrowExceptionMapper INSTANCE = Mappers.getMapper( OrderThrowExceptionMapper.class );
|
||||||
|
|
||||||
|
OrderDto orderEntityToDto(OrderEntity order);
|
||||||
|
|
||||||
|
@ValueMappings({
|
||||||
|
@ValueMapping(source = "EXTRA", target = "SPECIAL"),
|
||||||
|
@ValueMapping(source = "STANDARD", target = "DEFAULT"),
|
||||||
|
@ValueMapping(source = "NORMAL", target = MappingConstants.THROW_EXCEPTION)
|
||||||
|
})
|
||||||
|
ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
|
||||||
|
|
||||||
|
@InheritInverseConfiguration
|
||||||
|
OrderType externalOrderTypeToOrderType(ExternalOrderType orderType);
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright MapStruct Authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*/
|
||||||
|
package org.mapstruct.ap.test.value.enum2enum;
|
||||||
|
|
||||||
|
import org.mapstruct.InheritInverseConfiguration;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.MappingConstants;
|
||||||
|
import org.mapstruct.Named;
|
||||||
|
import org.mapstruct.ValueMapping;
|
||||||
|
import org.mapstruct.ValueMappings;
|
||||||
|
import org.mapstruct.ap.test.value.ExternalOrderType;
|
||||||
|
import org.mapstruct.ap.test.value.OrderType;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jude Niroshan
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface SpecialThrowExceptionMapper {
|
||||||
|
SpecialThrowExceptionMapper INSTANCE = Mappers.getMapper( SpecialThrowExceptionMapper.class );
|
||||||
|
|
||||||
|
@Mapping(target = "orderType", source = "orderType", qualifiedByName = "orderTypeToExternalOrderType")
|
||||||
|
OrderDto orderEntityToDto(OrderEntity order);
|
||||||
|
|
||||||
|
@Named("orderTypeToExternalOrderType")
|
||||||
|
@ValueMappings({
|
||||||
|
@ValueMapping(source = MappingConstants.NULL, target = "DEFAULT"),
|
||||||
|
@ValueMapping(source = "STANDARD", target = MappingConstants.NULL),
|
||||||
|
@ValueMapping(source = MappingConstants.ANY_REMAINING, target = MappingConstants.THROW_EXCEPTION)
|
||||||
|
})
|
||||||
|
ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
|
||||||
|
|
||||||
|
@InheritInverseConfiguration(name = "orderTypeToExternalOrderType")
|
||||||
|
@ValueMapping(target = "EXTRA", source = "SPECIAL")
|
||||||
|
OrderType externalOrderTypeToOrderType(ExternalOrderType orderType);
|
||||||
|
|
||||||
|
@ValueMappings({
|
||||||
|
@ValueMapping(source = MappingConstants.NULL, target = MappingConstants.THROW_EXCEPTION),
|
||||||
|
@ValueMapping(source = "STANDARD", target = MappingConstants.NULL),
|
||||||
|
@ValueMapping(source = MappingConstants.ANY_REMAINING, target = MappingConstants.NULL)
|
||||||
|
})
|
||||||
|
ExternalOrderType anyRemainingToNullToException(OrderType orderType);
|
||||||
|
}
|
@ -11,8 +11,8 @@ import org.mapstruct.ap.test.value.OrderType;
|
|||||||
|
|
||||||
@Generated(
|
@Generated(
|
||||||
value = "org.mapstruct.ap.MappingProcessor",
|
value = "org.mapstruct.ap.MappingProcessor",
|
||||||
date = "2017-02-20T21:25:45+0100",
|
date = "2021-02-19T21:20:19+0100",
|
||||||
comments = "version: , compiler: javac, environment: Java 1.8.0_112 (Oracle Corporation)"
|
comments = "version: , compiler: javac, environment: Java 1.8.0_191 (Oracle Corporation)"
|
||||||
)
|
)
|
||||||
public class SpecialOrderMapperImpl implements SpecialOrderMapper {
|
public class SpecialOrderMapperImpl implements SpecialOrderMapper {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user