diff --git a/core/src/main/java/org/mapstruct/EnumMapping.java b/core/src/main/java/org/mapstruct/EnumMapping.java
index c184448aa..2f908579e 100644
--- a/core/src/main/java/org/mapstruct/EnumMapping.java
+++ b/core/src/main/java/org/mapstruct/EnumMapping.java
@@ -111,7 +111,7 @@ public @interface EnumMapping {
*
* @return the name transformation strategy
*/
- String nameTransformationStrategy();
+ String nameTransformationStrategy() default "";
/**
* The configuration that should be passed on the appropriate name transformation strategy.
@@ -119,5 +119,26 @@ public @interface EnumMapping {
*
* @return the configuration to use
*/
- String configuration();
+ String configuration() default "";
+
+ /**
+ * Exception that should be thrown by the generated code if no mapping matches.
+ * If no exception is configured, the exception given via {@link MapperConfig#unexpectedValueMappingException()} or
+ * {@link Mapper#unexpectedValueMappingException()} will be used, using {@link IllegalArgumentException} by default.
+ *
+ *
+ * Note:
+ *
+ * -
+ * The defined exception should at least have a constructor with a {@link String} parameter.
+ *
+ * -
+ * If the defined exception is a checked exception then the enum mapping methods should have that exception
+ * in the throws clause.
+ *
+ *
+ *
+ * @return the exception that should be used in the generated code
+ */
+ Class extends Exception> unexpectedValueMappingException() default IllegalArgumentException.class;
}
diff --git a/core/src/main/java/org/mapstruct/Mapper.java b/core/src/main/java/org/mapstruct/Mapper.java
index ce8eebf1c..233907621 100644
--- a/core/src/main/java/org/mapstruct/Mapper.java
+++ b/core/src/main/java/org/mapstruct/Mapper.java
@@ -296,4 +296,27 @@ public @interface Mapper {
* @see org.mapstruct.control.MappingControl
*/
Class extends Annotation> mappingControl() default MappingControl.class;
+
+ /**
+ * Exception that should be thrown by the generated code if no mapping matches for enums.
+ * If no exception is configured, the exception given via {@link MapperConfig#unexpectedValueMappingException()}
+ * will be used, using {@link IllegalArgumentException} by default.
+ *
+ *
+ * Note:
+ *
+ * -
+ * The defined exception should at least have a constructor with a {@link String} parameter.
+ *
+ * -
+ * If the defined exception is a checked exception then the enum mapping methods should have that exception
+ * in the throws clause.
+ *
+ *
+ *
+ * @return the exception that should be used in the generated code
+ *
+ * @since 1.4
+ */
+ Class extends Exception> unexpectedValueMappingException() default IllegalArgumentException.class;
}
diff --git a/core/src/main/java/org/mapstruct/MapperConfig.java b/core/src/main/java/org/mapstruct/MapperConfig.java
index 24951fb34..d251ff379 100644
--- a/core/src/main/java/org/mapstruct/MapperConfig.java
+++ b/core/src/main/java/org/mapstruct/MapperConfig.java
@@ -273,5 +273,27 @@ public @interface MapperConfig {
*/
Class extends Annotation> mappingControl() default MappingControl.class;
+ /**
+ * Exception that should be thrown by the generated code if no mapping matches for enums.
+ * If no exception is configured, {@link IllegalArgumentException} will be used by default.
+ *
+ *
+ * Note:
+ *
+ * -
+ * The defined exception should at least have a constructor with a {@link String} parameter.
+ *
+ * -
+ * If the defined exception is a checked exception then the enum mapping methods should have that exception
+ * in the throws clause.
+ *
+ *
+ *
+ * @return the exception that should be used in the generated code
+ *
+ * @since 1.4
+ */
+ Class extends Exception> unexpectedValueMappingException() default IllegalArgumentException.class;
+
}
diff --git a/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc b/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc
index 54c33ed93..51fec968b 100644
--- a/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc
+++ b/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc
@@ -202,7 +202,7 @@ include::{processor-ap-main}/spi/NoOpBuilderProvider.java[tag=documentation]
[[custom-enum-naming-strategy]]
=== Custom Enum Naming Strategy
-MapStruct offers the possibility to override the `EnumNamingStrategy` via the Service Provider Interface (SPI).
+MapStruct offers the possibility to override the `EnumMappingStrategy` via the Service Provider Interface (SPI).
This can be used when you have certain enums that follow some conventions within your organization.
For example all enums which implement an interface named `CustomEnumMarker` are prefixed with `CUSTOM_`
and the default value for them when mapping from `null` is `UNSPECIFIED`
@@ -250,15 +250,15 @@ public interface CheeseTypeMapper {
----
====
-This can be achieved with implementing the SPI `org.mapstruct.ap.spi.EnumNamingStrategy` as in the following example.
-Here’s an implemented `org.mapstruct.ap.spi.EnumNamingStrategy`:
+This can be achieved with implementing the SPI `org.mapstruct.ap.spi.EnumMappingStrategy` as in the following example.
+Here’s an implemented `org.mapstruct.ap.spi.EnumMappingStrategy`:
.Custom enum naming strategy
====
[source, java, linenums]
[subs="verbatim,attributes"]
----
-public class CustomEnumNamingStrategy extends DefaultEnumNamingStrategy {
+public class CustomEnumMappingStrategy extends DefaultEnumMappingStrategy {
@Override
public String getDefaultNullEnumConstant(TypeElement enumType) {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java
index f5c5887d5..8da5cb508 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java
@@ -30,7 +30,7 @@ import org.mapstruct.ap.internal.option.Options;
import org.mapstruct.ap.internal.util.AccessorNamingUtils;
import org.mapstruct.ap.internal.util.FormattingMessager;
import org.mapstruct.ap.internal.util.Services;
-import org.mapstruct.ap.spi.EnumNamingStrategy;
+import org.mapstruct.ap.spi.EnumMappingStrategy;
import org.mapstruct.ap.spi.EnumTransformationStrategy;
import org.mapstruct.ap.spi.MappingExclusionProvider;
@@ -107,7 +107,7 @@ public class MappingBuilderContext {
private final Types typeUtils;
private final FormattingMessager messager;
private final AccessorNamingUtils accessorNaming;
- private final EnumNamingStrategy enumNamingStrategy;
+ private final EnumMappingStrategy enumMappingStrategy;
private final Map enumTransformationStrategies;
private final Options options;
private final TypeElement mapperTypeElement;
@@ -124,7 +124,7 @@ public class MappingBuilderContext {
Types typeUtils,
FormattingMessager messager,
AccessorNamingUtils accessorNaming,
- EnumNamingStrategy enumNamingStrategy,
+ EnumMappingStrategy enumMappingStrategy,
Map enumTransformationStrategies,
Options options,
MappingResolver mappingResolver,
@@ -136,7 +136,7 @@ public class MappingBuilderContext {
this.typeUtils = typeUtils;
this.messager = messager;
this.accessorNaming = accessorNaming;
- this.enumNamingStrategy = enumNamingStrategy;
+ this.enumMappingStrategy = enumMappingStrategy;
this.enumTransformationStrategies = enumTransformationStrategies;
this.options = options;
this.mappingResolver = mappingResolver;
@@ -191,8 +191,8 @@ public class MappingBuilderContext {
return accessorNaming;
}
- public EnumNamingStrategy getEnumNamingStrategy() {
- return enumNamingStrategy;
+ public EnumMappingStrategy getEnumMappingStrategy() {
+ return enumMappingStrategy;
}
public Map getEnumTransformationStrategies() {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java
index 72f8153c5..9c7272f2b 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java
@@ -43,7 +43,9 @@ public class ValueMappingMethod extends MappingMethod {
private final List valueMappings;
private final String defaultTarget;
private final String nullTarget;
- private final boolean throwIllegalArgumentException;
+
+ private final Type unexpectedValueMappingException;
+
private final boolean overridden;
public static class Builder {
@@ -90,7 +92,7 @@ public class ValueMappingMethod extends MappingMethod {
if ( targetType.isEnumType() && valueMappings.nullTarget == null ) {
// If null target is not set it means that the user has not explicitly defined a mapping for null
- valueMappings.nullValueTarget = ctx.getEnumNamingStrategy()
+ valueMappings.nullValueTarget = ctx.getEnumMappingStrategy()
.getDefaultNullEnumConstant( targetType.getTypeElement() );
}
@@ -118,14 +120,14 @@ public class ValueMappingMethod extends MappingMethod {
mappingEntries,
valueMappings.nullValueTarget,
valueMappings.defaultTargetValue,
- !valueMappings.hasDefaultValue,
+ determineUnexpectedValueMappingException(),
beforeMappingMethods,
afterMappingMethods
);
}
private void initializeEnumTransformationStrategy() {
- if ( !enumMapping.hasAnnotation() ) {
+ if ( !enumMapping.hasNameTransformationStrategy() ) {
enumTransformationInvoker = EnumTransformationStrategyInvoker.DEFAULT;
}
else {
@@ -290,7 +292,7 @@ public class ValueMappingMethod extends MappingMethod {
}
private String getEnumConstant(TypeElement typeElement, String enumConstant) {
- return ctx.getEnumNamingStrategy().getEnumConstant( typeElement, enumConstant );
+ return ctx.getEnumMappingStrategy().getEnumConstant( typeElement, enumConstant );
}
private SelectionParameters getSelectionParameters(Method method, Types typeUtils) {
@@ -408,12 +410,26 @@ public class ValueMappingMethod extends MappingMethod {
Message.VALUEMAPPING_NON_EXISTING_CONSTANT_FROM_SPI,
valueMappings.nullValueTarget,
method.getReturnType(),
- ctx.getEnumNamingStrategy()
+ ctx.getEnumMappingStrategy()
);
}
return !foundIncorrectMapping;
}
+
+ private Type determineUnexpectedValueMappingException() {
+ if ( !valueMappings.hasDefaultValue ) {
+ TypeMirror unexpectedValueMappingException = enumMapping.getUnexpectedValueMappingException();
+ if ( unexpectedValueMappingException != null ) {
+ return ctx.getTypeFactory().getType( unexpectedValueMappingException );
+ }
+
+ return ctx.getTypeFactory()
+ .getType( ctx.getEnumMappingStrategy().getUnexpectedValueMappingExceptionType() );
+ }
+
+ return null;
+ }
}
private static class EnumTransformationStrategyInvoker {
@@ -485,16 +501,28 @@ public class ValueMappingMethod extends MappingMethod {
}
private ValueMappingMethod(Method method, List enumMappings, String nullTarget, String defaultTarget,
- boolean throwIllegalArgumentException, List beforeMappingMethods,
+ Type unexpectedValueMappingException,
+ List beforeMappingMethods,
List afterMappingMethods) {
super( method, beforeMappingMethods, afterMappingMethods );
this.valueMappings = enumMappings;
this.nullTarget = nullTarget;
this.defaultTarget = defaultTarget;
- this.throwIllegalArgumentException = throwIllegalArgumentException;
+ this.unexpectedValueMappingException = unexpectedValueMappingException;
this.overridden = method.overridesMethod();
}
+ @Override
+ public Set getImportTypes() {
+ Set importTypes = super.getImportTypes();
+
+ if ( unexpectedValueMappingException != null && !unexpectedValueMappingException.isJavaLangType() ) {
+ importTypes.addAll( unexpectedValueMappingException.getImportTypes() );
+ }
+
+ return importTypes;
+ }
+
public List getValueMappings() {
return valueMappings;
}
@@ -507,8 +535,8 @@ public class ValueMappingMethod extends MappingMethod {
return nullTarget;
}
- public boolean isThrowIllegalArgumentException() {
- return throwIllegalArgumentException;
+ public Type getUnexpectedValueMappingException() {
+ return unexpectedValueMappingException;
}
public Parameter getSourceParameter() {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java
index 77911be2e..81f870e25 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java
@@ -8,6 +8,7 @@ package org.mapstruct.ap.internal.model.source;
import java.util.Collections;
import java.util.Set;
import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import org.mapstruct.ap.internal.option.Options;
@@ -127,6 +128,11 @@ public class DefaultOptions extends DelegatingOptions {
return MappingControl.fromTypeMirror( mapper.mappingControl().getDefaultValue(), elementUtils );
}
+ @Override
+ public TypeMirror getUnexpectedValueMappingException() {
+ return null;
+ }
+
@Override
public boolean hasAnnotation() {
return false;
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java
index 8bc6ab982..c45868198 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java
@@ -105,6 +105,10 @@ public abstract class DelegatingOptions {
return next.getMappingControl( elementUtils );
}
+ public TypeMirror getUnexpectedValueMappingException() {
+ return next.getUnexpectedValueMappingException();
+ }
+
DelegatingOptions next() {
return next;
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java
index 576474e68..86c415a4f 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java
@@ -7,6 +7,7 @@ package org.mapstruct.ap.internal.model.source;
import java.util.Map;
import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.internal.gem.EnumMappingGem;
import org.mapstruct.ap.internal.util.FormattingMessager;
@@ -14,6 +15,8 @@ import org.mapstruct.ap.internal.util.Strings;
import org.mapstruct.ap.spi.EnumTransformationStrategy;
import static org.mapstruct.ap.internal.util.Message.ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY;
+import static org.mapstruct.ap.internal.util.Message.ENUMMAPPING_MISSING_CONFIGURATION;
+import static org.mapstruct.ap.internal.util.Message.ENUMMAPPING_NO_ELEMENTS;
/**
* @author Filip Hrisafov
@@ -40,12 +43,25 @@ public class EnumMappingOptions extends DelegatingOptions {
return valid;
}
+ public boolean hasNameTransformationStrategy() {
+ return hasAnnotation() && Strings.isNotEmpty( getNameTransformationStrategy() );
+ }
+
public String getNameTransformationStrategy() {
- return enumMapping.nameTransformationStrategy().get();
+ return enumMapping.nameTransformationStrategy().getValue();
}
public String getNameTransformationConfiguration() {
- return enumMapping.configuration().get();
+ return enumMapping.configuration().getValue();
+ }
+
+ @Override
+ public TypeMirror getUnexpectedValueMappingException() {
+ if ( enumMapping != null && enumMapping.unexpectedValueMappingException().hasValue() ) {
+ return enumMapping.unexpectedValueMappingException().getValue();
+ }
+
+ return next().getUnexpectedValueMappingException();
}
public boolean isInverse() {
@@ -79,21 +95,47 @@ public class EnumMappingOptions extends DelegatingOptions {
Map enumTransformationStrategies, FormattingMessager messager) {
String strategy = gem.nameTransformationStrategy().getValue();
+ String configuration = gem.configuration().getValue();
- if ( !enumTransformationStrategies.containsKey( strategy ) ) {
- String registeredStrategies = Strings.join( enumTransformationStrategies.keySet(), ", " );
+ boolean isConsistent = false;
+
+ if ( Strings.isNotEmpty( strategy ) || Strings.isNotEmpty( configuration ) ) {
+ if ( !enumTransformationStrategies.containsKey( strategy ) ) {
+ String registeredStrategies = Strings.join( enumTransformationStrategies.keySet(), ", " );
+ messager.printMessage(
+ method,
+ gem.mirror(),
+ gem.nameTransformationStrategy().getAnnotationValue(),
+ ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY,
+ strategy,
+ registeredStrategies
+ );
+
+ return false;
+ }
+ else if ( Strings.isEmpty( configuration ) ) {
+ messager.printMessage(
+ method,
+ gem.mirror(),
+ gem.configuration().getAnnotationValue(),
+ ENUMMAPPING_MISSING_CONFIGURATION
+ );
+ return false;
+ }
+
+ isConsistent = true;
+ }
+
+ isConsistent = isConsistent || gem.unexpectedValueMappingException().hasValue();
+
+ if ( !isConsistent ) {
messager.printMessage(
method,
gem.mirror(),
- gem.nameTransformationStrategy().getAnnotationValue(),
- ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY,
- strategy,
- registeredStrategies
+ ENUMMAPPING_NO_ELEMENTS
);
-
- return false;
}
- return true;
+ return isConsistent;
}
}
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java
index ef25fda05..07f668e65 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java
@@ -7,6 +7,7 @@ package org.mapstruct.ap.internal.model.source;
import java.util.Set;
import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import org.mapstruct.ap.internal.gem.BuilderGem;
@@ -137,6 +138,13 @@ public class MapperConfigOptions extends DelegatingOptions {
next().getMappingControl( elementUtils );
}
+ @Override
+ public TypeMirror getUnexpectedValueMappingException() {
+ return mapperConfig.unexpectedValueMappingException().hasValue() ?
+ mapperConfig.unexpectedValueMappingException().get() :
+ next().getUnexpectedValueMappingException();
+ }
+
@Override
public boolean hasAnnotation() {
return mapperConfig != null;
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java
index 19b7d8f0b..b054c628a 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java
@@ -11,6 +11,7 @@ import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import org.mapstruct.ap.internal.option.Options;
@@ -167,6 +168,13 @@ public class MapperOptions extends DelegatingOptions {
next().getMappingControl( elementUtils );
}
+ @Override
+ public TypeMirror getUnexpectedValueMappingException() {
+ return mapper.unexpectedValueMappingException().hasValue() ?
+ mapper.unexpectedValueMappingException().get() :
+ next().getUnexpectedValueMappingException();
+ }
+
// @Mapper specific
public DeclaredType mapperConfigType() {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java
index f8f7eee5b..1514f4f5e 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java
@@ -26,7 +26,7 @@ import org.mapstruct.ap.internal.util.Message;
import org.mapstruct.ap.internal.util.RoundContext;
import org.mapstruct.ap.internal.util.workarounds.TypesDecorator;
import org.mapstruct.ap.internal.version.VersionInformation;
-import org.mapstruct.ap.spi.EnumNamingStrategy;
+import org.mapstruct.ap.spi.EnumMappingStrategy;
import org.mapstruct.ap.spi.EnumTransformationStrategy;
/**
@@ -101,8 +101,8 @@ public class DefaultModelElementProcessorContext implements ProcessorContext {
}
@Override
- public EnumNamingStrategy getEnumNamingStrategy() {
- return roundContext.getAnnotationProcessorContext().getEnumNamingStrategy();
+ public EnumMappingStrategy getEnumMappingStrategy() {
+ return roundContext.getAnnotationProcessorContext().getEnumMappingStrategy();
}
@Override
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java
index adb0b8f24..58c6f2513 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java
@@ -101,7 +101,7 @@ public class MapperCreationProcessor implements ModelElementProcessor {
Map getEnumTransformationStrategies();
- EnumNamingStrategy getEnumNamingStrategy();
+ EnumMappingStrategy getEnumMappingStrategy();
Options getOptions();
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java b/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java
index 4b70bd60a..86fb7e309 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java
@@ -24,8 +24,8 @@ import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor;
import org.mapstruct.ap.spi.BuilderProvider;
import org.mapstruct.ap.spi.DefaultAccessorNamingStrategy;
import org.mapstruct.ap.spi.DefaultBuilderProvider;
-import org.mapstruct.ap.spi.DefaultEnumNamingStrategy;
-import org.mapstruct.ap.spi.EnumNamingStrategy;
+import org.mapstruct.ap.spi.DefaultEnumMappingStrategy;
+import org.mapstruct.ap.spi.EnumMappingStrategy;
import org.mapstruct.ap.spi.EnumTransformationStrategy;
import org.mapstruct.ap.spi.FreeBuilderAccessorNamingStrategy;
import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy;
@@ -43,7 +43,7 @@ public class AnnotationProcessorContext implements MapStructProcessingEnvironmen
private BuilderProvider builderProvider;
private AccessorNamingStrategy accessorNamingStrategy;
- private EnumNamingStrategy enumNamingStrategy;
+ private EnumMappingStrategy enumMappingStrategy;
private boolean initialized;
private Map enumTransformationStrategies;
@@ -113,13 +113,13 @@ public class AnnotationProcessorContext implements MapStructProcessingEnvironmen
}
this.accessorNaming = new AccessorNamingUtils( this.accessorNamingStrategy );
- this.enumNamingStrategy = Services.get( EnumNamingStrategy.class, new DefaultEnumNamingStrategy() );
- this.enumNamingStrategy.init( this );
+ this.enumMappingStrategy = Services.get( EnumMappingStrategy.class, new DefaultEnumMappingStrategy() );
+ this.enumMappingStrategy.init( this );
if ( verbose ) {
messager.printMessage(
Diagnostic.Kind.NOTE,
"MapStruct: Using enum naming strategy: "
- + this.enumNamingStrategy.getClass().getCanonicalName()
+ + this.enumMappingStrategy.getClass().getCanonicalName()
);
}
@@ -250,9 +250,9 @@ public class AnnotationProcessorContext implements MapStructProcessingEnvironmen
return accessorNamingStrategy;
}
- public EnumNamingStrategy getEnumNamingStrategy() {
+ public EnumMappingStrategy getEnumMappingStrategy() {
initialize();
- return enumNamingStrategy;
+ return enumMappingStrategy;
}
public BuilderProvider getBuilderProvider() {
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java
index 6f0db248b..87d3a9abd 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java
@@ -105,6 +105,8 @@ public enum Message {
ENUMMAPPING_UNMAPPED_SOURCES( "The following constants from the source enum have no corresponding constant in the target enum and must be be mapped via adding additional mappings: %s." ),
ENUMMAPPING_REMOVED( "Mapping of Enums via @Mapping is removed. Please use @ValueMapping instead!" ),
ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY( "There is no registered EnumTransformationStrategy for '%s'. Registered strategies are: %s." ),
+ ENUMMAPPING_MISSING_CONFIGURATION( "Configuration has to be defined when strategy is defined." ),
+ ENUMMAPPING_NO_ELEMENTS( "'nameTransformationStrategy', 'configuration' and 'unexpectedValueMappingException' are undefined in @EnumMapping, define at least one of them." ),
LIFECYCLEMETHOD_AMBIGUOUS_PARAMETERS( "Lifecycle method has multiple matching parameters (e. g. same type), in this case please ensure to name the parameters in the lifecycle and mapping method identical. This lifecycle method will not be used for the mapping method '%s'.", Diagnostic.Kind.WARNING),
@@ -169,7 +171,7 @@ public enum Message {
VALUEMAPPING_UNMAPPED_SOURCES( "The following constants from the %s enum have no corresponding constant in the %s enum and must be be mapped via adding additional mappings: %s." ),
VALUEMAPPING_ANY_REMAINING_FOR_NON_ENUM( "Source = \"\" can only be used on targets of type enum and not for %s." ),
VALUEMAPPING_ANY_REMAINING_OR_UNMAPPED_MISSING( "Source = \"\" or \"\" 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 EnumNamingStrategy: %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." );
// CHECKSTYLE:ON
diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java
index 07049c17a..f1eca8815 100644
--- a/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java
+++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java
@@ -129,6 +129,10 @@ public class Strings {
return string == null || string.isEmpty();
}
+ public static boolean isNotEmpty(String string) {
+ return !isEmpty( string );
+ }
+
public static String getSafeVariableName(String name, String... existingVariableNames) {
return getSafeVariableName( name, Arrays.asList( existingVariableNames ) );
}
diff --git a/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumMappingStrategy.java
similarity index 68%
rename from processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumNamingStrategy.java
rename to processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumMappingStrategy.java
index a54df7bc0..62d6c3280 100644
--- a/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumNamingStrategy.java
+++ b/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumMappingStrategy.java
@@ -14,7 +14,7 @@ import javax.lang.model.util.Types;
*
* @since 1.4
*/
-public class DefaultEnumNamingStrategy implements EnumNamingStrategy {
+public class DefaultEnumMappingStrategy implements EnumMappingStrategy {
protected Elements elementUtils;
protected Types typeUtils;
@@ -34,4 +34,13 @@ public class DefaultEnumNamingStrategy implements EnumNamingStrategy {
public String getEnumConstant(TypeElement enumType, String enumConstant) {
return enumConstant;
}
+
+ @Override
+ public TypeElement getUnexpectedValueMappingExceptionType() {
+ return elementUtils.getTypeElement( getUnexpectedValueMappingExceptionClass().getCanonicalName() );
+ }
+
+ protected Class extends Exception> getUnexpectedValueMappingExceptionClass() {
+ return IllegalArgumentException.class;
+ }
}
diff --git a/processor/src/main/java/org/mapstruct/ap/spi/EnumNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/EnumMappingStrategy.java
similarity index 80%
rename from processor/src/main/java/org/mapstruct/ap/spi/EnumNamingStrategy.java
rename to processor/src/main/java/org/mapstruct/ap/spi/EnumMappingStrategy.java
index a2361eefd..97088cd8c 100644
--- a/processor/src/main/java/org/mapstruct/ap/spi/EnumNamingStrategy.java
+++ b/processor/src/main/java/org/mapstruct/ap/spi/EnumMappingStrategy.java
@@ -13,11 +13,12 @@ import org.mapstruct.util.Experimental;
* A service provider interface for the mapping between different enum constants
*
* @author Arne Seime
+ * @author Filip Hrisafov
*
* @since 1.4
*/
@Experimental("This SPI can have it's signature changed in subsequent releases")
-public interface EnumNamingStrategy {
+public interface EnumMappingStrategy {
/**
* Initializes the enum value mapping strategy
@@ -47,4 +48,12 @@ public interface EnumNamingStrategy {
* never return null
*/
String getEnumConstant(TypeElement enumType, String enumConstant);
+
+ /**
+ * Return the type element of the exception that should be used in the generated code
+ * for an unexpected enum constant.
+ *
+ * @return the type element of the exception that should be used, never {@code null}
+ */
+ TypeElement getUnexpectedValueMappingExceptionType();
}
diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl
index ba16d56a2..530d5643e 100644
--- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl
+++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl
@@ -25,7 +25,7 @@
case <@writeSource source=valueMapping.source/>: ${resultName} = <@writeTarget target=valueMapping.target/>;
break;
#list>
- default: <#if throwIllegalArgumentException>throw new IllegalArgumentException( "Unexpected enum constant: " + ${sourceParameter.name} )<#else>${resultName} = <@writeTarget target=defaultTarget/>#if>;
+ default: <#if unexpectedValueMappingException??>throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} )<#else>${resultName} = <@writeTarget target=defaultTarget/>#if>;
}
<#list beforeMappingReferencesWithMappingTarget as callback>
<#if callback_index = 0>
@@ -40,7 +40,7 @@
<@includeModel object=callback targetBeanName=resultName targetType=resultType/>
#list>
- <#if !(valueMappings.empty && throwIllegalArgumentException)>
+ <#if !(valueMappings.empty && unexpectedValueMappingException??)>
return ${resultName};
#if>
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/CustomIllegalArgumentException.java b/processor/src/test/java/org/mapstruct/ap/test/value/CustomIllegalArgumentException.java
new file mode 100644
index 000000000..e5552d798
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/CustomIllegalArgumentException.java
@@ -0,0 +1,16 @@
+/*
+ * 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;
+
+/**
+ * @author Filip Hrisafov
+ */
+public class CustomIllegalArgumentException extends RuntimeException {
+
+ public CustomIllegalArgumentException(String message) {
+ super( message );
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/EmptyEnumMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/EmptyEnumMappingMapper.java
new file mode 100644
index 000000000..e0f2f112d
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/EmptyEnumMappingMapper.java
@@ -0,0 +1,25 @@
+/*
+ * 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.erroneous;
+
+import org.mapstruct.EnumMapping;
+import org.mapstruct.Mapper;
+import org.mapstruct.ValueMapping;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+/**
+ * @author Filip Hrisafov
+ */
+@Mapper
+public interface EmptyEnumMappingMapper {
+
+ @EnumMapping
+ @ValueMapping(source = "EXTRA", target = "SPECIAL")
+ @ValueMapping(source = "STANDARD", target = "DEFAULT")
+ @ValueMapping(source = "NORMAL", target = "DEFAULT")
+ ExternalOrderType onlyWithMappings(OrderType orderType);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/ErroneousEnumMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/ErroneousEnumMappingTest.java
new file mode 100644
index 000000000..45d374f21
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/ErroneousEnumMappingTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.erroneous;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+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;
+
+/**
+ * @author Filip Hrisafov
+ */
+@IssueKey("2169")
+@RunWith(AnnotationProcessorTestRunner.class)
+@WithClasses({
+ CustomIllegalArgumentException.class,
+ ExternalOrderType.class,
+ OrderType.class,
+})
+public class ErroneousEnumMappingTest {
+
+ @Test
+ @WithClasses({
+ EmptyEnumMappingMapper.class
+ })
+ @ExpectedCompilationOutcome(value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = EmptyEnumMappingMapper.class,
+ kind = javax.tools.Diagnostic.Kind.ERROR,
+ line = 20,
+ message = "'nameTransformationStrategy', 'configuration' and 'unexpectedValueMappingException' are " +
+ "undefined in @EnumMapping, define at least one of them."
+ )
+ }
+ )
+ public void shouldCompileErrorWhenEnumMappingIsEmpty() {
+ }
+
+ @Test
+ @WithClasses({
+ NoConfigurationEnumMappingMapper.class
+ })
+ @ExpectedCompilationOutcome(value = CompilationResult.FAILED,
+ diagnostics = {
+ @Diagnostic(type = NoConfigurationEnumMappingMapper.class,
+ kind = javax.tools.Diagnostic.Kind.ERROR,
+ line = 21,
+ message = "Configuration has to be defined when strategy is defined.")
+ }
+ )
+ public void shouldCompileErrorWhenEnumMappingHasStrategyButNoConfiguration() {
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/NoConfigurationEnumMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/NoConfigurationEnumMappingMapper.java
new file mode 100644
index 000000000..9d82ed059
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/erroneous/NoConfigurationEnumMappingMapper.java
@@ -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.erroneous;
+
+import org.mapstruct.EnumMapping;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.ValueMapping;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+/**
+ * @author Filip Hrisafov
+ */
+@Mapper
+public interface NoConfigurationEnumMappingMapper {
+
+ @EnumMapping(nameTransformationStrategy = MappingConstants.PREFIX_TRANSFORMATION)
+ @ValueMapping(source = "EXTRA", target = "SPECIAL")
+ @ValueMapping(source = "STANDARD", target = "DEFAULT")
+ @ValueMapping(source = "NORMAL", target = "DEFAULT")
+ ExternalOrderType onlyWithMappings(OrderType orderType);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/exception/Config.java b/processor/src/test/java/org/mapstruct/ap/test/value/exception/Config.java
new file mode 100644
index 000000000..627ac7970
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/exception/Config.java
@@ -0,0 +1,16 @@
+/*
+ * 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.exception;
+
+import org.mapstruct.MapperConfig;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+
+/**
+ * @author Filip Hrisafov
+ */
+@MapperConfig(unexpectedValueMappingException = CustomIllegalArgumentException.class)
+public interface Config {
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapper.java b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapper.java
new file mode 100644
index 000000000..6fc94fb8a
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapper.java
@@ -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.exception;
+
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.ValueMapping;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+/**
+ * @author Filip Hrisafov
+ */
+@Mapper(unexpectedValueMappingException = CustomIllegalArgumentException.class)
+public interface CustomUnexpectedValueMappingExceptionDefinedInMapper {
+
+ @ValueMapping(source = MappingConstants.ANY_UNMAPPED, target = "DEFAULT")
+ ExternalOrderType withAnyUnmapped(OrderType orderType);
+
+ @ValueMapping(source = MappingConstants.ANY_REMAINING, target = "DEFAULT")
+ ExternalOrderType withAnyRemaining(OrderType orderType);
+
+ @ValueMapping(source = "EXTRA", target = "SPECIAL")
+ @ValueMapping(source = "STANDARD", target = "DEFAULT")
+ @ValueMapping(source = "NORMAL", target = "DEFAULT")
+ ExternalOrderType onlyWithMappings(OrderType orderType);
+
+ @InheritInverseConfiguration(name = "onlyWithMappings")
+ OrderType inverseOnlyWithMappings(ExternalOrderType orderType);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping.java b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping.java
new file mode 100644
index 000000000..c5396ad48
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping.java
@@ -0,0 +1,38 @@
+/*
+ * 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.exception;
+
+import org.mapstruct.EnumMapping;
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.ValueMapping;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+/**
+ * @author Filip Hrisafov
+ */
+@Mapper(unexpectedValueMappingException = CustomIllegalArgumentException.class)
+public interface CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping {
+
+ @ValueMapping(source = MappingConstants.ANY_UNMAPPED, target = "DEFAULT")
+ ExternalOrderType withAnyUnmapped(OrderType orderType);
+
+ @ValueMapping(source = MappingConstants.ANY_REMAINING, target = "DEFAULT")
+ ExternalOrderType withAnyRemaining(OrderType orderType);
+
+ @ValueMapping(source = "EXTRA", target = "SPECIAL")
+ @ValueMapping(source = "STANDARD", target = "DEFAULT")
+ @ValueMapping(source = "NORMAL", target = "DEFAULT")
+ ExternalOrderType onlyWithMappings(OrderType orderType);
+
+ // If unexpectedValueMappingException is explicitly defined then it should be used instead of what is in the SPI
+ @EnumMapping(unexpectedValueMappingException = IllegalArgumentException.class)
+ @InheritInverseConfiguration(name = "onlyWithMappings")
+ OrderType inverseOnlyWithMappings(ExternalOrderType orderType);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperConfig.java
new file mode 100644
index 000000000..3e3d7e219
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperConfig.java
@@ -0,0 +1,34 @@
+/*
+ * 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.exception;
+
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.ValueMapping;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+/**
+ * @author Filip Hrisafov
+ */
+@Mapper(config = Config.class)
+public interface CustomUnexpectedValueMappingExceptionDefinedInMapperConfig {
+
+ @ValueMapping(source = MappingConstants.ANY_UNMAPPED, target = "DEFAULT")
+ ExternalOrderType withAnyUnmapped(OrderType orderType);
+
+ @ValueMapping(source = MappingConstants.ANY_REMAINING, target = "DEFAULT")
+ ExternalOrderType withAnyRemaining(OrderType orderType);
+
+ @ValueMapping(source = "EXTRA", target = "SPECIAL")
+ @ValueMapping(source = "STANDARD", target = "DEFAULT")
+ @ValueMapping(source = "NORMAL", target = "DEFAULT")
+ ExternalOrderType onlyWithMappings(OrderType orderType);
+
+ @InheritInverseConfiguration(name = "onlyWithMappings")
+ OrderType inverseOnlyWithMappings(ExternalOrderType orderType);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionMapper.java
new file mode 100644
index 000000000..96c8b297c
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionMapper.java
@@ -0,0 +1,39 @@
+/*
+ * 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.exception;
+
+import org.mapstruct.EnumMapping;
+import org.mapstruct.InheritInverseConfiguration;
+import org.mapstruct.Mapper;
+import org.mapstruct.MappingConstants;
+import org.mapstruct.ValueMapping;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+/**
+ * @author Filip Hrisafov
+ */
+@Mapper
+public interface CustomUnexpectedValueMappingExceptionMapper {
+
+ @EnumMapping(unexpectedValueMappingException = CustomIllegalArgumentException.class)
+ @ValueMapping( source = MappingConstants.ANY_UNMAPPED, target = "DEFAULT" )
+ ExternalOrderType withAnyUnmapped(OrderType orderType);
+
+ @EnumMapping(unexpectedValueMappingException = CustomIllegalArgumentException.class)
+ @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "DEFAULT" )
+ ExternalOrderType withAnyRemaining(OrderType orderType);
+
+ @EnumMapping(unexpectedValueMappingException = CustomIllegalArgumentException.class)
+ @ValueMapping(source = "EXTRA", target = "SPECIAL")
+ @ValueMapping(source = "STANDARD", target = "DEFAULT")
+ @ValueMapping(source = "NORMAL", target = "DEFAULT")
+ ExternalOrderType onlyWithMappings(OrderType orderType);
+
+ @InheritInverseConfiguration(name = "onlyWithMappings")
+ OrderType inverseOnlyWithMappings(ExternalOrderType orderType);
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionTest.java b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionTest.java
new file mode 100644
index 000000000..fbbf70285
--- /dev/null
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.exception;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+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.runner.AnnotationProcessorTestRunner;
+import org.mapstruct.ap.testutil.runner.GeneratedSource;
+
+/**
+ * @author Filip Hrisafov
+ */
+@IssueKey("2169")
+@RunWith(AnnotationProcessorTestRunner.class)
+@WithClasses({
+ Config.class,
+ CustomUnexpectedValueMappingExceptionDefinedInMapper.class,
+ CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping.class,
+ CustomUnexpectedValueMappingExceptionDefinedInMapperConfig.class,
+ CustomUnexpectedValueMappingExceptionMapper.class,
+ CustomIllegalArgumentException.class,
+ ExternalOrderType.class,
+ OrderType.class
+})
+public class CustomUnexpectedValueMappingExceptionTest {
+
+ @Rule
+ public final GeneratedSource generatedSource = new GeneratedSource();
+
+ @Test
+ public void shouldGenerateCustomUnexpectedValueMappingException() {
+ generatedSource.addComparisonToFixtureFor(
+ CustomUnexpectedValueMappingExceptionDefinedInMapper.class,
+ CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping.class,
+ CustomUnexpectedValueMappingExceptionDefinedInMapperConfig.class,
+ CustomUnexpectedValueMappingExceptionMapper.class
+ );
+ }
+}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomCheeseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomCheeseMapper.java
index 6524f67c3..b042405c4 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomCheeseMapper.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomCheeseMapper.java
@@ -5,6 +5,7 @@
*/
package org.mapstruct.ap.test.value.spi;
+import org.mapstruct.EnumMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingConstants;
import org.mapstruct.ValueMapping;
@@ -24,6 +25,8 @@ public interface CustomCheeseMapper {
String mapToString(CustomCheeseType cheeseType);
+ // If unexpectedValueMappingException is explicitly defined then it should be used instead of what is in the SPI
+ @EnumMapping(unexpectedValueMappingException = IllegalArgumentException.class)
String mapToString(CheeseType cheeseType);
@ValueMapping(source = MappingConstants.ANY_REMAINING, target = "CUSTOM_BRIE")
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumNamingStrategy.java b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumMappingStrategy.java
similarity index 77%
rename from processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumNamingStrategy.java
rename to processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumMappingStrategy.java
index f84ebaf7b..b505dd640 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumNamingStrategy.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumMappingStrategy.java
@@ -9,13 +9,14 @@ import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.internal.gem.MappingConstantsGem;
-import org.mapstruct.ap.spi.DefaultEnumNamingStrategy;
-import org.mapstruct.ap.spi.EnumNamingStrategy;
+import org.mapstruct.ap.spi.DefaultEnumMappingStrategy;
+import org.mapstruct.ap.spi.EnumMappingStrategy;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
/**
* @author Filip Hrisafov
*/
-public class CustomEnumNamingStrategy extends DefaultEnumNamingStrategy implements EnumNamingStrategy {
+public class CustomEnumMappingStrategy extends DefaultEnumMappingStrategy implements EnumMappingStrategy {
@Override
public String getDefaultNullEnumConstant(TypeElement enumType) {
@@ -51,4 +52,9 @@ public class CustomEnumNamingStrategy extends DefaultEnumNamingStrategy implemen
return false;
}
+
+ @Override
+ protected Class extends Exception> getUnexpectedValueMappingExceptionClass() {
+ return CustomIllegalArgumentException.class;
+ }
}
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumNamingStrategyTest.java b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumMappingStrategyTest.java
similarity index 94%
rename from processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumNamingStrategyTest.java
rename to processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumMappingStrategyTest.java
index 47a0a5d64..9cce52d7b 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumNamingStrategyTest.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomEnumMappingStrategyTest.java
@@ -8,6 +8,7 @@ package org.mapstruct.ap.test.value.spi;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.WithServiceImplementation;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
@@ -23,9 +24,10 @@ import static org.assertj.core.api.Assertions.assertThat;
CheeseType.class,
CustomCheeseType.class,
CustomEnumMarker.class,
+ CustomIllegalArgumentException.class,
})
-@WithServiceImplementation(CustomEnumNamingStrategy.class)
-public class CustomEnumNamingStrategyTest {
+@WithServiceImplementation(CustomEnumMappingStrategy.class)
+public class CustomEnumMappingStrategyTest {
@Rule
public final GeneratedSource generatedSource = new GeneratedSource();
@@ -34,7 +36,7 @@ public class CustomEnumNamingStrategyTest {
@WithClasses({
CustomCheeseMapper.class
})
- public void shouldApplyCustomEnumNamingStrategy() {
+ public void shouldApplyCustomEnumMappingStrategy() {
generatedSource.addComparisonToFixtureFor( CustomCheeseMapper.class );
CustomCheeseMapper mapper = CustomCheeseMapper.INSTANCE;
@@ -80,7 +82,7 @@ public class CustomEnumNamingStrategyTest {
@WithClasses({
OverridesCustomCheeseMapper.class
})
- public void shouldApplyDefinedMappingsInsteadOfCustomEnumNamingStrategy() {
+ public void shouldApplyDefinedMappingsInsteadOfCustomEnumMappingStrategy() {
OverridesCustomCheeseMapper mapper = OverridesCustomCheeseMapper.INSTANCE;
// CheeseType -> CustomCheeseType
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumNamingStrategy.java b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumMappingStrategy.java
similarity index 87%
rename from processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumNamingStrategy.java
rename to processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumMappingStrategy.java
index 671ad45c0..8a4f2b5bd 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumNamingStrategy.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumMappingStrategy.java
@@ -9,13 +9,13 @@ import javax.lang.model.element.TypeElement;
import javax.lang.model.type.TypeMirror;
import org.mapstruct.ap.internal.gem.MappingConstantsGem;
-import org.mapstruct.ap.spi.DefaultEnumNamingStrategy;
-import org.mapstruct.ap.spi.EnumNamingStrategy;
+import org.mapstruct.ap.spi.DefaultEnumMappingStrategy;
+import org.mapstruct.ap.spi.EnumMappingStrategy;
/**
* @author Filip Hrisafov
*/
-public class CustomErroneousEnumNamingStrategy extends DefaultEnumNamingStrategy implements EnumNamingStrategy {
+public class CustomErroneousEnumMappingStrategy extends DefaultEnumMappingStrategy implements EnumMappingStrategy {
@Override
public String getDefaultNullEnumConstant(TypeElement enumType) {
diff --git a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumNamingStrategyTest.java b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumMappingStrategyTest.java
similarity index 90%
rename from processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumNamingStrategyTest.java
rename to processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumMappingStrategyTest.java
index 82d6be4c2..9cb1337bc 100644
--- a/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumNamingStrategyTest.java
+++ b/processor/src/test/java/org/mapstruct/ap/test/value/spi/CustomErroneousEnumMappingStrategyTest.java
@@ -25,8 +25,8 @@ import static org.assertj.core.api.Assertions.assertThat;
CustomCheeseType.class,
CustomEnumMarker.class,
})
-@WithServiceImplementation(CustomErroneousEnumNamingStrategy.class)
-public class CustomErroneousEnumNamingStrategyTest {
+@WithServiceImplementation(CustomErroneousEnumMappingStrategy.class)
+public class CustomErroneousEnumMappingStrategyTest {
@Test
@WithClasses({
@@ -37,18 +37,18 @@ public class CustomErroneousEnumNamingStrategyTest {
@Diagnostic(
type = CustomCheeseMapper.class,
kind = javax.tools.Diagnostic.Kind.ERROR,
- line = 23,
+ line = 24,
messageRegExp = "Constant INCORRECT doesn't exist in enum type " +
"org\\.mapstruct\\.ap\\.test\\.value\\.spi\\.CustomCheeseType." +
- " Constant was returned from EnumNamingStrategy: .*CustomErroneousEnumNamingStrategy@.*"
+ " Constant was returned from EnumMappingStrategy: .*CustomErroneousEnumMappingStrategy@.*"
),
@Diagnostic(
type = CustomCheeseMapper.class,
kind = javax.tools.Diagnostic.Kind.ERROR,
- line = 30,
+ line = 33,
messageRegExp = "Constant INCORRECT doesn't exist in enum type " +
"org\\.mapstruct\\.ap\\.test\\.value\\.spi\\.CustomCheeseType." +
- " Constant was returned from EnumNamingStrategy: .*CustomErroneousEnumNamingStrategy@.*"
+ " Constant was returned from EnumMappingStrategy: .*CustomErroneousEnumMappingStrategy@.*"
)
}
)
@@ -59,7 +59,7 @@ public class CustomErroneousEnumNamingStrategyTest {
@WithClasses({
OverridesCustomCheeseMapper.class
})
- public void shouldApplyDefinedMappingsInsteadOfCustomEnumNamingStrategy() {
+ public void shouldApplyDefinedMappingsInsteadOfCustomEnumMappingStrategy() {
OverridesCustomCheeseMapper mapper = OverridesCustomCheeseMapper.INSTANCE;
// CheeseType -> CustomCheeseType
diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMappingImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMappingImpl.java
new file mode 100644
index 000000000..f0ae6eecd
--- /dev/null
+++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMappingImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.exception;
+
+import javax.annotation.Generated;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+@Generated(
+ value = "org.mapstruct.ap.MappingProcessor",
+ date = "2020-08-29T09:36:57+0200",
+ comments = "version: , compiler: javac, environment: Java 11.0.2 (AdoptOpenJDK)"
+)
+public class CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMappingImpl implements CustomUnexpectedValueMappingExceptionDefinedInMapperAndEnumMapping {
+
+ @Override
+ public ExternalOrderType withAnyUnmapped(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType withAnyRemaining(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType onlyWithMappings(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case EXTRA: externalOrderType = ExternalOrderType.SPECIAL;
+ break;
+ case STANDARD: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case NORMAL: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public OrderType inverseOnlyWithMappings(ExternalOrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ OrderType orderType1;
+
+ switch ( orderType ) {
+ case SPECIAL: orderType1 = OrderType.EXTRA;
+ break;
+ case DEFAULT: orderType1 = OrderType.STANDARD;
+ break;
+ case RETAIL: orderType1 = OrderType.RETAIL;
+ break;
+ case B2B: orderType1 = OrderType.B2B;
+ break;
+ default: throw new IllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return orderType1;
+ }
+}
diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperConfigImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperConfigImpl.java
new file mode 100644
index 000000000..fee7a2bb1
--- /dev/null
+++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperConfigImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.exception;
+
+import javax.annotation.Generated;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+@Generated(
+ value = "org.mapstruct.ap.MappingProcessor",
+ date = "2020-08-29T09:36:57+0200",
+ comments = "version: , compiler: javac, environment: Java 11.0.2 (AdoptOpenJDK)"
+)
+public class CustomUnexpectedValueMappingExceptionDefinedInMapperConfigImpl implements CustomUnexpectedValueMappingExceptionDefinedInMapperConfig {
+
+ @Override
+ public ExternalOrderType withAnyUnmapped(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType withAnyRemaining(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType onlyWithMappings(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case EXTRA: externalOrderType = ExternalOrderType.SPECIAL;
+ break;
+ case STANDARD: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case NORMAL: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public OrderType inverseOnlyWithMappings(ExternalOrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ OrderType orderType1;
+
+ switch ( orderType ) {
+ case SPECIAL: orderType1 = OrderType.EXTRA;
+ break;
+ case DEFAULT: orderType1 = OrderType.STANDARD;
+ break;
+ case RETAIL: orderType1 = OrderType.RETAIL;
+ break;
+ case B2B: orderType1 = OrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return orderType1;
+ }
+}
diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperImpl.java
new file mode 100644
index 000000000..a89733918
--- /dev/null
+++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionDefinedInMapperImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.exception;
+
+import javax.annotation.Generated;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+@Generated(
+ value = "org.mapstruct.ap.MappingProcessor",
+ date = "2020-08-29T09:36:57+0200",
+ comments = "version: , compiler: javac, environment: Java 11.0.2 (AdoptOpenJDK)"
+)
+public class CustomUnexpectedValueMappingExceptionDefinedInMapperImpl implements CustomUnexpectedValueMappingExceptionDefinedInMapper {
+
+ @Override
+ public ExternalOrderType withAnyUnmapped(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType withAnyRemaining(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType onlyWithMappings(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case EXTRA: externalOrderType = ExternalOrderType.SPECIAL;
+ break;
+ case STANDARD: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case NORMAL: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public OrderType inverseOnlyWithMappings(ExternalOrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ OrderType orderType1;
+
+ switch ( orderType ) {
+ case SPECIAL: orderType1 = OrderType.EXTRA;
+ break;
+ case DEFAULT: orderType1 = OrderType.STANDARD;
+ break;
+ case RETAIL: orderType1 = OrderType.RETAIL;
+ break;
+ case B2B: orderType1 = OrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return orderType1;
+ }
+}
diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionMapperImpl.java
new file mode 100644
index 000000000..c22ff08f6
--- /dev/null
+++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/exception/CustomUnexpectedValueMappingExceptionMapperImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.exception;
+
+import javax.annotation.Generated;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
+import org.mapstruct.ap.test.value.ExternalOrderType;
+import org.mapstruct.ap.test.value.OrderType;
+
+@Generated(
+ value = "org.mapstruct.ap.MappingProcessor",
+ date = "2020-08-02T09:36:57+0200",
+ comments = "version: , compiler: javac, environment: Java 11.0.2 (AdoptOpenJDK)"
+)
+public class CustomUnexpectedValueMappingExceptionMapperImpl implements CustomUnexpectedValueMappingExceptionMapper {
+
+ @Override
+ public ExternalOrderType withAnyUnmapped(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType withAnyRemaining(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: externalOrderType = ExternalOrderType.DEFAULT;
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public ExternalOrderType onlyWithMappings(OrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ ExternalOrderType externalOrderType;
+
+ switch ( orderType ) {
+ case EXTRA: externalOrderType = ExternalOrderType.SPECIAL;
+ break;
+ case STANDARD: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case NORMAL: externalOrderType = ExternalOrderType.DEFAULT;
+ break;
+ case RETAIL: externalOrderType = ExternalOrderType.RETAIL;
+ break;
+ case B2B: externalOrderType = ExternalOrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return externalOrderType;
+ }
+
+ @Override
+ public OrderType inverseOnlyWithMappings(ExternalOrderType orderType) {
+ if ( orderType == null ) {
+ return null;
+ }
+
+ OrderType orderType1;
+
+ switch ( orderType ) {
+ case SPECIAL: orderType1 = OrderType.EXTRA;
+ break;
+ case DEFAULT: orderType1 = OrderType.STANDARD;
+ break;
+ case RETAIL: orderType1 = OrderType.RETAIL;
+ break;
+ case B2B: orderType1 = OrderType.B2B;
+ break;
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + orderType );
+ }
+
+ return orderType1;
+ }
+}
diff --git a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/spi/CustomCheeseMapperImpl.java b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/spi/CustomCheeseMapperImpl.java
index 9798c4159..b2ba34a32 100644
--- a/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/spi/CustomCheeseMapperImpl.java
+++ b/processor/src/test/resources/fixtures/org/mapstruct/ap/test/value/spi/CustomCheeseMapperImpl.java
@@ -6,6 +6,7 @@
package org.mapstruct.ap.test.value.spi;
import javax.annotation.processing.Generated;
+import org.mapstruct.ap.test.value.CustomIllegalArgumentException;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
@@ -31,7 +32,7 @@ public class CustomCheeseMapperImpl implements CustomCheeseMapper {
break;
case UNRECOGNIZED: cheeseType = null;
break;
- default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheese );
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + cheese );
}
return cheeseType;
@@ -50,7 +51,7 @@ public class CustomCheeseMapperImpl implements CustomCheeseMapper {
break;
case ROQUEFORT: customCheeseType = CustomCheeseType.CUSTOM_ROQUEFORT;
break;
- default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheese );
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + cheese );
}
return customCheeseType;
@@ -73,7 +74,7 @@ public class CustomCheeseMapperImpl implements CustomCheeseMapper {
break;
case UNRECOGNIZED: string = null;
break;
- default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheeseType );
+ default: throw new CustomIllegalArgumentException( "Unexpected enum constant: " + cheeseType );
}
return string;