#2391 Add implicit conversion between UUID <-> String

This commit is contained in:
jason.bodnar@blackbaud.com 2021-03-23 13:40:30 -05:00 committed by Filip Hrisafov
parent 627be53088
commit 0cb053df8d
8 changed files with 195 additions and 2 deletions

View File

@ -115,7 +115,10 @@ public interface CarMapper {
* When converting from a `String`, omitting `Mapping#dateFormat`, it leads to usage of the default pattern and date format symbols for the default locale. An exception to this rule is `XmlGregorianCalendar` which results in parsing the `String` according to http://www.w3.org/TR/xmlschema-2/#dateTime[XML Schema 1.0 Part 2, Section 3.2.7-14.1, Lexical Representation].
* Between `java.util.Currency` and `String`.
** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/ISO_4217[ISO-4217] alphabetic code otherwise an `IllegalArgumentException` is thrown
** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/ISO_4217[ISO-4217] alphabetic code otherwise an `IllegalArgumentException` is thrown.
* Between `java.util.UUID` and `String`.
** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/Universally_unique_identifier[UUID] otherwise an `IllegalArgumentException` is thrown.
* Between `String` and `StringBuilder`
@ -326,7 +329,7 @@ public abstract class FishTankMapperWithVolume {
----
====
Note the `@Mapping` annotation where `source` field is equal to `"source"`, indicating the parameter name `source` itself in the method `map(FishTank source)` instead of a (target) property in `FishTank`.
Note the `@Mapping` annotation where `source` field is equal to `"source"`, indicating the parameter name `source` itself in the method `map(FishTank source)` instead of a (target) property in `FishTank`.
[[invoking-other-mappers]]

View File

@ -18,6 +18,7 @@ import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Currency;
import java.util.Locale;
import java.util.UUID;
import org.mapstruct.ap.internal.model.common.ConversionContext;
import org.mapstruct.ap.internal.util.JodaTimeConstants;
@ -242,4 +243,15 @@ public final class ConversionUtils {
public static String stringBuilder(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, StringBuilder.class );
}
/**
* Name for {@link java.util.UUID}.
*
* @param conversionContext Conversion context
*
* @return Name or fully-qualified name.
*/
public static String uuid(ConversionContext conversionContext) {
return typeReferenceName( conversionContext, UUID.class );
}
}

View File

@ -22,6 +22,7 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.model.common.TypeFactory;
@ -190,6 +191,8 @@ public class Conversions {
// java.util.Currency <~> String
register( Currency.class, String.class, new CurrencyToStringConversion() );
register( UUID.class, String.class, new UUIDToStringConversion() );
}
private void registerJodaConversions() {

View File

@ -0,0 +1,37 @@
/*
* 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.internal.conversion;
import java.util.Set;
import java.util.UUID;
import org.mapstruct.ap.internal.model.common.ConversionContext;
import org.mapstruct.ap.internal.model.common.Type;
import org.mapstruct.ap.internal.util.Collections;
import static org.mapstruct.ap.internal.conversion.ConversionUtils.uuid;
/**
* Conversion between {@link java.util.UUID} and {@link String}.
*
* @author Jason Bodnar
*/
public class UUIDToStringConversion extends SimpleConversion {
@Override
protected String getToExpression(ConversionContext conversionContext) {
return "<SOURCE>.toString()";
}
@Override
protected String getFromExpression(ConversionContext conversionContext) {
return uuid( conversionContext ) + ".fromString( <SOURCE> )";
}
@Override
protected Set<Type> getFromConversionImportTypes(final ConversionContext conversionContext) {
return Collections.asSet( conversionContext.getTypeFactory().getType( UUID.class ) );
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.conversion.uuid;
import java.util.UUID;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
/**
* Tests conversions between {@link java.util.UUID} and String.
*
* @author Jason Bodnar
*/
@IssueKey("2391")
@WithClasses({ UUIDSource.class, UUIDTarget.class, UUIDMapper.class })
public class UUIDConversionTest {
@ProcessorTest
public void shouldApplyUUIDConversion() {
UUIDSource source = new UUIDSource();
source.setUUIDA( UUID.randomUUID() );
UUIDTarget target = UUIDMapper.INSTANCE.sourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getUUIDA() ).isEqualTo( source.getUUIDA().toString() );
}
@ProcessorTest
public void shouldApplyReverseUUIDConversion() {
UUIDTarget target = new UUIDTarget();
target.setUUIDA( UUID.randomUUID().toString() );
UUIDSource source = UUIDMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getUUIDA() ).isEqualTo( UUID.fromString( target.getUUIDA() ) );
}
@ProcessorTest
public void shouldHandleInvalidUUIDString() {
UUIDTarget target = new UUIDTarget();
target.setInvalidUUID( "XXXXXXXXX" );
assertThatThrownBy( () -> UUIDMapper.INSTANCE.targetToSource( target ) )
.isInstanceOf( IllegalArgumentException.class );
}
}

View File

@ -0,0 +1,19 @@
/*
* 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.conversion.uuid;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UUIDMapper {
UUIDMapper INSTANCE = Mappers.getMapper( UUIDMapper.class );
UUIDTarget sourceToTarget(UUIDSource source);
UUIDSource targetToSource(UUIDTarget target);
}

View File

@ -0,0 +1,33 @@
/*
* 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.conversion.uuid;
import java.util.UUID;
/**
* @author Jason Bodnar
*/
public class UUIDSource {
private UUID uuidA;
private UUID invalidUUID;
public UUID getUUIDA() {
return this.uuidA;
}
public void setUUIDA(final UUID uuidA) {
this.uuidA = uuidA;
}
public UUID getInvalidUUID() {
return invalidUUID;
}
public void setInvalidUUID(final UUID invalidUUID) {
this.invalidUUID = invalidUUID;
}
}

View File

@ -0,0 +1,30 @@
/*
* 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.conversion.uuid;
/**
* @author Jason Bodnar
*/
public class UUIDTarget {
private String uuidA;
private String invalidUUID;
public String getUUIDA() {
return this.uuidA;
}
public void setUUIDA(final String uuidA) {
this.uuidA = uuidA;
}
public String getInvalidUUID() {
return this.invalidUUID;
}
public void setInvalidUUID(final String invalidUUID) {
this.invalidUUID = invalidUUID;
}
}