diff --git a/example/pom.xml b/example/pom.xml index e945593..88c1d1e 100644 --- a/example/pom.xml +++ b/example/pom.xml @@ -21,6 +21,7 @@ 1.4.1-SNAPSHOT 1.18.22 5.8.26 + 32.1.3-jre @@ -50,6 +51,11 @@ hutool-all ${hutool.version} + + com.google.guava + guava + ${guava.version} + diff --git a/example/spring-boot-with-lombok/pom.xml b/example/spring-boot-with-lombok/pom.xml index 81a92c8..34776f9 100644 --- a/example/spring-boot-with-lombok/pom.xml +++ b/example/spring-boot-with-lombok/pom.xml @@ -50,6 +50,10 @@ cn.hutool hutool-all + + com.google.guava + guava + diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/MapStructPlusConfiguration.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/MapStructPlusConfiguration.java index e9849a7..7e5302a 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/MapStructPlusConfiguration.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/MapStructPlusConfiguration.java @@ -1,12 +1,14 @@ package io.github.linpeilie; import io.github.linpeilie.annotations.MapperConfig; +import org.mapstruct.Builder; @MapperConfig(adapterClassName = "DemoConvertMapperAdapter", adapterPackage = "io.github.linpeilie.adapter", mapAdapterClassName = "DemoMapConvertMapperAdapter", autoConfigPackage = "cn.easii", autoMapperConfigClassName = "EasiiAutoMapperConfig", - autoMapMapperConfigClassName = "EasiiAutoMapMapperConfig") + autoMapMapperConfigClassName = "EasiiAutoMapMapperConfig", + builder = @Builder(disableBuilder = false)) public class MapStructPlusConfiguration { } diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/mapper/Titles.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/mapper/Titles.java index a30b35d..3374568 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/mapper/Titles.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/mapper/Titles.java @@ -13,6 +13,9 @@ public class Titles { if ("One Hundred Years of Solitude".equals(title)) { return "Cent ans de solitude"; } + if ("Default".equals(title)) { + return null; + } return "Inconnu et inconnu"; } diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/NoProperties.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/NoProperties.java new file mode 100644 index 0000000..3a70260 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/NoProperties.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me; + +/** + * @author Filip Hrisafov + */ +public class NoProperties { +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/WithProperties.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/WithProperties.java new file mode 100644 index 0000000..e503a50 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/WithProperties.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 io.github.linpeilie.me; + +import io.github.linpeilie.annotations.AutoMapper; + +/** + * @author Filip Hrisafov + */ +@AutoMapper(target = NoProperties.class) +public class WithProperties { + + private String string; + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/array/Scientist.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/array/Scientist.java new file mode 100644 index 0000000..cdc07a4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/array/Scientist.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.array; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = ScientistDto.class) +public class Scientist { + + //CHECKSTYLE:OFF + public String[] publicPublications; + public String[] publicPublicationYears; + //CHECKSTYLE:ON + private String name; + private String[] publications; + private String[] publicationYears; + + public Scientist(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String[] getPublications() { + return publications; + } + + public void setPublications(String[] publications) { + this.publications = publications; + } + + public String[] getPublicationYears() { + return publicationYears; + } + + public void setPublicationYears(String[] publicationYears) { + this.publicationYears = publicationYears; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/array/ScientistDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/array/ScientistDto.java new file mode 100644 index 0000000..175e5da --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/array/ScientistDto.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.array; + +public class ScientistDto { + + //CHECKSTYLE:OFF + public String[] publicPublications; + public int[] publicPublicationYears; + //CHECKSTYLE:ON + + private String name; + private String[] publications; + private int[] publicationYears; + + public ScientistDto() { + } + + public ScientistDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String[] getPublications() { + return publications; + } + + public void setPublications(String[] publications) { + this.publications = publications; + } + + public int[] getPublicationYears() { + return publicationYears; + } + + public void setPublicationYears(int[] publicationYears) { + this.publicationYears = publicationYears; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/Person.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/Person.java new file mode 100644 index 0000000..54948df --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/Person.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.bool; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = PersonDto.class, uses = YesNoMapper.class, reverseConvertGenerate = false) +public class Person { + + private Boolean married; + private Boolean engaged; + private YesNo divorced; + private YesNo widowed; + + public Boolean isMarried() { + return married; + } + + public void setMarried(Boolean married) { + this.married = married; + } + + // START: please note: deliberately ordered, first getEngaged, then isEngaged. + public Boolean getEngaged() { + return engaged; + } + + public Boolean isEngaged() { + return engaged != null && !engaged; + } + // END + + public void setEngaged(Boolean engaged) { + this.engaged = engaged; + } + + public YesNo getDivorced() { + return divorced; + } + + public void setDivorced(YesNo divorced) { + this.divorced = divorced; + } + + public YesNo getWidowed() { + return widowed; + } + + public void setWidowed(YesNo widowed) { + this.widowed = widowed; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/PersonDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/PersonDto.java new file mode 100644 index 0000000..0768d89 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/PersonDto.java @@ -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 io.github.linpeilie.me.bool; + +public class PersonDto { + + private String married; + private String engaged; + private String divorced; + private Boolean widowed; + + public String getMarried() { + return married; + } + + public void setMarried(String married) { + this.married = married; + } + + public String getEngaged() { + return engaged; + } + + public void setEngaged(String engaged) { + this.engaged = engaged; + } + + public String getDivorced() { + return divorced; + } + + public void setDivorced(String divorced) { + this.divorced = divorced; + } + + public Boolean getWidowed() { + return widowed; + } + + public void setWidowed(Boolean widowed) { + this.widowed = widowed; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/YesNo.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/YesNo.java new file mode 100644 index 0000000..5389beb --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/YesNo.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 io.github.linpeilie.me.bool; + +/** + * @author Andreas Gudian + * + */ +public class YesNo { + private boolean yes; + + public YesNo(boolean yes) { + this.yes = yes; + } + + public boolean isYes() { + return yes; + } + + public void setYes(boolean yes) { + this.yes = yes; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/YesNoMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/YesNoMapper.java new file mode 100644 index 0000000..e5f8f2e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/bool/YesNoMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.bool; + +import org.mapstruct.Mapper; +import org.springframework.stereotype.Component; + +/** + * @author Andreas Gudian + * + */ +@Component +public class YesNoMapper { + public String toString(YesNo yesNo) { + if ( null != yesNo && yesNo.isYes() ) { + return "yes"; + } + + return "no"; + } + + public boolean toBool(YesNo yesNo) { + return ( null != yesNo && yesNo.isYes() ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/AbstractImmutableProduct.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/AbstractImmutableProduct.java new file mode 100644 index 0000000..6ed77d1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/AbstractImmutableProduct.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.abstractBuilder; + +/** + * @author Filip Hrisafov + */ +public abstract class AbstractImmutableProduct { + + private final String name; + + public AbstractImmutableProduct(AbstractProductBuilder builder) { + this.name = builder.name; + } + + public String getName() { + return name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/AbstractProductBuilder.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/AbstractProductBuilder.java new file mode 100644 index 0000000..8385b8d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/AbstractProductBuilder.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.abstractBuilder; + +public abstract class AbstractProductBuilder { + + protected String name; + + public AbstractProductBuilder name(String name) { + this.name = name; + return this; + } + + public abstract T build(); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/ImmutableProduct.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/ImmutableProduct.java new file mode 100644 index 0000000..4d445ef --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/ImmutableProduct.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 io.github.linpeilie.me.builder.abstractBuilder; + +public class ImmutableProduct extends AbstractImmutableProduct { + + private final Integer price; + + public ImmutableProduct(ImmutableProductBuilder builder) { + super( builder ); + this.price = builder.price; + } + + public static ImmutableProductBuilder builder() { + return new ImmutableProductBuilder(); + } + + public Integer getPrice() { + return price; + } + + public static class ImmutableProductBuilder extends AbstractProductBuilder { + private Integer price; + + public ImmutableProductBuilder price(Integer price) { + this.price = price; + return this; + } + + @Override + public ImmutableProduct build() { + return new ImmutableProduct( this ); + } + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/ProductDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/ProductDto.java new file mode 100644 index 0000000..b1048d3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractBuilder/ProductDto.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 io.github.linpeilie.me.builder.abstractBuilder; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = ImmutableProduct.class) +public class ProductDto { + private String name; + private Integer price; + + public ProductDto() { + } + + public ProductDto(String name, Integer price) { + this.name = name; + this.price = price; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getPrice() { + return price; + } + + public void setPrice(Integer price) { + this.price = price; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/Child.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/Child.java new file mode 100644 index 0000000..43e7650 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/Child.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.abstractGenericTarget; + +public interface Child { + String getName(); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ChildSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ChildSource.java new file mode 100644 index 0000000..c76df2e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ChildSource.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.abstractGenericTarget; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = ImmutableChild.class) +public class ChildSource { + private String name; + + public ChildSource() { + } + + public ChildSource(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ImmutableChild.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ImmutableChild.java new file mode 100644 index 0000000..3f3ff93 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ImmutableChild.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 io.github.linpeilie.me.builder.abstractGenericTarget; + +public class ImmutableChild implements Child { + private final String name; + + private ImmutableChild(Builder builder) { + this.name = builder.name; + } + + public static Builder builder() { + return new Builder(); + } + + public String getName() { + return name; + } + + public static class Builder { + private String name; + + public Builder name(String name) { + this.name = name; + return this; + } + + public ImmutableChild build() { + return new ImmutableChild( this ); + } + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ImmutableParent.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ImmutableParent.java new file mode 100644 index 0000000..3229f0e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ImmutableParent.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 io.github.linpeilie.me.builder.abstractGenericTarget; + +public class ImmutableParent implements Parent { + private final int count; + private final ImmutableChild child; + private final Child nonGenericChild; + + public ImmutableParent(Builder builder) { + this.count = builder.count; + this.child = builder.child; + this.nonGenericChild = builder.nonGenericChild; + } + + public static Builder builder() { + return new Builder(); + } + + @Override + public Child getNonGenericChild() { + return nonGenericChild; + } + + @Override + public int getCount() { + return count; + } + + @Override + public ImmutableChild getChild() { + return child; + } + + public static class Builder { + private int count; + private ImmutableChild child; + private Child nonGenericChild; + + public Builder count(int count) { + this.count = count; + return this; + } + + public Builder nonGenericChild(Child nonGenericChild) { + this.nonGenericChild = nonGenericChild; + return this; + } + + public Builder child(ImmutableChild child) { + this.child = child; + return this; + } + + public ImmutableParent build() { + return new ImmutableParent( this ); + } + + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/MutableChild.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/MutableChild.java new file mode 100644 index 0000000..6bf2ebc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/MutableChild.java @@ -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 io.github.linpeilie.me.builder.abstractGenericTarget; + +public class MutableChild implements Child { + private String name; + + @Override + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/MutableParent.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/MutableParent.java new file mode 100644 index 0000000..8c3caeb --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/MutableParent.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 io.github.linpeilie.me.builder.abstractGenericTarget; + +public class MutableParent implements Parent { + private int count; + private ImmutableChild child; + private Child nonGenericChild; + + @Override + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + @Override + public ImmutableChild getChild() { + return child; + } + + public void setChild(ImmutableChild child) { + this.child = child; + } + + @Override + public Child getNonGenericChild() { + return nonGenericChild; + } + + public void setNonGenericChild(Child nonGenericChild) { + this.nonGenericChild = nonGenericChild; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/Parent.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/Parent.java new file mode 100644 index 0000000..72a0af6 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/Parent.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.abstractGenericTarget; + +public interface Parent { + int getCount(); + + T getChild(); + + Child getNonGenericChild(); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ParentSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ParentSource.java new file mode 100644 index 0000000..74271fc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/abstractGenericTarget/ParentSource.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.builder.abstractGenericTarget; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; + +@AutoMappers({ + @AutoMapper(target = ImmutableParent.class), + @AutoMapper(target = MutableParent.class) +}) +public class ParentSource { + private int count; + private ChildSource child; + private ChildSource nonGenericChild; + + public ChildSource getNonGenericChild() { + return nonGenericChild; + } + + public void setNonGenericChild(ChildSource nonGenericChild) { + this.nonGenericChild = nonGenericChild; + } + + public int getCount() { + return count; + } + + public void setCount(int count) { + this.count = count; + } + + public ChildSource getChild() { + return child; + } + + public void setChild(ChildSource child) { + this.child = child; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/BuilderFactoryMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/BuilderFactoryMapper.java new file mode 100644 index 0000000..088ec34 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/BuilderFactoryMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.factory; + +import org.mapstruct.Mapper; +import org.mapstruct.ObjectFactory; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +/** + * @author Filip Hrisafov + */ +@Component +public class BuilderFactoryMapper { + + @ObjectFactory + public Person.PersonBuilder personBuilder() { + return new Person.PersonBuilder( "Factory with @ObjectFactory" ); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/BuilderImplicitFactoryMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/BuilderImplicitFactoryMapper.java new file mode 100644 index 0000000..2a7ae85 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/BuilderImplicitFactoryMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.builder.factory; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +/** + * @author Filip Hrisafov + */ +@Component +public class BuilderImplicitFactoryMapper { + + public ImplicitPerson.PersonBuilder personBuilder() { + return new ImplicitPerson.PersonBuilder("Implicit Factory"); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/ImplicitPerson.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/ImplicitPerson.java new file mode 100644 index 0000000..0685331 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/ImplicitPerson.java @@ -0,0 +1,43 @@ +package io.github.linpeilie.me.builder.factory; + +public class ImplicitPerson { + + private final String name; + private final String source; + + protected ImplicitPerson(ImplicitPerson.PersonBuilder builder) { + this.name = builder.name; + this.source = builder.source; + } + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + public static ImplicitPerson.PersonBuilder builder() { + throw new UnsupportedOperationException( "Factory should be used" ); + } + + public static class PersonBuilder { + private String name; + private final String source; + + public PersonBuilder(String source) { + this.source = source; + } + + public ImplicitPerson.PersonBuilder name(String name) { + this.name = name; + return this; + } + + public ImplicitPerson build() { + return new ImplicitPerson( this ); + } + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/Person.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/Person.java new file mode 100644 index 0000000..bfa2a0b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/Person.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.factory; + +/** + * @author Filip Hrisafov + */ +public class Person { + + private final String name; + private final String source; + + protected Person(PersonBuilder builder) { + this.name = builder.name; + this.source = builder.source; + } + + public String getName() { + return name; + } + + public String getSource() { + return source; + } + + public static PersonBuilder builder() { + throw new UnsupportedOperationException( "Factory should be used" ); + } + + public static class PersonBuilder { + private String name; + private final String source; + + public PersonBuilder(String source) { + this.source = source; + } + + public PersonBuilder name(String name) { + this.name = name; + return this; + } + + public Person build() { + return new Person( this ); + } + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/PersonDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/PersonDto.java new file mode 100644 index 0000000..9da8384 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/builder/factory/PersonDto.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.builder.factory; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; + +/** + * @author Filip Hrisafov + */ +@AutoMappers({ + @AutoMapper(target = Person.class, uses = BuilderFactoryMapper.class, reverseConvertGenerate = false), + @AutoMapper(target = ImplicitPerson.class, uses = BuilderImplicitFactoryMapper.class, reverseConvertGenerate = false), +}) +public class PersonDto { + + private String name; + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/BaseMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/BaseMapper.java new file mode 100644 index 0000000..9e8173e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/BaseMapper.java @@ -0,0 +1,244 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.TargetType; +import org.springframework.stereotype.Component; + +/** + * @author Andreas Gudian + */ +@Component +public class BaseMapper { + + private static final List INVOCATIONS = new ArrayList(); + + @BeforeMapping + public void noArgsBeforeMapping() { + INVOCATIONS.add( new Invocation( "noArgsBeforeMapping" ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(Source source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Source source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(SourceEnum source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(List source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(List source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(Map source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Map source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + + @BeforeMapping + public void withSourceAsObjectBeforeMapping(Object source) { + INVOCATIONS.add( new Invocation( "withSourceAsObjectBeforeMapping", source ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(Source source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(SourceEnum source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(List source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(Map source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(Source source, @MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(SourceEnum source, @MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(List source, @MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(Map source, + @MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetAsObjectBeforeMapping(@MappingTarget Object target) { + INVOCATIONS.add( new Invocation( "withTargetAsObjectBeforeMapping", target ) ); + } + + @AfterMapping + public void noArgsAfterMapping() { + INVOCATIONS.add( new Invocation( "noArgsAfterMapping" ) ); + } + + @AfterMapping + public void withSourceAfterMapping(Source source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAfterMapping(SourceEnum source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAfterMapping(List source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAfterMapping(Map source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAsObjectAfterMapping(Object source) { + INVOCATIONS.add( new Invocation( "withSourceAsObjectAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(Source source, @MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(SourceEnum source, @MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(List source, @MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(Map source, @MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + + @AfterMapping + public void withTargetAsObjectAfterMapping(@MappingTarget Object target) { + INVOCATIONS.add( new Invocation( "withTargetAsObjectAfterMapping", target ) ); + } + + @AfterMapping + public void withTargetAndTargetTypeAfterMapping(@MappingTarget T target, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withTargetAndTargetTypeAfterMapping", target, targetClass ) ); + } + + public static List getInvocations() { + return INVOCATIONS; + } + + public static void reset() { + INVOCATIONS.clear(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ClassContainingCallbacks.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ClassContainingCallbacks.java new file mode 100644 index 0000000..b441be0 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ClassContainingCallbacks.java @@ -0,0 +1,243 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.TargetType; +import org.springframework.stereotype.Component; + +/** + * @author Andreas Gudian + */ +@Component +public class ClassContainingCallbacks { + private static final List INVOCATIONS = new ArrayList(); + + @BeforeMapping + public void noArgsBeforeMapping() { + INVOCATIONS.add( new Invocation( "noArgsBeforeMapping" ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(Source source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Source source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(SourceEnum source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(List source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(List source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + + @BeforeMapping + public void withSourceBeforeMapping(Map source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMapping", source ) ); + } + + @BeforeMapping + @Qualified + public void withSourceBeforeMappingQualified(Map source) { + INVOCATIONS.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); + } + + @BeforeMapping + public void withSourceAsObjectBeforeMapping(Object source) { + INVOCATIONS.add( new Invocation( "withSourceAsObjectBeforeMapping", source ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(Source source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(SourceEnum source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(List source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetTypeBeforeMapping(Map source, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetTypeBeforeMapping", source, targetClass ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(Source source, @MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(SourceEnum source, @MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(List source, @MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withSourceAndTargetBeforeMapping(Map source, + @MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetBeforeMapping", source, target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetBeforeMapping(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetBeforeMapping", target ) ); + } + + @BeforeMapping + public void withTargetAsObjectBeforeMapping(@MappingTarget Object target) { + INVOCATIONS.add( new Invocation( "withTargetAsObjectBeforeMapping", target ) ); + } + + @AfterMapping + public void noArgsAfterMapping() { + INVOCATIONS.add( new Invocation( "noArgsAfterMapping" ) ); + } + + @AfterMapping + public void withSourceAfterMapping(Source source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAfterMapping(SourceEnum source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAfterMapping(List source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAfterMapping(Map source) { + INVOCATIONS.add( new Invocation( "withSourceAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAsObjectAfterMapping(Object source) { + INVOCATIONS.add( new Invocation( "withSourceAsObjectAfterMapping", source ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(Source source, @MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(SourceEnum source, @MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(List source, @MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withSourceAndTargetAfterMapping(Map source, @MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withSourceAndTargetAfterMapping", source, target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget TargetEnum target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Target target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget List target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + + @AfterMapping + public void withTargetAfterMapping(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMapping", target ) ); + } + + @AfterMapping + @Qualified + public void withTargetAfterMappingQualified(@MappingTarget Map target) { + INVOCATIONS.add( new Invocation( "withTargetAfterMappingQualified", target ) ); + } + + @AfterMapping + public void withTargetAsObjectAfterMapping(@MappingTarget Object target) { + INVOCATIONS.add( new Invocation( "withTargetAsObjectAfterMapping", target ) ); + } + + @AfterMapping + public void withTargetAndTargetTypeAfterMapping(@MappingTarget T target, @TargetType Class targetClass) { + INVOCATIONS.add( new Invocation( "withTargetAndTargetTypeAfterMapping", target, targetClass ) ); + } + + public static List getInvocations() { + return INVOCATIONS; + } + + public static void reset() { + INVOCATIONS.clear(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Invocation.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Invocation.java new file mode 100644 index 0000000..9a46e94 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Invocation.java @@ -0,0 +1,71 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +import java.util.Arrays; + +/** + * @author Andreas Gudian + */ +public class Invocation { + private final String methodName; + private final String arguments; + + public Invocation(String methodName, Object... arguments) { + this.methodName = methodName; + this.arguments = Arrays.toString( arguments ); + } + + public String getMethodName() { + return methodName; + } + + public String getArguments() { + return arguments; + } + + @Override + public String toString() { + return "Invocation [methodName=" + methodName + ", arguments=" + arguments + "]"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( arguments == null ) ? 0 : arguments.hashCode() ); + result = prime * result + ( ( methodName == null ) ? 0 : methodName.hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + Invocation other = (Invocation) obj; + if ( arguments == null ) { + if ( other.arguments != null ) { + return false; + } + } + else if ( !arguments.equals( other.arguments ) ) { + return false; + } + if ( methodName == null ) { + return other.methodName == null; + } + else { + return methodName.equals( other.methodName ); + } + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Qualified.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Qualified.java new file mode 100644 index 0000000..e067ca7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Qualified.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +import org.mapstruct.Qualifier; + +/** + * @author Andreas Gudian + * + */ +@Qualifier +public @interface Qualified { + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Source.java new file mode 100644 index 0000000..a650a39 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Source.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.callbacks; + +import io.github.linpeilie.annotations.AutoMapper; + +/** + * @author Andreas Gudian + */ +@AutoMapper(target = Target.class, uses = {ClassContainingCallbacks.class, BaseMapper.class}) +public class Source { + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((foo == null) ? 0 : foo.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Source other = (Source) obj; + if (foo == null) { + return other.foo == null; + } else { + return foo.equals(other.foo); + } + } + + @Override + public String toString() { + return "Source [foo=" + foo + "]"; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/SourceEnum.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/SourceEnum.java new file mode 100644 index 0000000..8746050 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/SourceEnum.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +/** + * @author Andreas Gudian + * + */ +public enum SourceEnum { + A, B, C; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Target.java new file mode 100644 index 0000000..20c1019 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/Target.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +/** + * @author Andreas Gudian + */ +public class Target { + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( foo == null ) ? 0 : foo.hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + Target other = (Target) obj; + if ( foo == null ) { + return other.foo == null; + } + else { + return foo.equals( other.foo ); + } + } + + @Override + public String toString() { + return "Target [foo=" + foo + "]"; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/TargetEnum.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/TargetEnum.java new file mode 100644 index 0000000..c98141d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/TargetEnum.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks; + +/** + * @author Andreas Gudian + * + */ +public enum TargetEnum { + A, B, C; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Address.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Address.java new file mode 100644 index 0000000..342f1dd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Address.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.callbacks.ongeneratedmethods; + +import io.github.linpeilie.annotations.AutoMapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = AddressDto.class, unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = CompanyMapperPostProcessing.class) +public class Address { + + private String addressLine; + private String town; + + public String getAddressLine() { + return addressLine; + } + + public void setAddressLine(String addressLine) { + this.addressLine = addressLine; + } + + public String getTown() { + return town; + } + + public void setTown(String town) { + this.town = town; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/AddressDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/AddressDto.java new file mode 100644 index 0000000..73533f3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/AddressDto.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks.ongeneratedmethods; + +/** + * + * @author Sjaak Derksen + */ +public class AddressDto { + + private int houseNumber; + private String street; + private String town; + + public int getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber( int houseNumber ) { + this.houseNumber = houseNumber; + } + + public String getStreet() { + return street; + } + + public void setStreet( String street ) { + this.street = street; + } + + public String getTown() { + return town; + } + + public void setTown( String town ) { + this.town = town; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Company.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Company.java new file mode 100644 index 0000000..cc0706e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Company.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.callbacks.ongeneratedmethods; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.List; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = CompanyDto.class, unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = CompanyMapperPostProcessing.class) +public class Company { + + private List employees; + + public List getEmployees() { + return employees; + } + + public void setEmployees(List employees) { + this.employees = employees; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/CompanyDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/CompanyDto.java new file mode 100644 index 0000000..5e94b72 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/CompanyDto.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 io.github.linpeilie.me.callbacks.ongeneratedmethods; + +import java.util.List; + +/** + * + * @author Sjaak Derksen + */ +public class CompanyDto { + + private List employees; + + public List getEmployees() { + return employees; + } + + public void setEmployees( List employees ) { + this.employees = employees; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java new file mode 100644 index 0000000..ededd66 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks.ongeneratedmethods; + +import org.mapstruct.AfterMapping; +import org.mapstruct.MappingTarget; +import org.springframework.stereotype.Component; + +/** + * + * @author Sjaak Derksen + */ +@Component +public class CompanyMapperPostProcessing { + + @AfterMapping + public void toAddressDto(Address address, @MappingTarget AddressDto addressDto) { + String addressLine = address.getAddressLine(); + int separatorIndex = addressLine.indexOf( ";" ); + addressDto.setStreet( addressLine.substring( 0, separatorIndex ) ); + String houseNumber = addressLine.substring( separatorIndex + 1 ); + addressDto.setHouseNumber( Integer.parseInt( houseNumber ) ); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Employee.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Employee.java new file mode 100644 index 0000000..b6011a5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/Employee.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.callbacks.ongeneratedmethods; + +import io.github.linpeilie.annotations.AutoMapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = EmployeeDto.class, unmappedTargetPolicy = ReportingPolicy.IGNORE, uses = CompanyMapperPostProcessing.class, mapperNameSuffix = "$1") +public class Employee { + + private Address address; + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/EmployeeDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/EmployeeDto.java new file mode 100644 index 0000000..197a6bc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/ongeneratedmethods/EmployeeDto.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.callbacks.ongeneratedmethods; + +/** + * + * @author Sjaak Derksen + */ +public class EmployeeDto { + + private AddressDto address; + + public AddressDto getAddress() { + return address; + } + + public void setAddress( AddressDto address ) { + this.address = address; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarDto.java new file mode 100644 index 0000000..b727fdb --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarDto.java @@ -0,0 +1,16 @@ +package io.github.linpeilie.me.callbacks.typematching; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = CarEntity.class, uses = CarMapper.class) +public class CarDto extends Identifiable { + private int seatCount; + + public int getSeatCount() { + return seatCount; + } + + public void setSeatCount(int seatCount) { + this.seatCount = seatCount; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarEntity.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarEntity.java new file mode 100644 index 0000000..b84e95b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarEntity.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.callbacks.typematching; + +public class CarEntity extends Identifiable { + private int seatCount; + + public int getSeatCount() { + return seatCount; + } + + public void setSeatCount(int seatCount) { + this.seatCount = seatCount; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarMapper.java new file mode 100644 index 0000000..e8b8fa2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/CarMapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.callbacks.typematching; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.MappingTarget; +import org.springframework.stereotype.Component; + +/** + * @author Andreas Gudian + */ +@Component +public class CarMapper { + + @AfterMapping + protected void neverMatched(ElectricCarDto electricDto) { + throw new RuntimeException("must not be called"); + } + + @AfterMapping + protected void neverMatched(@MappingTarget ElectricCarEntity electricEntity) { + throw new RuntimeException("must not be called"); + } + + @AfterMapping + protected void isCalled(@MappingTarget Object any) { + if (any instanceof CarEntity) { + CarEntity car = (CarEntity) any; + if (car.getSeatCount() == 0) { + car.setSeatCount(5); + } + } + } + + @AfterMapping + protected void incrementsTargetId(@MappingTarget Identifiable identifiable) { + identifiable.setId(identifiable.getId() + 1); + } + + @BeforeMapping + protected void incrementsSourceId(Identifiable identifiable) { + identifiable.setId(identifiable.getId() + 1); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/ElectricCarDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/ElectricCarDto.java new file mode 100644 index 0000000..988d99f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/ElectricCarDto.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.callbacks.typematching; + +public class ElectricCarDto extends CarDto { + private long batteryCapacity; + + public long getBatteryCapacity() { + return batteryCapacity; + } + + public void setBatteryCapacity(long batteryCapacity) { + this.batteryCapacity = batteryCapacity; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/ElectricCarEntity.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/ElectricCarEntity.java new file mode 100644 index 0000000..d597152 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/ElectricCarEntity.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.callbacks.typematching; + +public class ElectricCarEntity extends Identifiable { + private long batteryCapacity; + + public long getBatteryCapacity() { + return batteryCapacity; + } + + public void setBatteryCapacity(long batteryCapacity) { + this.batteryCapacity = batteryCapacity; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/Identifiable.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/Identifiable.java new file mode 100644 index 0000000..98dcb4a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/callbacks/typematching/Identifiable.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.callbacks.typematching; + +public abstract class Identifiable { + private long id; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Colour.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Colour.java new file mode 100644 index 0000000..1e71dff --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Colour.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection; + +public enum Colour { + RED, GREEN, BLUE; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Source.java new file mode 100644 index 0000000..54bba0b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Source.java @@ -0,0 +1,204 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +@AutoMapper(target = Target.class, uses = SourceTargetMapper.class) +public class Source { + + private List publicStringList; + + private List stringList; + private List otherStringList; + private ArrayList stringArrayList; + + private Set stringSet; + private HashSet stringHashSet; + + private Collection stringCollection; + + @AutoMapping(target = "integerCollection") + private List integerList; + + @AutoMapping(target = "set") + private Set integerSet; + + @AutoMapping(target = "anotherStringSet") + private Set anotherIntegerSet; + + private Set colours; + + private Map stringLongMap; + + private Map otherStringLongMap; + + @AutoMapping(target = "nonGenericMapStringtoLong") + private Map stringLongMapForNonGeneric; + + @AutoMapping(target = "stringListNoSetter") + private List stringList2; + + @AutoMapping(target = "stringListNoSetter2") + private Set stringSet2; + + private EnumSet enumSet; + + @AutoMapping(target = "nonGenericStringList") + private List stringList3; + + public List getPublicStringList() { + return publicStringList; + } + + public void setPublicStringList(List publicStringList) { + this.publicStringList = publicStringList; + } + + public List getStringList() { + return stringList; + } + + public void setStringList(List stringList) { + this.stringList = stringList; + } + + public ArrayList getStringArrayList() { + return stringArrayList; + } + + public void setStringArrayList(ArrayList stringArrayList) { + this.stringArrayList = stringArrayList; + } + + public Set getStringSet() { + return stringSet; + } + + public void setStringSet(Set stringSet) { + this.stringSet = stringSet; + } + + public HashSet getStringHashSet() { + return stringHashSet; + } + + public void setStringHashSet(HashSet stringHashSet) { + this.stringHashSet = stringHashSet; + } + + public Collection getStringCollection() { + return stringCollection; + } + + public void setStringCollection(Collection stringCollection) { + this.stringCollection = stringCollection; + } + + public List getIntegerList() { + return integerList; + } + + public void setIntegerList(List integerList) { + this.integerList = integerList; + } + + public Set getIntegerSet() { + return integerSet; + } + + public void setIntegerSet(Set integerSet) { + this.integerSet = integerSet; + } + + public Set getAnotherIntegerSet() { + return anotherIntegerSet; + } + + public void setAnotherIntegerSet(Set anotherIntegerSet) { + this.anotherIntegerSet = anotherIntegerSet; + } + + public Set getColours() { + return colours; + } + + public void setColours(Set colours) { + this.colours = colours; + } + + public Map getStringLongMap() { + return stringLongMap; + } + + public void setStringLongMap(Map stringLongMap) { + this.stringLongMap = stringLongMap; + } + + public List getStringList2() { + return stringList2; + } + + public void setStringList2(List stringList2) { + this.stringList2 = stringList2; + } + + public List getOtherStringList() { + return otherStringList; + } + + public void setOtherStringList(List otherStringList) { + this.otherStringList = otherStringList; + } + + public Map getOtherStringLongMap() { + return otherStringLongMap; + } + + public void setOtherStringLongMap(Map otherStringLongMap) { + this.otherStringLongMap = otherStringLongMap; + } + + public Set getStringSet2() { + return stringSet2; + } + + public void setStringSet2(Set stringSet2) { + this.stringSet2 = stringSet2; + } + + public EnumSet getEnumSet() { + return enumSet; + } + + public void setEnumSet(EnumSet enumSet) { + this.enumSet = enumSet; + } + + public List getStringList3() { + return stringList3; + } + + public void setStringList3(List stringList3) { + this.stringList3 = stringList3; + } + + public Map getStringLongMapForNonGeneric() { + return stringLongMapForNonGeneric; + } + + public void setStringLongMapForNonGeneric(Map stringLongMapForNonGeneric) { + this.stringLongMapForNonGeneric = stringLongMapForNonGeneric; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/SourceTargetMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/SourceTargetMapper.java new file mode 100644 index 0000000..5137f3a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/SourceTargetMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection; + +import org.springframework.stereotype.Component; + +@Component +public class SourceTargetMapper { + + protected StringHolder toStringHolder(String string) { + return new StringHolder( string ); + } + + protected String toString(StringHolder string) { + return string.getString(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolder.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolder.java new file mode 100644 index 0000000..88860e1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolder.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection; + +/** + * @author Andreas Gudian + * + */ +public class StringHolder { + private final String string; + + public StringHolder(String string) { + this.string = string; + } + + public String getString() { + return string; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( string == null ) ? 0 : string.hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + StringHolder other = (StringHolder) obj; + if ( string == null ) { + return other.string == null; + } + else { + return string.equals( other.string ); + } + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolderArrayList.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolderArrayList.java new file mode 100644 index 0000000..c19ebe0 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolderArrayList.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 io.github.linpeilie.me.collection; + +import java.util.ArrayList; + +/** + * @author Stefan May + */ +public class StringHolderArrayList extends ArrayList { + + private static final long serialVersionUID = 1L; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolderToLongMap.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolderToLongMap.java new file mode 100644 index 0000000..4a0e941 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/StringHolderToLongMap.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection; + +import java.util.HashMap; + +/** + * @author Stefan May + */ +public class StringHolderToLongMap extends HashMap { + + private static final long serialVersionUID = 1L; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Target.java new file mode 100644 index 0000000..96e4158 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/Target.java @@ -0,0 +1,197 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class Target { + + //CHECKSTYLE:OFF + public List publicStringList; + //CHECKSTYLE:On + + private List stringList; + private List otherStringList; + private ArrayList stringArrayList; + + private Set stringSet; + private HashSet stringHashSet; + + private Collection stringCollection; + + private Collection integerCollection; + + private Set anotherStringSet; + + private Set colours; + + private Map stringLongMap; + private Map otherStringLongMap; + + private List stringListNoSetter; + + private List stringListNoSetter2; + + @SuppressWarnings( "rawtypes" ) + private Set set; + + private EnumSet enumSet; + + private StringHolderArrayList nonGenericStringList; + + private StringHolderToLongMap nonGenericMapStringtoLong; + + public Target() { + otherStringLongMap = new HashMap<>(); + otherStringLongMap.put( "not-present-after-mapping", 42L ); + + otherStringList = new ArrayList<>(); + otherStringList.add( "not-present-after-mapping" ); + } + + public List getStringList() { + return stringList; + } + + public void setStringList(List stringList) { + this.stringList = stringList; + } + + public ArrayList getStringArrayList() { + return stringArrayList; + } + + public void setStringArrayList(ArrayList stringArrayList) { + this.stringArrayList = stringArrayList; + } + + public Set getStringSet() { + return stringSet; + } + + public void setStringSet(Set stringSet) { + this.stringSet = stringSet; + } + + public HashSet getStringHashSet() { + return stringHashSet; + } + + public void setStringHashSet(HashSet stringHashSet) { + this.stringHashSet = stringHashSet; + } + + public Collection getStringCollection() { + return stringCollection; + } + + public void setStringCollection(Collection stringCollection) { + this.stringCollection = stringCollection; + } + + public Collection getIntegerCollection() { + return integerCollection; + } + + public void setIntegerCollection(Collection integerCollection) { + this.integerCollection = integerCollection; + } + + @SuppressWarnings("rawtypes") + public Set getSet() { + return set; + } + + @SuppressWarnings("rawtypes") + public void setSet(Set set) { + this.set = set; + } + + public Set getAnotherStringSet() { + return anotherStringSet; + } + + public void setAnotherStringSet(Set anotherStringSet) { + this.anotherStringSet = anotherStringSet; + } + + public void setColours(Set colours) { + this.colours = colours; + } + + public Set getColours() { + return colours; + } + + public Map getStringLongMap() { + return stringLongMap; + } + + public void setStringLongMap(Map stringLongMap) { + this.stringLongMap = stringLongMap; + } + + public List getStringListNoSetter() { + if ( stringListNoSetter == null ) { + stringListNoSetter = new ArrayList<>(); + } + return stringListNoSetter; + } + + public List getStringListNoSetter2() { + if ( stringListNoSetter2 == null ) { + stringListNoSetter2 = new ArrayList<>(); + } + return stringListNoSetter2; + } + + public Map getOtherStringLongMap() { + return otherStringLongMap; + } + + public void setOtherStringLongMap(Map otherStringLongMap) { + this.otherStringLongMap = otherStringLongMap; + } + + public List getOtherStringList() { + return otherStringList; + } + + public void setOtherStringList(List otherStringList) { + this.otherStringList = otherStringList; + } + + public EnumSet getEnumSet() { + return enumSet; + } + + public void setEnumSet(EnumSet enumSet) { + this.enumSet = enumSet; + } + + public StringHolderArrayList getNonGenericStringList() { + return nonGenericStringList; + } + + public void setNonGenericStringList(StringHolderArrayList nonGenericStringList) { + this.nonGenericStringList = nonGenericStringList; + } + + public StringHolderToLongMap getNonGenericMapStringtoLong() { + return nonGenericMapStringtoLong; + } + + public void setNonGenericMapStringtoLong(StringHolderToLongMap nonGenericMapStringtoLong) { + this.nonGenericMapStringtoLong = nonGenericMapStringtoLong; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/TestList.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/TestList.java new file mode 100644 index 0000000..663627e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/TestList.java @@ -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 io.github.linpeilie.me.collection; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * @author Sjaak Derksen + */ +public class TestList extends ArrayList { + + private static final long serialVersionUID = 1L; + + private static boolean addAllCalled = false; + + public static boolean isAddAllCalled() { + return addAllCalled; + } + + public static void setAddAllCalled(boolean addAllCalled) { + TestList.addAllCalled = addAllCalled; + } + + @Override + public boolean addAll(Collection c) { + addAllCalled = true; + return super.addAll( c ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/TestMap.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/TestMap.java new file mode 100644 index 0000000..341a4e5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/TestMap.java @@ -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 io.github.linpeilie.me.collection; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Sjaak Derksen + */ +public class TestMap extends HashMap { + + private static final long serialVersionUID = 1L; + + private static boolean puttAllCalled = false; + + public static boolean isPuttAllCalled() { + return puttAllCalled; + } + + public static void setPuttAllCalled(boolean puttAllCalled) { + TestMap.puttAllCalled = puttAllCalled; + } + + @Override + public void putAll(Map m) { + puttAllCalled = true; + super.putAll( m ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/CatException.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/CatException.java new file mode 100644 index 0000000..54f3522 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/CatException.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder; + +/** + * @author Sjaak Derksen + */ +public class CatException extends Exception { + + private static final long serialVersionUID = 1L; + + public CatException() { + } + + public CatException(String msg) { + super( msg ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/DogException.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/DogException.java new file mode 100644 index 0000000..391892c --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/DogException.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder; + +/** + * @author Sjaak Derksen + */ +public class DogException extends Exception { + + private static final long serialVersionUID = 1L; + + public DogException() { + } + + public DogException(String msg) { + super( msg ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/PetMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/PetMapper.java new file mode 100644 index 0000000..4935452 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/PetMapper.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder; + +import com.google.common.collect.ImmutableMap; +import io.github.linpeilie.me.collection.adder._target.IndoorPet; +import io.github.linpeilie.me.collection.adder._target.OutdoorPet; +import io.github.linpeilie.me.collection.adder._target.Pet; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.mapstruct.TargetType; +import org.springframework.stereotype.Component; + +/** + * @author Sjaak Derksen + */ +@Component +public class PetMapper { + + private static final Map PETS_TO_TARGET = ImmutableMap.builder() + .put( "rabbit", 1L ) + .put( "mouse", 2L ).build(); + + private static final Map PETS_TO_SOURCE = ImmutableMap.builder() + .put( 1L, "rabbit" ) + .put( 2L, "mouse" ) + .put( 3L, "cat" ) + .put( 4L, "dog" ).build(); + + /** + * method to be used when using an adder + * + * @param pet + * + * @return + * + * @throws CatException + * @throws DogException + */ + public Long toPet(String pet) throws CatException, DogException { + if ( "cat".equals( pet ) ) { + throw new CatException(); + } + else if ( "dog".equals( pet ) ) { + throw new DogException(); + } + return PETS_TO_TARGET.get( pet ); + } + + /** + * Method to be used when not using an adder + * + * @param pets + * + * @return + * + * @throws CatException + * @throws DogException + */ + public List toPets(List pets) throws CatException, DogException { + List result = new ArrayList<>(); + for ( String pet : pets ) { + result.add( toPet( pet ) ); + } + return result; + } + + @SuppressWarnings("unchecked") + public T toPet(String pet, @TargetType Class clazz) throws CatException, DogException { + if ( clazz == IndoorPet.class ) { + return (T) new IndoorPet( toPet( pet ) ); + } + if ( clazz == OutdoorPet.class ) { + return (T) new OutdoorPet( toPet( pet ) ); + } + return null; + } + + public List toSourcePets(List pets) throws CatException, DogException { + List result = new ArrayList<>(); + for ( Long pet : pets ) { + result.add( PETS_TO_SOURCE.get( pet ) ); + } + return result; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/TeethMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/TeethMapper.java new file mode 100644 index 0000000..94f0d3b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/TeethMapper.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 io.github.linpeilie.me.collection.adder; + +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import org.springframework.stereotype.Component; + +/** + * @author Sjaak Derksen + */ +@Component +public class TeethMapper { + + private static final Map TEETH = ImmutableMap.builder() + .put( "incisor", 1 ) + .put( "canine", 2 ) + .put( "moler", 3 ).build(); + + public Integer toTooth(String tooth) { + return TEETH.get( tooth ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/AdderUsageObserver.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/AdderUsageObserver.java new file mode 100644 index 0000000..59992e4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/AdderUsageObserver.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 io.github.linpeilie.me.collection.adder._target; + +/** + * @author Sjaak Derksen + */ +public class AdderUsageObserver { + + private AdderUsageObserver() { + } + + private static boolean used = false; + + public static boolean isUsed() { + return used; + } + + public static void setUsed(boolean used) { + AdderUsageObserver.used = used; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/IndoorPet.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/IndoorPet.java new file mode 100644 index 0000000..55ee799 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/IndoorPet.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 io.github.linpeilie.me.collection.adder._target; + +/** + * @author Sjaak Derksen + */ +public class IndoorPet extends Pet { + + private Long value; + + public IndoorPet(Long value) { + this.value = value; + } + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/OutdoorPet.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/OutdoorPet.java new file mode 100644 index 0000000..908948d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/OutdoorPet.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 io.github.linpeilie.me.collection.adder._target; + +/** + * @author Sjaak Derksen + */ +public class OutdoorPet extends Pet { + + private Long value; + + public OutdoorPet(Long value) { + this.value = value; + } + + public Long getValue() { + return value; + } + + public void setValue(Long value) { + this.value = value; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Pet.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Pet.java new file mode 100644 index 0000000..eeb4567 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Pet.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder._target; + +/** + * @author Sjaak Derksen + */ +public class Pet { + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target.java new file mode 100644 index 0000000..aea270c --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class Target { + + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } + + public void addCat(Long cat) { + // dummy method to test selection mechanism + } + + public void addDog(Long cat) { + // dummy method to test selection mechanism + } + + public void addPets(Long cat) { + // dummy method to test selection mechanism + } + + public Long addPet(Long pet) { + AdderUsageObserver.setUsed( true ); + if ( pets == null ) { + pets = new ArrayList<>(); + } + pets.add( pet ); + return pet; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target2.java new file mode 100644 index 0000000..c78eaad --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target2.java @@ -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 io.github.linpeilie.me.collection.adder._target; + +import io.github.linpeilie.me.collection.adder.source.Foo; +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Sjaak Derksen + */ +public class Target2 { + + private List attributes = new ArrayList(); + + public Foo addAttribute( Foo foo ) { + attributes.add( foo ); + return foo; + } + + public List getAttributes() { + return attributes; + } + + public void setAttributes( List attributes ) { + this.attributes = attributes; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target3.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target3.java new file mode 100644 index 0000000..78b1007 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/Target3.java @@ -0,0 +1,38 @@ +package io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +public class Target3 { + + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } + + public void addCat(Long cat) { + // dummy method to test selection mechanism + } + + public void addDog(Long cat) { + // dummy method to test selection mechanism + } + + public void addPets(Long cat) { + // dummy method to test selection mechanism + } + + public Long addPet(Long pet) { + AdderUsageObserver.setUsed( true ); + if ( pets == null ) { + pets = new ArrayList<>(); + } + pets.add( pet ); + return pet; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetDali.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetDali.java new file mode 100644 index 0000000..2ce6081 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetDali.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 io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class TargetDali { + + private List teeth; + + public List getTeeth() { + return teeth; + } + + public void setTeeth(List teeth) { + this.teeth = teeth; + } + + public void addTeeth(Integer tooth) { + AdderUsageObserver.setUsed( true ); + if ( teeth == null ) { + teeth = new ArrayList<>(); + } + teeth.add( tooth ); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetHuman.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetHuman.java new file mode 100644 index 0000000..1050c13 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetHuman.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class TargetHuman { + + private List teeth; + + public List getTeeth() { + return teeth; + } + + public void setTeeth(List teeth) { + this.teeth = teeth; + } + + public void addTooth(Integer pet) { + AdderUsageObserver.setUsed( true ); + if ( teeth == null ) { + teeth = new ArrayList<>(); + } + teeth.add( pet ); + } + + public void addTeeth(Integer tooth) { + if ( teeth == null ) { + teeth = new ArrayList<>(); + } + teeth.add( tooth ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetOnlyGetter.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetOnlyGetter.java new file mode 100644 index 0000000..f885823 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetOnlyGetter.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class TargetOnlyGetter { + + private List pets; + + public List getPets() { + return pets; + } + + public void addCat(Long cat) { + // dummy method to test selection mechanism + } + + public void addDog(Long cat) { + // dummy method to test selection mechanism + } + + public void addPets(Long cat) { + // dummy method to test selection mechanism + } + + public void addPet(Long pet) { + AdderUsageObserver.setUsed( true ); + if ( pets == null ) { + pets = new ArrayList<>(); + } + pets.add( pet ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetViaTargetType.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetViaTargetType.java new file mode 100644 index 0000000..b7e83e3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetViaTargetType.java @@ -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 io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class TargetViaTargetType { + + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } + + public void addPet(IndoorPet pet) { + AdderUsageObserver.setUsed( true ); + if ( pets == null ) { + pets = new ArrayList<>(); + } + pets.add( pet ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetWithAnimals.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetWithAnimals.java new file mode 100644 index 0000000..f1c6e5a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetWithAnimals.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class TargetWithAnimals { + + private List animals = new ArrayList<>(); + + public List getAnimals() { + return animals; + } + + public void setAnimals(List animals) { + this.animals = animals; + } + + public void addAnimal(String animal) { + animals.add( animal ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetWithoutSetter.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetWithoutSetter.java new file mode 100644 index 0000000..432e9a7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/_target/TargetWithoutSetter.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class TargetWithoutSetter { + + private List pets; + + public List getPets() { + return pets; + } + + public void addPet(Long pet) { + AdderUsageObserver.setUsed( true ); + if ( pets == null ) { + pets = new ArrayList<>(); + } + pets.add( pet ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Foo.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Foo.java new file mode 100644 index 0000000..b32bcc5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Foo.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.adder.source; + +/** + * + * @author Sjaak Derksen + */ +public class Foo { + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SingleElementSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SingleElementSource.java new file mode 100644 index 0000000..2c8ecf2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SingleElementSource.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 io.github.linpeilie.me.collection.adder.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.me.collection.adder.PetMapper; +import io.github.linpeilie.me.collection.adder.TeethMapper; +import io.github.linpeilie.me.collection.adder._target.Target; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapping; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = Target.class, reverseConvertGenerate = false, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = { + PetMapper.class, TeethMapper.class}) +public class SingleElementSource { + + @AutoMapping(target = "pets") + private String pet; + + public String getPet() { + return pet; + } + + public void setPet(String pet) { + this.pet = pet; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source.java new file mode 100644 index 0000000..e229a4f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.collection.adder.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.me.collection.adder.PetMapper; +import io.github.linpeilie.me.collection.adder.TeethMapper; +import io.github.linpeilie.me.collection.adder._target.Target; +import io.github.linpeilie.me.collection.adder._target.TargetOnlyGetter; +import io.github.linpeilie.me.collection.adder._target.TargetViaTargetType; +import io.github.linpeilie.me.collection.adder._target.TargetWithoutSetter; +import java.util.List; +import org.mapstruct.CollectionMappingStrategy; + +/** + * @author Sjaak Derksen + */ +@AutoMappers({ + @AutoMapper(target = Target.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = { + PetMapper.class, TeethMapper.class}), + @AutoMapper(target = TargetOnlyGetter.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = { + PetMapper.class, TeethMapper.class}), + @AutoMapper(target = TargetViaTargetType.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, uses = { + PetMapper.class, TeethMapper.class}, reverseConvertGenerate = false), + @AutoMapper(target = TargetWithoutSetter.class, + collectionMappingStrategy = CollectionMappingStrategy.SETTER_PREFERRED, + uses = {PetMapper.class} + ) +}) +public class Source { + + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source2.java new file mode 100644 index 0000000..aa98004 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source2.java @@ -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 io.github.linpeilie.me.collection.adder.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.me.collection.adder._target.Target2; +import java.util.List; +import org.mapstruct.CollectionMappingStrategy; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = Target2.class, + reverseConvertGenerate = false, + collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public class Source2 { + + private List attributes; + + public List getAttributes() { + return attributes; + } + + public void setAttributes(List attributes) { + this.attributes = attributes; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source3.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source3.java new file mode 100644 index 0000000..d9d6068 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/Source3.java @@ -0,0 +1,20 @@ +package io.github.linpeilie.me.collection.adder.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.me.collection.adder.PetMapper; +import io.github.linpeilie.me.collection.adder._target.Target3; +import java.util.List; + +@AutoMapper(target = Target3.class, uses = PetMapper.class) +public class Source3 { + + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SourceTeeth.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SourceTeeth.java new file mode 100644 index 0000000..40af0a9 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SourceTeeth.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 io.github.linpeilie.me.collection.adder.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.me.collection.adder.PetMapper; +import io.github.linpeilie.me.collection.adder.TeethMapper; +import io.github.linpeilie.me.collection.adder._target.TargetDali; +import io.github.linpeilie.me.collection.adder._target.TargetHuman; +import java.util.List; +import org.mapstruct.CollectionMappingStrategy; + +/** + * @author Sjaak Derksen + */ +@AutoMappers({ + @AutoMapper(target = TargetDali.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, + uses = {PetMapper.class, TeethMapper.class}), + @AutoMapper(target = TargetHuman.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED, + uses = {PetMapper.class, TeethMapper.class}) +}) +public class SourceTeeth { + + private List teeth; + + public List getTeeth() { + return teeth; + } + + public void setTeeth(List teeth) { + this.teeth = teeth; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SourceWithPets.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SourceWithPets.java new file mode 100644 index 0000000..4a7e684 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/adder/source/SourceWithPets.java @@ -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 io.github.linpeilie.me.collection.adder.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.me.collection.adder._target.TargetWithAnimals; +import java.util.List; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapping; + +/** + * @author Filip Hrisafov + */ +@AutoMapper(target = TargetWithAnimals.class, collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public class SourceWithPets { + + @AutoMapping(target = "animals") + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/NoSetterSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/NoSetterSource.java new file mode 100644 index 0000000..6a77b9b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/NoSetterSource.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 io.github.linpeilie.me.collection.defaultimplementation; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import java.util.List; +import java.util.Map; + +/** + * @author Andreas Gudian + * + */ +@AutoMappers({ + @AutoMapper(target = NoSetterTarget.class) +}) +public class NoSetterSource { + private List listValues; + private Map mapValues; + + public List getListValues() { + return listValues; + } + + public void setListValues(List listValues) { + this.listValues = listValues; + } + + public Map getMapValues() { + return mapValues; + } + + public void setMapValues(Map mapValues) { + this.mapValues = mapValues; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/NoSetterTarget.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/NoSetterTarget.java new file mode 100644 index 0000000..ff301c8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/NoSetterTarget.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.defaultimplementation; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Andreas Gudian + * + */ +public class NoSetterTarget { + private List listValues = new ArrayList(); + private Map mapValues = new HashMap(); + + public List getListValues() { + return listValues; + } + + public Map getMapValues() { + return mapValues; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/Source.java new file mode 100644 index 0000000..59bf333 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/Source.java @@ -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 io.github.linpeilie.me.collection.defaultimplementation; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.List; +import org.mapstruct.Mapping; + +@AutoMappers({ + @AutoMapper(target = Target.class) +}) +public class Source { + + @AutoMapping(target = "fooListNoSetter") + private List fooList; + + public List getFooList() { + return fooList; + } + + public void setFooList(List fooList) { + this.fooList = fooList; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/SourceFoo.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/SourceFoo.java new file mode 100644 index 0000000..9976ebc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/SourceFoo.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.defaultimplementation; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = TargetFoo.class) +public class SourceFoo { + + private String name; + + public SourceFoo() { + } + + public SourceFoo(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/Target.java new file mode 100644 index 0000000..c5d0442 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/Target.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.defaultimplementation; + +import java.util.ArrayList; +import java.util.List; + +public class Target { + + private List fooListNoSetter; + + public List getFooListNoSetter() { + if ( fooListNoSetter == null ) { + fooListNoSetter = new ArrayList<>(); + } + return fooListNoSetter; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/TargetFoo.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/TargetFoo.java new file mode 100644 index 0000000..cf033f1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/defaultimplementation/TargetFoo.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.defaultimplementation; + +public class TargetFoo implements Comparable { + + private String name; + + public TargetFoo() { + } + + public TargetFoo(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( name == null ) ? 0 : name.hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + TargetFoo other = (TargetFoo) obj; + if ( name == null ) { + return other.name == null; + } + else { + return name.equals( other.name ); + } + } + + @Override + public int compareTo(TargetFoo o) { + return getName().compareTo( o.getName() ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Bar.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Bar.java new file mode 100644 index 0000000..5031bf5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Bar.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.forged; + +/** + * + * @author Sjaak Derksen + */ +public class Bar { + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Foo.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Foo.java new file mode 100644 index 0000000..51f6467 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Foo.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.forged; + +/** + * + * @author Sjaak Derksen + */ +public class Foo { + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Source.java new file mode 100644 index 0000000..f5bec01 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Source.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.forged; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Map; +import java.util.Set; + +@AutoMapper(target = Target.class) +public class Source { + + //CHECKSTYLE:OFF + public Set publicFooSet; + //CHECKSTYLE:ON + private Set fooSet; + private Set fooSet2; + + //CHECKSTYLE:OFF + public Map publicBarMap; + //CHECKSTYLE:ON + private Map barMap; + private Map barMap2; + + public Set getFooSet() { + return fooSet; + } + + public void setFooSet(Set fooSet) { + this.fooSet = fooSet; + } + + public Map getBarMap() { + return barMap; + } + + public void setBarMap(Map barMap) { + this.barMap = barMap; + } + + public Set getFooSet2() { + return fooSet2; + } + + public void setFooSet2( Set fooSet2 ) { + this.fooSet2 = fooSet2; + } + + public Map getBarMap2() { + return barMap2; + } + + public void setBarMap2( Map barMap2 ) { + this.barMap2 = barMap2; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Source1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Source1.java new file mode 100644 index 0000000..f0f5fb7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Source1.java @@ -0,0 +1,54 @@ +package io.github.linpeilie.me.collection.forged; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Map; +import java.util.Set; +import org.mapstruct.NullValueMappingStrategy; + +@AutoMapper(target = Target1.class, nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) +public class Source1 { + + //CHECKSTYLE:OFF + public Set publicFooSet; + //CHECKSTYLE:ON + private Set fooSet; + private Set fooSet2; + + //CHECKSTYLE:OFF + public Map publicBarMap; + //CHECKSTYLE:ON + private Map barMap; + private Map barMap2; + + public Set getFooSet() { + return fooSet; + } + + public void setFooSet(Set fooSet) { + this.fooSet = fooSet; + } + + public Map getBarMap() { + return barMap; + } + + public void setBarMap(Map barMap) { + this.barMap = barMap; + } + + public Set getFooSet2() { + return fooSet2; + } + + public void setFooSet2( Set fooSet2 ) { + this.fooSet2 = fooSet2; + } + + public Map getBarMap2() { + return barMap2; + } + + public void setBarMap2( Map barMap2 ) { + this.barMap2 = barMap2; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Target.java new file mode 100644 index 0000000..f9f35e3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Target.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.forged; + +import java.util.Map; +import java.util.Set; + +public class Target { + + private Set fooSet; + private Set fooSet2; + private Map barMap; + private Map barMap2; + + private Set publicFooSet; + private Map publicBarMap; + + public Set getFooSet() { + return fooSet; + } + + public void setFooSet(Set fooSet) { + this.fooSet = fooSet; + } + + public Map getBarMap() { + return barMap; + } + + public void setBarMap(Map barMap) { + this.barMap = barMap; + } + + public Set getFooSet2() { + return fooSet2; + } + + public void setFooSet2( Set fooSet2 ) { + this.fooSet2 = fooSet2; + } + + public Map getBarMap2() { + return barMap2; + } + + public void setBarMap2( Map barMap2 ) { + this.barMap2 = barMap2; + } + + public Set getPublicFooSet() { + return publicFooSet; + } + + public void setPublicFooSet(Set publicFooSet) { + this.publicFooSet = publicFooSet; + } + + public Map getPublicBarMap() { + return publicBarMap; + } + + public void setPublicBarMap(Map publicBarMap) { + this.publicBarMap = publicBarMap; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Target1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Target1.java new file mode 100644 index 0000000..d098c92 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/forged/Target1.java @@ -0,0 +1,66 @@ +package io.github.linpeilie.me.collection.forged; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Map; +import java.util.Set; +import org.mapstruct.NullValueMappingStrategy; + +@AutoMapper(target = Source1.class, nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) +public class Target1 { + + private Set fooSet; + private Set fooSet2; + private Map barMap; + private Map barMap2; + + private Set publicFooSet; + private Map publicBarMap; + + public Set getFooSet() { + return fooSet; + } + + public void setFooSet(Set fooSet) { + this.fooSet = fooSet; + } + + public Map getBarMap() { + return barMap; + } + + public void setBarMap(Map barMap) { + this.barMap = barMap; + } + + public Set getFooSet2() { + return fooSet2; + } + + public void setFooSet2( Set fooSet2 ) { + this.fooSet2 = fooSet2; + } + + public Map getBarMap2() { + return barMap2; + } + + public void setBarMap2( Map barMap2 ) { + this.barMap2 = barMap2; + } + + public Set getPublicFooSet() { + return publicFooSet; + } + + public void setPublicFooSet(Set publicFooSet) { + this.publicFooSet = publicFooSet; + } + + public Map getPublicBarMap() { + return publicBarMap; + } + + public void setPublicBarMap(Map publicBarMap) { + this.publicBarMap = publicBarMap; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/immutabletarget/CupboardDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/immutabletarget/CupboardDto.java new file mode 100644 index 0000000..628ce93 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/immutabletarget/CupboardDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.collection.immutabletarget; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import java.util.List; +import org.mapstruct.CollectionMappingStrategy; + +/** + * @author Sjaak Derksen + */ +@AutoMappers({ + @AutoMapper(target = CupboardEntity.class, collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE), +}) +public class CupboardDto { + + private List content; + + public List getContent() { + return content; + } + + public void setContent(List content) { + this.content = content; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/immutabletarget/CupboardEntity.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/immutabletarget/CupboardEntity.java new file mode 100644 index 0000000..7aec2a5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/immutabletarget/CupboardEntity.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 io.github.linpeilie.me.collection.immutabletarget; + +import java.util.List; + +/** + * + * @author Sjaak Derksen + */ +public class CupboardEntity { + + private List content; + + public List getContent() { + return content; + } + + public void setContent(List content) { + this.content = content; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Fruit.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Fruit.java new file mode 100644 index 0000000..5a0eeba --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Fruit.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.iterabletononiterable; + +/** + * + * @author Saheb Preet Singh + */ +public class Fruit { + + private String type; + + public Fruit(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/FruitSalad.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/FruitSalad.java new file mode 100644 index 0000000..8fc679a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/FruitSalad.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.iterabletononiterable; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.List; + +/** + * + * @author Saheb Preet Singh + */ +@AutoMapper(target = FruitsMenu.class) +public class FruitSalad { + + private List fruits; + + public FruitSalad(List fruits) { + this.fruits = fruits; + } + + public List getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/FruitsMenu.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/FruitsMenu.java new file mode 100644 index 0000000..c769bdc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/FruitsMenu.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 io.github.linpeilie.me.collection.iterabletononiterable; + +import java.util.Iterator; +import java.util.List; + +/** + * + * @author Saheb Preet Singh + */ +public class FruitsMenu implements Iterable { + + private List fruits; + + public FruitsMenu(List fruits) { + this.fruits = fruits; + } + + public List getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } + + @Override + public Iterator iterator() { + return this.fruits.iterator(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Source.java new file mode 100644 index 0000000..15d37d3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Source.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.iterabletononiterable; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.List; + +@AutoMapper(target = Target.class, uses = StringListMapper.class) +public class Source { + + //CHECKSTYLE:OFF + public List publicNames; + //CHECKSTYLE:ON + + private List names; + + public List getNames() { + return names; + } + + public void setNames(List names) { + this.names = names; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/StringListMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/StringListMapper.java new file mode 100644 index 0000000..2ac0113 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/StringListMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.collection.iterabletononiterable; + +import java.util.Arrays; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class StringListMapper { + + public String stringListToString(List strings) { + return strings == null ? null : String.join( "-", strings ); + } + + public List stringToStringList(String string) { + return string == null ? null : Arrays.asList( string.split( "-" ) ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Target.java new file mode 100644 index 0000000..a1a6a2f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/collection/iterabletononiterable/Target.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 io.github.linpeilie.me.collection.iterabletononiterable; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = Source.class, uses = StringListMapper.class) +public class Target { + + //CHECKSTYLE:OFF + public String publicNames; + //CHECKSTYLE:ON + + private String names; + + public String getNames() { + return names; + } + + public void setNames(String names) { + this.names = names; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/_target/CarDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/_target/CarDto.java new file mode 100644 index 0000000..ae57e8a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/_target/CarDto.java @@ -0,0 +1,86 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.complex._target; + +import java.util.List; + +public class CarDto { + + private String make; + private int seatCount; + private String manufacturingYear; + private PersonDto driver; + private List passengers; + private Long price; + private String category; + + public CarDto() { + } + + public CarDto(String make, int seatCount, String manufacturingYear, PersonDto driver, List passengers) { + this.make = make; + this.seatCount = seatCount; + this.manufacturingYear = manufacturingYear; + this.driver = driver; + this.passengers = passengers; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getSeatCount() { + return seatCount; + } + + public void setSeatCount(int seatCount) { + this.seatCount = seatCount; + } + + public String getManufacturingYear() { + return manufacturingYear; + } + + public void setManufacturingYear(String manufacturingYear) { + this.manufacturingYear = manufacturingYear; + } + + public PersonDto getDriver() { + return driver; + } + + public void setDriver(PersonDto driver) { + this.driver = driver; + } + + public List getPassengers() { + return passengers; + } + + public void setPassengers(List passengers) { + this.passengers = passengers; + } + + public Long getPrice() { + return price; + } + + public void setPrice(Long price) { + this.price = price; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/_target/PersonDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/_target/PersonDto.java new file mode 100644 index 0000000..e9a2a09 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/_target/PersonDto.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 io.github.linpeilie.me.complex._target; + +public class PersonDto { + + private String name; + + public PersonDto() { + } + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/other/DateMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/other/DateMapper.java new file mode 100644 index 0000000..67c7faa --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/other/DateMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.complex.other; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.springframework.stereotype.Component; + +@Component +public class DateMapper { + + public String asString(Date date) { + return date != null ? new SimpleDateFormat( "yyyy" ).format( date ) : null; + } + + public Date asDate(String date) { + try { + return date != null ? new SimpleDateFormat( "yyyy" ).parse( date ) : null; + } + catch ( ParseException e ) { + throw new RuntimeException( e ); + } + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Car.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Car.java new file mode 100644 index 0000000..3998717 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Car.java @@ -0,0 +1,96 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.complex.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.me.complex._target.CarDto; +import io.github.linpeilie.me.complex.other.DateMapper; +import java.util.Date; +import java.util.List; + +@AutoMapper(target = CarDto.class, uses = DateMapper.class) +public class Car { + + private String make; + + @AutoMapping(target = "seatCount") + private int numberOfSeats; + + @AutoMapping(target = "manufacturingYear") + private Date manufacturingDate; + private Person driver; + private List passengers; + private int price; + private Category category; + + public Car() { + } + + public Car(String make, int numberOfSeats, Date manufacturingDate, Person driver, List passengers) { + this.make = make; + this.numberOfSeats = numberOfSeats; + this.manufacturingDate = manufacturingDate; + this.driver = driver; + this.passengers = passengers; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getNumberOfSeats() { + return numberOfSeats; + } + + public void setNumberOfSeats(int numberOfSeats) { + this.numberOfSeats = numberOfSeats; + } + + public Date getManufacturingDate() { + return manufacturingDate; + } + + public void setManufacturingDate(Date manufacturingDate) { + this.manufacturingDate = manufacturingDate; + } + + public Person getDriver() { + return driver; + } + + public void setDriver(Person driver) { + this.driver = driver; + } + + public List getPassengers() { + return passengers; + } + + public void setPassengers(List passengers) { + this.passengers = passengers; + } + + public int getPrice() { + return price; + } + + public void setPrice(int price) { + this.price = price; + } + + public Category getCategory() { + return category; + } + + public void setCategory(Category category) { + this.category = category; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Category.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Category.java new file mode 100644 index 0000000..c9ce310 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Category.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.complex.source; + +public enum Category { + SEDAN, CONVERTIBLE, TRUCK; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Person.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Person.java new file mode 100644 index 0000000..207357c --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/complex/source/Person.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.complex.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.me.complex._target.PersonDto; +import io.github.linpeilie.me.complex.other.DateMapper; + +@AutoMapper(target = PersonDto.class, uses = DateMapper.class) +public class Person { + + private String name; + + public Person() { + } + + public Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/Author.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/Author.java new file mode 100644 index 0000000..14de4c5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/Author.java @@ -0,0 +1,24 @@ +package io.github.linpeilie.me.conditional.basic; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.List; + +@AutoMapper(target = AuthorDto.class, reverseConvertGenerate = false, + uses = ConditionalMethodForCollectionMapper.class) +public class Author { + + private List books; + + public List getBooks() { + return books; + } + + public boolean hasBooks() { + return false; + } + + public void setBooks(List books) { + this.books = books; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/AuthorDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/AuthorDto.java new file mode 100644 index 0000000..a38d508 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/AuthorDto.java @@ -0,0 +1,17 @@ +package io.github.linpeilie.me.conditional.basic; + +import java.util.List; + +public class AuthorDto { + + private List books; + + public List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee.java new file mode 100644 index 0000000..f2d822a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployee { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee1.java new file mode 100644 index 0000000..2e5995e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee1.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployee1 { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee2.java new file mode 100644 index 0000000..1bfd4b7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee2.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployee2 { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee3.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee3.java new file mode 100644 index 0000000..25827a0 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee3.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployee3 { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee4.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee4.java new file mode 100644 index 0000000..5f9d5c7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployee4.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployee4 { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployeeDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployeeDto.java new file mode 100644 index 0000000..c7432bd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BasicEmployeeDto.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.conditional.basic; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import org.mapstruct.NullValuePropertyMappingStrategy; + +/** + * @author Filip Hrisafov + */ +@AutoMappers({ + @AutoMapper(target = BasicEmployee.class, reverseConvertGenerate = false, uses = ConditionalMethodInMapper.class), + @AutoMapper(target = BasicEmployee1.class, reverseConvertGenerate = false, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, uses = ConditionalMethodWithMappingTargetInUpdateMapper.class), + @AutoMapper(target = BasicEmployee2.class, reverseConvertGenerate = false, uses = ConditionalMethodWithSourceParameterAndValueMapper.class), + @AutoMapper(target = BasicEmployee3.class, reverseConvertGenerate = false, uses = ConditionalMethodWithSourceParameterMapper.class), + @AutoMapper(target = BasicEmployee4.class, reverseConvertGenerate = false, uses = ConditionalMethodWithTargetType.class), +}) +public class BasicEmployeeDto { + + private final String name; + private final String strategy; + + public BasicEmployeeDto(String name) { + this(name, "default"); + } + + public BasicEmployeeDto(String name, String strategy) { + this.name = name; + this.strategy = strategy; + } + + public String getName() { + return name; + } + + public String getStrategy() { + return strategy; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/Book.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/Book.java new file mode 100644 index 0000000..0d99f61 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/Book.java @@ -0,0 +1,18 @@ +package io.github.linpeilie.me.conditional.basic; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = BookDto.class, reverseConvertGenerate = false) +public class Book { + + private final String name; + + public Book(String name) { + this.name = name; + } + + public String getName() { + return name; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BookDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BookDto.java new file mode 100644 index 0000000..3573d26 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/BookDto.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.conditional.basic; + +public class BookDto { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodAndBeanPresenceCheckMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodAndBeanPresenceCheckMapper.java new file mode 100644 index 0000000..fdad133 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodAndBeanPresenceCheckMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ConditionalMethodAndBeanPresenceCheckMapper { + + @Condition + public boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodForCollectionMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodForCollectionMapper.java new file mode 100644 index 0000000..e55f70b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodForCollectionMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.conditional.basic; + +import java.util.Collection; +import java.util.List; +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ConditionalMethodForCollectionMapper { + + @Condition + public boolean isNotEmpty(Collection collection) { + return collection != null && !collection.isEmpty(); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodInMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodInMapper.java new file mode 100644 index 0000000..c82049f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodInMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ConditionalMethodInMapper { + + @Condition + public boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithMappingTargetInUpdateMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithMappingTargetInUpdateMapper.java new file mode 100644 index 0000000..b089f8b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithMappingTargetInUpdateMapper.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 io.github.linpeilie.me.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +/** + * @author Ben Zegveld + */ +@Component +public class ConditionalMethodWithMappingTargetInUpdateMapper { + @Condition + public boolean isNotBlankAndNotPresent(String value, @MappingTarget BasicEmployee1 targetEmployee) { + return value != null && !value.trim().isEmpty() && targetEmployee.getName() == null; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithSourceParameterAndValueMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithSourceParameterAndValueMapper.java new file mode 100644 index 0000000..8450be5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithSourceParameterAndValueMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ConditionalMethodWithSourceParameterAndValueMapper { + + @Condition + public boolean isPresent(BasicEmployeeDto source, String value) { + if ( value == null ) { + return false; + } + switch ( source.getStrategy() ) { + case "blank": + return !value.trim().isEmpty(); + case "empty": + return !value.isEmpty(); + default: + return true; + } + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithSourceParameterMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithSourceParameterMapper.java new file mode 100644 index 0000000..f23d35f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithSourceParameterMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ConditionalMethodWithSourceParameterMapper { + + @Condition + public boolean shouldMap(BasicEmployeeDto source) { + return "map".equals(source.getStrategy()); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithTargetType.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithTargetType.java new file mode 100644 index 0000000..f934acb --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/ConditionalMethodWithTargetType.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.TargetType; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ConditionalMethodWithTargetType { + + @Condition + public boolean isNotBlank(String value, @TargetType Class targetType) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/EmployeeDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/EmployeeDto.java new file mode 100644 index 0000000..d12a9d1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/basic/EmployeeDto.java @@ -0,0 +1,21 @@ +package io.github.linpeilie.me.conditional.basic; + +import io.github.linpeilie.annotations.AutoMapper; + +@AutoMapper(target = BasicEmployee.class, reverseConvertGenerate = false, uses = ConditionalMethodAndBeanPresenceCheckMapper.class) +public class EmployeeDto { + private final String name; + + public EmployeeDto(String name) { + this.name = name; + } + + public boolean hasName() { + return false; + } + + public String getName() { + return name; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Address.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Address.java new file mode 100644 index 0000000..9849ba9 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Address.java @@ -0,0 +1,22 @@ +package io.github.linpeilie.me.conditional.expression; + +public class Address { + private String line1; + private String line2; + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Customer.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Customer.java new file mode 100644 index 0000000..ecbc3e8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Customer.java @@ -0,0 +1,22 @@ +package io.github.linpeilie.me.conditional.expression; + +public class Customer { + private String name; + private Address address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Employee.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Employee.java new file mode 100644 index 0000000..4ab467c --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Employee.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.expression; + +public class Employee { + private String name; + private String ssid; + private String nin; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSsid() { + return ssid; + } + + public void setSsid(String ssid) { + this.ssid = ssid; + } + + public String getNin() { + return nin; + } + + public void setNin(String nin) { + this.nin = nin; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/EmployeeDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/EmployeeDto.java new file mode 100644 index 0000000..56a9bb6 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/EmployeeDto.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.conditional.expression; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; + +@AutoMapper(target = Employee.class, reverseConvertGenerate = false, imports = StaticUtil.class) +public class EmployeeDto { + private String name; + private String country; + @AutoMappings({ + @AutoMapping(target = "ssid", conditionExpression = "java(StaticUtil.isAmericanCitizen( source ))"), + @AutoMapping(target = "nin", conditionExpression = "java(StaticUtil.isBritishCitizen( source ))")}) + private String uniqueIdNumber; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getUniqueIdNumber() { + return uniqueIdNumber; + } + + public void setUniqueIdNumber(String uniqueIdNumber) { + this.uniqueIdNumber = uniqueIdNumber; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Order.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Order.java new file mode 100644 index 0000000..47e2b76 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Order.java @@ -0,0 +1,15 @@ +package io.github.linpeilie.me.conditional.expression; + +public class Order { + + private Customer customer; + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/OrderDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/OrderDTO.java new file mode 100644 index 0000000..a13146b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/OrderDTO.java @@ -0,0 +1,45 @@ +package io.github.linpeilie.me.conditional.expression; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; + +@AutoMappers({@AutoMapper(target = Order.class, reverseConvertGenerate = false, imports = Util.class), + @AutoMapper(target = Customer.class, reverseConvertGenerate = false, imports = Util.class), + @AutoMapper(target = Address.class, reverseConvertGenerate = false, imports = Util.class),}) +public class OrderDTO { + + @AutoMappings({ + @AutoMapping(targetClass = Order.class, target = "customer", source = "source", conditionExpression = "java(Util.mapCustomerFromOrder( source ))"), + @AutoMapping(targetClass = Customer.class, target = "name"), + @AutoMapping(targetClass = Customer.class, target = "address", source = "source", conditionExpression = "java(Util.mapAddressFromOrder( source ))"),}) + private String customerName; + private String line1; + private String line2; + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Source.java new file mode 100644 index 0000000..b5f19e6 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Source.java @@ -0,0 +1,19 @@ +package io.github.linpeilie.me.conditional.expression; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; + +@AutoMapper(target = Target.class, reverseConvertGenerate = false) +public class Source { + + @AutoMapping(conditionExpression = "java(source.getValue() < 100)") + private final int value; + + public Source(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/StaticUtil.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/StaticUtil.java new file mode 100644 index 0000000..7e515c8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/StaticUtil.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.conditional.expression; + +public class StaticUtil { + + static boolean isAmericanCitizen(EmployeeDto employeeDto) { + return "US".equals(employeeDto.getCountry()); + } + + static boolean isBritishCitizen(EmployeeDto employeeDto) { + return "UK".equals(employeeDto.getCountry()); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Target.java new file mode 100644 index 0000000..7b22379 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Target.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.conditional.expression; + +public class Target { + private int value; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Util.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Util.java new file mode 100644 index 0000000..9e4d408 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/expression/Util.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.conditional.expression; + +public class Util { + + static boolean mapCustomerFromOrder(OrderDTO orderDTO) { + return orderDTO != null && (orderDTO.getCustomerName() != null || mapAddressFromOrder(orderDTO)); + } + + static boolean mapAddressFromOrder(OrderDTO orderDTO) { + return orderDTO != null && (orderDTO.getLine1() != null || orderDTO.getLine2() != null); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Address.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Address.java new file mode 100644 index 0000000..47c2a22 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Address.java @@ -0,0 +1,22 @@ +package io.github.linpeilie.me.conditional.qualifier; + +public class Address { + private String line1; + private String line2; + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/ConditionalMethodWithClassQualifiersMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/ConditionalMethodWithClassQualifiersMapper.java new file mode 100644 index 0000000..8958b18 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/ConditionalMethodWithClassQualifiersMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.conditional.qualifier; + +import org.mapstruct.Condition; +import org.mapstruct.Named; +import org.springframework.stereotype.Component; + +/** + * @author Filip Hrisafov + */ +@Component +public class ConditionalMethodWithClassQualifiersMapper { + + @Condition + public boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + @Condition + @Named("american") + public boolean isAmericanCitizen(EmployeeDto employerDto) { + return "US".equals(employerDto.getCountry()); + } + + @Condition + @Named("british") + public boolean isBritishCitizen(EmployeeDto employeeDto) { + return "UK".equals(employeeDto.getCountry()); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/ConditionalMethodWithSourceToTargetMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/ConditionalMethodWithSourceToTargetMapper.java new file mode 100644 index 0000000..d2a32af --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/ConditionalMethodWithSourceToTargetMapper.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 io.github.linpeilie.me.conditional.qualifier; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +/** + * @author Filip Hrisafov + */ +@Component +public class ConditionalMethodWithSourceToTargetMapper { + + @Condition + @Named("mapCustomerFromOrder") + public boolean mapCustomerFromOrder(OrderDTO orderDTO) { + return orderDTO != null && (orderDTO.getCustomerName() != null || mapAddressFromOrder(orderDTO)); + } + + @Condition + @Named("mapAddressFromOrder") + public boolean mapAddressFromOrder(OrderDTO orderDTO) { + return orderDTO != null && (orderDTO.getLine1() != null || orderDTO.getLine2() != null); + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Customer.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Customer.java new file mode 100644 index 0000000..d3b0ab2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Customer.java @@ -0,0 +1,22 @@ +package io.github.linpeilie.me.conditional.qualifier; + +public class Customer { + private String name; + private Address address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Employee.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Employee.java new file mode 100644 index 0000000..ce033b5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Employee.java @@ -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 io.github.linpeilie.me.conditional.qualifier; + +public class Employee { + + private String name; + private String ssid; + private String nin; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSsid() { + return ssid; + } + + public void setSsid(String ssid) { + this.ssid = ssid; + } + + public String getNin() { + return nin; + } + + public void setNin(String nin) { + this.nin = nin; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/EmployeeDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/EmployeeDto.java new file mode 100644 index 0000000..a528668 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/EmployeeDto.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conditional.qualifier; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; + +@AutoMapper(target = Employee.class, + reverseConvertGenerate = false, + uses = ConditionalMethodWithClassQualifiersMapper.class) +public class EmployeeDto { + + private String name; + private String country; + + @AutoMappings({ + @AutoMapping(target = "ssid", conditionQualifiedByName = "american"), + @AutoMapping(target = "nin", conditionQualifiedByName = "british") + }) + private String uniqueIdNumber; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getUniqueIdNumber() { + return uniqueIdNumber; + } + + public void setUniqueIdNumber(String uniqueIdNumber) { + this.uniqueIdNumber = uniqueIdNumber; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Order.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Order.java new file mode 100644 index 0000000..199763d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/Order.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.conditional.qualifier; + +public class Order { + private Customer customer; + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/OrderDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/OrderDTO.java new file mode 100644 index 0000000..82c3f15 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conditional/qualifier/OrderDTO.java @@ -0,0 +1,45 @@ +package io.github.linpeilie.me.conditional.qualifier; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; + +@AutoMappers({ + @AutoMapper(target = Order.class, reverseConvertGenerate = false, uses = ConditionalMethodWithSourceToTargetMapper.class), + @AutoMapper(target = Customer.class, reverseConvertGenerate = false, uses = ConditionalMethodWithSourceToTargetMapper.class), + @AutoMapper(target = Address.class, reverseConvertGenerate = false, uses = ConditionalMethodWithSourceToTargetMapper.class)}) +public class OrderDTO { + @AutoMappings({ + @AutoMapping(targetClass = Order.class, target = "customer", source = "source", conditionQualifiedByName = "mapCustomerFromOrder"), + @AutoMapping(targetClass = Customer.class, target = "name"), + @AutoMapping(targetClass = Customer.class, target = "address", source = "source", conditionQualifiedByName = "mapAddressFromOrder"), + }) + private String customerName; + private String line1; + private String line2; + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigDecimalSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigDecimalSource.java new file mode 100644 index 0000000..65f5cdd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigDecimalSource.java @@ -0,0 +1,140 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.bignumbers; + +import io.github.linpeilie.annotations.AutoMapper; +import java.math.BigDecimal; + +@AutoMapper(target = BigDecimalTarget.class) +public class BigDecimalSource { + + private BigDecimal b; + private BigDecimal bb; + private BigDecimal s; + private BigDecimal ss; + private BigDecimal i; + private BigDecimal ii; + private BigDecimal l; + private BigDecimal ll; + private BigDecimal f; + private BigDecimal ff; + private BigDecimal d; + private BigDecimal dd; + private BigDecimal string; + private BigDecimal bigInteger; + + public BigDecimal getB() { + return b; + } + + public void setB(BigDecimal b) { + this.b = b; + } + + public BigDecimal getBb() { + return bb; + } + + public void setBb(BigDecimal bb) { + this.bb = bb; + } + + public BigDecimal getS() { + return s; + } + + public void setS(BigDecimal s) { + this.s = s; + } + + public BigDecimal getSs() { + return ss; + } + + public void setSs(BigDecimal ss) { + this.ss = ss; + } + + public BigDecimal getI() { + return i; + } + + public void setI(BigDecimal i) { + this.i = i; + } + + public BigDecimal getIi() { + return ii; + } + + public void setIi(BigDecimal ii) { + this.ii = ii; + } + + public BigDecimal getL() { + return l; + } + + public void setL(BigDecimal l) { + this.l = l; + } + + public BigDecimal getLl() { + return ll; + } + + public void setLl(BigDecimal ll) { + this.ll = ll; + } + + public BigDecimal getF() { + return f; + } + + public void setF(BigDecimal f) { + this.f = f; + } + + public BigDecimal getFf() { + return ff; + } + + public void setFf(BigDecimal ff) { + this.ff = ff; + } + + public BigDecimal getD() { + return d; + } + + public void setD(BigDecimal d) { + this.d = d; + } + + public BigDecimal getDd() { + return dd; + } + + public void setDd(BigDecimal dd) { + this.dd = dd; + } + + public BigDecimal getString() { + return string; + } + + public void setString(BigDecimal string) { + this.string = string; + } + + public BigDecimal getBigInteger() { + return bigInteger; + } + + public void setBigInteger(BigDecimal bigInteger) { + this.bigInteger = bigInteger; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigDecimalTarget.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigDecimalTarget.java new file mode 100644 index 0000000..7c15e9c --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigDecimalTarget.java @@ -0,0 +1,138 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.bignumbers; + +import java.math.BigInteger; + +public class BigDecimalTarget { + + private byte b; + private Byte bb; + private short s; + private Short ss; + private int i; + private Integer ii; + private long l; + private Long ll; + private float f; + private Float ff; + private double d; + private Double dd; + private String string; + private BigInteger bigInteger; + + public byte getB() { + return b; + } + + public void setB(byte b) { + this.b = b; + } + + public Byte getBb() { + return bb; + } + + public void setBb(Byte bb) { + this.bb = bb; + } + + public short getS() { + return s; + } + + public void setS(short s) { + this.s = s; + } + + public Short getSs() { + return ss; + } + + public void setSs(Short ss) { + this.ss = ss; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public Integer getIi() { + return ii; + } + + public void setIi(Integer ii) { + this.ii = ii; + } + + public long getL() { + return l; + } + + public void setL(long l) { + this.l = l; + } + + public Long getLl() { + return ll; + } + + public void setLl(Long ll) { + this.ll = ll; + } + + public float getF() { + return f; + } + + public void setF(float f) { + this.f = f; + } + + public Float getFf() { + return ff; + } + + public void setFf(Float ff) { + this.ff = ff; + } + + public double getD() { + return d; + } + + public void setD(double d) { + this.d = d; + } + + public Double getDd() { + return dd; + } + + public void setDd(Double dd) { + this.dd = dd; + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + public BigInteger getBigInteger() { + return bigInteger; + } + + public void setBigInteger(BigInteger bigInteger) { + this.bigInteger = bigInteger; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigIntegerSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigIntegerSource.java new file mode 100644 index 0000000..2080202 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigIntegerSource.java @@ -0,0 +1,131 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.bignumbers; + +import io.github.linpeilie.annotations.AutoMapper; +import java.math.BigInteger; + +@AutoMapper(target = BigIntegerTarget.class) +public class BigIntegerSource { + + private BigInteger b; + private BigInteger bb; + private BigInteger s; + private BigInteger ss; + private BigInteger i; + private BigInteger ii; + private BigInteger l; + private BigInteger ll; + private BigInteger f; + private BigInteger ff; + private BigInteger d; + private BigInteger dd; + private BigInteger string; + + public BigInteger getB() { + return b; + } + + public void setB(BigInteger b) { + this.b = b; + } + + public BigInteger getBb() { + return bb; + } + + public void setBb(BigInteger bb) { + this.bb = bb; + } + + public BigInteger getS() { + return s; + } + + public void setS(BigInteger s) { + this.s = s; + } + + public BigInteger getSs() { + return ss; + } + + public void setSs(BigInteger ss) { + this.ss = ss; + } + + public BigInteger getI() { + return i; + } + + public void setI(BigInteger i) { + this.i = i; + } + + public BigInteger getIi() { + return ii; + } + + public void setIi(BigInteger ii) { + this.ii = ii; + } + + public BigInteger getL() { + return l; + } + + public void setL(BigInteger l) { + this.l = l; + } + + public BigInteger getLl() { + return ll; + } + + public void setLl(BigInteger ll) { + this.ll = ll; + } + + public BigInteger getF() { + return f; + } + + public void setF(BigInteger f) { + this.f = f; + } + + public BigInteger getFf() { + return ff; + } + + public void setFf(BigInteger ff) { + this.ff = ff; + } + + public BigInteger getD() { + return d; + } + + public void setD(BigInteger d) { + this.d = d; + } + + public BigInteger getDd() { + return dd; + } + + public void setDd(BigInteger dd) { + this.dd = dd; + } + + public BigInteger getString() { + return string; + } + + public void setString(BigInteger string) { + this.string = string; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigIntegerTarget.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigIntegerTarget.java new file mode 100644 index 0000000..0591ebd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/bignumbers/BigIntegerTarget.java @@ -0,0 +1,127 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.bignumbers; + +public class BigIntegerTarget { + + private byte b; + private Byte bb; + private short s; + private Short ss; + private int i; + private Integer ii; + private long l; + private Long ll; + private float f; + private Float ff; + private double d; + private Double dd; + private String string; + + public byte getB() { + return b; + } + + public void setB(byte b) { + this.b = b; + } + + public Byte getBb() { + return bb; + } + + public void setBb(Byte bb) { + this.bb = bb; + } + + public short getS() { + return s; + } + + public void setS(short s) { + this.s = s; + } + + public Short getSs() { + return ss; + } + + public void setSs(Short ss) { + this.ss = ss; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public Integer getIi() { + return ii; + } + + public void setIi(Integer ii) { + this.ii = ii; + } + + public long getL() { + return l; + } + + public void setL(long l) { + this.l = l; + } + + public Long getLl() { + return ll; + } + + public void setLl(Long ll) { + this.ll = ll; + } + + public float getF() { + return f; + } + + public void setF(float f) { + this.f = f; + } + + public Float getFf() { + return ff; + } + + public void setFf(Float ff) { + this.ff = ff; + } + + public double getD() { + return d; + } + + public void setD(double d) { + this.d = d; + } + + public Double getDd() { + return dd; + } + + public void setDd(Double dd) { + this.dd = dd; + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/currency/CurrencySource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/currency/CurrencySource.java new file mode 100644 index 0000000..8efd6af --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/currency/CurrencySource.java @@ -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 io.github.linpeilie.me.conversion.currency; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Currency; +import java.util.Set; + +@AutoMapper(target = CurrencyTarget.class) +public class CurrencySource { + + private Currency currencyA; + private Set uniqueCurrencies; + + public Currency getCurrencyA() { + return this.currencyA; + } + + public void setCurrencyA(final Currency currencyA) { + this.currencyA = currencyA; + } + + public Set getUniqueCurrencies() { + return this.uniqueCurrencies; + } + + public void setUniqueCurrencies(final Set uniqueCurrencies) { + this.uniqueCurrencies = uniqueCurrencies; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/currency/CurrencyTarget.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/currency/CurrencyTarget.java new file mode 100644 index 0000000..e7e1506 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/currency/CurrencyTarget.java @@ -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 io.github.linpeilie.me.conversion.currency; + +import java.util.Set; + +/** + * @author Darren Rambaud + */ +public class CurrencyTarget { + + private String currencyA; + private Set uniqueCurrencies; + + public String getCurrencyA() { + return this.currencyA; + } + + public void setCurrencyA(final String currencyA) { + this.currencyA = currencyA; + } + + public Set getUniqueCurrencies() { + return this.uniqueCurrencies; + } + + public void setUniqueCurrencies(final Set uniqueCurrencies) { + this.uniqueCurrencies = uniqueCurrencies; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/DataStringMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/DataStringMapper.java new file mode 100644 index 0000000..1adaf9a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/DataStringMapper.java @@ -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 io.github.linpeilie.me.conversion.date; + +import java.util.Date; +import java.util.List; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.IterableMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +public interface DataStringMapper { + + @IterableMapping(dateFormat = "dd.MM.yyyy") + List stringListToDateList(List dates); + + @IterableMapping(dateFormat = "dd.MM.yyyy") + String[] stringListToDateArray(List dates); + + @InheritInverseConfiguration + List dateListToStringList(List strings); + + @InheritInverseConfiguration + List stringArrayToDateList(String[] dates); + + @IterableMapping(dateFormat = "dd.MM.yyyy") + String[] dateArrayToStringArray(Date[] dates); + + @InheritInverseConfiguration + Date[] stringArrayToDateArray(String[] dates); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/Source.java new file mode 100644 index 0000000..53b03cd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/Source.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 io.github.linpeilie.me.conversion.date; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.Date; +import org.mapstruct.Mapping; + +@AutoMapper(target = Target.class, uses = DataStringMapper.class) +public class Source { + + @AutoMapping(target = "date", dateFormat = "dd.MM.yyyy") + private Date date; + private Date anotherDate; + private Date time; + private Date sqlDate; + private Date timestamp; + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public Date getAnotherDate() { + return anotherDate; + } + + public void setAnotherDate(Date anotherDate) { + this.anotherDate = anotherDate; + } + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + + public Date getSqlDate() { + return sqlDate; + } + + public void setSqlDate(Date sqlDate) { + this.sqlDate = sqlDate; + } + + public Date getTimestamp() { + return timestamp; + } + + public void setTimestamp(Date timestamp) { + this.timestamp = timestamp; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/Target.java new file mode 100644 index 0000000..d4572ee --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/date/Target.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.date; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; + +@AutoMapper(target = Source.class, uses = DataStringMapper.class) +public class Target { + + @AutoMapping(target = "date", dateFormat = "dd.MM.yyyy") + private String date; + private String anotherDate; + private Time time; + private Date sqlDate; + private Timestamp timestamp; + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + + public String getAnotherDate() { + return anotherDate; + } + + public void setAnotherDate(String anotherDate) { + this.anotherDate = anotherDate; + } + + public Time getTime() { + return time; + } + + public void setTime(Time time) { + this.time = time; + } + + public Date getSqlDate() { + return sqlDate; + } + + public void setSqlDate(Date sqlDate) { + this.sqlDate = sqlDate; + } + + public Timestamp getTimestamp() { + return timestamp; + } + + public void setTimestamp(Timestamp timestamp) { + this.timestamp = timestamp; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/lossy/CutleryInventoryDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/lossy/CutleryInventoryDto.java new file mode 100644 index 0000000..fa3c5ea --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/lossy/CutleryInventoryDto.java @@ -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 io.github.linpeilie.me.conversion.lossy; + +import io.github.linpeilie.annotations.AutoMapper; +import org.mapstruct.ReportingPolicy; + +@AutoMapper( + target = CutleryInventoryEntity.class, + typeConversionPolicy = ReportingPolicy.ERROR, + reverseConvertGenerate = false +) +public class CutleryInventoryDto { + + private short numberOfKnifes; + private int numberOfForks; + private byte numberOfSpoons; + + private float approximateKnifeLength; + + public short getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(short numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public int getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(int numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public byte getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(byte numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public float getApproximateKnifeLength() { + return approximateKnifeLength; + } + + public void setApproximateKnifeLength(float approximateKnifeLength) { + this.approximateKnifeLength = approximateKnifeLength; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/lossy/CutleryInventoryEntity.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/lossy/CutleryInventoryEntity.java new file mode 100644 index 0000000..891320f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/lossy/CutleryInventoryEntity.java @@ -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 io.github.linpeilie.me.conversion.lossy; + +public class CutleryInventoryEntity { + + private int numberOfKnifes; + private Long numberOfForks; + private short numberOfSpoons; + + private double approximateKnifeLength; + + public int getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(int numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public Long getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(Long numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public short getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(short numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public double getApproximateKnifeLength() { + return approximateKnifeLength; + } + + public void setApproximateKnifeLength(double approximateKnifeLength) { + this.approximateKnifeLength = approximateKnifeLength; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/numbers/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/numbers/Source.java new file mode 100644 index 0000000..b1eafc4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/numbers/Source.java @@ -0,0 +1,172 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.numbers; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import java.math.BigDecimal; +import java.math.BigInteger; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; + +@AutoMapper(target = Target.class) +public class Source { + + @AutoMapping( target = "i", numberFormat = "##.00" ) + private int i; + + @AutoMapping( target = "ii", numberFormat = "##.00" ) + private Integer ii; + + @AutoMapping( target = "d", numberFormat = "##.00" ) + private double d; + + @AutoMapping( target = "dd", numberFormat = "##.00" ) + private Double dd; + + @AutoMapping( target = "f", numberFormat = "##.00" ) + private float f; + + @AutoMapping( target = "ff", numberFormat = "##.00" ) + private Float ff; + + @AutoMapping( target = "l", numberFormat = "##.00" ) + private long l; + + @AutoMapping( target = "ll", numberFormat = "##.00" ) + private Long ll; + + @AutoMapping( target = "b", numberFormat = "##.00" ) + private byte b; + + @AutoMapping( target = "bb", numberFormat = "##.00" ) + private Byte bb; + + @AutoMapping( target = "complex1", numberFormat = "##0.##E0" ) + private double complex1; + + @AutoMapping( target = "complex2", numberFormat = "$#.00" ) + private double complex2; + + @AutoMapping( target = "bigDecimal1", numberFormat = "#0.#E0" ) + private BigDecimal bigDecimal1; + + @AutoMapping( target = "bigInteger1", numberFormat = "0.#############E0" ) + private BigInteger bigInteger1; + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public Integer getIi() { + return ii; + } + + public void setIi(Integer ii) { + this.ii = ii; + } + + public double getD() { + return d; + } + + public void setD(double d) { + this.d = d; + } + + public Double getDd() { + return dd; + } + + public void setDd(Double dd) { + this.dd = dd; + } + + public float getF() { + return f; + } + + public void setF(float f) { + this.f = f; + } + + public Float getFf() { + return ff; + } + + public void setFf(Float ff) { + this.ff = ff; + } + + public long getL() { + return l; + } + + public void setL(long l) { + this.l = l; + } + + public Long getLl() { + return ll; + } + + public void setLl(Long ll) { + this.ll = ll; + } + + public byte getB() { + return b; + } + + public void setB(byte b) { + this.b = b; + } + + public Byte getBb() { + return bb; + } + + public void setBb(Byte bb) { + this.bb = bb; + } + + public double getComplex1() { + return complex1; + } + + public void setComplex1(double complex1) { + this.complex1 = complex1; + } + + public double getComplex2() { + return complex2; + } + + public void setComplex2(double complex2) { + this.complex2 = complex2; + } + + public BigDecimal getBigDecimal1() { + return bigDecimal1; + } + + public void setBigDecimal1(BigDecimal bigDecimal1) { + this.bigDecimal1 = bigDecimal1; + } + + public BigInteger getBigInteger1() { + return bigInteger1; + } + + public void setBigInteger1(BigInteger bigInteger1) { + this.bigInteger1 = bigInteger1; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/numbers/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/numbers/Target.java new file mode 100644 index 0000000..ac89f92 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/numbers/Target.java @@ -0,0 +1,169 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.numbers; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import java.math.BigDecimal; +import java.math.BigInteger; + +@AutoMapper(target = Source.class) +public class Target { + + @AutoMapping( target = "i", numberFormat = "##.00" ) + private String i; + + @AutoMapping( target = "ii", numberFormat = "##.00" ) + private String ii; + + @AutoMapping( target = "d", numberFormat = "##.00" ) + private String d; + + @AutoMapping( target = "dd", numberFormat = "##.00" ) + private String dd; + + @AutoMapping( target = "f", numberFormat = "##.00" ) + private String f; + + @AutoMapping( target = "ff", numberFormat = "##.00" ) + private String ff; + + @AutoMapping( target = "l", numberFormat = "##.00" ) + private String l; + + @AutoMapping( target = "ll", numberFormat = "##.00" ) + private String ll; + + @AutoMapping( target = "b", numberFormat = "##.00" ) + private String b; + + @AutoMapping( target = "bb", numberFormat = "##.00" ) + private String bb; + + @AutoMapping( target = "complex1", numberFormat = "##0.##E0" ) + private String complex1; + + @AutoMapping( target = "complex2", numberFormat = "$#.00" ) + private String complex2; + + @AutoMapping( target = "bigDecimal1", numberFormat = "#0.#E0" ) + private String bigDecimal1; + + @AutoMapping( target = "bigInteger1", numberFormat = "0.#############E0" ) + private String bigInteger1; + + public String getI() { + return i; + } + + public void setI(String i) { + this.i = i; + } + + public String getIi() { + return ii; + } + + public void setIi(String ii) { + this.ii = ii; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } + + public String getDd() { + return dd; + } + + public void setDd(String dd) { + this.dd = dd; + } + + public String getF() { + return f; + } + + public void setF(String f) { + this.f = f; + } + + public String getFf() { + return ff; + } + + public void setFf(String ff) { + this.ff = ff; + } + + public String getL() { + return l; + } + + public void setL(String l) { + this.l = l; + } + + public String getLl() { + return ll; + } + + public void setLl(String ll) { + this.ll = ll; + } + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getBb() { + return bb; + } + + public void setBb(String bb) { + this.bb = bb; + } + + public String getComplex1() { + return complex1; + } + + public void setComplex1(String complex1) { + this.complex1 = complex1; + } + + public String getComplex2() { + return complex2; + } + + public void setComplex2(String complex2) { + this.complex2 = complex2; + } + + public String getBigDecimal1() { + return bigDecimal1; + } + + public void setBigDecimal1(String bigDecimal1) { + this.bigDecimal1 = bigDecimal1; + } + + public String getBigInteger1() { + return bigInteger1; + } + + public void setBigInteger1(String bigInteger1) { + this.bigInteger1 = bigInteger1; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/string/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/string/Source.java new file mode 100644 index 0000000..2d76d32 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/string/Source.java @@ -0,0 +1,178 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.string; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; + +@AutoMapper(target = Target.class) +public class Source { + + private byte b; + private Byte bb; + private short s; + private Short ss; + private int i; + private Integer ii; + private long l; + private Long ll; + private float f; + private Float ff; + private double d; + private Double dd; + private boolean bool; + private Boolean boolBool; + private char c; + private Character cc; + private StringBuilder sb; + + @AutoMapping(target = "object", ignore = true) + private Object object; + + public byte getB() { + return b; + } + + public void setB(byte b) { + this.b = b; + } + + public Byte getBb() { + return bb; + } + + public void setBb(Byte bb) { + this.bb = bb; + } + + public short getS() { + return s; + } + + public void setS(short s) { + this.s = s; + } + + public Short getSs() { + return ss; + } + + public void setSs(Short ss) { + this.ss = ss; + } + + public int getI() { + return i; + } + + public void setI(int i) { + this.i = i; + } + + public Integer getIi() { + return ii; + } + + public void setIi(Integer ii) { + this.ii = ii; + } + + public long getL() { + return l; + } + + public void setL(long l) { + this.l = l; + } + + public Long getLl() { + return ll; + } + + public void setLl(Long ll) { + this.ll = ll; + } + + public float getF() { + return f; + } + + public void setF(float f) { + this.f = f; + } + + public Float getFf() { + return ff; + } + + public void setFf(Float ff) { + this.ff = ff; + } + + public double getD() { + return d; + } + + public void setD(double d) { + this.d = d; + } + + public Double getDd() { + return dd; + } + + public void setDd(Double dd) { + this.dd = dd; + } + + public boolean getBool() { + return bool; + } + + public void setBool(boolean bool) { + this.bool = bool; + } + + public Boolean getBoolBool() { + return boolBool; + } + + public void setBoolBool(Boolean boolBool) { + this.boolBool = boolBool; + } + + public char getC() { + return c; + } + + public void setC(char c) { + this.c = c; + } + + public Character getCc() { + return cc; + } + + public void setCc(Character cc) { + this.cc = cc; + } + + public Object getObject() { + return object; + } + + public void setObject(Object object) { + this.object = object; + } + + public StringBuilder getSb() { + return sb; + } + + public void setSb(StringBuilder sb) { + this.sb = sb; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/string/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/string/Target.java new file mode 100644 index 0000000..08e92ab --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/conversion/string/Target.java @@ -0,0 +1,178 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.conversion.string; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; + +@AutoMapper(target = Source.class) +public class Target { + + private String b; + private String bb; + private String s; + private String ss; + private String i; + private String ii; + private String l; + private String ll; + private String f; + private String ff; + private String d; + private String dd; + private String bool; + private String boolBool; + private String c; + private String cc; + private String sb; + + @AutoMapping(target = "object", ignore = true) + private String object; + + public String getB() { + return b; + } + + public void setB(String b) { + this.b = b; + } + + public String getBb() { + return bb; + } + + public void setBb(String bb) { + this.bb = bb; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } + + public String getSs() { + return ss; + } + + public void setSs(String ss) { + this.ss = ss; + } + + public String getI() { + return i; + } + + public void setI(String i) { + this.i = i; + } + + public String getIi() { + return ii; + } + + public void setIi(String ii) { + this.ii = ii; + } + + public String getL() { + return l; + } + + public void setL(String l) { + this.l = l; + } + + public String getLl() { + return ll; + } + + public void setLl(String ll) { + this.ll = ll; + } + + public String getF() { + return f; + } + + public void setF(String f) { + this.f = f; + } + + public String getFf() { + return ff; + } + + public void setFf(String ff) { + this.ff = ff; + } + + public String getD() { + return d; + } + + public void setD(String d) { + this.d = d; + } + + public String getDd() { + return dd; + } + + public void setDd(String dd) { + this.dd = dd; + } + + public String getBool() { + return bool; + } + + public void setBool(String bool) { + this.bool = bool; + } + + public String getBoolBool() { + return boolBool; + } + + public void setBoolBool(String boolBool) { + this.boolBool = boolBool; + } + + public String getC() { + return c; + } + + public void setC(String c) { + this.c = c; + } + + public String getCc() { + return cc; + } + + public void setCc(String cc) { + this.cc = cc; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + public String getSb() { + return sb; + } + + public void setSb(String sb) { + this.sb = sb; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryDts.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryDts.java new file mode 100644 index 0000000..25c1f50 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryDts.java @@ -0,0 +1,71 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.defaultvalue; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.me.defaultvalue.other.Continent; +import org.mapstruct.Mapping; + +@AutoMapper(target = CountryEntity.class) +public class CountryDts { + + @AutoMapping(target = "code", defaultValue = "DE") + private String code; + + @AutoMapping(target = "id", defaultValue = "42") + private int id; + + @AutoMapping(target = "zipcode", defaultValue = "1337") + private long zipcode; + + @AutoMapping(target = "region", ignore = true) + private String region; + + @AutoMapping(target = "continent", defaultValue = "EUROPE") + private Continent continent; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public long getZipcode() { + return zipcode; + } + + public void setZipcode(long zipcode) { + this.zipcode = zipcode; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public Continent getContinent() { + return continent; + } + + public void setContinent(Continent continent) { + this.continent = continent; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryEntity.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryEntity.java new file mode 100644 index 0000000..076fea1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryEntity.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.defaultvalue; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.me.defaultvalue.other.Continent; + +@AutoMapper(target = CountryDts.class) +public class CountryEntity { + + @AutoMapping(target = "code", defaultValue = "DE") + private String code; + + @AutoMapping(target = "id", defaultValue = "42") + private Integer id; + + @AutoMapping(target = "zipcode", defaultValue = "1337") + private long zipcode; + + @AutoMapping(target = "region", defaultValue = "someRegion") + private Region region; + + @AutoMapping(target = "continent", defaultValue = "EUROPE") + private Continent continent; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public long getZipcode() { + return zipcode; + } + + public void setZipcode(long zipcode) { + this.zipcode = zipcode; + } + + public Region getRegion() { + return region; + } + + public void setRegion(Region region) { + this.region = region; + } + + public Continent getContinent() { + return continent; + } + + public void setContinent(Continent continent) { + this.continent = continent; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryMapper.java new file mode 100644 index 0000000..643df0d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/CountryMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.defaultvalue; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +public abstract class CountryMapper { + + protected String mapToString(Region region) { + return ( region != null ) ? region.getCode() : null; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/Region.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/Region.java new file mode 100644 index 0000000..48b70e2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/Region.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.defaultvalue; + +public class Region { + private String code; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/other/Continent.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/other/Continent.java new file mode 100644 index 0000000..cb49c83 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/defaultvalue/other/Continent.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.defaultvalue.other; + +/** + * @author Andreas Gudian + * + */ +public enum Continent { + AFRICA, + ANTARCTICA, + ASIA, + EUROPE, + NORTH_AMERICA, + OCEANIA, + SOUTH_AMERICA +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/Address.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/Address.java new file mode 100644 index 0000000..d50cd34 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/Address.java @@ -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 io.github.linpeilie.me.dependency; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import org.mapstruct.Mapping; + +@AutoMapper(target = AddressDto.class, reverseConvertGenerate = false) +public class Address { + + @AutoMapping(target = "givenName") + private String firstName; + + @AutoMapping(target = "middleName", dependsOn = "givenName") + private String middleName; + + @AutoMapping(target = "surName", dependsOn = "middleName") + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/AddressDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/AddressDto.java new file mode 100644 index 0000000..943e986 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/AddressDto.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.dependency; + +public class AddressDto { + + private String givenName; + private String middleName; + private String surName; + private String fullName; + + public String getGivenName() { + return givenName; + } + + public void setGivenName(String givenName) { + this.givenName = givenName; + this.fullName = givenName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + this.fullName += " " + middleName; + } + + public String getSurName() { + return surName; + } + + public void setSurName(String surName) { + this.surName = surName; + this.fullName += " " + surName; + } + + public String getFullName() { + return fullName; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/Person.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/Person.java new file mode 100644 index 0000000..3a43041 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/Person.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.dependency; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import org.mapstruct.Mapping; + +@AutoMapper(target = PersonDto.class, reverseConvertGenerate = false) +public class Person { + + private String firstName; + private String middleName; + + @AutoMapping(target = "lastName", dependsOn = {"firstName", "middleName" }) + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/PersonDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/PersonDto.java new file mode 100644 index 0000000..cff9de7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/dependency/PersonDto.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.dependency; + +public class PersonDto { + + private String firstName; + private String middleName; + private String lastName; + private String fullName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + this.fullName = firstName + " " + middleName + " " + lastName; + } + + public String getFullName() { + return fullName; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/Customer.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/Customer.java new file mode 100644 index 0000000..597f0bc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/Customer.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 io.github.linpeilie.me.field_mapping; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.Collection; +import lombok.Data; + +@Data +@AutoMapper(target = CustomerDto.class) +public class Customer { + + private Long id; + + @AutoMapping(target = "customerName") + private String name; + + @AutoMapping(target = "orders") + private Collection orderItems; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/CustomerDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/CustomerDto.java new file mode 100644 index 0000000..41366bf --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/CustomerDto.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.field_mapping; + +import java.util.List; +import lombok.Data; + +@Data +public class CustomerDto { + + public Long id; + public String customerName; + public List orders; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/OrderItem.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/OrderItem.java new file mode 100644 index 0000000..1fdedce --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/OrderItem.java @@ -0,0 +1,11 @@ +package io.github.linpeilie.me.field_mapping; + +import lombok.Data; + +@Data +public class OrderItem { + + private String name; + private Long quantity; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/OrderItemDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/OrderItemDto.java new file mode 100644 index 0000000..0466d80 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/field_mapping/OrderItemDto.java @@ -0,0 +1,10 @@ +package io.github.linpeilie.me.field_mapping; + +import lombok.Data; + +@Data +public class OrderItemDto { + + public String name; + public Long quantity; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/Source.java new file mode 100644 index 0000000..03273ed --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/Source.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.iterable_to_non_iterable; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.me.iterable_to_non_iterable.util.FirstElement; +import io.github.linpeilie.me.iterable_to_non_iterable.util.IterableNonIterableUtil; +import io.github.linpeilie.me.iterable_to_non_iterable.util.LastElement; +import java.util.List; +import lombok.Data; + +@Data +@AutoMapper(target = Target.class, reverseConvertGenerate = false, uses = IterableNonIterableUtil.class, mapperNameSuffix = "$4") +public class Source { + + @AutoMapping(target = "myInteger", qualifiedBy = FirstElement.class) + private List myIntegers; + + @AutoMapping(target = "myString", qualifiedBy = LastElement.class) + private List myStrings; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/Target.java new file mode 100644 index 0000000..33f1381 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/Target.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 io.github.linpeilie.me.iterable_to_non_iterable; + +import lombok.Data; + +@Data +public class Target { + + private Integer myInteger; + private String myString; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/FirstElement.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/FirstElement.java new file mode 100644 index 0000000..a87ddf5 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/FirstElement.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.iterable_to_non_iterable.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.mapstruct.Qualifier; + +@Qualifier +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface FirstElement { +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/IterableNonIterableUtil.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/IterableNonIterableUtil.java new file mode 100644 index 0000000..c060a0b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/IterableNonIterableUtil.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.iterable_to_non_iterable.util; + +import java.util.List; +import org.springframework.stereotype.Component; +//import org.mapstruct.ap.test.selection.qualifier.annotation.TitleTranslator; + +@Component +public class IterableNonIterableUtil { + + @FirstElement + public T first( List in ) { + if ( in != null && !in.isEmpty() ) { + return in.get( 0 ); + } + else { + return null; + } + } + + @LastElement + public T last( List in ) { + if ( in != null && !in.isEmpty() ) { + return in.get( in.size() - 1 ); + } + else { + return null; + } + } + + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/LastElement.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/LastElement.java new file mode 100644 index 0000000..7fbe0cb --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/iterable_to_non_iterable/util/LastElement.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.iterable_to_non_iterable.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.mapstruct.Qualifier; + +@Qualifier +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface LastElement { +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningBeanMappingMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningBeanMappingMapper.java new file mode 100644 index 0000000..787a7b2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningBeanMappingMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.mappingcontrol; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CloningBeanMappingMapper { + + CloningBeanMappingMapper INSTANCE = Mappers.getMapper( CloningBeanMappingMapper.class ); + + @BeanMapping(mappingControl = DeepClone.class) + FridgeDTO clone(FridgeDTO in); + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningListMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningListMapper.java new file mode 100644 index 0000000..1cfc359 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningListMapper.java @@ -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 io.github.linpeilie.me.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = DeepClone.class) +public interface CloningListMapper { + + CloningListMapper INSTANCE = Mappers.getMapper( CloningListMapper.class ); + + CustomerDto clone(CustomerDto in); + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningMapper.java new file mode 100644 index 0000000..ae64974 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CloningMapper.java @@ -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 io.github.linpeilie.me.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = DeepClone.class) +public interface CloningMapper { + + CloningMapper INSTANCE = Mappers.getMapper( CloningMapper.class ); + + FridgeDTO clone(FridgeDTO in); + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ComplexMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ComplexMapper.java new file mode 100644 index 0000000..5f79693 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ComplexMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; +import org.springframework.stereotype.Component; + +@Component +public class ComplexMapper { + + public String toBeerCount(ShelveDTO in) { + return in.getCoolBeer().getBeerCount(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ConversionMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ConversionMapper.java new file mode 100644 index 0000000..0a9c400 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ConversionMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ConversionMapper { + + ConversionMapper INSTANCE = Mappers.getMapper( ConversionMapper.class ); + + Fridge map(CoolBeerDTO in); + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CoolBeerDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CoolBeerDTO.java new file mode 100644 index 0000000..1439870 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CoolBeerDTO.java @@ -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 io.github.linpeilie.me.mappingcontrol; + +public class CoolBeerDTO { + + private String beerCount; + + public String getBeerCount() { + return beerCount; + } + + public void setBeerCount(String beerCount) { + this.beerCount = beerCount; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CustomerDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CustomerDto.java new file mode 100644 index 0000000..e1a9758 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/CustomerDto.java @@ -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 io.github.linpeilie.me.mappingcontrol; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.List; +import java.util.Map; +import org.mapstruct.control.DeepClone; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = CustomerDto.class, mappingControl = DeepClone.class, reverseConvertGenerate = false) +public class CustomerDto { + + private Long id; + private String customerName; + private List orders; + private Map stock; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public List getOrders() { + return orders; + } + + public void setOrders(List orders) { + this.orders = orders; + } + + public Map getStock() { + return stock; + } + + public void setStock(Map stock) { + this.stock = stock; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/Fridge.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/Fridge.java new file mode 100644 index 0000000..4b58628 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/Fridge.java @@ -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 io.github.linpeilie.me.mappingcontrol; + +public class Fridge { + + private int beerCount; + + public int getBeerCount() { + return beerCount; + } + + public void setBeerCount(int beerCount) { + this.beerCount = beerCount; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/FridgeDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/FridgeDTO.java new file mode 100644 index 0000000..22e65d1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/FridgeDTO.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.mappingcontrol; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import org.mapstruct.control.DeepClone; +import org.mapstruct.control.MappingControl; + +@AutoMappers({ + @AutoMapper(target = FridgeDTO.class, mappingControl = DeepClone.class, reverseConvertGenerate = false), + @AutoMapper(target = Fridge.class, reverseConvertGenerate = false, uses = ComplexMapper.class) +}) +public class FridgeDTO { + + private ShelveDTO shelve; + + public ShelveDTO getShelve() { + return shelve; + } + + public void setShelve(ShelveDTO shelve) { + this.shelve = shelve; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/OrderItemDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/OrderItemDto.java new file mode 100644 index 0000000..378080c --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/OrderItemDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.mappingcontrol; + +/** + * @author Sjaak Derksen + */ +public class OrderItemDto { + + private String name; + private Long quantity; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getQuantity() { + return quantity; + } + + public void setQuantity(Long quantity) { + this.quantity = quantity; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/OrderItemKeyDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/OrderItemKeyDto.java new file mode 100644 index 0000000..ca544e7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/OrderItemKeyDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.mappingcontrol; + +/** + * @author Sjaak Derksen + */ +public class OrderItemKeyDto { + + private long stockNumber; + + public long getStockNumber() { + return stockNumber; + } + + public void setStockNumber(long stockNumber) { + this.stockNumber = stockNumber; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ShelveDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ShelveDTO.java new file mode 100644 index 0000000..1fb93d4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/mappingcontrol/ShelveDTO.java @@ -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 io.github.linpeilie.me.mappingcontrol; + +public class ShelveDTO { + + private CoolBeerDTO coolBeer; + + public CoolBeerDTO getCoolBeer() { + return coolBeer; + } + + public void setCoolBeer(CoolBeerDTO coolBeer) { + this.coolBeer = coolBeer; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishDto.java new file mode 100644 index 0000000..826da42 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class FishDto { + + private String kind; + + // make sure that mapping on name does not happen based on name mapping + private String name; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto.java new file mode 100644 index 0000000..59f476e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto.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 io.github.linpeilie.me.nested_bean_mappings.dto; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import io.github.linpeilie.me.nested_bean_mappings.model.FishTank; +import lombok.Data; + +@Data +@AutoMapper(target = FishTank.class) +public class FishTankDto { + + @AutoMappings({ + @AutoMapping(target = "fish.type", source = "fish.kind"), + }) + private FishDto fish; + private WaterPlantDto plant; + private String name; + + @AutoMapping(target = "material", source = "material.materialType") + private MaterialDto material; + + @AutoMapping(target = "interior.ornament", source = "ornament") + private OrnamentDto ornament; + + @AutoMapping(target = "quality.report.organisationName", source = "quality.report.organisation.name") + private WaterQualityDto quality; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto1.java new file mode 100644 index 0000000..557bf76 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto1.java @@ -0,0 +1,15 @@ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class FishTankDto1 { + + private FishDto fish; + private WaterPlantDto plant; + private String name; + private MaterialDto material; + private OrnamentDto ornament; + private WaterQualityDto quality; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto2.java new file mode 100644 index 0000000..86c87dd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankDto2.java @@ -0,0 +1,15 @@ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class FishTankDto2 { + + private FishDto fish; + private WaterPlantDto plant; + private String name; + private MaterialDto material; + private OrnamentDto ornament; + private WaterQualityDto quality; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankWithNestedDocumentDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankWithNestedDocumentDto.java new file mode 100644 index 0000000..2ba155a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/FishTankWithNestedDocumentDto.java @@ -0,0 +1,15 @@ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class FishTankWithNestedDocumentDto { + + private FishDto fish; + private WaterPlantDto plant; + private String name; + private MaterialDto material; + private OrnamentDto ornament; + private WaterQualityWithDocumentDto quality; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/MaterialDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/MaterialDto.java new file mode 100644 index 0000000..08daf55 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/MaterialDto.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 io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class MaterialDto { + + private String manufacturer; + private MaterialTypeDto materialType; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/MaterialTypeDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/MaterialTypeDto.java new file mode 100644 index 0000000..d18c95a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/MaterialTypeDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class MaterialTypeDto { + + private String type; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/OrnamentDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/OrnamentDto.java new file mode 100644 index 0000000..7145e9b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/OrnamentDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class OrnamentDto { + + private String type; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterPlantDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterPlantDto.java new file mode 100644 index 0000000..f2a6428 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterPlantDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class WaterPlantDto { + + private String kind; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityDto.java new file mode 100644 index 0000000..bdf256e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class WaterQualityDto { + + private WaterQualityReportDto report; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityOrganisationDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityOrganisationDto.java new file mode 100644 index 0000000..823ac6d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityOrganisationDto.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 io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class WaterQualityOrganisationDto { + + private String name; + private String approval; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityReportDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityReportDto.java new file mode 100644 index 0000000..102970d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityReportDto.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 io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class WaterQualityReportDto { + + private WaterQualityOrganisationDto organisation; + private String verdict; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityWithDocumentDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityWithDocumentDto.java new file mode 100644 index 0000000..f48d49d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/dto/WaterQualityWithDocumentDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.dto; + +import lombok.Data; + +@Data +public class WaterQualityWithDocumentDto { + + private WaterQualityReportDto document; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Fish.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Fish.java new file mode 100644 index 0000000..c3c1642 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Fish.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class Fish { + + private String type; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/FishTank.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/FishTank.java new file mode 100644 index 0000000..b7cc550 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/FishTank.java @@ -0,0 +1,73 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.nested_bean_mappings.model; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankDto; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankDto1; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankDto2; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankWithNestedDocumentDto; +import lombok.Data; + +@Data +@AutoMappers({ + @AutoMapper(target = FishTankDto.class), + @AutoMapper(target = FishTankDto1.class, reverseConvertGenerate = false), + @AutoMapper(target = FishTankDto2.class, reverseConvertGenerate = false), + @AutoMapper(target = FishTankWithNestedDocumentDto.class, reverseConvertGenerate = false), +}) +public class FishTank { + + @AutoMappings({ + @AutoMapping(targetClass = FishTankDto.class, target = "fish.kind", source = "fish.type"), + @AutoMapping(targetClass = FishTankDto.class, target = "fish.name", ignore = true), + @AutoMapping(targetClass = FishTankDto1.class, target = "fish.kind", source = "fish.type"), + @AutoMapping(targetClass = FishTankDto1.class, target = "fish.name", constant = "Nemo"), + @AutoMapping(targetClass = FishTankDto2.class, target = "fish.kind", source = "fish.type"), + @AutoMapping(targetClass = FishTankDto2.class, target = "fish.name", expression = "java(\"Jaws\")"), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "fish.kind", source = "fish.type"), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "fish.name", expression = "java(\"Jaws\")"), + }) + private Fish fish; + + @AutoMappings({ + @AutoMapping(targetClass = FishTankDto2.class, target = "plant", ignore = true), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "plant", ignore = true) + }) + private WaterPlant plant; + private String name; + + @AutoMappings({ + @AutoMapping(targetClass = FishTankDto.class, target = "material.materialType"), + @AutoMapping(targetClass = FishTankDto1.class, target = "material.materialType"), + @AutoMapping(targetClass = FishTankDto1.class, target = "material.manufacturer", constant = "MMM"), + @AutoMapping(targetClass = FishTankDto2.class, target = "material", ignore = true), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "material", ignore = true), + }) + private MaterialType material; + + @AutoMappings({ + @AutoMapping(targetClass = FishTankDto.class, target = "ornament", source = "interior.ornament"), + @AutoMapping(targetClass = FishTankDto1.class, target = "ornament", ignore = true), + @AutoMapping(targetClass = FishTankDto2.class, target = "ornament", ignore = true), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "ornament", ignore = true), + }) + private Interior interior; + + @AutoMappings({ + @AutoMapping(targetClass = FishTankDto.class, target = "quality.report.organisation.name", source = "quality.report.organisationName"), + @AutoMapping(targetClass = FishTankDto1.class, target = "quality", ignore = true), + @AutoMapping(targetClass = FishTankDto2.class, target = "quality.report.organisation.name", expression = "java(\"Dunno\")"), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "quality.document", source = "quality.report"), + @AutoMapping(targetClass = FishTankWithNestedDocumentDto.class, target = "quality.document.organisation.name", constant = "NoIdeaInc"), + }) + private WaterQuality quality; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Interior.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Interior.java new file mode 100644 index 0000000..e77a7d8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Interior.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 io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class Interior { + + private String designer; + private Ornament ornament; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/MaterialType.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/MaterialType.java new file mode 100644 index 0000000..2d6e152 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/MaterialType.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class MaterialType { + + private String type; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Ornament.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Ornament.java new file mode 100644 index 0000000..5f4949e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/Ornament.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class Ornament { + + private String type; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterPlant.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterPlant.java new file mode 100644 index 0000000..8e6052f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterPlant.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class WaterPlant { + + private String kind; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterQuality.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterQuality.java new file mode 100644 index 0000000..6910b6b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterQuality.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class WaterQuality { + + private WaterQualityReport report; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterQualityReport.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterQualityReport.java new file mode 100644 index 0000000..ac499ff --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nested_bean_mappings/model/WaterQualityReport.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 io.github.linpeilie.me.nested_bean_mappings.model; + +import lombok.Data; + +@Data +public class WaterQualityReport { + + private String organisationName; + private String verdict; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/CustomMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/CustomMapper.java new file mode 100644 index 0000000..f0007e4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/CustomMapper.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 io.github.linpeilie.me.nullcheck; + +import java.math.BigInteger; +import org.springframework.stereotype.Component; + +@Component +public class CustomMapper { + + public MyBigIntWrapper toMyBigIntWrapper(BigInteger bigInteger) { + MyBigIntWrapper wrapper = new MyBigIntWrapper(); + wrapper.setMyBigInt( bigInteger ); + return wrapper; + } + + public MyLongWrapper toMyBigIntWrapperViaPrimitive(long primitive) { + MyLongWrapper wrapper = new MyLongWrapper(); + wrapper.setMyLong( primitive ); + return wrapper; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/MyBigIntWrapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/MyBigIntWrapper.java new file mode 100644 index 0000000..3e07088 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/MyBigIntWrapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck; + +import java.math.BigInteger; + +/** + * @author Sjaak Derksen + */ +public class MyBigIntWrapper { + + private BigInteger myBigInt; + + public BigInteger getMyBigInt() { + return myBigInt; + } + + public void setMyBigInt(BigInteger myBigInt) { + this.myBigInt = myBigInt; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/MyLongWrapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/MyLongWrapper.java new file mode 100644 index 0000000..5212690 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/MyLongWrapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck; + +/** + * @author Sjaak Derksen + */ +public class MyLongWrapper { + + private Long myLong; + + public Long getMyLong() { + return myLong; + } + + public void setMyLong(Long myLong) { + this.myLong = myLong; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/NullObject.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/NullObject.java new file mode 100644 index 0000000..37c89d4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/NullObject.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck; + +/** + * @author Sjaak Derksen + */ +public class NullObject { + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/NullObjectMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/NullObjectMapper.java new file mode 100644 index 0000000..a2bc312 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/NullObjectMapper.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 io.github.linpeilie.me.nullcheck; + +import org.springframework.stereotype.Component; + +@Component +public class NullObjectMapper { + + public String toNullString(NullObject in) { + return in.toString(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/Source.java new file mode 100644 index 0000000..4c5444f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/Source.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 io.github.linpeilie.me.nullcheck; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.List; + +@AutoMapper(target = Target.class, + uses = {NullObjectMapper.class, CustomMapper.class}, + reverseConvertGenerate = false) +public class Source { + + private NullObject someObject; + private String number; + private List someList; + private Integer someInteger; + private Long someLong; + + public NullObject getSomeObject() { + return someObject; + } + + public void setSomeObject(NullObject someObject) { + this.someObject = someObject; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public List getSomeList() { + return someList; + } + + public void setSomeList(List someList) { + this.someList = someList; + } + + public Integer getSomeInteger() { + return someInteger; + } + + public void setSomeInteger(Integer someInteger) { + this.someInteger = someInteger; + } + + public Long getSomeLong() { + return someLong; + } + + public void setSomeLong(Long someLong) { + this.someLong = someLong; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/Target.java new file mode 100644 index 0000000..ab832c0 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/Target.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck; + +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class Target { + + private String someObject; + private Integer number; + private List someList; + private MyBigIntWrapper someInteger; + private MyLongWrapper someLong; + + public String getSomeObject() { + return someObject; + } + + public void setSomeObject(String someObject) { + this.someObject = someObject; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } + + public List getSomeList() { + return someList; + } + + public void setSomeList(List someList) { + this.someList = someList; + } + + public MyBigIntWrapper getSomeInteger() { + return someInteger; + } + + public void setSomeInteger(MyBigIntWrapper someInteger) { + this.someInteger = someInteger; + } + + public MyLongWrapper getSomeLong() { + return someLong; + } + + public void setSomeLong(MyLongWrapper someLong) { + this.someLong = someLong; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseDto.java new file mode 100644 index 0000000..b89991b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseDto.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.nullcheck.strategy; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; + +@AutoMappers({ + @AutoMapper(target = HouseEntity.class, nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS), + @AutoMapper(target = HouseEntity1.class, nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION), + @AutoMapper(target = HouseEntity2.class, nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION), +}) +public class HouseDto { + + private String owner; + + @AutoMapping(targetClass = HouseEntity2.class, target = "number", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) + private Integer number; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity.java new file mode 100644 index 0000000..79892b7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck.strategy; + +public class HouseEntity { + + private String owner; + private boolean ownerSet = false; + + private Integer number; + private boolean numberSet = false; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + ownerSet = true; + this.owner = owner; + } + + public boolean ownerSet() { + return ownerSet; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + numberSet = true; + this.number = number; + } + + public boolean numberSet() { + return numberSet; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity1.java new file mode 100644 index 0000000..ee362fc --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity1.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck.strategy; + +public class HouseEntity1 { + + private String owner; + private boolean ownerSet = false; + + private Integer number; + private boolean numberSet = false; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + ownerSet = true; + this.owner = owner; + } + + public boolean ownerSet() { + return ownerSet; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + numberSet = true; + this.number = number; + } + + public boolean numberSet() { + return numberSet; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity2.java new file mode 100644 index 0000000..2071821 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseEntity2.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck.strategy; + +public class HouseEntity2 { + + private String owner; + private boolean ownerSet = false; + + private Integer number; + private boolean numberSet = false; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + ownerSet = true; + this.owner = owner; + } + + public boolean ownerSet() { + return ownerSet; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + numberSet = true; + this.number = number; + } + + public boolean numberSet() { + return numberSet; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseMapper.java new file mode 100644 index 0000000..973d323 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullcheck/strategy/HouseMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullcheck.strategy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface HouseMapper { + + HouseMapper INSTANCE = Mappers.getMapper( HouseMapper.class ); + + HouseEntity mapWithNvcsOnMapper(HouseDto in); + + @BeanMapping(nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION) + HouseEntity mapWithNvcsOnBean(HouseDto in); + + @BeanMapping(nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION) + @Mapping(target = "number", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) + HouseEntity mapWithNvcsOnMapping(HouseDto in); + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/CarMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/CarMapper.java new file mode 100644 index 0000000..ca72491 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/CarMapper.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 io.github.linpeilie.me.nullvaluemapping; + +import io.github.linpeilie.me.nullvaluemapping._target.CarDto; +import io.github.linpeilie.me.nullvaluemapping.source.Car; +import java.util.List; +import java.util.UUID; +import org.mapstruct.BeanMapping; +import org.mapstruct.IterableMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValueMappingStrategy.RETURN_DEFAULT; + +@Mapper(imports = UUID.class) +public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + @BeanMapping(nullValueMappingStrategy = RETURN_DEFAULT) + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") + CarDto carToCarDto(Car car); + + @IterableMapping(nullValueMappingStrategy = RETURN_DEFAULT) + List carsToCarDtos(List cars); + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/CarDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/CarDto.java new file mode 100644 index 0000000..99fd1b3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/CarDto.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullvaluemapping._target; + +public class CarDto { + + private String make; + private int seatCount; + private String model; + private String catalogId; + + public CarDto() { + } + + public CarDto(String make, int seatCount) { + this.make = make; + this.seatCount = seatCount; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getSeatCount() { + return seatCount; + } + + public void setSeatCount(int seatCount) { + this.seatCount = seatCount; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getCatalogId() { + return catalogId; + } + + public void setCatalogId(String catalogId) { + this.catalogId = catalogId; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/CarDto1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/CarDto1.java new file mode 100644 index 0000000..b0b8402 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/CarDto1.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullvaluemapping._target; + +public class CarDto1 { + + private String make; + private int seatCount; + private String model; + private String catalogId; + + public CarDto1() { + } + + public CarDto1(String make, int seatCount) { + this.make = make; + this.seatCount = seatCount; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getSeatCount() { + return seatCount; + } + + public void setSeatCount(int seatCount) { + this.seatCount = seatCount; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public String getCatalogId() { + return catalogId; + } + + public void setCatalogId(String catalogId) { + this.catalogId = catalogId; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/DriverAndCarDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/DriverAndCarDto.java new file mode 100644 index 0000000..b00b0e4 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/_target/DriverAndCarDto.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullvaluemapping._target; + +public class DriverAndCarDto { + + private String name; + private String make; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Car.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Car.java new file mode 100644 index 0000000..b5e77a2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Car.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.nullvaluemapping.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import io.github.linpeilie.me.nullvaluemapping._target.CarDto; +import java.util.UUID; + +import static org.mapstruct.NullValueMappingStrategy.RETURN_DEFAULT; + +@AutoMapper(target = CarDto.class, + imports = UUID.class, + nullValueMappingStrategy = RETURN_DEFAULT, + reverseConvertGenerate = false) +public class Car { + + private String make; + + @AutoMappings({ + @AutoMapping(target = "seatCount", source = "numberOfSeats"), + @AutoMapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )"), + @AutoMapping(target = "model", constant = "ModelT") + }) + private int numberOfSeats; + + public Car() { + } + + public Car(String make, int numberOfSeats) { + this.make = make; + this.numberOfSeats = numberOfSeats; + + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getNumberOfSeats() { + return numberOfSeats; + } + + public void setNumberOfSeats(int numberOfSeats) { + this.numberOfSeats = numberOfSeats; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Car1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Car1.java new file mode 100644 index 0000000..de5764f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Car1.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.nullvaluemapping.source; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import io.github.linpeilie.me.nullvaluemapping._target.CarDto1; +import java.util.UUID; +import org.mapstruct.NullValueMappingStrategy; + +import static org.mapstruct.NullValueMappingStrategy.RETURN_DEFAULT; + +@AutoMapper(target = CarDto1.class, + imports = UUID.class, + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueIterableMappingStrategy = NullValueMappingStrategy.RETURN_NULL, + reverseConvertGenerate = false) +public class Car1 { + + private String make; + + @AutoMappings({ + @AutoMapping(target = "seatCount", source = "numberOfSeats"), + @AutoMapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )"), + @AutoMapping(target = "model", constant = "ModelT") + }) + private int numberOfSeats; + + public Car1() { + } + + public Car1(String make, int numberOfSeats) { + this.make = make; + this.numberOfSeats = numberOfSeats; + + } + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getNumberOfSeats() { + return numberOfSeats; + } + + public void setNumberOfSeats(int numberOfSeats) { + this.numberOfSeats = numberOfSeats; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Driver.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Driver.java new file mode 100644 index 0000000..3f92d13 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluemapping/source/Driver.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullvaluemapping.source; + +public class Driver { + + private String name; + + public Driver(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/Address.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/Address.java new file mode 100644 index 0000000..23f0140 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/Address.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 io.github.linpeilie.me.nullvaluepropertymapping; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import org.mapstruct.NullValuePropertyMappingStrategy; + +@AutoMappers({ + @AutoMapper(target = AddressDTO.class, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT), + @AutoMapper(target = AddressDTO1.class, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE), + @AutoMapper(target = AddressDTO2.class) +}) +public class Address { + + @AutoMappings({ + @AutoMapping(targetClass = AddressDTO.class, target = "houseNo", defaultValue = "0"), + @AutoMapping(targetClass = AddressDTO1.class, target = "houseNo"), + @AutoMapping(targetClass = AddressDTO2.class, target = "houseNo") + }) + private Integer houseNumber; + + public Integer getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber(Integer houseNumber) { + this.houseNumber = houseNumber; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO.java new file mode 100644 index 0000000..8cc051a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +public class AddressDTO { + + private Integer houseNo; + + public Integer getHouseNo() { + return houseNo; + } + + public void setHouseNo(Integer houseNo) { + this.houseNo = houseNo; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO1.java new file mode 100644 index 0000000..aae9fdb --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO1.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +public class AddressDTO1 { + + private Integer houseNo; + + public Integer getHouseNo() { + return houseNo; + } + + public void setHouseNo(Integer houseNo) { + this.houseNo = houseNo; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO2.java new file mode 100644 index 0000000..0e3ae3a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/AddressDTO2.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +public class AddressDTO2 { + + private Integer houseNo; + + public Integer getHouseNo() { + return houseNo; + } + + public void setHouseNo(Integer houseNo) { + this.houseNo = houseNo; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/Customer.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/Customer.java new file mode 100644 index 0000000..4706a90 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/Customer.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.nullvaluepropertymapping; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import java.util.List; +import org.mapstruct.Mapping; +import org.mapstruct.NullValuePropertyMappingStrategy; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@AutoMappers({ + @AutoMapper(target = UserDTO.class, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT, + reverseConvertGenerate = false), + @AutoMapper(target = UserDTO1.class, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, + reverseConvertGenerate = false), + @AutoMapper(target = CustomerDTO.class, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE, + reverseConvertGenerate = false), + @AutoMapper(target = CustomerDTO1.class, + reverseConvertGenerate = false) +}) +public class Customer { + + @AutoMappings({ + @AutoMapping(targetClass = UserDTO.class, target = "homeDTO.addressDTO"), + @AutoMapping(targetClass = UserDTO1.class, target = "homeDTO.addressDTO"), + @AutoMapping(targetClass = CustomerDTO1.class, target = "address", nullValuePropertyMappingStrategy = IGNORE), + }) + private Address address; + + @AutoMapping(targetClass = CustomerDTO1.class, target = "details", nullValuePropertyMappingStrategy = IGNORE) + private List details; + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/CustomerDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/CustomerDTO.java new file mode 100644 index 0000000..4f1824a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/CustomerDTO.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +import java.util.List; + +public class CustomerDTO { + + private AddressDTO1 address; + private List details; + + public AddressDTO1 getAddress() { + return address; + } + + public void setAddress(AddressDTO1 address) { + this.address = address; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/CustomerDTO1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/CustomerDTO1.java new file mode 100644 index 0000000..9d13f01 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/CustomerDTO1.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +import java.util.List; + +public class CustomerDTO1 { + + private AddressDTO2 address; + private List details; + + public AddressDTO2 getAddress() { + return address; + } + + public void setAddress(AddressDTO2 address) { + this.address = address; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/HomeDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/HomeDTO.java new file mode 100644 index 0000000..0372377 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/HomeDTO.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +public class HomeDTO { + + private AddressDTO addressDTO; + + public AddressDTO getAddressDTO() { + return addressDTO; + } + + public void setAddressDTO(AddressDTO addressDTO) { + this.addressDTO = addressDTO; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/HomeDTO1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/HomeDTO1.java new file mode 100644 index 0000000..07c88c3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/HomeDTO1.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +public class HomeDTO1 { + + private AddressDTO1 addressDTO; + + public AddressDTO1 getAddressDTO() { + return addressDTO; + } + + public void setAddressDTO(AddressDTO1 addressDTO) { + this.addressDTO = addressDTO; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/NvpmsConfig.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/NvpmsConfig.java new file mode 100644 index 0000000..ee45d6b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/NvpmsConfig.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.nullvaluepropertymapping; + +import org.mapstruct.MapperConfig; +import org.mapstruct.NullValuePropertyMappingStrategy; + +@MapperConfig( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE ) +public interface NvpmsConfig { +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/UserDTO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/UserDTO.java new file mode 100644 index 0000000..be904fa --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/UserDTO.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +import java.util.List; + +public class UserDTO { + + private HomeDTO homeDTO; + private List details; + + public HomeDTO getHomeDTO() { + return homeDTO; + } + + public void setHomeDTO(HomeDTO homeDTO) { + this.homeDTO = homeDTO; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/UserDTO1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/UserDTO1.java new file mode 100644 index 0000000..6c6f4a3 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/nullvaluepropertymapping/UserDTO1.java @@ -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 io.github.linpeilie.me.nullvaluepropertymapping; + +import java.util.List; + +public class UserDTO1 { + + private HomeDTO1 homeDTO; + private List details; + + public HomeDTO1 getHomeDTO() { + return homeDTO; + } + + public void setHomeDTO(HomeDTO1 homeDTO) { + this.homeDTO = homeDTO; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/CountryEnum.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/CountryEnum.java new file mode 100644 index 0000000..5d0543e --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/CountryEnum.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.constants; + +/** + * + * @author Sjaak Derksen + */ +public enum CountryEnum { + + GERMANY, THE_NETHERLANDS, BELGIUM; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source.java new file mode 100644 index 0000000..53c7d4d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source.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 io.github.linpeilie.me.source.constants; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = Target.class, uses = StringList1Mapper.class) +public class Source { + + @AutoMappings({ + @AutoMapping(target = "stringConstant", constant = "stringConstant"), + @AutoMapping(target = "integerConstant", constant = "14"), + @AutoMapping(target = "longWrapperConstant", constant = "3001L"), + @AutoMapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"), + @AutoMapping(target = "nameConstants", constant = "jack-jill-tom"), + @AutoMapping(target = "country", constant = "THE_NETHERLANDS") + }) + private String propertyThatShouldBeMapped; + + public String getPropertyThatShouldBeMapped() { + return propertyThatShouldBeMapped; + } + + public void setPropertyThatShouldBeMapped(String propertyThatShouldBeMapped) { + this.propertyThatShouldBeMapped = propertyThatShouldBeMapped; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source1.java new file mode 100644 index 0000000..0dccc2a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source1.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.constants; + +/** + * + * @author Sjaak Derksen + */ +public class Source1 { + + private String someProp; + + public String getSomeProp() { + return someProp; + } + + public void setSomeProp( String someProp ) { + this.someProp = someProp; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source2.java new file mode 100644 index 0000000..3553765 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Source2.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.constants; + +/** + * + * @author Sjaak Derksen + */ +public class Source2 { + + private String anotherProp; + + public String getAnotherProp() { + return anotherProp; + } + + public void setAnotherProp( String anotherProp ) { + this.anotherProp = anotherProp; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/StringList1Mapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/StringList1Mapper.java new file mode 100644 index 0000000..0cb4f14 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/StringList1Mapper.java @@ -0,0 +1,13 @@ +package io.github.linpeilie.me.source.constants; + +import java.util.Arrays; +import java.util.List; +import org.springframework.stereotype.Component; + +@Component +public class StringList1Mapper { + + public List stringToStringList(String string) { + return string == null ? null : Arrays.asList( string.split( "-" ) ); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Target.java new file mode 100644 index 0000000..868e8ed --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Target.java @@ -0,0 +1,89 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.source.constants; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @author Sjaak Derksen + */ +@AutoMapper(target = Source.class, uses = StringList1Mapper.class) +public class Target { + + private String propertyThatShouldBeMapped; + private String stringConstant; + private String emptyStringConstant; + private int integerConstant; + private Long longWrapperConstant; + private Date dateConstant; + private List nameConstants = new ArrayList(); + private CountryEnum country; + + public String getPropertyThatShouldBeMapped() { + return propertyThatShouldBeMapped; + } + + public void setPropertyThatShouldBeMapped(String propertyThatShouldBeMapped) { + this.propertyThatShouldBeMapped = propertyThatShouldBeMapped; + } + + public String getStringConstant() { + return stringConstant; + } + + public void setStringConstant(String stringConstant) { + this.stringConstant = stringConstant; + } + + public int getIntegerConstant() { + return integerConstant; + } + + public void setIntegerConstant(int integerConstant) { + this.integerConstant = integerConstant; + } + + public Long getLongWrapperConstant() { + return longWrapperConstant; + } + + public void setLongWrapperConstant(Long longWrapperConstant) { + this.longWrapperConstant = longWrapperConstant; + } + + public Date getDateConstant() { + return dateConstant; + } + + public void setDateConstant(Date dateConstant) { + this.dateConstant = dateConstant; + } + + public List getNameConstants() { + return nameConstants; + } + + public String getEmptyStringConstant() { + return emptyStringConstant; + } + + public void setEmptyStringConstant(String emptyStringConstant) { + this.emptyStringConstant = emptyStringConstant; + } + + public CountryEnum getCountry() { + return country; + } + + public void setCountry(CountryEnum country) { + this.country = country; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Target2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Target2.java new file mode 100644 index 0000000..da1ff55 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/constants/Target2.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.constants; + +/** + * + * @author Sjaak Derksen + */ +public class Target2 { + + private String someProp; + private String anotherProp; + private String someConstant; + + public String getSomeProp() { + return someProp; + } + + public void setSomeProp( String someProp ) { + this.someProp = someProp; + } + + public String getAnotherProp() { + return anotherProp; + } + + public void setAnotherProp( String anotherProp ) { + this.anotherProp = anotherProp; + } + + public String getSomeConstant() { + return someConstant; + } + + public void setSomeConstant( String someConstant ) { + this.someConstant = someConstant; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Source.java new file mode 100644 index 0000000..87febcf --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Source.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.source.defaultExpressions.java; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneOffset; +import java.util.Date; + +@AutoMappers({ + @AutoMapper(target = Target.class, reverseConvertGenerate = false, imports = {Date.class}), + @AutoMapper(target = Target1.class, + reverseConvertGenerate = false, + imports = {Date.class, LocalDate.class, ZoneOffset.class, Month.class}) +}) +public class Source { + + @AutoMappings({ + @AutoMapping(targetClass = Target.class, target = "sourceId", defaultExpression = "java( String.valueOf( \"test\" ) )"), + @AutoMapping( + targetClass = Target1.class, + target = "sourceId", + defaultExpression = "java( new StringBuilder()\n.append( \"test\" )\n.toString() )" + ) + }) + private int id = -1; + + @AutoMappings({ + @AutoMapping(targetClass = Target.class, target = "sourceDate", defaultExpression = "java( new Date( 30L ))"), + @AutoMapping( + targetClass = Target1.class, + target = "sourceDate", + defaultExpression = "java(" + + "Date.from(\n" + + "LocalDate.of( 2022, Month.JUNE, 5 )\n" + + ".atTime( 17, 10 )\n" + + ".toInstant( ZoneOffset.UTC )\n)" + + ")" + ) + }) + private Date date; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public boolean hasId() { + return id != -1; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Target.java new file mode 100644 index 0000000..c6b681a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Target.java @@ -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 io.github.linpeilie.me.source.defaultExpressions.java; + +import java.util.Date; + +/** + * @author Jeffrey Smyth + */ +public class Target { + + private String sourceId; + private Date sourceDate; + + public String getSourceId() { + return sourceId; + } + + public void setSourceId(String sourceId) { + this.sourceId = sourceId; + } + + public Date getSourceDate() { + return sourceDate; + } + + public void setSourceDate(Date sourceDate) { + this.sourceDate = sourceDate; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Target1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Target1.java new file mode 100644 index 0000000..fc1bc14 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/defaultExpressions/java/Target1.java @@ -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 io.github.linpeilie.me.source.defaultExpressions.java; + +import java.util.Date; + +/** + * @author Jeffrey Smyth + */ +public class Target1 { + + private String sourceId; + private Date sourceDate; + + public String getSourceId() { + return sourceId; + } + + public void setSourceId(String sourceId) { + this.sourceId = sourceId; + } + + public Date getSourceDate() { + return sourceDate; + } + + public void setSourceDate(Date sourceDate) { + this.sourceDate = sourceDate; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/BooleanWorkAroundMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/BooleanWorkAroundMapper.java new file mode 100644 index 0000000..b607769 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/BooleanWorkAroundMapper.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 io.github.linpeilie.me.source.expressions.java; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper +public interface BooleanWorkAroundMapper { + + BooleanWorkAroundMapper INSTANCE = Mappers.getMapper( BooleanWorkAroundMapper.class ); + + @Mapping( expression = "java(source.isVal())", target = "val" ) + TargetBooleanWorkAround mapST( SourceBooleanWorkAround source ); + + SourceBooleanWorkAround mapTS( TargetBooleanWorkAround target ); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/MultiLineExpressionMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/MultiLineExpressionMapper.java new file mode 100644 index 0000000..755e6b8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/MultiLineExpressionMapper.java @@ -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 io.github.linpeilie.me.source.expressions.java; + +import io.github.linpeilie.me.source.expressions.java.mapper.TimeAndFormat; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(imports = TimeAndFormat.class) +public interface MultiLineExpressionMapper { + + + MultiLineExpressionMapper INSTANCE = Mappers.getMapper( MultiLineExpressionMapper.class ); + + @Mappings({ + @Mapping(target = "timeAndFormat", expression = "java( new TimeAndFormat(\ns.getTime(),\ns.getFormat()\n ))"), + @Mapping(target = "anotherProp", ignore = true) + }) + Target mapUsingMultiLineExpression(Source s); + + @Mappings({ + @Mapping( + target = "timeAndFormat", + expression = " java( new TimeAndFormat(\ns.getTime(),\ns.getFormat()\n )) " + ), + @Mapping(target = "anotherProp", ignore = true) + }) + Target1 mapUsingMultiLineExpressionWithLeadingSpaces(Source s); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/QualifierProvider.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/QualifierProvider.java new file mode 100644 index 0000000..eb54e06 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/QualifierProvider.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +public class QualifierProvider { + + public @interface ToUpper { + } + + @ToUpper + public String toUpper( String string ) { + return string.toUpperCase(); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Source.java new file mode 100644 index 0000000..7395dc2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Source.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.source.expressions.java; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import io.github.linpeilie.me.source.expressions.java.mapper.TimeAndFormat; +import java.util.Date; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; + +@AutoMappers({ + @AutoMapper(target = Target.class, reverseConvertGenerate = false, imports = TimeAndFormat.class), + @AutoMapper(target = Target1.class, reverseConvertGenerate = false, imports = TimeAndFormat.class) +}) +public class Source { + + @AutoMappings({ + @AutoMapping(targetClass = Target.class, target = "timeAndFormat", expression = "java( new TimeAndFormat(\nsource.getTime(),\nsource.getFormat()\n ))"), + @AutoMapping(target = "anotherProp", ignore = true), + @AutoMapping( + targetClass = Target1.class, + target = "timeAndFormat", + expression = " java( new TimeAndFormat(\nsource.getTime(),\nsource.getFormat()\n )) " + ), + }) + private String format; + private Date time; + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Source2.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Source2.java new file mode 100644 index 0000000..0e6e666 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Source2.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +/** + * + * @author Sjaak Derksen + */ +public class Source2 { + + private String anotherProp; + + public String getAnotherProp() { + return anotherProp; + } + + public void setAnotherProp( String anotherProp ) { + this.anotherProp = anotherProp; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceBooleanWorkAround.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceBooleanWorkAround.java new file mode 100644 index 0000000..611eaad --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceBooleanWorkAround.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; + +@AutoMapper(target = TargetBooleanWorkAround.class) +public class SourceBooleanWorkAround { + + @AutoMapping( expression = "java(source.isVal())", target = "val" ) + private Boolean val; + + public Boolean isVal() { + return val; + } + + public void setVal(Boolean val) { + this.val = val; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceList.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceList.java new file mode 100644 index 0000000..0cfbcd8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceList.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import java.util.Arrays; +import java.util.List; +import org.mapstruct.Mapping; + +@AutoMappers({ + @AutoMapper(target = TargetList.class, imports = { Arrays.class }) +}) +public class SourceList { + + @AutoMapping(target = "list", expression = "java(Arrays.asList( \"test2\" ))") + private List list; + + public List getList() { + return list; + } + + public void setList( List list ) { + this.list = list; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceTargetListMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceTargetListMapper.java new file mode 100644 index 0000000..722e80b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/SourceTargetListMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +import java.util.Arrays; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( imports = { Arrays.class } ) +public interface SourceTargetListMapper { + + SourceTargetListMapper INSTANCE = Mappers.getMapper( SourceTargetListMapper.class ); + + @Mapping(target = "list", expression = "java(Arrays.asList( \"test2\" ))") + TargetList map( SourceList source ); +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Target.java new file mode 100644 index 0000000..0eb7fc1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Target.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 io.github.linpeilie.me.source.expressions.java; + +import io.github.linpeilie.me.source.expressions.java.mapper.TimeAndFormat; + +/** + * @author Sjaak Derksen + */ +public class Target { + + private TimeAndFormat timeAndFormat; + private String anotherProp; + + public TimeAndFormat getTimeAndFormat() { + return timeAndFormat; + } + + public String getAnotherProp() { + return anotherProp; + } + + public void setAnotherProp( String anotherProp ) { + this.anotherProp = anotherProp; + } + + public void setTimeAndFormat(TimeAndFormat timeAndFormat) { + this.timeAndFormat = timeAndFormat; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Target1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Target1.java new file mode 100644 index 0000000..925d4df --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/Target1.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 io.github.linpeilie.me.source.expressions.java; + +import io.github.linpeilie.me.source.expressions.java.mapper.TimeAndFormat; + +/** + * @author Sjaak Derksen + */ +public class Target1 { + + private TimeAndFormat timeAndFormat; + private String anotherProp; + + public TimeAndFormat getTimeAndFormat() { + return timeAndFormat; + } + + public String getAnotherProp() { + return anotherProp; + } + + public void setAnotherProp( String anotherProp ) { + this.anotherProp = anotherProp; + } + + public void setTimeAndFormat(TimeAndFormat timeAndFormat) { + this.timeAndFormat = timeAndFormat; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/TargetBooleanWorkAround.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/TargetBooleanWorkAround.java new file mode 100644 index 0000000..53609a0 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/TargetBooleanWorkAround.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +public class TargetBooleanWorkAround { + private boolean val; + + public boolean isVal() { + return val; + } + + public void setVal(boolean val) { + this.val = val; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/TargetList.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/TargetList.java new file mode 100644 index 0000000..2346172 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/TargetList.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.expressions.java; + +import java.util.ArrayList; +import java.util.List; + +/** + * + * @author Sjaak Derksen + */ +public class TargetList { + + private List list = new ArrayList<>(); + + public List getList() { + return list; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/mapper/TimeAndFormat.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/mapper/TimeAndFormat.java new file mode 100644 index 0000000..cf91b0b --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/expressions/java/mapper/TimeAndFormat.java @@ -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 io.github.linpeilie.me.source.expressions.java.mapper; + +import java.util.Date; + +/** + * @author Sjaak Derksen + */ +public class TimeAndFormat { + private Date time; + private String format; + + public TimeAndFormat(Date time, String format) { + this.time = time; + this.format = format; + } + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + + public String getFormat() { + return format; + } + + public void setFormat(String tfFormat) { + this.format = tfFormat; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/Source.java new file mode 100644 index 0000000..2ae43c2 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/Source.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie.me.source.manytargetproperties; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; + +@AutoMapper(target = Target.class, uses = TimeAndFormatMapper.class, reverseConvertGenerate = false, + mapperName = "SourceToTargetForManyTargetPropertiesMapper") +public class Source { + + @AutoMappings({ + @AutoMapping(target = "time", source = "timeAndFormat"), + @AutoMapping(target = "format", source = "timeAndFormat") + }) + private TimeAndFormat timeAndFormat; + + @AutoMappings({ + @AutoMapping(target = "name1", source = "name"), + @AutoMapping(target = "name2", source = "name") + }) + private String name; + + public TimeAndFormat getTimeAndFormat() { + return timeAndFormat; + } + + public void setTimeAndFormat(TimeAndFormat timeAndFormat) { + this.timeAndFormat = timeAndFormat; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/Target.java new file mode 100644 index 0000000..1adea9a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/Target.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.manytargetproperties; + +import java.util.Date; + +/** + * @author Sjaak Derksen + */ +public class Target { + + private String format; + private Date time; + private String name1; + private String name2; + + public String getFormat() { + return format; + } + + public void setFormat(String format) { + this.format = format; + } + + public Date getTime() { + return time; + } + + public void setTime(Date time) { + this.time = time; + } + + public String getName1() { + return name1; + } + + public void setName1(String name1) { + this.name1 = name1; + } + + public String getName2() { + return name2; + } + + public void setName2(String name2) { + this.name2 = name2; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/TimeAndFormat.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/TimeAndFormat.java new file mode 100644 index 0000000..7d3ade7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/TimeAndFormat.java @@ -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 io.github.linpeilie.me.source.manytargetproperties; + +import java.util.Date; + +/** + * @author Sjaak Derksen + */ +public class TimeAndFormat { + private Date tfTime; + private String tfFormat; + + public Date getTfTime() { + return tfTime; + } + + public void setTfTime(Date tfTime) { + this.tfTime = tfTime; + } + + public String getTfFormat() { + return tfFormat; + } + + public void setTfFormat(String tfFormat) { + this.tfFormat = tfFormat; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/TimeAndFormatMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/TimeAndFormatMapper.java new file mode 100644 index 0000000..fb56518 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/manytargetproperties/TimeAndFormatMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.manytargetproperties; + +import java.util.Date; +import org.springframework.stereotype.Component; + +/** + * @author Sjaak Derksen + */ +@Component +public class TimeAndFormatMapper { + + public String getFormat(TimeAndFormat t) { + return t != null ? t.getTfFormat() : null; + } + + public Date getTime(TimeAndFormat t) { + return t != null ? t.getTfTime() : null; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalSource.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalSource.java new file mode 100644 index 0000000..98c3aae --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalSource.java @@ -0,0 +1,36 @@ +package io.github.linpeilie.me.source.nullvaluecheckstrategy; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; + +@AutoMappers({ + @AutoMapper( + target = RockFestivalTarget.class, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + reverseConvertGenerate = false + ), + @AutoMapper( + target = RockFestivalTarget1.class, + nullValueCheckStrategy = ON_IMPLICIT_CONVERSION, + reverseConvertGenerate = false + ), +}) +public class RockFestivalSource { + + @AutoMapping( target = "stage", source = "artistName" ) + private String artistName; + + public String getArtistName() { + return artistName; + } + + public void setArtistName(String artistName) { + this.artistName = artistName; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalTarget.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalTarget.java new file mode 100644 index 0000000..f07e7db --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalTarget.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.nullvaluecheckstrategy; + +/** + * + * @author Sjaak Derksen + */ +public class RockFestivalTarget { + + private Stage stage; + + public Stage getStage() { + return stage; + } + + public void setStage(Stage stage) { + this.stage = stage; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalTarget1.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalTarget1.java new file mode 100644 index 0000000..e31627d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/RockFestivalTarget1.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.nullvaluecheckstrategy; + +/** + * + * @author Sjaak Derksen + */ +public class RockFestivalTarget1 { + + private Stage stage; + + public Stage getStage() { + return stage; + } + + public void setStage(Stage stage) { + this.stage = stage; + } + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/Stage.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/Stage.java new file mode 100644 index 0000000..ea21d0a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/Stage.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.source.nullvaluecheckstrategy; + +import java.util.Arrays; +import java.util.List; + +/** + * + * @author Sjaak Derksen + */ +public enum Stage { + + MAIN("Paul McCartney", "Ellie Goulding", "Disclosure", "Kaiser Chiefs", "Rammstein"), + KLUB_C("James Blake", "Lost Frequencies"), + THE_BARN("New Order", "Year and Years"); + + private final List artists; + + Stage(String... artist) { + this.artists = Arrays.asList( artist ); + } + + public static Stage forArtist( String name ) { + + if ( name == null ) { + throw new IllegalArgumentException(); + } + + for ( Stage value : Stage.values() ) { + if ( value.artists.contains( name ) ) { + return value; + } + } + return null; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/StageMapper.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/StageMapper.java new file mode 100644 index 0000000..63639ef --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/source/nullvaluecheckstrategy/StageMapper.java @@ -0,0 +1,11 @@ +package io.github.linpeilie.me.source.nullvaluecheckstrategy; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +public interface StageMapper { + default Stage artistToStage(String name) { + return Stage.forArtist(name); + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/unmappedtarget/Source.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/unmappedtarget/Source.java new file mode 100644 index 0000000..71e7b3a --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/unmappedtarget/Source.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 io.github.linpeilie.me.unmappedtarget; + +import io.github.linpeilie.annotations.AutoMapper; +import org.mapstruct.ReportingPolicy; + +@AutoMapper( + target = Target.class, + unmappedSourcePolicy = ReportingPolicy.WARN, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +public class Source { + + private Long foo; + + private String qux; + + public Long getFoo() { + return foo; + } + + public void setFoo(Long foo) { + this.foo = foo; + } + + public String getQux() { + return qux; + } + + public void setQux(String qux) { + this.qux = qux; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/unmappedtarget/Target.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/unmappedtarget/Target.java new file mode 100644 index 0000000..411761d --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/me/unmappedtarget/Target.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie.me.unmappedtarget; + +import io.github.linpeilie.annotations.AutoMapper; +import org.mapstruct.ReportingPolicy; + +@AutoMapper( + target = Source.class, + unmappedSourcePolicy = ReportingPolicy.WARN, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +public class Target { + + private Long foo; + private int bar; + + public Long getFoo() { + return foo; + } + + public void setFoo(Long foo) { + this.foo = foo; + } + + public int getBar() { + return bar; + } + + public void setBar(int bar) { + this.bar = bar; + } +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/Car.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/Car.java index 23aba5f..4a67e74 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/Car.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/Car.java @@ -10,6 +10,7 @@ import lombok.Data; public class Car { private String make; + @AutoMapping(target = "seatMaterial", source = "seatConfiguration.seatMaterial") private SeatConfiguration seatConfiguration; private CarType type; private Tyre tyre; diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/CarDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/CarDto.java index b7bd6f1..e0e5b66 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/CarDto.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/CarDto.java @@ -10,5 +10,6 @@ public class CarDto { private String type; private List wheels; private TyreDTO tyre; + private String seatMaterial; } diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/EnglishRelease.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/EnglishRelease.java index 104423a..2cbff87 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/EnglishRelease.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/EnglishRelease.java @@ -10,7 +10,7 @@ import lombok.Data; @AutoMapper(target = FrenchRelease.class, uses = Titles.class) public class EnglishRelease { - @AutoMapping(qualifiedByName = "EnglishToFrench") + @AutoMapping(qualifiedByName = "EnglishToFrench", defaultValue = "DefaultTitle") @ReverseAutoMapping(qualifiedByName = "FrenchToEnglish") private String title; diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsDto.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsDto.java index 7e9c50e..5ec6fd0 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsDto.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsDto.java @@ -9,7 +9,7 @@ import lombok.Data; @Data @AutoMappers({ @AutoMapper(target = Goods.class), - @AutoMapper(target = GoodsVo.class) +// @AutoMapper(target = GoodsVo.class) }) public class GoodsDto extends BaseDTO { diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsVo.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsVo.java index deb4910..2f2f39c 100644 --- a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsVo.java +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GoodsVo.java @@ -4,7 +4,7 @@ import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; @Data -@AutoMapper(target = GoodsDto.class) +//@AutoMapper(target = GoodsDto.class) public class GoodsVo extends BaseVO { private Integer price; diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GrantedAuthority.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GrantedAuthority.java new file mode 100644 index 0000000..c38b024 --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/GrantedAuthority.java @@ -0,0 +1,7 @@ +package io.github.linpeilie.model; + +public class GrantedAuthority { + + private String authority; + +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/LoginUser.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/LoginUser.java new file mode 100644 index 0000000..c9844dd --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/LoginUser.java @@ -0,0 +1,14 @@ +package io.github.linpeilie.model; + +import java.util.Collection; +import lombok.Data; + +@Data +public class LoginUser { + + private Long userId; + + private String username; + + private Collection authorities; +} diff --git a/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/LoginUserVO.java b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/LoginUserVO.java new file mode 100644 index 0000000..74cae5f --- /dev/null +++ b/example/spring-boot-with-lombok/src/main/java/io/github/linpeilie/model/LoginUserVO.java @@ -0,0 +1,18 @@ +package io.github.linpeilie.model; + +import io.github.linpeilie.annotations.AutoMapper; +import java.util.Collection; +import lombok.Data; +import org.mapstruct.CollectionMappingStrategy; + +@Data +@AutoMapper(target = LoginUser.class, collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE) +public class LoginUserVO { + + private Long userId; + + private String username; + + private Collection authorities; + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/AdderTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/AdderTest.java new file mode 100644 index 0000000..987685a --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/AdderTest.java @@ -0,0 +1,214 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.collection.adder.DogException; +import io.github.linpeilie.me.collection.adder._target.AdderUsageObserver; +import io.github.linpeilie.me.collection.adder._target.Target; +import io.github.linpeilie.me.collection.adder._target.Target2; +import io.github.linpeilie.me.collection.adder._target.Target3; +import io.github.linpeilie.me.collection.adder._target.TargetDali; +import io.github.linpeilie.me.collection.adder._target.TargetHuman; +import io.github.linpeilie.me.collection.adder._target.TargetOnlyGetter; +import io.github.linpeilie.me.collection.adder._target.TargetViaTargetType; +import io.github.linpeilie.me.collection.adder._target.TargetWithAnimals; +import io.github.linpeilie.me.collection.adder._target.TargetWithoutSetter; +import io.github.linpeilie.me.collection.adder.source.Foo; +import io.github.linpeilie.me.collection.adder.source.SingleElementSource; +import io.github.linpeilie.me.collection.adder.source.Source; +import io.github.linpeilie.me.collection.adder.source.Source2; +import io.github.linpeilie.me.collection.adder.source.Source3; +import io.github.linpeilie.me.collection.adder.source.SourceTeeth; +import io.github.linpeilie.me.collection.adder.source.SourceWithPets; +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@SpringBootTest(classes = Application.class) +public class AdderTest { + + @Autowired + private Converter converter; + + @Test + public void testAdd() throws DogException { + AdderUsageObserver.setUsed(false); + + Source source = new Source(); + source.setPets(Arrays.asList("mouse")); + + Target target = converter.convert(source, Target.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isEqualTo(2L); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testAddWithExceptionNotInThrowsClause() throws DogException { + AdderUsageObserver.setUsed(false); + + Source source = new Source(); + source.setPets(Arrays.asList("cat")); + + assertThatThrownBy(() -> converter.convert(source, Target.class)) + .isInstanceOf(RuntimeException.class); + } + + @Test + public void testAddWithExistingTarget() { + AdderUsageObserver.setUsed(false); + + Source source = new Source(); + source.setPets(Arrays.asList("mouse")); + + Target target = new Target(); + target.setPets(new ArrayList<>(Arrays.asList(1L))); + + converter.convert(source, target); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(2); + assertThat(target.getPets().get(0)).isEqualTo(1L); + assertThat(target.getPets().get(1)).isEqualTo(2L); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testShouldUseDefaultStrategy() throws DogException { + AdderUsageObserver.setUsed(false); + + Source3 source = new Source3(); + source.setPets(Arrays.asList("mouse")); + + Target3 target = converter.convert(source, Target3.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isEqualTo(2L); + assertFalse(AdderUsageObserver.isUsed()); + } + + @Test + public void testShouldPreferSetterStrategyButThereIsNone() throws DogException { + AdderUsageObserver.setUsed(false); + + Source source = new Source(); + source.setPets(Arrays.asList("mouse")); + + TargetWithoutSetter target = converter.convert(source, TargetWithoutSetter.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isEqualTo(2L); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testShouldPreferHumanSingular() { + + AdderUsageObserver.setUsed(false); + + SourceTeeth source = new SourceTeeth(); + source.setTeeth(Arrays.asList("moler")); + + TargetHuman target = converter.convert(source, TargetHuman.class); + assertThat(target).isNotNull(); + assertThat(target.getTeeth().size()).isEqualTo(1); + assertThat(target.getTeeth().get(0)).isEqualTo(3); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testShouldFallBackToDaliSingularInAbsenceOfHumanSingular() { + AdderUsageObserver.setUsed(false); + + SourceTeeth source = new SourceTeeth(); + source.setTeeth(Arrays.asList("moler")); + + TargetDali target = converter.convert(source, TargetDali.class); + assertThat(target).isNotNull(); + assertThat(target.getTeeth().size()).isEqualTo(1); + assertThat(target.getTeeth().get(0)).isEqualTo(3); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testAddReverse() { + AdderUsageObserver.setUsed(false); + + Target source = new Target(); + source.setPets(Arrays.asList(3L)); + + Source target = converter.convert(source, Source.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isEqualTo("cat"); + } + + @Test + public void testAddOnlyGetter() throws DogException { + AdderUsageObserver.setUsed(false); + + Source source = new Source(); + source.setPets(Arrays.asList("mouse")); + + TargetOnlyGetter target = converter.convert(source, TargetOnlyGetter.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isEqualTo(2L); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testAddViaTargetType() { + AdderUsageObserver.setUsed(false); + + Source source = new Source(); + source.setPets(Arrays.asList("mouse")); + + TargetViaTargetType target = converter.convert(source, TargetViaTargetType.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isNotNull(); + assertThat(target.getPets().get(0).getValue()).isEqualTo(2L); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testSingleElementSource() { + AdderUsageObserver.setUsed(false); + + SingleElementSource source = new SingleElementSource(); + source.setPet("mouse"); + + Target target = converter.convert(source, Target.class); + assertThat(target).isNotNull(); + assertThat(target.getPets().size()).isEqualTo(1); + assertThat(target.getPets().get(0)).isEqualTo(2L); + assertTrue(AdderUsageObserver.isUsed()); + } + + @Test + public void testMissingImport() { + Source2 source = new Source2(); + source.setAttributes(Arrays.asList(new Foo())); + + Target2 target = converter.convert(source, Target2.class); + assertThat(target).isNotNull(); + assertThat(target.getAttributes().size()).isEqualTo(1); + } + + @Test + public void useIterationNameFromSource() { + SourceWithPets source = new SourceWithPets(); + source.setPets(Arrays.asList("dog", "cat")); + + TargetWithAnimals target = converter.convert(source, TargetWithAnimals.class); + + assertThat(target.getAnimals()).containsExactly("dog", "cat"); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/BigNumbersConversionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/BigNumbersConversionTest.java new file mode 100644 index 0000000..816059b --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/BigNumbersConversionTest.java @@ -0,0 +1,169 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie; + +import io.github.linpeilie.me.conversion.bignumbers.BigDecimalSource; +import io.github.linpeilie.me.conversion.bignumbers.BigDecimalTarget; +import io.github.linpeilie.me.conversion.bignumbers.BigIntegerSource; +import io.github.linpeilie.me.conversion.bignumbers.BigIntegerTarget; +import java.math.BigDecimal; +import java.math.BigInteger; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class BigNumbersConversionTest { + + @Autowired + private Converter converter; + + @Test + public void shouldApplyBigIntegerConversions() { + BigIntegerSource source = new BigIntegerSource(); + source.setB( new BigInteger( "1" ) ); + source.setBb( new BigInteger( "2" ) ); + source.setS( new BigInteger( "3" ) ); + source.setSs( new BigInteger( "4" ) ); + source.setI( new BigInteger( "5" ) ); + source.setIi( new BigInteger( "6" ) ); + source.setL( new BigInteger( "7" ) ); + source.setLl( new BigInteger( "8" ) ); + source.setF( new BigInteger( "9" ) ); + source.setFf( new BigInteger( "10" ) ); + source.setD( new BigInteger( "11" ) ); + source.setDd( new BigInteger( "12" ) ); + source.setString( new BigInteger( "13" ) ); + + BigIntegerTarget target = converter.convert( source, BigIntegerTarget.class ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( (byte) 2 ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( (short) 4 ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( 6 ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( 8 ); + assertThat( target.getF() ).isEqualTo( 9.0f ); + assertThat( target.getFf() ).isEqualTo( 10.0f ); + assertThat( target.getD() ).isEqualTo( 11.0d ); + assertThat( target.getDd() ).isEqualTo( 12.0d ); + assertThat( target.getString() ).isEqualTo( "13" ); + } + + @Test + public void shouldApplyReverseBigIntegerConversions() { + BigIntegerTarget target = new BigIntegerTarget(); + target.setB( (byte) 1 ); + target.setBb( (byte) 2 ); + target.setS( (short) 3 ); + target.setSs( (short) 4 ); + target.setI( 5 ); + target.setIi( 6 ); + target.setL( 7 ); + target.setLl( 8L ); + target.setF( 9.0f ); + target.setFf( 10.0f ); + target.setD( 11.0d ); + target.setDd( 12.0d ); + target.setString( "13" ); + + BigIntegerSource source = converter.convert( target, BigIntegerSource.class ); + + assertThat( source ).isNotNull(); + assertThat( source.getB() ).isEqualTo( new BigInteger( "1" ) ); + assertThat( source.getBb() ).isEqualTo( new BigInteger( "2" ) ); + assertThat( source.getS() ).isEqualTo( new BigInteger( "3" ) ); + assertThat( source.getSs() ).isEqualTo( new BigInteger( "4" ) ); + assertThat( source.getI() ).isEqualTo( new BigInteger( "5" ) ); + assertThat( source.getIi() ).isEqualTo( new BigInteger( "6" ) ); + assertThat( source.getL() ).isEqualTo( new BigInteger( "7" ) ); + assertThat( source.getLl() ).isEqualTo( new BigInteger( "8" ) ); + assertThat( source.getF() ).isEqualTo( new BigInteger( "9" ) ); + assertThat( source.getFf() ).isEqualTo( new BigInteger( "10" ) ); + assertThat( source.getD() ).isEqualTo( new BigInteger( "11" ) ); + assertThat( source.getDd() ).isEqualTo( new BigInteger( "12" ) ); + assertThat( source.getString() ).isEqualTo( new BigInteger( "13" ) ); + } + + @Test + public void shouldApplyBigDecimalConversions() { + BigDecimalSource source = new BigDecimalSource(); + source.setB( new BigDecimal( "1.45" ) ); + source.setBb( new BigDecimal( "2.45" ) ); + source.setS( new BigDecimal( "3.45" ) ); + source.setSs( new BigDecimal( "4.45" ) ); + source.setI( new BigDecimal( "5.45" ) ); + source.setIi( new BigDecimal( "6.45" ) ); + source.setL( new BigDecimal( "7.45" ) ); + source.setLl( new BigDecimal( "8.45" ) ); + source.setF( new BigDecimal( "9.45" ) ); + source.setFf( new BigDecimal( "10.45" ) ); + source.setD( new BigDecimal( "11.45" ) ); + source.setDd( new BigDecimal( "12.45" ) ); + source.setString( new BigDecimal( "13.45" ) ); + source.setBigInteger( new BigDecimal( "14.45" ) ); + + BigDecimalTarget target = converter.convert( source, BigDecimalTarget.class ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( (byte) 2 ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( (short) 4 ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( 6 ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( 8 ); + assertThat( target.getF() ).isEqualTo( 9.45f ); + assertThat( target.getFf() ).isEqualTo( 10.45f ); + assertThat( target.getD() ).isEqualTo( 11.45d ); + assertThat( target.getDd() ).isEqualTo( 12.45d ); + assertThat( target.getString() ).isEqualTo( "13.45" ); + assertThat( target.getBigInteger() ).isEqualTo( new BigInteger( "14" ) ); + } + + @Test + public void shouldApplyReverseBigDecimalConversions() { + BigDecimalTarget target = new BigDecimalTarget(); + target.setB( (byte) 1 ); + target.setBb( (byte) 2 ); + target.setS( (short) 3 ); + target.setSs( (short) 4 ); + target.setI( 5 ); + target.setIi( 6 ); + target.setL( 7 ); + target.setLl( 8L ); + target.setF( 9.0f ); + target.setFf( 10.0f ); + target.setD( 11.0d ); + target.setDd( 12.0d ); + target.setString( "13.45" ); + target.setBigInteger( new BigInteger( "14" ) ); + + BigDecimalSource source = converter.convert( target, BigDecimalSource.class ); + + assertThat( source ).isNotNull(); + assertThat( source.getB() ).isEqualTo( new BigDecimal( "1" ) ); + assertThat( source.getBb() ).isEqualTo( new BigDecimal( "2" ) ); + assertThat( source.getS() ).isEqualTo( new BigDecimal( "3" ) ); + assertThat( source.getSs() ).isEqualTo( new BigDecimal( "4" ) ); + assertThat( source.getI() ).isEqualTo( new BigDecimal( "5" ) ); + assertThat( source.getIi() ).isEqualTo( new BigDecimal( "6" ) ); + assertThat( source.getL() ).isEqualTo( new BigDecimal( "7" ) ); + assertThat( source.getLl() ).isEqualTo( new BigDecimal( "8" ) ); + assertThat( source.getF() ).isEqualTo( new BigDecimal( "9.0" ) ); + assertThat( source.getFf() ).isEqualTo( new BigDecimal( "10.0" ) ); + assertThat( source.getD() ).isEqualTo( new BigDecimal( "11.0" ) ); + assertThat( source.getDd() ).isEqualTo( new BigDecimal( "12.0" ) ); + assertThat( source.getString() ).isEqualTo( new BigDecimal( "13.45" ) ); + assertThat( source.getBigInteger() ).isEqualTo( new BigDecimal( "14" ) ); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CallbackMethodTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CallbackMethodTest.java new file mode 100644 index 0000000..fec987e --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CallbackMethodTest.java @@ -0,0 +1,100 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.callbacks.ClassContainingCallbacks; +import io.github.linpeilie.me.callbacks.Invocation; +import io.github.linpeilie.me.callbacks.Source; +import io.github.linpeilie.me.callbacks.Target; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class CallbackMethodTest { + + @Autowired + private Converter converter; + + @BeforeEach + public void reset() { + ClassContainingCallbacks.reset(); + io.github.linpeilie.me.callbacks.BaseMapper.reset(); + } + + @Test + public void callbackMethodsForBeanMappingCalled() { + converter.convert(createSource(), Target.class); + + assertBeanMappingInvocations(ClassContainingCallbacks.getInvocations()); + assertBeanMappingInvocations(io.github.linpeilie.me.callbacks.BaseMapper.getInvocations()); + } + + @Test + public void callbackMethodsForBeanMappingWithResultParamCalled() { + converter.convert(createSource(), createEmptyTarget()); + + assertBeanMappingInvocations(ClassContainingCallbacks.getInvocations()); + assertBeanMappingInvocations(io.github.linpeilie.me.callbacks.BaseMapper.getInvocations()); + } + + private void assertBeanMappingInvocations(List invocations) { + Source source = createSource(); + Target target = createResultTarget(); + Target emptyTarget = createEmptyTarget(); + + assertThat(invocations).isEqualTo(beanMappingInvocationList(source, target, emptyTarget)); + } + + private List beanMappingInvocationList(Object source, Object target, Object emptyTarget) { + List invocations = new ArrayList<>(); + + invocations.addAll(allBeforeMappingMethods(source, emptyTarget, Target.class)); + invocations.addAll(allAfterMappingMethods(source, target, Target.class)); + + return invocations; + } + + private List allAfterMappingMethods(Object source, Object target, Class targetClass) { + return new ArrayList<>(Arrays.asList( + new Invocation("noArgsAfterMapping"), + new Invocation("withSourceAfterMapping", source), + new Invocation("withSourceAsObjectAfterMapping", source), + new Invocation("withSourceAndTargetAfterMapping", source, target), + new Invocation("withTargetAfterMapping", target), + new Invocation("withTargetAsObjectAfterMapping", target), + new Invocation("withTargetAndTargetTypeAfterMapping", target, targetClass))); + } + + private List allBeforeMappingMethods(Object source, Object emptyTarget, Class targetClass) { + return new ArrayList<>(Arrays.asList( + new Invocation("noArgsBeforeMapping"), + new Invocation("withSourceBeforeMapping", source), + new Invocation("withSourceAsObjectBeforeMapping", source), + new Invocation("withSourceAndTargetTypeBeforeMapping", source, targetClass), + new Invocation("withSourceAndTargetBeforeMapping", source, emptyTarget), + new Invocation("withTargetBeforeMapping", emptyTarget), + new Invocation("withTargetAsObjectBeforeMapping", emptyTarget))); + } + + private Source createSource() { + Source source = new Source(); + source.setFoo("foo"); + return source; + } + + private Target createEmptyTarget() { + return new Target(); + } + + private Target createResultTarget() { + Target target = createEmptyTarget(); + target.setFoo("foo"); + return target; + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CarMapperTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CarMapperTest.java new file mode 100644 index 0000000..eff8da7 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CarMapperTest.java @@ -0,0 +1,283 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.complex._target.CarDto; +import io.github.linpeilie.me.complex._target.PersonDto; +import io.github.linpeilie.me.complex.source.Car; +import io.github.linpeilie.me.complex.source.Category; +import io.github.linpeilie.me.complex.source.Person; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class CarMapperTest { + + @Autowired + private Converter converter; + + @Test + public void shouldMapAttributeByName() { + //given + Car car = new Car( + "Morris", + 2, + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime(), + new Person("Bob"), + new ArrayList<>() + ); + + //when + CarDto carDto = converter.convert(car, CarDto.class); + + //then + assertThat(carDto).isNotNull(); + assertThat(carDto.getMake()).isEqualTo(car.getMake()); + } + + @Test + public void shouldMapReferenceAttribute() { + //given + Car car = new Car( + "Morris", + 2, + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime(), + new Person("Bob"), + new ArrayList<>() + ); + + //when + CarDto carDto = converter.convert(car, CarDto.class); + + //then + assertThat(carDto).isNotNull(); + assertThat(carDto.getDriver()).isNotNull(); + assertThat(carDto.getDriver().getName()).isEqualTo("Bob"); + } + + @Test + public void shouldReverseMapReferenceAttribute() { + //given + CarDto carDto = new CarDto("Morris", 2, "1980", new PersonDto("Bob"), new ArrayList<>()); + + //when + Car car = converter.convert(carDto, Car.class); + + //then + assertThat(car).isNotNull(); + assertThat(car.getDriver()).isNotNull(); + assertThat(car.getDriver().getName()).isEqualTo("Bob"); + } + + @Test + public void shouldMapAttributeWithCustomMapping() { + //given + Car car = new Car( + "Morris", + 2, + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime(), + new Person("Bob"), + new ArrayList<>() + ); + + //when + CarDto carDto = converter.convert(car, CarDto.class); + + //then + assertThat(carDto).isNotNull(); + assertThat(carDto.getSeatCount()).isEqualTo(car.getNumberOfSeats()); + } + + @Test + public void shouldConsiderCustomMappingForReverseMapping() { + //given + CarDto carDto = new CarDto("Morris", 2, "1980", new PersonDto("Bob"), new ArrayList<>()); + + //when + Car car = converter.convert(carDto, Car.class); + + //then + assertThat(car).isNotNull(); + assertThat(car.getNumberOfSeats()).isEqualTo(carDto.getSeatCount()); + } + + @Test + public void shouldApplyConverter() { + //given + Car car = new Car( + "Morris", + 2, + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime(), + new Person("Bob"), + new ArrayList<>() + ); + + //when + CarDto carDto = converter.convert(car, CarDto.class); + + //then + assertThat(carDto).isNotNull(); + assertThat(carDto.getManufacturingYear()).isEqualTo("1980"); + } + + @Test + public void shouldApplyConverterForReverseMapping() { + //given + CarDto carDto = new CarDto("Morris", 2, "1980", new PersonDto("Bob"), new ArrayList<>()); + + //when + Car car = converter.convert(carDto, Car.class); + + //then + assertThat(car).isNotNull(); + assertThat(car.getManufacturingDate()).isEqualTo( + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime() + ); + } + + @Test + public void shouldMapIterable() { + //given + Car car1 = new Car( + "Morris", + 2, + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime(), + new Person("Bob"), + new ArrayList<>() + ); + Car car2 = new Car( + "Railton", + 4, + new GregorianCalendar(1934, Calendar.JANUARY, 1).getTime(), + new Person("Bill"), + new ArrayList<>() + ); + + //when + List dtos = converter.convert(Arrays.asList(car1, car2), CarDto.class); + + //then + assertThat(dtos).isNotNull(); + assertThat(dtos).hasSize(2); + + assertThat(dtos.get(0).getMake()).isEqualTo("Morris"); + assertThat(dtos.get(0).getSeatCount()).isEqualTo(2); + assertThat(dtos.get(0).getManufacturingYear()).isEqualTo("1980"); + assertThat(dtos.get(0).getDriver().getName()).isEqualTo("Bob"); + + assertThat(dtos.get(1).getMake()).isEqualTo("Railton"); + assertThat(dtos.get(1).getSeatCount()).isEqualTo(4); + assertThat(dtos.get(1).getManufacturingYear()).isEqualTo("1934"); + assertThat(dtos.get(1).getDriver().getName()).isEqualTo("Bill"); + } + + @Test + public void shouldReverseMapIterable() { + //given + CarDto car1 = new CarDto("Morris", 2, "1980", new PersonDto("Bob"), new ArrayList<>()); + CarDto car2 = new CarDto("Railton", 4, "1934", new PersonDto("Bill"), new ArrayList<>()); + + //when + List cars = converter.convert(Arrays.asList(car1, car2), Car.class); + + //then + assertThat(cars).isNotNull(); + assertThat(cars).hasSize(2); + + assertThat(cars.get(0).getMake()).isEqualTo("Morris"); + assertThat(cars.get(0).getNumberOfSeats()).isEqualTo(2); + assertThat(cars.get(0).getManufacturingDate()).isEqualTo( + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime() + ); + assertThat(cars.get(0).getDriver().getName()).isEqualTo("Bob"); + + assertThat(cars.get(1).getMake()).isEqualTo("Railton"); + assertThat(cars.get(1).getNumberOfSeats()).isEqualTo(4); + assertThat(cars.get(1).getManufacturingDate()).isEqualTo( + new GregorianCalendar(1934, Calendar.JANUARY, 1).getTime() + ); + assertThat(cars.get(1).getDriver().getName()).isEqualTo("Bill"); + } + + @Test + public void shouldMapIterableAttribute() { + //given + Car car = new Car( + "Morris", + 2, + new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime(), + new Person("Bob"), + Arrays.asList(new Person("Alice"), new Person("Bill")) + ); + + //when + CarDto dto = converter.convert(car, CarDto.class); + + //then + assertThat(dto).isNotNull(); + + assertThat(dto.getPassengers()).hasSize(2); + assertThat(dto.getPassengers().get(0).getName()).isEqualTo("Alice"); + assertThat(dto.getPassengers().get(1).getName()).isEqualTo("Bill"); + } + + @Test + public void shouldReverseMapIterableAttribute() { + //given + CarDto carDto = new CarDto( + "Morris", + 2, + "1980", + new PersonDto("Bob"), + Arrays.asList(new PersonDto("Alice"), new PersonDto("Bill")) + ); + + //when + Car car = converter.convert(carDto, Car.class); + + //then + assertThat(car).isNotNull(); + + assertThat(car.getPassengers()).hasSize(2); + assertThat(car.getPassengers().get(0).getName()).isEqualTo("Alice"); + assertThat(car.getPassengers().get(1).getName()).isEqualTo("Bill"); + } + + @Test + public void shouldMapEnumToString() { + //given + Car car = new Car(); + car.setCategory(Category.CONVERTIBLE); + //when + CarDto carDto = converter.convert(car, CarDto.class); + + //then + assertThat(carDto).isNotNull(); + assertThat(carDto.getCategory()).isEqualTo("CONVERTIBLE"); + } + + @Test + public void shouldMapStringToEnum() { + //given + CarDto carDto = new CarDto(); + carDto.setCategory("CONVERTIBLE"); + //when + Car car = converter.convert(carDto, Car.class); + + //then + assertThat(car).isNotNull(); + assertThat(car.getCategory()).isEqualTo(Category.CONVERTIBLE); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CollectionMapping1Test.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CollectionMapping1Test.java new file mode 100644 index 0000000..453deed --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CollectionMapping1Test.java @@ -0,0 +1,402 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.collection.Colour; +import io.github.linpeilie.me.collection.Source; +import io.github.linpeilie.me.collection.StringHolder; +import io.github.linpeilie.me.collection.StringHolderArrayList; +import io.github.linpeilie.me.collection.StringHolderToLongMap; +import io.github.linpeilie.me.collection.Target; +import io.github.linpeilie.me.collection.TestList; +import io.github.linpeilie.me.collection.TestMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +@SpringBootTest(classes = Application.class) +public class CollectionMapping1Test { + + @Autowired + private Converter converter; + + @Test + public void shouldMapNullList() { + Source source = new Source(); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getStringList()).isNull(); + } + + @Test + public void shouldReverseMapNullList() { + Target target = new Target(); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getStringList()).isNull(); + } + + @Test + public void shouldMapList() { + Source source = new Source(); + source.setStringList(Arrays.asList("Bob", "Alice")); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getStringList()).containsExactly("Bob", "Alice"); + } + + @Test + public void shouldMapListWithoutSetter() { + Source source = new Source(); + source.setStringList2(Arrays.asList("Bob", "Alice")); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getStringListNoSetter()).containsExactly("Bob", "Alice"); + } + + @Test + public void shouldReverseMapList() { + Target target = new Target(); + target.setStringList(Arrays.asList("Bob", "Alice")); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getStringList()).containsExactly("Bob", "Alice"); + } + + @Test + public void shouldMapListAsCopy() { + Source source = new Source(); + source.setStringList(Arrays.asList("Bob", "Alice")); + + Target target = converter.convert(source, Target.class); + target.getStringList().add("Bill"); + + assertThat(source.getStringList()).containsExactly("Bob", "Alice"); + assertThat(source.getStringList()).isNotEqualTo(target.getStringList()); + } + + @Test + public void shouldMapListWithClearAndAddAll() { + Source source = new Source(); + source.setOtherStringList(Arrays.asList("Bob", "Alice")); + + Target target = converter.convert(source, Target.class); + target.getOtherStringList().add("Bill"); + + assertThat(source.getOtherStringList()).containsExactly("Bob", "Alice"); + + // prepare a test list to monitor add all behaviour + List testList = new TestList<>(); + testList.addAll(target.getOtherStringList()); + TestList.setAddAllCalled(false); + target.setOtherStringList(testList); + + // prepare new source + source.setOtherStringList(Arrays.asList("Bob")); + List originalInstance = target.getOtherStringList(); + + converter.convert(source, target); + + assertThat(target.getOtherStringList()).isSameAs(originalInstance); + assertThat(target.getOtherStringList()).containsExactly("Bob"); + assertThat(TestList.isAddAllCalled()).isTrue(); + TestList.setAddAllCalled(false); + } + + @Test + public void shouldReverseMapListAsCopy() { + Target target = new Target(); + target.setStringList(Arrays.asList("Bob", "Alice")); + + Source source = converter.convert(target, Source.class); + source.getStringList().add("Bill"); + + assertThat(target.getStringList()).containsExactly("Bob", "Alice"); + } + + @Test + public void shouldMapArrayList() { + Source source = new Source(); + source.setStringArrayList(new ArrayList<>(Arrays.asList("Bob", "Alice"))); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getStringArrayList()).containsExactly("Bob", "Alice"); + } + + @Test + public void shouldReverseMapArrayList() { + Target target = new Target(); + target.setStringArrayList(new ArrayList<>(Arrays.asList("Bob", "Alice"))); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getStringArrayList()).containsExactly("Bob", "Alice"); + } + + @Test + public void shouldMapSet() { + Source source = new Source(); + source.setStringSet(new HashSet<>(Arrays.asList("Bob", "Alice"))); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getStringSet()).contains("Bob", "Alice"); + } + + @Test + public void shouldReverseMapSet() { + Target target = new Target(); + target.setStringSet(new HashSet<>(Arrays.asList("Bob", "Alice"))); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getStringSet()).contains("Bob", "Alice"); + } + + @Test + public void shouldMapSetAsCopy() { + Source source = new Source(); + source.setStringSet(new HashSet<>(Arrays.asList("Bob", "Alice"))); + + Target target = converter.convert(source, Target.class); + target.getStringSet().add("Bill"); + + assertThat(source.getStringSet()).containsOnly("Bob", "Alice"); + } + + @Test + public void shouldMapHashSetAsCopy() { + Source source = new Source(); + source.setStringHashSet(new HashSet<>(Arrays.asList("Bob", "Alice"))); + + Target target = converter.convert(source, Target.class); + target.getStringHashSet().add("Bill"); + + assertThat(source.getStringHashSet()).containsOnly("Bob", "Alice"); + } + + @Test + public void shouldReverseMapSetAsCopy() { + Target target = new Target(); + target.setStringSet(new HashSet<>(Arrays.asList("Bob", "Alice"))); + + Source source = converter.convert(target, Source.class); + source.getStringSet().add("Bill"); + + assertThat(target.getStringSet()).containsOnly("Bob", "Alice"); + } + + @Test + public void shouldMapListToCollection() { + Source source = new Source(); + source.setIntegerList(Arrays.asList(1, 2)); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getIntegerCollection()).containsOnly(1, 2); + } + + @Test + public void shouldReverseMapListToCollection() { + Target target = new Target(); + target.setIntegerCollection(Arrays.asList(1, 2)); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getIntegerList()).containsOnly(1, 2); + } + + @Test + public void shouldMapIntegerSetToRawSet() { + Source source = new Source(); + source.setIntegerSet(new HashSet<>(Arrays.asList(1, 2))); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getSet()).containsOnly(1, 2); + } + + @Test + public void shouldMapIntegerSetToStringSet() { + Source source = new Source(); + source.setAnotherIntegerSet(new HashSet<>(Arrays.asList(1, 2))); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getAnotherStringSet()).containsOnly("1", "2"); + } + + @Test + public void shouldReverseMapIntegerSetToStringSet() { + Target target = new Target(); + target.setAnotherStringSet(new HashSet<>(Arrays.asList("1", "2"))); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getAnotherIntegerSet()).containsOnly(1, 2); + } + + @Test + public void shouldMapSetOfEnumToStringSet() { + Source source = new Source(); + source.setColours(EnumSet.of(Colour.BLUE, Colour.GREEN)); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getColours()).containsOnly("BLUE", "GREEN"); + } + + @Test + public void shouldReverseMapSetOfEnumToStringSet() { + Target target = new Target(); + target.setColours(new HashSet<>(Arrays.asList("BLUE", "GREEN"))); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getColours()).containsOnly(Colour.GREEN, Colour.BLUE); + } + + @Test + public void shouldMapMapAsCopy() { + Source source = new Source(); + + Map map = new HashMap<>(); + map.put("Bob", 123L); + map.put("Alice", 456L); + source.setStringLongMap(map); + + Target target = converter.convert(source, Target.class); + target.getStringLongMap().put("Bill", 789L); + + assertThat(source.getStringLongMap()).hasSize(2); + assertThat(target.getStringLongMap()).hasSize(3); + } + + @Test + public void shouldMapMapWithClearAndPutAll() { + Source source = new Source(); + + Map map = new HashMap<>(); + map.put("Bob", 123L); + map.put("Alice", 456L); + source.setOtherStringLongMap(map); + + Target target = converter.convert(source, Target.class); + target.getOtherStringLongMap().put("Bill", 789L); + + assertThat(source.getOtherStringLongMap()).hasSize(2); + assertThat(target.getOtherStringLongMap()).hasSize(3); + + source.getOtherStringLongMap().remove("Alice"); + + // prepare a test list to monitor add all behaviour + Map originalInstance = new TestMap<>(); + originalInstance.putAll(target.getOtherStringLongMap()); + TestMap.setPuttAllCalled(false); + target.setOtherStringLongMap(originalInstance); + + converter.convert(source, target); + + assertThat(target.getOtherStringLongMap()).isSameAs(originalInstance); + assertThat(target.getOtherStringLongMap()).hasSize(1); + assertThat(TestMap.isPuttAllCalled()).isTrue(); + TestMap.setPuttAllCalled(false); + } + + @Test + public void shouldEnumSetAsCopy() { + Source source = new Source(); + source.setEnumSet(EnumSet.of(Colour.BLUE, Colour.GREEN)); + + Target target = converter.convert(source, Target.class); + source.getEnumSet().add(Colour.RED); + + assertThat(source.getEnumSet()).containsOnly(Colour.BLUE, Colour.GREEN, Colour.RED); + assertThat(target.getEnumSet()).containsOnly(Colour.BLUE, Colour.GREEN); + } + + @Test + public void shouldMapNonGenericList() { + Source source = new Source(); + source.setStringList3(new ArrayList<>(Arrays.asList("Bob", "Alice"))); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getNonGenericStringList()).containsExactly( + new StringHolder("Bob"), + new StringHolder("Alice")); + + // Inverse direction + Target newTarget = new Target(); + StringHolderArrayList nonGenericStringList = new StringHolderArrayList(); + nonGenericStringList.addAll(Arrays.asList(new StringHolder("Bill"), new StringHolder("Bob"))); + newTarget.setNonGenericStringList(nonGenericStringList); + + Source mappedSource = converter.convert(newTarget, Source.class); + + assertThat(mappedSource).isNotNull(); + assertThat(mappedSource.getStringList3()).containsExactly("Bill", "Bob"); + } + + @Test + public void shouldMapNonGenericMap() { + Source source = new Source(); + Map map = new HashMap<>(); + map.put("Bob", 123L); + map.put("Alice", 456L); + source.setStringLongMapForNonGeneric(map); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getNonGenericMapStringtoLong()).contains( + entry(new StringHolder("Bob"), 123L), + entry(new StringHolder("Alice"), 456L)); + + // Inverse direction + Target newTarget = new Target(); + StringHolderToLongMap stringToLongMap = new StringHolderToLongMap(); + stringToLongMap.put(new StringHolder("Blue"), 321L); + stringToLongMap.put(new StringHolder("Green"), 654L); + newTarget.setNonGenericMapStringtoLong(stringToLongMap); + + Source mappedSource = converter.convert(newTarget, Source.class); + + assertThat(mappedSource).isNotNull(); + assertThat(mappedSource.getStringLongMapForNonGeneric()).contains( + entry("Blue", 321L), + entry("Green", 654L)); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CollectionMappingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CollectionMappingTest.java new file mode 100644 index 0000000..51c3d01 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CollectionMappingTest.java @@ -0,0 +1,117 @@ +package io.github.linpeilie; + +import com.google.common.collect.ImmutableMap; +import io.github.linpeilie.me.collection.forged.Source; +import io.github.linpeilie.me.collection.forged.Source1; +import io.github.linpeilie.me.collection.forged.Target; +import io.github.linpeilie.me.collection.forged.Target1; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class CollectionMappingTest { + + @Autowired + private Converter converter; + + @Test + public void shouldForgeNewMapMappingMethod() { + + Map sourceMap = ImmutableMap.builder().put("rabbit", 1L).build(); + Source source = new Source(); + source.setBarMap(sourceMap); + source.publicBarMap = ImmutableMap.builder().put("fox", 2L).build(); + + Target target = converter.convert(source, Target.class); + assertThat(target).isNotNull(); + Map targetMap = ImmutableMap.builder().put("rabbit", "1").build(); + Map targetMap2 = ImmutableMap.builder().put("fox", "2").build(); + assertThat(target.getBarMap()).isEqualTo(targetMap); + assertThat(target.getPublicBarMap()).isEqualTo(targetMap2); + + Source source2 = converter.convert(target, Source.class); + assertThat(source2).isNotNull(); + assertThat(source2.getBarMap()).isEqualTo(sourceMap); + assertThat(source2.publicBarMap).isEqualTo(source.publicBarMap); + } + + @Test + public void shouldForgeNewIterableMappingMethodReturnNullOnNullSource() { + + Source source = new Source(); + source.setFooSet(null); + source.publicFooSet = null; + + Target target = converter.convert(source, Target.class); + assertThat(target).isNotNull(); + assertThat(target.getFooSet()).isNull(); + assertThat(target.getPublicFooSet()).isNull(); + + Source source2 = converter.convert(target, Source.class); + assertThat(source2).isNotNull(); + assertThat(source2.getFooSet()).isNull(); + assertThat(source2.publicFooSet).isNull(); + } + + @Test + public void shouldForgeNewMapMappingMethodReturnNullOnNullSource() { + + Source source = new Source(); + source.setBarMap(null); + source.publicBarMap = null; + + Target target = converter.convert(source, Target.class); + assertThat(target).isNotNull(); + assertThat(target.getBarMap()).isNull(); + assertThat(target.getPublicBarMap()).isNull(); + + Source source2 = converter.convert(target, Source.class); + assertThat(source2).isNotNull(); + assertThat(source2.getBarMap()).isNull(); + assertThat(source2.publicBarMap).isNull(); + } + + @Test + public void shouldForgeNewIterableMappingMethodReturnEmptyOnNullSource() { + + Source1 source = new Source1(); + source.setFooSet(null); + source.publicFooSet = null; + + Target1 target = converter.convert(source, Target1.class); + assertThat(target).isNotNull(); + assertThat(target.getFooSet()).isEmpty(); + assertThat(target.getPublicFooSet()).isEmpty(); + + target.setPublicBarMap(null); + + Source1 source2 = converter.convert(target, Source1.class); + assertThat(source2).isNotNull(); + assertThat(source2.getFooSet()).isEmpty(); + assertThat(source2.publicBarMap).isEmpty(); + } + + @Test + public void shouldForgeNewMapMappingMethodReturnEmptyOnNullSource() { + + Source1 source = new Source1(); + source.setBarMap(null); + source.publicBarMap = null; + + Target1 target = converter.convert(source, Target1.class); + assertThat(target).isNotNull(); + assertThat(target.getBarMap()).isEmpty(); + assertThat(target.getPublicBarMap()).isEmpty(); + + target.setPublicBarMap(null); + + Source1 source2 = converter.convert(target, Source1.class); + assertThat(source2).isNotNull(); + assertThat(source2.getBarMap()).isEmpty(); + assertThat(source2.publicBarMap).isEmpty(); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalExpressionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalExpressionTest.java new file mode 100644 index 0000000..68e99a1 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalExpressionTest.java @@ -0,0 +1,92 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.conditional.expression.Employee; +import io.github.linpeilie.me.conditional.expression.EmployeeDto; +import io.github.linpeilie.me.conditional.expression.Order; +import io.github.linpeilie.me.conditional.expression.OrderDTO; +import io.github.linpeilie.me.conditional.expression.Source; +import io.github.linpeilie.me.conditional.expression.Target; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class ConditionalExpressionTest { + + @Autowired + private Converter converter; + + @Test + public void conditionalExpressionInStaticClassMethod() { + EmployeeDto dto = new EmployeeDto(); + dto.setName("Tester"); + dto.setUniqueIdNumber("SSID-001"); + dto.setCountry(null); + + Employee employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isNull(); + + dto.setCountry("UK"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isEqualTo("SSID-001"); + assertThat(employee.getSsid()).isNull(); + + dto.setCountry("US"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isEqualTo("SSID-001"); + + dto.setCountry("CH"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isNull(); + } + + @Test + public void conditionalSimpleExpression() { + Target target = converter.convert(new Source(50), Target.class); + assertThat(target.getValue()).isEqualTo(50); + + target = converter.convert(new Source(101), Target.class); + assertThat(target.getValue()).isEqualTo(0); + } + + @Test + public void conditionalExpressionForSourceToTarget() { + OrderDTO orderDto = new OrderDTO(); + + Order order = converter.convert(orderDto, Order.class); + assertThat(order).isNotNull(); + assertThat(order.getCustomer()).isNull(); + + orderDto = new OrderDTO(); + orderDto.setCustomerName("Tester"); + order = converter.convert(orderDto, Order.class); + + assertThat(order).isNotNull(); + assertThat(order.getCustomer()).isNotNull(); + assertThat(order.getCustomer().getName()).isEqualTo("Tester"); + assertThat(order.getCustomer().getAddress()).isNull(); + + orderDto = new OrderDTO(); + orderDto.setLine1("Line 1"); + order = converter.convert(orderDto, Order.class); + + assertThat(order).isNotNull(); + assertThat(order.getCustomer()).isNotNull(); + assertThat(order.getCustomer().getName()).isNull(); + assertThat(order.getCustomer().getAddress()).isNotNull(); + assertThat(order.getCustomer().getAddress().getLine1()).isEqualTo("Line 1"); + assertThat(order.getCustomer().getAddress().getLine2()).isNull(); + + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalMappingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalMappingTest.java new file mode 100644 index 0000000..d32c104 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalMappingTest.java @@ -0,0 +1,112 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.conditional.basic.Author; +import io.github.linpeilie.me.conditional.basic.AuthorDto; +import io.github.linpeilie.me.conditional.basic.BasicEmployee; +import io.github.linpeilie.me.conditional.basic.BasicEmployee1; +import io.github.linpeilie.me.conditional.basic.BasicEmployee2; +import io.github.linpeilie.me.conditional.basic.BasicEmployee3; +import io.github.linpeilie.me.conditional.basic.BasicEmployeeDto; +import io.github.linpeilie.me.conditional.basic.Book; +import io.github.linpeilie.me.conditional.basic.BookDto; +import io.github.linpeilie.me.conditional.basic.EmployeeDto; +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@SpringBootTest(classes = Application.class) +public class ConditionalMappingTest { + + @Autowired + private Converter converter; + + @Test + public void conditionalMethodInMapper() { + BasicEmployee employee = converter.convert(new BasicEmployeeDto("Tester"), BasicEmployee.class); + assertThat(employee.getName()).isEqualTo("Tester"); + + employee = converter.convert(new BasicEmployeeDto(""), BasicEmployee.class); + assertThat(employee.getName()).isNull(); + + employee = converter.convert(new BasicEmployeeDto(" "), BasicEmployee.class); + assertThat(employee.getName()).isNull(); + } + + @Test + public void conditionalMethodAndBeanPresenceCheckMapper() { + BasicEmployee employee = converter.convert(new EmployeeDto("Tester"), BasicEmployee.class); + assertThat(employee.getName()).isEqualTo("Tester"); + + employee = converter.convert(new EmployeeDto(""), BasicEmployee.class); + assertThat(employee.getName()).isNull(); + + employee = converter.convert(new EmployeeDto(" "), BasicEmployee.class); + assertThat(employee.getName()).isNull(); + } + + @Test + public void conditionalMethodWithSourceParameter() { + BasicEmployee3 employee = converter.convert(new BasicEmployeeDto("Tester"), BasicEmployee3.class); + assertThat(employee.getName()).isNull(); + + employee = converter.convert(new BasicEmployeeDto("Tester", "map"), BasicEmployee3.class); + assertThat(employee.getName()).isEqualTo("Tester"); + } + + @Test + public void conditionalMethodWithSourceParameterAndValue() { + BasicEmployee2 employee = converter.convert(new BasicEmployeeDto(" ", "empty"), BasicEmployee2.class); + assertThat(employee.getName()).isEqualTo(" "); + + employee = converter.convert(new BasicEmployeeDto(" ", "blank"), BasicEmployee2.class); + assertThat(employee.getName()).isNull(); + + employee = converter.convert(new BasicEmployeeDto("Tester", "blank"), BasicEmployee2.class); + assertThat(employee.getName()).isEqualTo("Tester"); + } + + @Test + public void conditionalMethodForCollection() { + Author author = new Author(); + AuthorDto dto = converter.convert(author, AuthorDto.class); + + assertThat(dto.getBooks()).isNull(); + + author.setBooks(Collections.emptyList()); + dto = converter.convert(author, AuthorDto.class); + + assertThat(dto.getBooks()).isNull(); + + author.setBooks(Arrays.asList( + new Book("Test"), + new Book("Test Vol. 2") + )); + dto = converter.convert(author, AuthorDto.class); + + assertThat(dto.getBooks()) + .extracting(BookDto::getName) + .containsExactly("Test", "Test Vol. 2"); + } + + @Test + public void conditionalMethodWithMappingTarget() { + BasicEmployee1 targetEmployee = new BasicEmployee1(); + targetEmployee.setName("CurrentName"); + converter.convert(new BasicEmployeeDto("ReplacementName"), targetEmployee); + + assertThat(targetEmployee.getName()).isEqualTo("CurrentName"); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalQualifierTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalQualifierTest.java new file mode 100644 index 0000000..1134577 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ConditionalQualifierTest.java @@ -0,0 +1,108 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.conditional.qualifier.Employee; +import io.github.linpeilie.me.conditional.qualifier.EmployeeDto; +import io.github.linpeilie.me.conditional.qualifier.Order; +import io.github.linpeilie.me.conditional.qualifier.OrderDTO; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class ConditionalQualifierTest { + + @Autowired + private Converter converter; + + @Test + public void conditionalMethodWithSourceParameter() { + EmployeeDto dto = new EmployeeDto(); + dto.setName("Tester"); + dto.setUniqueIdNumber("SSID-001"); + dto.setCountry(null); + + Employee employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isNull(); + + dto.setCountry("UK"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isEqualTo("SSID-001"); + assertThat(employee.getSsid()).isNull(); + + dto.setCountry("US"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isEqualTo("SSID-001"); + + dto.setCountry("CH"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isNull(); + } + + @Test + public void conditionalClassQualifiers() { + EmployeeDto dto = new EmployeeDto(); + dto.setName("Tester"); + dto.setUniqueIdNumber("SSID-001"); + dto.setCountry(null); + + Employee employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isNull(); + + dto.setCountry("UK"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isEqualTo("SSID-001"); + assertThat(employee.getSsid()).isNull(); + + dto.setCountry("US"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isEqualTo("SSID-001"); + + dto.setCountry("CH"); + employee = converter.convert(dto, Employee.class); + assertThat(employee.getNin()).isNull(); + assertThat(employee.getSsid()).isNull(); + } + + @Test + public void conditionalQualifiersForSourceToTarget() { + OrderDTO orderDto = new OrderDTO(); + + Order order = converter.convert(orderDto, Order.class); + assertThat(order).isNotNull(); + assertThat(order.getCustomer()).isNull(); + + orderDto = new OrderDTO(); + orderDto.setCustomerName("Tester"); + order = converter.convert(orderDto, Order.class); + + assertThat(order).isNotNull(); + assertThat(order.getCustomer()).isNotNull(); + assertThat(order.getCustomer().getName()).isEqualTo("Tester"); + assertThat(order.getCustomer().getAddress()).isNull(); + + orderDto = new OrderDTO(); + orderDto.setLine1("Line 1"); + order = converter.convert(orderDto, Order.class); + + assertThat(order).isNotNull(); + assertThat(order.getCustomer()).isNotNull(); + assertThat(order.getCustomer().getName()).isNull(); + assertThat(order.getCustomer().getAddress()).isNotNull(); + assertThat(order.getCustomer().getAddress().getLine1()).isEqualTo("Line 1"); + assertThat(order.getCustomer().getAddress().getLine2()).isNull(); + + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CurrencyConversionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CurrencyConversionTest.java new file mode 100644 index 0000000..3bfec65 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/CurrencyConversionTest.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import cn.hutool.core.collection.CollectionUtil; +import io.github.linpeilie.me.conversion.currency.CurrencySource; +import io.github.linpeilie.me.conversion.currency.CurrencyTarget; +import java.util.Currency; +import java.util.HashSet; +import java.util.Set; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class CurrencyConversionTest { + + @Autowired + private Converter converter; + + @Test + public void shouldApplyCurrencyConversions() { + final CurrencySource source = new CurrencySource(); + source.setCurrencyA(Currency.getInstance("USD")); + Set currencies = new HashSet<>(); + currencies.add(Currency.getInstance("EUR")); + currencies.add(Currency.getInstance("CHF")); + source.setUniqueCurrencies(currencies); + + CurrencyTarget target = converter.convert(source, CurrencyTarget.class); + + assertThat(target).isNotNull(); + assertThat(target.getCurrencyA()).isEqualTo("USD"); + assertThat(target.getUniqueCurrencies()).isNotEmpty().containsExactlyInAnyOrder("EUR", "CHF"); + } + + @Test + public void shouldApplyReverseConversions() { + final CurrencyTarget target = new CurrencyTarget(); + target.setCurrencyA("USD"); + target.setUniqueCurrencies(CollectionUtil.newHashSet("JPY")); + + CurrencySource source = converter.convert(target, CurrencySource.class); + + assertThat(source).isNotNull(); + assertThat(source.getCurrencyA().getCurrencyCode()).isEqualTo(Currency.getInstance("USD").getCurrencyCode()); + assertThat(source.getUniqueCurrencies()).containsExactlyInAnyOrder(Currency.getInstance("JPY")); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DateConversionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DateConversionTest.java new file mode 100644 index 0000000..ae1e360 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DateConversionTest.java @@ -0,0 +1,128 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.conversion.date.Source; +import io.github.linpeilie.me.conversion.date.Target; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.GregorianCalendar; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.EnabledOnJre; +import org.junit.jupiter.api.condition.JRE; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests application of format strings for conversions between strings and dates. + * + * @author Gunnar Morling + */ +@SpringBootTest(classes = Application.class) +public class DateConversionTest { + + @Autowired + private Converter converter; + + @Test + @EnabledOnJre(JRE.JAVA_8) + public void shouldApplyDateFormatForConversions() { + Source source = new Source(); + source.setDate(new GregorianCalendar(2013, Calendar.JULY, 6).getTime()); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getDate()).isEqualTo("06.07.2013"); + } + + @Test + @EnabledForJreRange(min = JRE.JAVA_11) + // See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+ + public void shouldApplyDateFormatForConversionsJdk11() { + Source source = new Source(); + source.setDate(new GregorianCalendar(2013, Calendar.JULY, 6).getTime()); + source.setAnotherDate(new GregorianCalendar(2013, Calendar.FEBRUARY, 14).getTime()); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getDate()).isEqualTo("06.07.2013"); + assertThat(target.getAnotherDate()).isEqualTo("14.02.13, 00:00"); + } + + @Test + @EnabledOnJre(JRE.JAVA_8) + // See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+ + public void shouldApplyDateFormatForConversionInReverseMapping() { + Target target = new Target(); + target.setDate("06.07.2013"); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getDate()).isEqualTo(new GregorianCalendar(2013, Calendar.JULY, 6).getTime()); + } + + @Test + @EnabledForJreRange(min = JRE.JAVA_11) + // See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+ + public void shouldApplyDateFormatForConversionInReverseMappingJdk11() { + Target target = new Target(); + target.setDate("06.07.2013"); + target.setAnotherDate("14.02.13, 8:30"); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getDate()).isEqualTo(new GregorianCalendar(2013, Calendar.JULY, 6).getTime()); + assertThat(source.getAnotherDate()).isEqualTo( + new GregorianCalendar(2013, Calendar.FEBRUARY, 14, 8, 30).getTime()); + } + + @Test + public void shouldApplyDateToSqlConversion() { + GregorianCalendar time = new GregorianCalendar(2016, Calendar.AUGUST, 24, 20, 30, 30); + GregorianCalendar sqlDate = new GregorianCalendar(2016, Calendar.AUGUST, 23, 21, 35, 35); + GregorianCalendar timestamp = new GregorianCalendar(2016, Calendar.AUGUST, 22, 21, 35, 35); + Source source = new Source(); + source.setTime(time.getTime()); + source.setSqlDate(sqlDate.getTime()); + source.setTimestamp(timestamp.getTime()); + + Target target = converter.convert(source, Target.class); + Time expectedTime = new Time(time.getTime().getTime()); + java.sql.Date expectedSqlDate = new java.sql.Date(sqlDate.getTime().getTime()); + Timestamp expectedTimestamp = new Timestamp(timestamp.getTime().getTime()); + + assertThat(target.getTime()).isEqualTo(expectedTime); + assertThat(target.getSqlDate()).isEqualTo(expectedSqlDate); + assertThat(target.getTimestamp()).isEqualTo(expectedTimestamp); + } + + @Test + public void shouldApplySqlToDateConversion() { + Target target = new Target(); + GregorianCalendar time = new GregorianCalendar(2016, Calendar.AUGUST, 24, 20, 30, 30); + GregorianCalendar sqlDate = new GregorianCalendar(2016, Calendar.AUGUST, 23, 21, 35, 35); + GregorianCalendar timestamp = new GregorianCalendar(2016, Calendar.AUGUST, 22, 21, 35, 35); + target.setTime(new Time(time.getTime().getTime())); + target.setSqlDate(new java.sql.Date(sqlDate.getTime().getTime())); + target.setTimestamp(new Timestamp(timestamp.getTime().getTime())); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getTime()).isEqualTo(target.getTime()); + assertThat(source.getSqlDate()).isEqualTo(target.getSqlDate()); + assertThat(source.getTimestamp()).isEqualTo(target.getTimestamp()); + } +} \ No newline at end of file diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DefaultCollectionImplementationTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DefaultCollectionImplementationTest.java new file mode 100644 index 0000000..8228cb8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DefaultCollectionImplementationTest.java @@ -0,0 +1,50 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.collection.defaultimplementation.Source; +import io.github.linpeilie.me.collection.defaultimplementation.SourceFoo; +import io.github.linpeilie.me.collection.defaultimplementation.Target; +import io.github.linpeilie.me.collection.defaultimplementation.TargetFoo; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +@SpringBootTest(classes = Application.class) +public class DefaultCollectionImplementationTest { + + @Autowired + private Converter converter; + + @Test + public void shouldUseDefaultImplementationForList() { + List target = converter.convert(createSourceFooList(), TargetFoo.class); + + assertResultList(target); + } + + @Test + public void shouldUseDefaultImplementationForListWithoutSetter() { + Source source = new Source(); + source.setFooList(createSourceFooList()); + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getFooListNoSetter()).containsExactly(new TargetFoo("Bob"), new TargetFoo("Alice")); + } + + private void assertResultList(Iterable fooIterable) { + assertThat(fooIterable).isNotNull(); + assertThat(fooIterable).containsOnly(new TargetFoo("Bob"), new TargetFoo("Alice")); + } + + private List createSourceFooList() { + return Arrays.asList(new SourceFoo("Bob"), new SourceFoo("Alice")); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DefaultValueTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DefaultValueTest.java new file mode 100644 index 0000000..94d5ecd --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/DefaultValueTest.java @@ -0,0 +1,81 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.defaultvalue.CountryDts; +import io.github.linpeilie.me.defaultvalue.CountryEntity; +import io.github.linpeilie.me.defaultvalue.Region; +import io.github.linpeilie.me.defaultvalue.other.Continent; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class DefaultValueTest { + @Autowired + private Converter converter; + + @Test + /** + * Checks: + *
    + *
  • On code: Using defaultValue without type conversion
  • + *
  • On id: Type conversion of the defaultValue (string expr to int)
  • + *
  • On name: Using ConstantExpression instead of defaultValue
  • + *
  • On zipcode: Ignoring defaultValue on primitive target types
  • + *
  • On region: Using defaultValue before the assignment by an intern method (mapToString)
  • + *
+ */ + public void shouldDefaultValueAndUseConstantExpression() { + CountryEntity countryEntity = new CountryEntity(); + + CountryDts countryDts = converter.convert(countryEntity, CountryDts.class); + + // id is null so it should fall back to the default value + assertThat(countryDts.getId()).isEqualTo(42); + + // code is null so it should fall back to the default value + assertThat(countryDts.getCode()).isEqualTo("DE"); + assertThat(countryDts.getZipcode()).isEqualTo(0); + assertThat(countryDts.getRegion()).isEqualTo("someRegion"); + assertThat(countryDts.getContinent()).isEqualTo(Continent.EUROPE); + } + + @Test + public void shouldIgnoreDefaultValue() { + CountryEntity countryEntity = new CountryEntity(); + countryEntity.setCode("US"); + Region region = new Region(); + region.setCode("foobar"); + countryEntity.setRegion(region); + countryEntity.setContinent(Continent.NORTH_AMERICA); + + CountryDts countryDts = converter.convert(countryEntity, CountryDts.class); + + // the source entity had a code set, so the default value shouldn't be used + assertThat(countryDts.getCode()).isEqualTo("US"); + assertThat(countryDts.getRegion()).isEqualTo("foobar"); + assertThat(countryDts.getContinent()).isEqualTo(Continent.NORTH_AMERICA); + } + + @Test + public void shouldHandleUpdateMethodsFromDtsToEntity() { + CountryEntity countryEntity = new CountryEntity(); + CountryDts countryDts = new CountryDts(); + + converter.convert(countryDts, countryEntity); + + assertThat(countryEntity.getId()).isEqualTo(0); + // no code is set, so fall back to default value + assertThat(countryEntity.getCode()).isEqualTo("DE"); + assertThat(countryEntity.getZipcode()).isEqualTo(0); + assertThat(countryEntity.getContinent()).isEqualTo(Continent.EUROPE); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ImmutableProductTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ImmutableProductTest.java new file mode 100644 index 0000000..8b5374e --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/ImmutableProductTest.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.collection.immutabletarget.CupboardDto; +import io.github.linpeilie.me.collection.immutabletarget.CupboardEntity; +import java.util.Arrays; +import java.util.Collections; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@SpringBootTest(classes = Application.class) +public class ImmutableProductTest { + + @Autowired + private Converter converter; + + @Test + public void shouldHandleImmutableTarget() { + + CupboardDto in = new CupboardDto(); + in.setContent(Arrays.asList("cups", "soucers")); + CupboardEntity out = new CupboardEntity(); + out.setContent(Collections.emptyList()); + + converter.convert(in, out); + + assertThat(out.getContent()).isNotNull(); + assertThat(out.getContent()).containsExactly("cups", "soucers"); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/IterableToNonIterableMappingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/IterableToNonIterableMappingTest.java new file mode 100644 index 0000000..0fef9fe --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/IterableToNonIterableMappingTest.java @@ -0,0 +1,72 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.collection.iterabletononiterable.Fruit; +import io.github.linpeilie.me.collection.iterabletononiterable.FruitSalad; +import io.github.linpeilie.me.collection.iterabletononiterable.FruitsMenu; +import io.github.linpeilie.me.collection.iterabletononiterable.Source; +import io.github.linpeilie.me.collection.iterabletononiterable.Target; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class IterableToNonIterableMappingTest { + + @Autowired + private Converter converter; + + @Test + public void shouldMapStringListToStringUsingCustomMapper() { + Source source = new Source(); + source.setNames(Arrays.asList("Alice", "Bob", "Jim")); + source.publicNames = Arrays.asList("Alice", "Bob", "Jim"); + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getNames()).isEqualTo("Alice-Bob-Jim"); + assertThat(target.publicNames).isEqualTo("Alice-Bob-Jim"); + } + + @Test + public void shouldReverseMapStringListToStringUsingCustomMapper() { + Target target = new Target(); + target.setNames("Alice-Bob-Jim"); + target.publicNames = "Alice-Bob-Jim"; + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getNames()).isEqualTo(Arrays.asList("Alice", "Bob", "Jim")); + assertThat(source.publicNames).isEqualTo(Arrays.asList("Alice", "Bob", "Jim")); + } + + @Test + public void shouldMapIterableToNonIterable() { + List fruits = Arrays.asList(new Fruit("mango"), new Fruit("apple"), + new Fruit("banana")); + FruitsMenu menu = new FruitsMenu(fruits); + FruitSalad salad = converter.convert(menu, FruitSalad.class); + assertThat(salad.getFruits().get(0).getType()).isEqualTo("mango"); + assertThat(salad.getFruits().get(1).getType()).isEqualTo("apple"); + assertThat(salad.getFruits().get(2).getType()).isEqualTo("banana"); + } + + @Test + public void shouldMapNonIterableToIterable() { + List fruits = Arrays.asList(new Fruit("mango"), new Fruit("apple"), + new Fruit("banana")); + FruitSalad salad = new FruitSalad(fruits); + FruitsMenu menu = converter.convert(salad, FruitsMenu.class); + assertThat(salad.getFruits()).extracting(Fruit::getType).containsExactly("mango", "apple", "banana"); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/JavaExpressionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/JavaExpressionTest.java new file mode 100644 index 0000000..7f2cb20 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/JavaExpressionTest.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.source.expressions.java.BooleanWorkAroundMapper; +import io.github.linpeilie.me.source.expressions.java.MultiLineExpressionMapper; +import io.github.linpeilie.me.source.expressions.java.QualifierProvider; +import io.github.linpeilie.me.source.expressions.java.Source; +import io.github.linpeilie.me.source.expressions.java.Source2; +import io.github.linpeilie.me.source.expressions.java.SourceBooleanWorkAround; +import io.github.linpeilie.me.source.expressions.java.SourceList; +import io.github.linpeilie.me.source.expressions.java.SourceTargetListMapper; +import io.github.linpeilie.me.source.expressions.java.Target; +import io.github.linpeilie.me.source.expressions.java.Target1; +import io.github.linpeilie.me.source.expressions.java.TargetBooleanWorkAround; +import io.github.linpeilie.me.source.expressions.java.TargetList; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class JavaExpressionTest { + + @Autowired + private Converter converter; + + private Date getTime(String format, String date) throws ParseException { + SimpleDateFormat dateFormat = new SimpleDateFormat(format); + return dateFormat.parse(date); + } + + @Test + public void testBooleanGetterWorkAround() throws ParseException { + SourceBooleanWorkAround source = new SourceBooleanWorkAround(); + source.setVal(Boolean.TRUE); + + TargetBooleanWorkAround target = converter.convert(source, TargetBooleanWorkAround.class); + assertThat(target).isNotNull(); + assertThat(target.isVal()).isTrue(); + + SourceBooleanWorkAround source2 = converter.convert(target, SourceBooleanWorkAround.class); + assertThat(source2).isNotNull(); + assertThat(source2.isVal()).isTrue(); + } + + @Test + public void testGetterOnly() throws ParseException { + SourceList source = new SourceList(); + source.setList(Arrays.asList("test1")); + + TargetList target = converter.convert(source, TargetList.class); + assertThat(target).isNotNull(); + assertThat(target.getList()).isEqualTo(Arrays.asList("test2")); + } + + @Test + public void testMultiLineJavaExpressionInsertion() throws ParseException { + Source source = new Source(); + String format = "dd-MM-yyyy,hh:mm:ss"; + Date time = getTime(format, "09-01-2014,01:35:03"); + + source.setFormat(format); + source.setTime(time); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getTimeAndFormat().getTime()).isEqualTo(time); + assertThat(target.getTimeAndFormat().getFormat()).isEqualTo(format); + assertThat(target.getAnotherProp()).isNull(); + + Target1 target1 = converter.convert(source, Target1.class); + + assertThat(target1).isNotNull(); + assertThat(target1.getTimeAndFormat().getTime()).isEqualTo(time); + assertThat(target1.getTimeAndFormat().getFormat()).isEqualTo(format); + assertThat(target1.getAnotherProp()).isNull(); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/LossyConversionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/LossyConversionTest.java new file mode 100644 index 0000000..378081f --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/LossyConversionTest.java @@ -0,0 +1,34 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.conversion.lossy.CutleryInventoryDto; +import io.github.linpeilie.me.conversion.lossy.CutleryInventoryEntity; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.withinPercentage; + +@SpringBootTest(classes = Application.class) +public class LossyConversionTest { + + @Autowired + private Converter converter; + + @Test + public void testNoErrorCase() { + + CutleryInventoryDto dto = new CutleryInventoryDto(); + dto.setNumberOfForks(5); + dto.setNumberOfKnifes((short) 7); + dto.setNumberOfSpoons((byte) 3); + dto.setApproximateKnifeLength(3.7f); + + CutleryInventoryEntity entity = converter.convert(dto, CutleryInventoryEntity.class); + assertThat(entity.getNumberOfForks()).isEqualTo(5L); + assertThat(entity.getNumberOfKnifes()).isEqualTo(7); + assertThat(entity.getNumberOfSpoons()).isEqualTo((short) 3); + assertThat(entity.getApproximateKnifeLength()).isCloseTo(3.7d, withinPercentage(0.0001d)); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/MappingControlTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/MappingControlTest.java new file mode 100644 index 0000000..3042759 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/MappingControlTest.java @@ -0,0 +1,112 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.mappingcontrol.CoolBeerDTO; +import io.github.linpeilie.me.mappingcontrol.CustomerDto; +import io.github.linpeilie.me.mappingcontrol.FridgeDTO; +import io.github.linpeilie.me.mappingcontrol.OrderItemDto; +import io.github.linpeilie.me.mappingcontrol.OrderItemKeyDto; +import io.github.linpeilie.me.mappingcontrol.ShelveDTO; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +@SpringBootTest(classes = Application.class) +public class MappingControlTest { + + @Autowired + private Converter converter; + + /** + * Test the deep cloning annotation + */ + @Test + public void testDeepCloning() { + + FridgeDTO in = createFridgeDTO(); + FridgeDTO out = converter.convert(in, FridgeDTO.class); + + assertThat(out).isNotNull(); + assertThat(out.getShelve()).isNotNull(); + assertThat(out.getShelve()).isNotSameAs(in.getShelve()); + assertThat(out.getShelve().getCoolBeer()).isNotSameAs(in.getShelve().getCoolBeer()); + assertThat(out.getShelve().getCoolBeer().getBeerCount()).isEqualTo("5"); + } + + @Test + public void testDeepCloningViaBeanMapping() { + + FridgeDTO in = createFridgeDTO(); + FridgeDTO out = converter.convert(in, FridgeDTO.class); + + assertThat(out).isNotNull(); + assertThat(out.getShelve()).isNotNull(); + assertThat(out.getShelve()).isNotSameAs(in.getShelve()); + assertThat(out.getShelve().getCoolBeer()).isNotSameAs(in.getShelve().getCoolBeer()); + assertThat(out.getShelve().getCoolBeer().getBeerCount()).isEqualTo("5"); + } + + /** + * Test the deep cloning annotation with lists + */ + @Test + public void testDeepCloningListsAndMaps() { + + CustomerDto in = new CustomerDto(); + in.setId(10L); + in.setCustomerName("Jaques"); + OrderItemDto order1 = new OrderItemDto(); + order1.setName("Table"); + order1.setQuantity(2L); + in.setOrders(new ArrayList<>(Collections.singleton(order1))); + OrderItemKeyDto key = new OrderItemKeyDto(); + key.setStockNumber(5); + Map stock = new HashMap<>(); + stock.put(key, order1); + in.setStock(stock); + + CustomerDto out = converter.convert(in, CustomerDto.class); + + assertThat(out.getId()).isEqualTo(10); + assertThat(out.getCustomerName()).isEqualTo("Jaques"); + assertThat(out.getOrders()) + .extracting("name", "quantity") + .containsExactly(tuple("Table", 2L)); + assertThat(out.getStock()).isNotNull(); + assertThat(out.getStock()).hasSize(1); + + Map.Entry entry = out.getStock().entrySet().iterator().next(); + assertThat(entry.getKey().getStockNumber()).isEqualTo(5); + assertThat(entry.getValue().getName()).isEqualTo("Table"); + assertThat(entry.getValue().getQuantity()).isEqualTo(2L); + + // check mapper really created new objects + assertThat(out).isNotSameAs(in); + assertThat(out.getOrders().get(0)).isNotSameAs(order1); + assertThat(entry.getKey()).isNotSameAs(key); + assertThat(entry.getValue()).isNotSameAs(order1); + assertThat(entry.getValue()).isNotSameAs(out.getOrders().get(0)); + } + + private FridgeDTO createFridgeDTO() { + FridgeDTO fridgeDTO = new FridgeDTO(); + ShelveDTO shelveDTO = new ShelveDTO(); + CoolBeerDTO coolBeerDTO = new CoolBeerDTO(); + fridgeDTO.setShelve(shelveDTO); + shelveDTO.setCoolBeer(coolBeerDTO); + coolBeerDTO.setBeerCount("5"); + return fridgeDTO; + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NoSetterCollectionMappingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NoSetterCollectionMappingTest.java new file mode 100644 index 0000000..2db007a --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NoSetterCollectionMappingTest.java @@ -0,0 +1,53 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.collection.defaultimplementation.NoSetterSource; +import io.github.linpeilie.me.collection.defaultimplementation.NoSetterTarget; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +@SpringBootTest(classes = Application.class) +public class NoSetterCollectionMappingTest { + + @Autowired + private Converter converter; + + @Test + public void compilesAndMapsCorrectly() { + NoSetterSource source = new NoSetterSource(); + source.setListValues(Arrays.asList("foo", "bar")); + HashMap mapValues = new HashMap<>(); + mapValues.put("fooKey", "fooVal"); + mapValues.put("barKey", "barVal"); + + source.setMapValues(mapValues); + NoSetterTarget target = converter.convert(source, NoSetterTarget.class); + + assertThat(target.getListValues()).containsExactly("foo", "bar"); + assertThat(target.getMapValues()).contains(entry("fooKey", "fooVal"), entry("barKey", "barVal")); + + // now test existing instances + + NoSetterSource source2 = new NoSetterSource(); + source2.setListValues(Arrays.asList("baz")); + List originalCollectionInstance = target.getListValues(); + Map originalMapInstance = target.getMapValues(); + + NoSetterTarget target2 = converter.convert(source2, target); + + assertThat(target2.getListValues()).isSameAs(originalCollectionInstance); + assertThat(target2.getListValues()).containsExactly("baz"); + assertThat(target2.getMapValues()).isSameAs(originalMapInstance); + // source2 mapvalues is empty, so the map is not cleared + //assertThat( target2.getMapValues() ).contains( entry( "fooKey", "fooVal" ), entry( "barKey", "barVal" ) ); + + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullCheckTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullCheckTest.java new file mode 100644 index 0000000..b632765 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullCheckTest.java @@ -0,0 +1,89 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.nullcheck.NullObject; +import io.github.linpeilie.me.nullcheck.Source; +import io.github.linpeilie.me.nullcheck.Target; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@SpringBootTest(classes = Application.class) +public class NullCheckTest { + + @Autowired + private Converter converter; + + @Test + public void shouldThrowNullptrWhenCustomMapperIsInvoked() { + + Source source = new Source(); + source.setNumber("5"); + source.setSomeInteger(7); + source.setSomeLong(2L); + + assertThatThrownBy(() -> converter.convert(source, Target.class)) + .isInstanceOf(NullPointerException.class); + } + + @Test + public void shouldSurroundTypeConversionWithNullCheck() { + + Source source = new Source(); + source.setSomeObject(new NullObject()); + source.setSomeInteger(7); + source.setSomeLong(2L); + + Target target = converter.convert(source, Target.class); + + assertThat(target.getNumber()).isNull(); + + } + + @Test + public void shouldSurroundArrayListConstructionWithNullCheck() { + + Source source = new Source(); + source.setSomeObject(new NullObject()); + source.setSomeInteger(7); + source.setSomeLong(2L); + + Target target = converter.convert(source, Target.class); + + assertThat(target.getSomeList()).isNull(); + } + + @Test + public void shouldSurroundConversionPassedToMappingMethodWithNullCheck() { + + Source source = new Source(); + source.setSomeObject(new NullObject()); + source.setSomeLong(2L); + + Target target = converter.convert(source, Target.class); + + assertThat(target.getSomeList()).isNull(); + assertThat(target.getSomeInteger()).isNull(); + } + + @Test + public void shouldSurroundConversionFromWrappedPassedToMappingMethodWithPrimitiveArgWithNullCheck() { + + Source source = new Source(); + source.setSomeObject(new NullObject()); + source.setSomeInteger(7); + + Target target = converter.convert(source, Target.class); + + assertThat(target.getSomeList()).isNull(); + assertThat(target.getSomeLong()).isNull(); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValueCheckTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValueCheckTest.java new file mode 100644 index 0000000..e23a753 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValueCheckTest.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.nullcheck.strategy.HouseDto; +import io.github.linpeilie.me.nullcheck.strategy.HouseEntity; +import io.github.linpeilie.me.nullcheck.strategy.HouseEntity1; +import io.github.linpeilie.me.nullcheck.strategy.HouseEntity2; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class NullValueCheckTest { + + @Autowired + private Converter converter; + + @Test + public void testDefinedOnMapper() { + + HouseEntity entity = converter.convert(new HouseDto(), HouseEntity.class); + + assertThat(entity).isNotNull(); + assertThat(entity.ownerSet()).isFalse(); + assertThat(entity.numberSet()).isFalse(); + + } + + @Test + public void testDefinedOnBean() { + + HouseEntity1 entity = converter.convert(new HouseDto(), HouseEntity1.class); + + assertThat(entity).isNotNull(); + assertThat(entity.ownerSet()).isTrue(); + assertThat(entity.numberSet()).isTrue(); + + } + + @Test + public void testDefinedOnMapping() { + + HouseEntity2 entity = converter.convert(new HouseDto(), HouseEntity2.class); + + assertThat(entity).isNotNull(); + assertThat(entity.ownerSet()).isTrue(); + assertThat(entity.numberSet()).isFalse(); + + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValueMappingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValueMappingTest.java new file mode 100644 index 0000000..9d0701e --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValueMappingTest.java @@ -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 io.github.linpeilie; + +import io.github.linpeilie.me.nullvaluemapping._target.CarDto; +import io.github.linpeilie.me.nullvaluemapping.source.Car; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class NullValueMappingTest { + + @Autowired + private Converter converter; + + @Test + public void shouldMapExpressionAndConstantRegardlessNullArg() { + //given + Car car = new Car("Morris", 2); + + //when + CarDto carDto1 = converter.convert(car, CarDto.class); + + //then + assertThat(carDto1).isNotNull(); + assertThat(carDto1.getMake()).isEqualTo(car.getMake()); + assertThat(carDto1.getSeatCount()).isEqualTo(car.getNumberOfSeats()); + assertThat(carDto1.getModel()).isEqualTo("ModelT"); + assertThat(carDto1.getCatalogId()).isNotEmpty(); + } + + @Test + public void shouldMapIterableWithNullArg() { + + //given + Car car = new Car("Morris", 2); + + //when + List carDtos1 = converter.convert(Arrays.asList(car), CarDto.class); + + //then + assertThat(carDtos1).isNotNull(); + assertThat(carDtos1.size()).isEqualTo(1); + + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValuePropertyMappingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValuePropertyMappingTest.java new file mode 100644 index 0000000..8814347 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NullValuePropertyMappingTest.java @@ -0,0 +1,109 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package io.github.linpeilie; + +import io.github.linpeilie.me.nullvaluepropertymapping.AddressDTO; +import io.github.linpeilie.me.nullvaluepropertymapping.AddressDTO1; +import io.github.linpeilie.me.nullvaluepropertymapping.AddressDTO2; +import io.github.linpeilie.me.nullvaluepropertymapping.Customer; +import io.github.linpeilie.me.nullvaluepropertymapping.CustomerDTO; +import io.github.linpeilie.me.nullvaluepropertymapping.CustomerDTO1; +import io.github.linpeilie.me.nullvaluepropertymapping.HomeDTO; +import io.github.linpeilie.me.nullvaluepropertymapping.HomeDTO1; +import io.github.linpeilie.me.nullvaluepropertymapping.UserDTO; +import io.github.linpeilie.me.nullvaluepropertymapping.UserDTO1; +import java.util.Arrays; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class NullValuePropertyMappingTest { + + @Autowired + private Converter converter; + + @Test + public void testStrategyAppliedOnForgedMethod() { + + Customer customer = new Customer(); + customer.setAddress( null ); + + UserDTO1 userDTO = new UserDTO1(); + userDTO.setHomeDTO( new HomeDTO1() ); + userDTO.getHomeDTO().setAddressDTO( new AddressDTO1() ); + userDTO.getHomeDTO().getAddressDTO().setHouseNo( 5 ); + userDTO.setDetails( Arrays.asList( "green hair" ) ); + + converter.convert( customer, userDTO ); + + assertThat( userDTO.getHomeDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO().getHouseNo() ).isEqualTo( 5 ); + assertThat( userDTO.getDetails() ).isNotNull(); + assertThat( userDTO.getDetails() ).containsExactly( "green hair" ); + } + + @Test + public void testHierarchyIgnoreOnMapping() { + Customer customer = new Customer(); + customer.setAddress( null ); + + CustomerDTO customerDto = new CustomerDTO(); + customerDto.setAddress( new AddressDTO1() ); + customerDto.getAddress().setHouseNo( 5 ); + customerDto.setDetails( Arrays.asList( "green hair" ) ); + + converter.convert( customer, customerDto ); + + assertThat( customerDto.getAddress() ).isNotNull(); + assertThat( customerDto.getAddress().getHouseNo() ).isEqualTo( 5 ); + assertThat( customerDto.getDetails() ).isNotNull(); + assertThat( customerDto.getDetails() ).containsExactly( "green hair" ); + } + + @Test + public void testHierarchyIgnoreOnPropertyMappingMethod() { + Customer customer = new Customer(); + customer.setAddress( null ); + + CustomerDTO1 customerDto = new CustomerDTO1(); + customerDto.setAddress( new AddressDTO2() ); + customerDto.getAddress().setHouseNo( 5 ); + customerDto.setDetails( Arrays.asList( "green hair" ) ); + + converter.convert( customer, customerDto ); + + assertThat( customerDto.getAddress() ).isNotNull(); + assertThat( customerDto.getAddress().getHouseNo() ).isEqualTo( 5 ); + assertThat( customerDto.getDetails() ).isNotNull(); + assertThat( customerDto.getDetails() ).containsExactly( "green hair" ); + } + + @Test + public void testStrategyDefaultAppliedOnForgedMethod() { + + Customer customer = new Customer(); + customer.setAddress( null ); + + UserDTO userDTO = new UserDTO(); + userDTO.setHomeDTO( new HomeDTO() ); + userDTO.getHomeDTO().setAddressDTO( new AddressDTO() ); + userDTO.getHomeDTO().getAddressDTO().setHouseNo( 5 ); + userDTO.setDetails( Arrays.asList( "green hair" ) ); + + converter.convert( customer, userDTO ); + + assertThat( userDTO.getHomeDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO().getHouseNo() ).isNull(); + assertThat( userDTO.getDetails() ).isNotNull(); + assertThat( userDTO.getDetails() ).isEmpty(); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NumberFormatConversionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NumberFormatConversionTest.java new file mode 100644 index 0000000..fb51ddf --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/NumberFormatConversionTest.java @@ -0,0 +1,106 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.conversion.numbers.Source; +import io.github.linpeilie.me.conversion.numbers.Target; +import java.math.BigDecimal; +import java.math.BigInteger; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class NumberFormatConversionTest { + + @Autowired + private Converter converter; + + @Test + public void shouldApplyStringConversions() { + Source source = new Source(); + source.setI(1); + source.setIi(2); + source.setD(3.0); + source.setDd(4.0); + source.setF(3.0f); + source.setFf(4.0f); + source.setL(5L); + source.setLl(6L); + source.setB((byte) 7); + source.setBb((byte) 8); + + source.setComplex1(345346.456756); + source.setComplex2(5007034.3); + + source.setBigDecimal1(new BigDecimal("987E-20")); + source.setBigInteger1(new BigInteger("1234567890000")); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getI()).isEqualTo("1.00"); + assertThat(target.getIi()).isEqualTo("2.00"); + assertThat(target.getD()).isEqualTo("3.00"); + assertThat(target.getDd()).isEqualTo("4.00"); + assertThat(target.getF()).isEqualTo("3.00"); + assertThat(target.getFf()).isEqualTo("4.00"); + assertThat(target.getL()).isEqualTo("5.00"); + assertThat(target.getLl()).isEqualTo("6.00"); + assertThat(target.getB()).isEqualTo("7.00"); + assertThat(target.getBb()).isEqualTo("8.00"); + + assertThat(target.getComplex1()).isEqualTo("345.35E3"); + assertThat(target.getComplex2()).isEqualTo("$5007034.30"); + + assertThat(target.getBigDecimal1()).isEqualTo("9.87E-18"); + assertThat(target.getBigInteger1()).isEqualTo("1.23456789E12"); + } + + @Test + public void shouldApplyReverseStringConversions() { + Target target = new Target(); + target.setI("1.00"); + target.setIi("2.00"); + target.setD("3.00"); + target.setDd("4.00"); + target.setF("3.00"); + target.setFf("4.00"); + target.setL("5.00"); + target.setLl("6.00"); + target.setB("7.00"); + target.setBb("8.00"); + + target.setComplex1("345.35E3"); + target.setComplex2("$5007034.30"); + + target.setBigDecimal1("9.87E-18"); + target.setBigInteger1("1.23456789E12"); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getI()).isEqualTo(1); + assertThat(source.getIi()).isEqualTo(Integer.valueOf(2)); + assertThat(source.getD()).isEqualTo(3.0); + assertThat(source.getDd()).isEqualTo(Double.valueOf(4.0)); + assertThat(source.getF()).isEqualTo(3.0f); + assertThat(source.getFf()).isEqualTo(Float.valueOf(4.0f)); + assertThat(source.getL()).isEqualTo(5L); + assertThat(source.getLl()).isEqualTo(Long.valueOf(6L)); + assertThat(source.getB()).isEqualTo((byte) 7); + assertThat(source.getBb()).isEqualTo((byte) 8); + + assertThat(source.getComplex1()).isEqualTo(345350.0); + assertThat(source.getComplex2()).isEqualTo(5007034.3); + + assertThat(source.getBigDecimal1()).isEqualTo(new BigDecimal("987E-20")); + assertThat(source.getBigInteger1()).isEqualTo(new BigInteger("1234567890000")); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/OrderingTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/OrderingTest.java new file mode 100644 index 0000000..6401d31 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/OrderingTest.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.dependency.Address; +import io.github.linpeilie.me.dependency.AddressDto; +import io.github.linpeilie.me.dependency.Person; +import io.github.linpeilie.me.dependency.PersonDto; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class OrderingTest { + + @Autowired + private Converter converter; + + @Test + public void shouldApplyChainOfDependencies() { + Address source = new Address(); + source.setFirstName("Bob"); + source.setMiddleName("J."); + source.setLastName("McRobb"); + + AddressDto target = converter.convert(source, AddressDto.class); + + assertThat(target).isNotNull(); + assertThat(target.getFullName()).isEqualTo("Bob J. McRobb"); + } + + @Test + public void shouldApplySeveralDependenciesConfiguredForOneProperty() { + Person source = new Person(); + source.setFirstName("Bob"); + source.setMiddleName("J."); + source.setLastName("McRobb"); + + PersonDto target = converter.convert(source, PersonDto.class); + + assertThat(target).isNotNull(); + assertThat(target.getFullName()).isEqualTo("Bob J. McRobb"); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/PresenceCheckTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/PresenceCheckTest.java new file mode 100644 index 0000000..d4dd7ec --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/PresenceCheckTest.java @@ -0,0 +1,40 @@ +package io.github.linpeilie; + +import io.github.linpeilie.me.source.nullvaluecheckstrategy.RockFestivalSource; +import io.github.linpeilie.me.source.nullvaluecheckstrategy.RockFestivalTarget; +import io.github.linpeilie.me.source.nullvaluecheckstrategy.RockFestivalTarget1; +import io.github.linpeilie.me.source.nullvaluecheckstrategy.Stage; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@SpringBootTest(classes = Application.class) +public class PresenceCheckTest { + + @Autowired + private Converter converter; + + @Test + public void testCallingMappingMethodWithNullSource() { + + RockFestivalSource source = new RockFestivalSource(); + RockFestivalTarget target = converter.convert(source, RockFestivalTarget.class); + assertThat(target.getStage()).isNull(); + + source.setArtistName("New Order"); + target = converter.convert(source, RockFestivalTarget.class); + assertThat(target.getStage()).isEqualTo(Stage.THE_BARN); + + } + + @Test + public void testCallingMappingMethodWithNullSourceOveridingConfig() { + + RockFestivalSource source = new RockFestivalSource(); + assertThatThrownBy(() -> converter.convert(source, RockFestivalTarget1.class)).isInstanceOf( + IllegalArgumentException.class); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/QuickStartTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/QuickStartTest.java index ee90bba..d4d9e1c 100644 --- a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/QuickStartTest.java +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/QuickStartTest.java @@ -1,8 +1,47 @@ package io.github.linpeilie; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; +import io.github.linpeilie.me.array.Scientist; +import io.github.linpeilie.me.array.ScientistDto; +import io.github.linpeilie.me.bool.Person; +import io.github.linpeilie.me.bool.PersonDto; +import io.github.linpeilie.me.bool.YesNo; +import io.github.linpeilie.me.builder.abstractBuilder.ImmutableProduct; +import io.github.linpeilie.me.builder.abstractBuilder.ProductDto; +import io.github.linpeilie.me.builder.abstractGenericTarget.ChildSource; +import io.github.linpeilie.me.builder.abstractGenericTarget.ImmutableChild; +import io.github.linpeilie.me.builder.abstractGenericTarget.ImmutableParent; +import io.github.linpeilie.me.builder.abstractGenericTarget.MutableParent; +import io.github.linpeilie.me.builder.abstractGenericTarget.Parent; +import io.github.linpeilie.me.builder.abstractGenericTarget.ParentSource; +import io.github.linpeilie.me.builder.factory.ImplicitPerson; +import io.github.linpeilie.me.callbacks.ongeneratedmethods.Address; +import io.github.linpeilie.me.callbacks.ongeneratedmethods.Company; +import io.github.linpeilie.me.callbacks.ongeneratedmethods.CompanyDto; +import io.github.linpeilie.me.callbacks.ongeneratedmethods.Employee; +import io.github.linpeilie.me.callbacks.typematching.CarDto; +import io.github.linpeilie.me.callbacks.typematching.CarEntity; +import io.github.linpeilie.me.callbacks.typematching.CarMapper; +import io.github.linpeilie.me.field_mapping.Customer; +import io.github.linpeilie.me.field_mapping.CustomerDto; +import io.github.linpeilie.me.field_mapping.OrderItem; +import io.github.linpeilie.me.field_mapping.OrderItemDto; +import io.github.linpeilie.me.iterable_to_non_iterable.Source; +import io.github.linpeilie.me.iterable_to_non_iterable.Target; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankDto; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankDto1; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankDto2; +import io.github.linpeilie.me.nested_bean_mappings.dto.FishTankWithNestedDocumentDto; +import io.github.linpeilie.me.nested_bean_mappings.model.Fish; +import io.github.linpeilie.me.nested_bean_mappings.model.FishTank; +import io.github.linpeilie.me.nested_bean_mappings.model.Interior; +import io.github.linpeilie.me.nested_bean_mappings.model.MaterialType; +import io.github.linpeilie.me.nested_bean_mappings.model.Ornament; +import io.github.linpeilie.me.nested_bean_mappings.model.WaterPlant; +import io.github.linpeilie.me.nested_bean_mappings.model.WaterQuality; +import io.github.linpeilie.me.nested_bean_mappings.model.WaterQualityReport; import io.github.linpeilie.model.Car; import io.github.linpeilie.model.EnglishRelease; import io.github.linpeilie.model.FrenchRelease; @@ -32,6 +71,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -40,7 +80,11 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -@SpringBootTest +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest(classes = Application.class) public class QuickStartTest { @Autowired @@ -309,6 +353,440 @@ public class QuickStartTest { frenchRelease2.setTitle("Cent ans de solitude"); EnglishRelease englishRelease2 = converter.convert(frenchRelease2, EnglishRelease.class); Assert.equals(englishRelease2.getTitle(), "One Hundred Years of Solitude"); + + EnglishRelease englishRelease3 = new EnglishRelease(); + englishRelease3.setTitle("Default"); + FrenchRelease frenchRelease = converter.convert(englishRelease3, FrenchRelease.class); + System.out.println(frenchRelease); + } + + @Test + public void testMapDtoToEntity() { + + CustomerDto customerDto = new CustomerDto(); + customerDto.id = 10L; + customerDto.customerName = "Filip"; + OrderItemDto order1 = new OrderItemDto(); + order1.name = "Table"; + order1.quantity = 2L; + customerDto.orders = new ArrayList<>(Collections.singleton(order1)); + + Customer customer = converter.convert(customerDto, Customer.class); + + assertThat(customer.getId()).isEqualTo(10); + assertThat(customer.getName()).isEqualTo("Filip"); + assertThat(customer.getOrderItems()) + .extracting("name", "quantity") + .containsExactly(tuple("Table", 2L)); + } + + @Test + public void testEntityDtoToDto() { + + Customer customer = new Customer(); + customer.setId(10L); + customer.setName("Filip"); + OrderItem order1 = new OrderItem(); + order1.setName("Table"); + order1.setQuantity(2L); + customer.setOrderItems(Collections.singleton(order1)); + + CustomerDto customerDto = converter.convert(customer, CustomerDto.class); + + assertThat(customerDto.id).isEqualTo(10); + assertThat(customerDto.customerName).isEqualTo("Filip"); + assertThat(customerDto.orders) + .extracting("name", "quantity") + .containsExactly(tuple("Table", 2L)); + } + + @Test + public void testToTarget() { + + Source s = new Source(); + s.setMyIntegers(Arrays.asList(5, 3, 7)); + s.setMyStrings(Arrays.asList("five", "three", "seven")); + + Target t = converter.convert(s, Target.class); + assertEquals(new Integer(5), t.getMyInteger()); + assertEquals("seven", t.getMyString()); + } + + @Test + public void testToTargetWithConstant() { + Source s = new Source(); + Target t = converter.convert(s, Target.class); + System.out.println(t); + } + + @Test + public void shouldAutomapAndHandleSourceAndTargetPropertyNesting() { + + // -- prepare + FishTank source = createFishTank(); + + // -- action + FishTankDto target = converter.convert(source, FishTankDto.class); + + // -- result + assertThat(target.getName()).isEqualTo(source.getName()); + + // fish and fishDto can be automapped + assertThat(target.getFish()).isNotNull(); + assertThat(target.getFish().getKind()).isEqualTo(source.getFish().getType()); + assertThat(target.getFish().getName()).isNull(); + + // automapping takes care of mapping property "waterPlant". + assertThat(target.getPlant()).isNotNull(); + assertThat(target.getPlant().getKind()).isEqualTo(source.getPlant().getKind()); + + // ornament (nested asymetric source) + assertThat(target.getOrnament()).isNotNull(); + assertThat(target.getOrnament().getType()).isEqualTo(source.getInterior().getOrnament().getType()); + + // material (nested asymetric target) + assertThat(target.getMaterial()).isNotNull(); + assertThat(target.getMaterial().getManufacturer()).isNull(); + assertThat(target.getMaterial().getMaterialType()).isNotNull(); + assertThat(target.getMaterial().getMaterialType().getType()).isEqualTo(source.getMaterial().getType()); + + // first symetric then asymetric + assertThat(target.getQuality()).isNotNull(); + assertThat(target.getQuality().getReport()).isNotNull(); + assertThat(target.getQuality().getReport().getVerdict()) + .isEqualTo(source.getQuality().getReport().getVerdict()); + assertThat(target.getQuality().getReport().getOrganisation().getApproval()).isNull(); + assertThat(target.getQuality().getReport().getOrganisation()).isNotNull(); + assertThat(target.getQuality().getReport().getOrganisation().getName()) + .isEqualTo(source.getQuality().getReport().getOrganisationName()); + } + + @Test + public void shouldAutomapAndHandleSourceAndTargetPropertyNestingReverse() { + + // -- prepare + FishTank source = createFishTank(); + + // -- action + FishTankDto target = converter.convert(source, FishTankDto.class); + FishTank source2 = converter.convert(target, FishTank.class); + + // -- result + assertThat(source2.getName()).isEqualTo(source.getName()); + + // fish + assertThat(source2.getFish()).isNotNull(); + assertThat(source2.getFish().getType()).isEqualTo(source.getFish().getType()); + + // interior, designer will not be mapped (asymetric) to target. Here it shows. + assertThat(source2.getInterior()).isNotNull(); + assertThat(source2.getInterior().getDesigner()).isNull(); + assertThat(source2.getInterior().getOrnament()).isNotNull(); + assertThat(source2.getInterior().getOrnament().getType()) + .isEqualTo(source.getInterior().getOrnament().getType()); + + // material + assertThat(source2.getMaterial()).isNotNull(); + assertThat(source2.getMaterial().getType()).isEqualTo(source.getMaterial().getType()); + + // plant + assertThat(source2.getPlant().getKind()).isEqualTo(source.getPlant().getKind()); + + // quality + assertThat(source2.getQuality().getReport()).isNotNull(); + assertThat(source2.getQuality().getReport().getOrganisationName()) + .isEqualTo(source.getQuality().getReport().getOrganisationName()); + assertThat(source2.getQuality().getReport().getVerdict()) + .isEqualTo(source.getQuality().getReport().getVerdict()); + } + + @Test + public void shouldAutomapAndHandleSourceAndTargetPropertyNestingAndConstant() { + + // -- prepare + FishTank source = createFishTank(); + + // -- action + FishTankDto1 target = converter.convert(source, FishTankDto1.class); + + // -- result + + // fixed value + assertThat(target.getFish().getName()).isEqualTo("Nemo"); + + // automapping takes care of mapping property "waterPlant". + assertThat(target.getPlant()).isNotNull(); + assertThat(target.getPlant().getKind()).isEqualTo(source.getPlant().getKind()); + + // non-nested and constant + assertThat(target.getMaterial()).isNotNull(); + assertThat(target.getMaterial().getManufacturer()).isEqualTo("MMM"); + assertThat(target.getMaterial().getMaterialType()).isNotNull(); + assertThat(target.getMaterial().getMaterialType().getType()).isEqualTo(source.getMaterial().getType()); + + assertThat(target.getOrnament()).isNull(); + assertThat(target.getQuality()).isNull(); + + } + + @Test + public void shouldAutomapAndHandleSourceAndTargetPropertyNestingAndExpresion() { + + // -- prepare + FishTank source = createFishTank(); + + // -- action + FishTankDto2 target = converter.convert(source, FishTankDto2.class); + + // -- result + assertThat(target.getFish().getName()).isEqualTo("Jaws"); + + assertThat(target.getMaterial()).isNull(); + assertThat(target.getOrnament()).isNull(); + assertThat(target.getPlant()).isNull(); + + assertThat(target.getQuality()).isNotNull(); + assertThat(target.getQuality().getReport()).isNotNull(); + assertThat(target.getQuality().getReport().getVerdict()) + .isEqualTo(source.getQuality().getReport().getVerdict()); + assertThat(target.getQuality().getReport().getOrganisation()).isNotNull(); + assertThat(target.getQuality().getReport().getOrganisation().getApproval()).isNull(); + assertThat(target.getQuality().getReport().getOrganisation().getName()).isEqualTo("Dunno"); + } + + @Test + public void shouldAutomapIntermediateLevelAndMapConstant() { + + // -- prepare + FishTank source = createFishTank(); + + // -- action + FishTankWithNestedDocumentDto target = converter.convert(source, FishTankWithNestedDocumentDto.class); + + // -- result + assertThat(target.getFish().getName()).isEqualTo("Jaws"); + + assertThat(target.getMaterial()).isNull(); + assertThat(target.getOrnament()).isNull(); + assertThat(target.getPlant()).isNull(); + + assertThat(target.getQuality()).isNotNull(); + assertThat(target.getQuality().getDocument()).isNotNull(); + assertThat(target.getQuality().getDocument().getVerdict()) + .isEqualTo(source.getQuality().getReport().getVerdict()); + assertThat(target.getQuality().getDocument().getOrganisation()).isNotNull(); + assertThat(target.getQuality().getDocument().getOrganisation().getApproval()).isNull(); + assertThat(target.getQuality().getDocument().getOrganisation().getName()).isEqualTo("NoIdeaInc"); + } + + private FishTank createFishTank() { + FishTank fishTank = new FishTank(); + + Fish fish = new Fish(); + fish.setType("Carp"); + + WaterPlant waterplant = new WaterPlant(); + waterplant.setKind("Water Hyacinth"); + + Interior interior = new Interior(); + interior.setDesigner("MrVeryFamous"); + Ornament ornament = new Ornament(); + ornament.setType("castle"); + interior.setOrnament(ornament); + + WaterQuality quality = new WaterQuality(); + WaterQualityReport report = new WaterQualityReport(); + report.setVerdict("PASSED"); + report.setOrganisationName("ACME"); + quality.setReport(report); + + MaterialType materialType = new MaterialType(); + materialType.setType("myMaterialType"); + + fishTank.setName("MyLittleFishTank"); + fishTank.setFish(fish); + fishTank.setPlant(waterplant); + fishTank.setInterior(interior); + fishTank.setMaterial(materialType); + fishTank.setQuality(quality); + + return fishTank; + } + + @Test + public void shouldCopyArraysInBean() { + + Scientist source = new Scientist("Bob"); + source.setPublications(new String[] {"the Lancet", "Nature"}); + source.publicPublications = new String[] {"public the Lancet", "public Nature"}; + + ScientistDto dto = converter.convert(source, ScientistDto.class); + + assertThat(dto).isNotNull(); + assertThat(dto).isNotEqualTo(source); + assertThat(dto.getPublications()).containsOnly("the Lancet", "Nature"); + assertThat(dto.publicPublications).containsOnly("public the Lancet", "public Nature"); + } + + @Test + public void shouldForgeMappingForIntToString() { + + Scientist source = new Scientist("Bob"); + source.setPublicationYears(new String[] {"1993", "1997"}); + source.publicPublicationYears = new String[] {"1994", "1998"}; + + ScientistDto dto = converter.convert(source, ScientistDto.class); + + assertThat(dto).isNotNull(); + assertThat(dto.getPublicationYears()).containsOnly(1993, 1997); + assertThat(dto.publicPublicationYears).containsOnly(1994, 1998); + } + + @Test + public void shouldMapArrayToList() { + List dtos = + converter.convert(CollectionUtil.newArrayList(new Scientist("Bob"), new Scientist("Larry")), + ScientistDto.class); + + assertThat(dtos).isNotNull(); + assertThat(dtos).extracting("name").containsOnly("Bob", "Larry"); + } + + @Test + public void shouldMapBooleanPropertyWithIsPrefixedGetter() { + //given + Person person = new Person(); + person.setMarried(Boolean.TRUE); + + //when + PersonDto personDto = converter.convert(person, PersonDto.class); + + //then + assertThat(personDto.getMarried()).isEqualTo("true"); + } + + @Test + public void shouldMapBooleanPropertyPreferringGetPrefixedGetterOverIsPrefixedGetter() { + //given + Person person = new Person(); + person.setEngaged(Boolean.TRUE); + + //when + PersonDto personDto = converter.convert(person, PersonDto.class); + + //then + assertThat(personDto.getEngaged()).isEqualTo("true"); + } + + @Test + public void shouldMapBooleanPropertyWithPropertyMappingMethod() { + // given + Person person = new Person(); + person.setDivorced(new YesNo(true)); + person.setWidowed(new YesNo(true)); + + // when + PersonDto personDto = converter.convert(person, PersonDto.class); + + // then + assertThat(personDto.getDivorced()).isEqualTo("yes"); + assertThat(personDto.getWidowed()).isEqualTo(Boolean.TRUE); + } + + @Test + public void testThatAbstractBuilderMapsAllProperties() { + ImmutableProduct product = converter.convert(new ProductDto("router", 31), ImmutableProduct.class); + + assertThat(product.getPrice()).isEqualTo(31); + assertThat(product.getName()).isEqualTo("router"); + } + + @Test + public void testThatAbstractBuilderReverseMapsAllProperties() { + ProductDto product = converter.convert(ImmutableProduct.builder() + .price(31000) + .name("car") + .build(), ProductDto.class); + + assertThat(product.getPrice()).isEqualTo(31000); + assertThat(product.getName()).isEqualTo("car"); + } + + @Test + public void testAbstractTargetMapper() { + ParentSource parent = new ParentSource(); + parent.setCount(4); + parent.setChild(new ChildSource("Phineas")); + parent.setNonGenericChild(new ChildSource("Ferb")); + + // transform + Parent immutableParent = converter.convert(parent, ImmutableParent.class); + assertThat(immutableParent.getCount()).isEqualTo(4); + assertThat(immutableParent.getChild().getName()).isEqualTo("Phineas"); + assertThat(immutableParent.getNonGenericChild()) + .isNotNull() + .isInstanceOf(ImmutableChild.class); + assertThat(immutableParent.getNonGenericChild().getName()).isEqualTo("Ferb"); + + Parent mutableParent = converter.convert(parent, MutableParent.class); + + assertThat(mutableParent.getCount()).isEqualTo(4); + assertThat(mutableParent.getChild().getName()).isEqualTo("Phineas"); + assertThat(mutableParent.getNonGenericChild()) + .isNotNull() + .isInstanceOf(ImmutableChild.class); + assertThat(mutableParent.getNonGenericChild().getName()).isEqualTo("Ferb"); + + } + + @Test + public void shouldUseBuilderFactory() { + io.github.linpeilie.me.builder.factory.Person person = + converter.convert(new io.github.linpeilie.me.builder.factory.PersonDto("Filip"), + io.github.linpeilie.me.builder.factory.Person.class); + + assertThat(person.getName()).isEqualTo("Filip"); + assertThat(person.getSource()).isEqualTo("Factory with @ObjectFactory"); + } + + @Test + public void shouldUseImplicitBuilderFactory() { + ImplicitPerson person = + converter.convert(new io.github.linpeilie.me.builder.factory.PersonDto("Filip"), ImplicitPerson.class); + + assertThat(person.getName()).isEqualTo("Filip"); + assertThat(person.getSource()).isEqualTo("Implicit Factory"); + } + + @Test + public void testOngeneratedMethods() { + // setup + Address address = new Address(); + address.setAddressLine("RoadToNowhere;5"); + address.setTown("SmallTown"); + Employee employee = new Employee(); + employee.setAddress(address); + Company company = new Company(); + company.setEmployees(Arrays.asList(employee)); + + // test + CompanyDto companyDto = converter.convert(company, CompanyDto.class); + + // verify + assertThat(companyDto.getEmployees()).isNotEmpty(); + assertThat(companyDto.getEmployees().size()).isEqualTo(1); + assertThat(companyDto.getEmployees().get(0).getAddress()).isNotNull(); + assertThat(companyDto.getEmployees().get(0).getAddress().getHouseNumber()).isEqualTo(5); + assertThat(companyDto.getEmployees().get(0).getAddress().getStreet()).isEqualTo("RoadToNowhere"); + assertThat(companyDto.getEmployees().get(0).getAddress().getTown()).isEqualTo("SmallTown"); + } + + @Test + public void callbackMethodAreCalled() { + CarEntity carEntity = converter.convert(new CarDto(), CarEntity.class); + + assertThat(carEntity.getId()).isEqualTo(2); + assertThat(carEntity.getSeatCount()).isEqualTo(5); } } diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/SourceConstantsTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/SourceConstantsTest.java new file mode 100644 index 0000000..75bdd73 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/SourceConstantsTest.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.source.constants.CountryEnum; +import io.github.linpeilie.me.source.constants.Source; +import io.github.linpeilie.me.source.constants.Target; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class SourceConstantsTest { + + @Autowired + private Converter converter; + + @Test + public void shouldMapSameSourcePropertyToSeveralTargetProperties() throws ParseException { + Source source = new Source(); + source.setPropertyThatShouldBeMapped("SomeProperty"); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getPropertyThatShouldBeMapped()).isEqualTo("SomeProperty"); + assertThat(target.getStringConstant()).isEqualTo("stringConstant"); + assertThat(target.getIntegerConstant()).isEqualTo(14); + assertThat(target.getLongWrapperConstant()).isEqualTo(new Long(3001L)); + assertThat(target.getDateConstant()).isEqualTo(getDate("dd-MM-yyyy", "09-01-2014")); + assertThat(target.getNameConstants()).isEqualTo(Arrays.asList("jack", "jill", "tom")); + assertThat(target.getCountry()).isEqualTo(CountryEnum.THE_NETHERLANDS); + } + + @Test + public void shouldMapTargetToSourceWithoutWhining() throws ParseException { + Target target = new Target(); + target.setPropertyThatShouldBeMapped("SomeProperty"); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(target.getPropertyThatShouldBeMapped()).isEqualTo("SomeProperty"); + } + + private Date getDate(String format, String date) throws ParseException { + SimpleDateFormat dateFormat = new SimpleDateFormat(format); + return dateFormat.parse(date); + } + +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/SourceToManyTargetPropertiesTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/SourceToManyTargetPropertiesTest.java new file mode 100644 index 0000000..07903f8 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/SourceToManyTargetPropertiesTest.java @@ -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 io.github.linpeilie; + +import io.github.linpeilie.me.source.manytargetproperties.Source; +import io.github.linpeilie.me.source.manytargetproperties.Target; +import io.github.linpeilie.me.source.manytargetproperties.TimeAndFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class SourceToManyTargetPropertiesTest { + + @Autowired + private Converter converter; + + @Test + public void shouldMapSameSourcePropertyToSeveralTargetProperties() { + Source source = new Source(); + source.setName("Bob"); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getName1()).isEqualTo("Bob"); + assertThat(target.getName2()).isEqualTo("Bob"); + } + + @Test + public void shouldMapSameSourcePropertyToSeveralTargetPropertiesInvokingOtherMapper() throws ParseException { + Source source = new Source(); + String sourceFormat = "dd-MM-yyyy"; + SimpleDateFormat dateFormat = new SimpleDateFormat(sourceFormat); + Date sourceTime = dateFormat.parse("09-01-2014"); + TimeAndFormat sourceTimeAndFormat = new TimeAndFormat(); + sourceTimeAndFormat.setTfFormat(sourceFormat); + sourceTimeAndFormat.setTfTime(sourceTime); + source.setTimeAndFormat(sourceTimeAndFormat); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getFormat()).isEqualTo(sourceFormat); + assertThat(target.getTime()).isEqualTo(sourceTime); + } +} diff --git a/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/StringConversionTest.java b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/StringConversionTest.java new file mode 100644 index 0000000..2a6ae77 --- /dev/null +++ b/example/spring-boot-with-lombok/src/test/java/io/github/linpeilie/StringConversionTest.java @@ -0,0 +1,146 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package io.github.linpeilie; + +import io.github.linpeilie.me.conversion.string.Source; +import io.github.linpeilie.me.conversion.string.Target; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = Application.class) +public class StringConversionTest { + + private static final String STRING_CONSTANT = "String constant"; + @Autowired + private Converter converter; + + @Test + public void shouldApplyStringConversions() { + Source source = new Source(); + source.setB((byte) 1); + source.setBb((byte) 2); + source.setS((short) 3); + source.setSs((short) 4); + source.setI(5); + source.setIi(6); + source.setL(7L); + source.setLl(8L); + source.setF(9f); + source.setFf(10f); + source.setD(11d); + source.setDd(12d); + source.setBool(true); + source.setBoolBool(Boolean.TRUE); + source.setC('G'); + source.setCc('H'); + source.setSb(new StringBuilder("SB")); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getB()).isEqualTo("1"); + assertThat(target.getBb()).isEqualTo("2"); + assertThat(target.getS()).isEqualTo("3"); + assertThat(target.getSs()).isEqualTo("4"); + assertThat(target.getI()).isEqualTo("5"); + assertThat(target.getIi()).isEqualTo("6"); + assertThat(target.getL()).isEqualTo("7"); + assertThat(target.getLl()).isEqualTo("8"); + assertThat(target.getF()).isEqualTo("9.0"); + assertThat(target.getFf()).isEqualTo("10.0"); + assertThat(target.getD()).isEqualTo("11.0"); + assertThat(target.getDd()).isEqualTo("12.0"); + assertThat(target.getBool()).isEqualTo("true"); + assertThat(target.getBoolBool()).isEqualTo("true"); + assertThat(target.getC()).isEqualTo("G"); + assertThat(target.getCc()).isEqualTo("H"); + assertThat(target.getSb()).isEqualTo("SB"); + } + + @Test + public void shouldNotApplyStringConversionsWhenNull() { + Source source = new Source(); + + Target target = converter.convert(source, Target.class); + + assertThat(target).isNotNull(); + assertThat(target.getB()).isEqualTo("0"); + assertThat(target.getBb()).isNull(); + assertThat(target.getS()).isEqualTo("0"); + assertThat(target.getSs()).isNull(); + assertThat(target.getI()).isEqualTo("0"); + assertThat(target.getIi()).isNull(); + assertThat(target.getL()).isEqualTo("0"); + assertThat(target.getLl()).isNull(); + assertThat(target.getF()).isEqualTo("0.0"); + assertThat(target.getFf()).isNull(); + assertThat(target.getD()).isEqualTo("0.0"); + assertThat(target.getDd()).isNull(); + assertThat(target.getBool()).isEqualTo("false"); + assertThat(target.getBoolBool()).isNull(); + assertThat(target.getC()).isEqualTo(String.valueOf('\u0000')); + assertThat(target.getCc()).isNull(); + assertThat(target.getSb()).isNull(); + } + + @Test + public void shouldApplyReverseStringConversions() { + Target target = new Target(); + target.setB("1"); + target.setBb("2"); + target.setS("3"); + target.setSs("4"); + target.setI("5"); + target.setIi("6"); + target.setL("7"); + target.setLl("8"); + target.setF("9.0"); + target.setFf("10.0"); + target.setD("11.0"); + target.setDd("12.0"); + target.setBool("true"); + target.setBoolBool("true"); + target.setC("G"); + target.setCc("H"); + target.setSb("SB"); + + Source source = converter.convert(target, Source.class); + + assertThat(source).isNotNull(); + assertThat(source.getB()).isEqualTo((byte) 1); + assertThat(source.getBb()).isEqualTo(Byte.valueOf((byte) 2)); + assertThat(source.getS()).isEqualTo((short) 3); + assertThat(source.getSs()).isEqualTo(Short.valueOf((short) 4)); + assertThat(source.getI()).isEqualTo(5); + assertThat(source.getIi()).isEqualTo(Integer.valueOf(6)); + assertThat(source.getL()).isEqualTo(7); + assertThat(source.getLl()).isEqualTo(Long.valueOf(8)); + assertThat(source.getF()).isEqualTo(9f); + assertThat(source.getFf()).isEqualTo(Float.valueOf(10f)); + assertThat(source.getD()).isEqualTo(11d); + assertThat(source.getDd()).isEqualTo(Double.valueOf(12d)); + assertThat(source.getBool()).isEqualTo(true); + assertThat(source.getBoolBool()).isEqualTo(true); + assertThat(source.getC()).isEqualTo('G'); + assertThat(source.getCc()).isEqualTo('H'); + assertThat(source.getSb().toString()).isEqualTo("SB"); + } + + @Test + public void stringShouldBeMappedToObjectByReference() { + Target target = new Target(); + target.setObject(STRING_CONSTANT); + + Source source = converter.convert(target, Source.class); + + // no conversion, no built-in method + assertThat(source.getObject()).isNotSameAs(STRING_CONSTANT); + } +} diff --git a/mapstruct-plus-processor/pom.xml b/mapstruct-plus-processor/pom.xml index e11702d..6676744 100644 --- a/mapstruct-plus-processor/pom.xml +++ b/mapstruct-plus-processor/pom.xml @@ -31,6 +31,10 @@ org.mapstruct mapstruct-processor + + org.mapstruct.tools.gem + gem-api + @@ -43,7 +47,13 @@ ${maven.compiler.source} ${maven.compiler.target} UTF-8 - none + + + org.mapstruct.tools.gem + gem-processor + ${gem.version} + + diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java index 21b45ad..64989db 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AbstractAdapterMapperGenerator.java @@ -11,7 +11,8 @@ import com.squareup.javapoet.TypeSpec; import io.github.linpeilie.processor.metadata.AbstractAdapterMethodMetadata; import io.github.linpeilie.processor.metadata.AdapterMapMethodMetadata; import io.github.linpeilie.processor.metadata.AdapterMethodMetadata; -import io.github.linpeilie.processor.utils.ClassUtil; +import io.github.linpeilie.utils.ClassUtil; +import io.github.linpeilie.utils.MapperUtils; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java index a4708ce..4a4da21 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProcessor.java @@ -5,14 +5,15 @@ import com.squareup.javapoet.TypeName; import io.github.linpeilie.ComponentModelConstant; import io.github.linpeilie.annotations.AutoEnumMapper; import io.github.linpeilie.annotations.AutoMapMapper; -import io.github.linpeilie.annotations.AutoMapper; -import io.github.linpeilie.annotations.AutoMappers; -import io.github.linpeilie.annotations.AutoMapping; -import io.github.linpeilie.annotations.AutoMappings; import io.github.linpeilie.annotations.ComponentModelConfig; -import io.github.linpeilie.annotations.MapperConfig; -import io.github.linpeilie.annotations.ReverseAutoMapping; -import io.github.linpeilie.annotations.ReverseAutoMappings; +import io.github.linpeilie.processor.gem.AutoMapperGem; +import io.github.linpeilie.processor.gem.AutoMappersGem; +import io.github.linpeilie.processor.gem.AutoMappingGem; +import io.github.linpeilie.processor.gem.AutoMappingsGem; +import io.github.linpeilie.processor.gem.BuilderGem; +import io.github.linpeilie.processor.gem.MapperConfigGem; +import io.github.linpeilie.processor.gem.ReverseAutoMappingGem; +import io.github.linpeilie.processor.gem.ReverseAutoMappingsGem; import io.github.linpeilie.processor.generator.AutoEnumMapperGenerator; import io.github.linpeilie.processor.generator.AutoMapperGenerator; import io.github.linpeilie.processor.generator.DefaultAdapterMapperGenerator; @@ -34,7 +35,6 @@ import io.github.linpeilie.utils.StrUtil; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -68,11 +68,17 @@ import static io.github.linpeilie.processor.ProcessorOptions.ADAPTER_CLASS_NAME; import static io.github.linpeilie.processor.ProcessorOptions.ADAPTER_PACKAGE; import static io.github.linpeilie.processor.ProcessorOptions.BUILDER_BUILD_METHOD; import static io.github.linpeilie.processor.ProcessorOptions.BUILDER_DISABLE_BUILDER; +import static io.github.linpeilie.processor.ProcessorOptions.COLLECTION_MAPPING_STRATEGY; import static io.github.linpeilie.processor.ProcessorOptions.MAPPER_CONFIG_CLASS; import static io.github.linpeilie.processor.ProcessorOptions.MAPPER_PACKAGE; import static io.github.linpeilie.processor.ProcessorOptions.MAP_ADAPTER_CLASS_NAME; +import static io.github.linpeilie.processor.ProcessorOptions.NULL_VALUE_CHECK_STRATEGY; +import static io.github.linpeilie.processor.ProcessorOptions.NULL_VALUE_ITERABLE_MAPPING_STRATEGY; import static io.github.linpeilie.processor.ProcessorOptions.NULL_VALUE_MAPPING_STRATEGY; +import static io.github.linpeilie.processor.ProcessorOptions.NULL_VALUE_MAP_MAPPING_STRATEGY; import static io.github.linpeilie.processor.ProcessorOptions.NULL_VALUE_PROPERTY_MAPPING_STRATEGY; +import static io.github.linpeilie.processor.ProcessorOptions.SUPPRESS_TIMESTAMP_IN_GENERATED; +import static io.github.linpeilie.processor.ProcessorOptions.TYPE_CONVERSION_POLICY; import static io.github.linpeilie.processor.ProcessorOptions.UNMAPPED_SOURCE_POLICY; import static io.github.linpeilie.processor.ProcessorOptions.UNMAPPED_TARGET_POLICY; import static javax.tools.Diagnostic.Kind.ERROR; @@ -87,7 +93,9 @@ import static javax.tools.Diagnostic.Kind.ERROR; ContextConstants.Annotations.mapper}) @SupportedOptions({MAPPER_CONFIG_CLASS, MAPPER_PACKAGE, UNMAPPED_SOURCE_POLICY, UNMAPPED_TARGET_POLICY, NULL_VALUE_MAPPING_STRATEGY, NULL_VALUE_PROPERTY_MAPPING_STRATEGY, BUILDER_BUILD_METHOD, - BUILDER_DISABLE_BUILDER, ADAPTER_PACKAGE, ADAPTER_CLASS_NAME, MAP_ADAPTER_CLASS_NAME,}) + BUILDER_DISABLE_BUILDER, ADAPTER_PACKAGE, ADAPTER_CLASS_NAME, MAP_ADAPTER_CLASS_NAME, + TYPE_CONVERSION_POLICY, COLLECTION_MAPPING_STRATEGY, NULL_VALUE_ITERABLE_MAPPING_STRATEGY, + NULL_VALUE_MAP_MAPPING_STRATEGY, NULL_VALUE_CHECK_STRATEGY, SUPPRESS_TIMESTAMP_IN_GENERATED}) public class AutoMapperProcessor extends AbstractProcessor { private static final ClassName MAPPING_DEFAULT_TARGET = ClassName.get("io.github.linpeilie", "DefaultMapping"); @@ -345,9 +353,7 @@ public class AutoMapperProcessor extends AbstractProcessor { List uses = Collections.singletonList( ClassName.get(ContextConstants.MapObjectConvert.packageName, ContextConstants.MapObjectConvert.className)); - final AutoMapperMetadata autoMapperMetadata = new AutoMapMapperMetadata(); - autoMapperMetadata.setTargetClassName(target); - autoMapperMetadata.setSourceClassName(source); + final AutoMapperMetadata autoMapperMetadata = new AutoMapMapperMetadata(source, target); autoMapperMetadata.setUsesClassNameList(uses); autoMapperMetadata.setSuperClass( ClassName.get(ContextConstants.BaseMapMapper.packageName, ContextConstants.BaseMapMapper.className)); @@ -365,36 +371,55 @@ public class AutoMapperProcessor extends AbstractProcessor { false); } - private void loadMapperConfig(MapperConfig mapperConfig) { - if (mapperConfig == null) { + private void loadMapperConfig(MapperConfigGem mapperConfigGem) { + if (mapperConfigGem == null || !mapperConfigGem.isValid()) { return; } - AutoMapperProperties.setUnmappedSourcePolicy(mapperConfig.unmappedSourcePolicy()); - AutoMapperProperties.setUnmappedTargetPolicy(mapperConfig.unmappedTargetPolicy()); - AutoMapperProperties.setNullValueMappingStrategy(mapperConfig.nullValueMappingStrategy()); - AutoMapperProperties.setNullValuePropertyMappingStrategy(mapperConfig.nullValuePropertyMappingStrategy()); - AutoMapperProperties.setBuildMethod(mapperConfig.builder().buildMethod()); - AutoMapperProperties.setDisableBuilder(mapperConfig.builder().disableBuilder()); - if (StrUtil.isNotEmpty(mapperConfig.mapperPackage())) { - AutoMapperProperties.setMapperPackage(mapperConfig.mapperPackage()); + if (mapperConfigGem.mapperPackage().hasValue()) { + AutoMapperProperties.setMapperPackage(mapperConfigGem.mapperPackage().get()); } - if (StrUtil.isNotEmpty(mapperConfig.adapterPackage())) { - AutoMapperProperties.setAdapterPackage(mapperConfig.adapterPackage()); + AutoMapperProperties.setUnmappedSourcePolicy(mapperConfigGem.unmappedSourcePolicy().getValue()); + // 重定义 MapStruct 中 unmappedTargetPolicy 的默认值 WARN ---> IGNORE + AutoMapperProperties.setUnmappedTargetPolicy(mapperConfigGem.unmappedTargetPolicy().getValue()); + AutoMapperProperties.setTypeConversionPolicy(mapperConfigGem.typeConversionPolicy().getValue()); + AutoMapperProperties.setCollectionMappingStrategy(mapperConfigGem.collectionMappingStrategy().getValue()); + AutoMapperProperties.setNullValueMappingStrategy(mapperConfigGem.nullValueMappingStrategy().getValue()); + AutoMapperProperties.setNullValueIterableMappingStrategy( + mapperConfigGem.nullValueIterableMappingStrategy().getValue()); + AutoMapperProperties.setNullValueMapMappingStrategy(mapperConfigGem.nullValueMapMappingStrategy().getValue()); + AutoMapperProperties.setNullValuePropertyMappingStrategy( + mapperConfigGem.nullValuePropertyMappingStrategy().getValue()); + AutoMapperProperties.setNullValueCheckStrategy(mapperConfigGem.nullValueCheckStrategy().getValue()); + if (mapperConfigGem.mappingControl().hasValue()) { + AutoMapperProperties.setMappingControl(transToClassName(mapperConfigGem.mappingControl().get())); } - if (StrUtil.isNotEmpty(mapperConfig.adapterClassName())) { - AutoMapperProperties.setAdapterClassName(mapperConfig.adapterClassName()); + if (mapperConfigGem.unexpectedValueMappingException().hasValue()) { + AutoMapperProperties.setUnexpectedValueMappingException( + transToClassName(mapperConfigGem.unexpectedValueMappingException().get())); } - if (StrUtil.isNotEmpty(mapperConfig.mapAdapterClassName())) { - AutoMapperProperties.setMapAdapterClassName(mapperConfig.mapAdapterClassName()); + AutoMapperProperties.setSuppressTimestampInGenerated(mapperConfigGem.suppressTimestampInGenerated().getValue()); + BuilderGem builderGem = mapperConfigGem.builder().get(); + if (builderGem.buildMethod().hasValue()) { + AutoMapperProperties.setBuildMethod(builderGem.buildMethod().get()); } - if (StrUtil.isNotEmpty(mapperConfig.autoConfigPackage())) { - AutoMapperProperties.setAutoConfigPackage(mapperConfig.autoConfigPackage()); + AutoMapperProperties.setDisableBuilder(builderGem.disableBuilder().get()); + if (mapperConfigGem.adapterPackage().hasValue()) { + AutoMapperProperties.setAdapterPackage(mapperConfigGem.adapterPackage().get()); } - if (StrUtil.isNotEmpty(mapperConfig.autoMapperConfigClassName())) { - AutoMapperProperties.setAutoMapperConfigClassName(mapperConfig.autoMapperConfigClassName()); + if (mapperConfigGem.adapterClassName().hasValue()) { + AutoMapperProperties.setAdapterClassName(mapperConfigGem.adapterClassName().get()); } - if (StrUtil.isNotEmpty(mapperConfig.autoMapMapperConfigClassName())) { - AutoMapperProperties.setAutoMapMapperConfigClassName(mapperConfig.autoMapMapperConfigClassName()); + if (mapperConfigGem.mapAdapterClassName().hasValue()) { + AutoMapperProperties.setMapAdapterClassName(mapperConfigGem.mapAdapterClassName().get()); + } + if (mapperConfigGem.autoConfigPackage().hasValue()) { + AutoMapperProperties.setAutoConfigPackage(mapperConfigGem.autoConfigPackage().get()); + } + if (mapperConfigGem.autoMapperConfigClassName().hasValue()) { + AutoMapperProperties.setAutoMapperConfigClassName(mapperConfigGem.autoMapperConfigClassName().get()); + } + if (mapperConfigGem.autoMapMapperConfigClassName().hasValue()) { + AutoMapperProperties.setAutoMapMapperConfigClassName(mapperConfigGem.autoMapMapperConfigClassName().get()); } } @@ -406,7 +431,7 @@ public class AutoMapperProcessor extends AbstractProcessor { if (CollectionUtils.isNotEmpty(typeElements)) { messager.printMessage(Diagnostic.Kind.NOTE, "The previous Mapper Config Class was read , class name : " + typeElements.get(0)); - loadMapperConfig(typeElements.get(0).getAnnotation(MapperConfig.class)); + loadMapperConfig(MapperConfigGem.instanceOn(typeElements.get(0))); } // annotation --> MapperConfig @@ -416,7 +441,7 @@ public class AutoMapperProcessor extends AbstractProcessor { final Optional mapperConfigOptional = roundEnv.getElementsAnnotatedWith(mapperConfigAnnotation).stream().findFirst(); if (mapperConfigOptional.isPresent()) { - loadMapperConfig(mapperConfigOptional.get().getAnnotation(MapperConfig.class)); + loadMapperConfig(MapperConfigGem.instanceOn(mapperConfigOptional.get())); // record buildCollator.writeTypeElements(Collections.singletonList((TypeElement) mapperConfigOptional.get())); } @@ -427,7 +452,7 @@ public class AutoMapperProcessor extends AbstractProcessor { if (StrUtil.isNotEmpty(mapperConfigClass)) { final TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(mapperConfigClass); if (typeElement != null) { - loadMapperConfig(typeElement.getAnnotation(MapperConfig.class)); + loadMapperConfig(MapperConfigGem.instanceOn(typeElement)); } } @@ -491,8 +516,8 @@ public class AutoMapperProcessor extends AbstractProcessor { boolean defineReverseMapping = CollectionUtils.isNotEmpty(autoMapperMetadata.getFieldReverseMappingList()); final AutoMapperMetadata reverseMapperMetadata = reverseMapper(autoMapperMetadata); if (defineReverseMapping) { - addMapper(reverseMapperMetadata); - } else if (!mapperSet.add(reverseMapperMetadata.mapperName())) { + addMapper(reverseMapperMetadata, true); + } else if (!addMapper(reverseMapperMetadata, false)) { return; } reverseMapperMetadataList.add(reverseMapperMetadata); @@ -553,14 +578,28 @@ public class AutoMapperProcessor extends AbstractProcessor { reverseMapperMetadata.setSuperClass( ClassName.get(ContextConstants.BaseMapper.packageName, ContextConstants.BaseMapper.className)); } - // 默认的规则 + reverseMapperMetadata.setUnmappedSourcePolicy(autoMapperMetadata.getUnmappedSourcePolicy()); + reverseMapperMetadata.setUnmappedTargetPolicy(autoMapperMetadata.getUnmappedTargetPolicy()); + reverseMapperMetadata.setTypeConversionPolicy(autoMapperMetadata.getTypeConversionPolicy()); + reverseMapperMetadata.setCollectionMappingStrategy(autoMapperMetadata.getCollectionMappingStrategy()); + reverseMapperMetadata.setNullValueMappingStrategy(autoMapperMetadata.getNullValueMappingStrategy()); + reverseMapperMetadata.setNullValueIterableMappingStrategy( + autoMapperMetadata.getNullValueIterableMappingStrategy()); + reverseMapperMetadata.setNullValuePropertyMappingStrategy( + autoMapperMetadata.getNullValuePropertyMappingStrategy()); + reverseMapperMetadata.setNullValueCheckStrategy(autoMapperMetadata.getNullValueCheckStrategy()); + reverseMapperMetadata.setMappingControl(autoMapperMetadata.getMappingControl()); + reverseMapperMetadata.setMapperNameSuffix(autoMapperMetadata.getMapperNameSuffix()); + // 默认的规则(当 source 属性包含 . 时,不生成相应的反向转换规则) Map autoMappingMap = - autoMapperMetadata.getFieldMappingList().stream().map(fieldMapping -> { - final AutoMappingMetadata autoMappingMetadata = new AutoMappingMetadata(); - autoMappingMetadata.setSource(fieldMapping.getTarget()); - autoMappingMetadata.setTarget(fieldMapping.getSource()); - return autoMappingMetadata; - }).collect(Collectors.toMap(AutoMappingMetadata::getTarget, Function.identity(), (a, b) -> a)); + autoMapperMetadata.getFieldMappingList().stream() + .filter(fieldMapping -> !fieldMapping.getSource().contains(".")) + .map(fieldMapping -> { + final AutoMappingMetadata autoMappingMetadata = new AutoMappingMetadata(); + autoMappingMetadata.setSource(fieldMapping.getTarget()); + autoMappingMetadata.setTarget(fieldMapping.getSource()); + return autoMappingMetadata; + }).collect(Collectors.toMap(AutoMappingMetadata::getTarget, Function.identity(), (a, b) -> a)); List fieldReverseMappingList = autoMapperMetadata.getFieldReverseMappingList(); if (CollectionUtils.isNotEmpty(fieldReverseMappingList)) { @@ -573,17 +612,7 @@ public class AutoMapperProcessor extends AbstractProcessor { } private void writeAutoMapperClassFile(AutoMapperMetadata metadata) { - String mapperPackage = metadata.mapperPackage(); - String mapperClassName = metadata.mapperName(); - try (final Writer writer = processingEnv.getFiler() - .createSourceFile(mapperPackage + "." + mapperClassName) - .openWriter()) { - mapperGenerator.write(metadata, processingEnv, writer); - } catch (IOException e) { - processingEnv.getMessager() - .printMessage(ERROR, - "Error while opening " + metadata.mapperName() + " output file: " + e.getMessage()); - } + mapperGenerator.write(metadata, processingEnv); } private void addAdapterMethod(AutoMapperMetadata metadata) { @@ -603,10 +632,8 @@ public class AutoMapperProcessor extends AbstractProcessor { } private AutoMapperMetadata initAutoMapperMetadata(ClassName source, ClassName target, boolean cycleAvoiding) { - AutoMapperMetadata metadata = new AutoMapperMetadata(); + AutoMapperMetadata metadata = new AutoMapperMetadata(source, target); - metadata.setSourceClassName(source); - metadata.setTargetClassName(target); metadata.setSuperGenerics(new ClassName[] {source, target}); ClassName mapStructConfigClass; if (cycleAvoiding) { @@ -621,26 +648,70 @@ public class AutoMapperProcessor extends AbstractProcessor { } private List buildAutoMapperMetadataByAutoMappers(final Element ele) { - final AutoMappers autoMappers = ele.getAnnotation(AutoMappers.class); - if (autoMappers == null) { + AutoMappersGem autoMappersGem = AutoMappersGem.instanceOn(ele); + if (autoMappersGem == null || !autoMappersGem.isValid()) { return null; } + Set targetClassNames = new HashSet<>(); - return Arrays.stream(autoMappers.value()).filter(autoMapper -> { - ClassName className = transToClassName(autoMapper::target); - if (className == null) { - return false; - } - return targetClassNames.add(className.reflectionName()); - }).map(autoMapper -> buildAutoMapperMetadata(autoMapper, ele)).collect(Collectors.toList()); + + return autoMappersGem.value().getValue().stream().filter(autoMapperGem -> { + if (autoMapperGem == null || !autoMapperGem.isValid()) { + return false; + } + TypeMirror target = autoMapperGem.target().getValue(); + return targetClassNames.add(target.toString()); + }).map(autoMapperGem -> buildAutoMapperMetadata(autoMapperGem, ele)) + .collect(Collectors.toList()); } private AutoMapperMetadata buildAutoMapperMetadata(final Element ele) { - AutoMapper autoMapperAnnotation = ele.getAnnotation(AutoMapper.class); - if (autoMapperAnnotation == null) { + AutoMapperGem autoMapperGem = AutoMapperGem.instanceOn(ele); + if (autoMapperGem == null || !autoMapperGem.isValid()) { return null; } - return buildAutoMapperMetadata(autoMapperAnnotation, ele); + + return buildAutoMapperMetadata(autoMapperGem, ele); + } + + private List matchTargetFieldMapping(List autoMappingMetadataList, + ClassName target) { + // 先删除非当面目标类或父类的 + autoMappingMetadataList.removeIf(mappingMetadata -> !isTargetFieldMapping(target, mappingMetadata)); + // 适配目标属性同时配置了目标类及目标类父类的场景 + Map> targetFieldAutoMappingMap = autoMappingMetadataList.stream() + .collect(Collectors.groupingBy(AutoMappingMetadata::getTarget)); + + List result = new ArrayList<>(); + + targetFieldAutoMappingMap.forEach((key, list) -> { + // 只有一个场景 + if (list.size() == 1) { + result.add(list.get(0)); + return; + } + // 有多个时,先匹配目标类型 + ClassName targetClassName = target; + while (targetClassName != null) { + ClassName finalTargetClassName = targetClassName; + List matchedList = list.stream() + .filter(mappingMetadata -> mappingMetadata.getTargetClass() + .reflectionName() + .equals(finalTargetClassName.reflectionName())) + .collect(Collectors.toList()); + if (!matchedList.isEmpty()) { + result.addAll(matchedList); + return; + } + targetClassName = getSuperClass(classNameToTypeElement(targetClassName)) + .map(ClassName::get) + .orElse(null); + } + // 如果没有匹配到,则添加所有的 + result.addAll(list); + }); + + return result; } private boolean isTargetFieldMapping(ClassName target, AutoMappingMetadata mappingMetadata) { @@ -670,29 +741,28 @@ public class AutoMapperProcessor extends AbstractProcessor { return Optional.of((TypeElement) processingEnv.getTypeUtils().asElement(superclass)); } - private AutoMapperMetadata buildAutoMapperMetadata(final AutoMapper autoMapper, final Element ele) { + private AutoMapperMetadata buildAutoMapperMetadata(final AutoMapperGem autoMapperGem, final Element ele) { ClassName source = ClassName.get((TypeElement) ele); - ClassName target = transToClassName(autoMapper::target); + ClassName target = (ClassName) ClassName.get(autoMapperGem.target().getValue()); if (target == null) { return null; } - List uses = transToClassNameList(autoMapper::uses); - final List importsClassNameList = transToClassNameList(autoMapper::imports); - List autoMappingMetadataList = buildFieldMappingMetadata((TypeElement) ele); - autoMappingMetadataList.removeIf(mappingMetadata -> !isTargetFieldMapping(target, mappingMetadata)); - List reverseMappingMetadataList = buildFieldReverseMappingMetadata((TypeElement) ele); - reverseMappingMetadataList.removeIf(mappingMetadata -> !isTargetFieldMapping(target, mappingMetadata)); + List autoMappingMetadataList = + matchTargetFieldMapping(buildFieldMappingMetadata((TypeElement) ele), target); - AutoMapperMetadata metadata = initAutoMapperMetadata(source, target, autoMapper.cycleAvoiding()); + List reverseMappingMetadataList = + matchTargetFieldMapping(buildFieldReverseMappingMetadata((TypeElement) ele), target); - metadata.setUsesClassNameList(uses); - metadata.setImportsClassNameList(importsClassNameList); + AutoMapperMetadata metadata = initAutoMapperMetadata(source, target, autoMapperGem.cycleAvoiding().get()); + + metadata.setUsesClassNameList(transToClassNameList(autoMapperGem.uses().get())); + metadata.setImportsClassNameList(transToClassNameList(autoMapperGem.imports().get())); metadata.setFieldMappingList(autoMappingMetadataList); metadata.setFieldReverseMappingList(reverseMappingMetadataList); - metadata.setConvertGenerate(autoMapper.convertGenerate()); - metadata.setReverseConvertGenerate(autoMapper.reverseConvertGenerate()); - metadata.setCycleAvoiding(autoMapper.cycleAvoiding()); + metadata.setConvertGenerate(autoMapperGem.convertGenerate().get()); + metadata.setReverseConvertGenerate(autoMapperGem.reverseConvertGenerate().get()); + metadata.setCycleAvoiding(autoMapperGem.cycleAvoiding().get()); if (metadata.isCycleAvoiding()) { metadata.setSuperClass(ClassName.get(ContextConstants.BaseCycleAvoidingMapper.packageName, ContextConstants.BaseCycleAvoidingMapper.className)); @@ -700,8 +770,21 @@ public class AutoMapperProcessor extends AbstractProcessor { metadata.setSuperClass( ClassName.get(ContextConstants.BaseMapper.packageName, ContextConstants.BaseMapper.className)); } + metadata.setUnmappedSourcePolicy(autoMapperGem.unmappedSourcePolicy().getValue()); + metadata.setUnmappedTargetPolicy(autoMapperGem.unmappedTargetPolicy().getValue()); + metadata.setTypeConversionPolicy(autoMapperGem.typeConversionPolicy().getValue()); + metadata.setCollectionMappingStrategy(autoMapperGem.collectionMappingStrategy().getValue()); + metadata.setNullValueMappingStrategy(autoMapperGem.nullValueMappingStrategy().getValue()); + metadata.setNullValueIterableMappingStrategy(autoMapperGem.nullValueIterableMappingStrategy().getValue()); + metadata.setNullValuePropertyMappingStrategy(autoMapperGem.nullValuePropertyMappingStrategy().getValue()); + metadata.setNullValueCheckStrategy(autoMapperGem.nullValueCheckStrategy().getValue()); + metadata.setMappingControl(transToClassName(autoMapperGem.mappingControl().getValue())); + if (StrUtil.isNotEmpty(autoMapperGem.mapperName().getValue())) { + metadata.setMapperName(autoMapperGem.mapperName().getValue()); + } + metadata.setMapperNameSuffix(autoMapperGem.mapperNameSuffix().getValue()); - addMapper(metadata); + addMapper(metadata, true); return metadata; } @@ -715,15 +798,13 @@ public class AutoMapperProcessor extends AbstractProcessor { if (field.getKind() != ElementKind.FIELD && field.getKind() != ElementKind.METHOD) { continue; } - ReverseAutoMapping reverseAutoMapping = field.getAnnotation(ReverseAutoMapping.class); - if (reverseAutoMapping != null) { - list.add(buildAutoMappingMetadata(reverseAutoMapping, field)); + ReverseAutoMappingGem reverseAutoMappingGem = ReverseAutoMappingGem.instanceOn(field); + if (reverseAutoMappingGem != null && reverseAutoMappingGem.isValid()) { + list.add(buildAutoMappingMetadata(reverseAutoMappingGem, field)); } - ReverseAutoMappings reverseAutoMappings = field.getAnnotation(ReverseAutoMappings.class); - if (reverseAutoMappings != null) { - for (ReverseAutoMapping mapping : reverseAutoMappings.value()) { - list.add(buildAutoMappingMetadata(mapping, field)); - } + ReverseAutoMappingsGem reverseAutoMappingsGem = ReverseAutoMappingsGem.instanceOn(field); + if (reverseAutoMappingsGem != null && reverseAutoMappingsGem.isValid()) { + reverseAutoMappingsGem.value().get().forEach(a -> buildAutoMappingMetadata(a, field)); } } @@ -734,44 +815,57 @@ public class AutoMapperProcessor extends AbstractProcessor { return list; } - private AutoMappingMetadata buildAutoMappingMetadata(ReverseAutoMapping reverseAutoMapping, Element ele) { - ClassName targetClass = transToClassName(reverseAutoMapping::targetClass); + private AutoMappingMetadata buildAutoMappingMetadata(ReverseAutoMappingGem reverseAutoMappingGem, Element ele) { + ClassName targetClass = transToClassName(reverseAutoMappingGem.targetClass().get()); if (targetClass == null) { return null; } AutoMappingMetadata metadata = new AutoMappingMetadata(); - if (StrUtil.isNotEmpty(reverseAutoMapping.source())) { - metadata.setSource(reverseAutoMapping.source()); + if (StrUtil.isNotEmpty(reverseAutoMappingGem.source().get())) { + metadata.setSource(reverseAutoMappingGem.source().get()); } else { metadata.setSource(ele.getSimpleName().toString()); } - if (StrUtil.isNotEmpty(reverseAutoMapping.target())) { - metadata.setTarget(reverseAutoMapping.target()); + if (StrUtil.isNotEmpty(reverseAutoMappingGem.target().get())) { + metadata.setTarget(reverseAutoMappingGem.target().get()); } else { metadata.setTarget(ele.getSimpleName().toString()); } metadata.setTargetClass(targetClass); - metadata.setDefaultValue(reverseAutoMapping.defaultValue()); - metadata.setIgnore(reverseAutoMapping.ignore()); - metadata.setExpression(reverseAutoMapping.expression()); - metadata.setDefaultExpression(reverseAutoMapping.defaultExpression()); - metadata.setConditionExpression(reverseAutoMapping.conditionExpression()); - metadata.setDateFormat(reverseAutoMapping.dateFormat()); - metadata.setNumberFormat(reverseAutoMapping.numberFormat()); - metadata.setQualifiedByName(reverseAutoMapping.qualifiedByName()); - metadata.setConditionQualifiedByName(reverseAutoMapping.conditionQualifiedByName()); - metadata.setDependsOn(reverseAutoMapping.dependsOn()); + metadata.setDefaultValue(reverseAutoMappingGem.defaultValue().getValue()); + metadata.setIgnore(reverseAutoMappingGem.ignore().getValue()); + metadata.setExpression(reverseAutoMappingGem.expression().getValue()); + metadata.setDefaultExpression(reverseAutoMappingGem.defaultExpression().getValue()); + metadata.setConditionExpression(reverseAutoMappingGem.conditionExpression().getValue()); + metadata.setDateFormat(reverseAutoMappingGem.dateFormat().getValue()); + metadata.setNumberFormat(reverseAutoMappingGem.numberFormat().getValue()); + metadata.setQualifiedByName(reverseAutoMappingGem.qualifiedByName().getValue()); + metadata.setConditionQualifiedByName(reverseAutoMappingGem.conditionQualifiedByName().getValue()); + metadata.setDependsOn(reverseAutoMappingGem.dependsOn().getValue()); + metadata.setConstant(reverseAutoMappingGem.constant().getValue()); + metadata.setQualifiedBy(transToClassNameList(reverseAutoMappingGem.qualifiedBy().getValue())); + metadata.setNullValueCheckStrategy(reverseAutoMappingGem.nullValueCheckStrategy().getValue()); + metadata.setNullValuePropertyMappingStrategy( + reverseAutoMappingGem.nullValuePropertyMappingStrategy().getValue()); + metadata.setMappingControl(transToClassName(reverseAutoMappingGem.mappingControl().getValue())); + return metadata; } - private void addMapper(AutoMapperMetadata metadata) { - if (!mapperSet.add(metadata.mapperName())) { - throw new DuplicateMapperException("An exception occurred to generate " + metadata.mapperName() + - ", check the mapping configuration for " + - metadata.getSourceClassName().reflectionName() + " or " + - metadata.getTargetClassName().reflectionName()); + private boolean addMapper(AutoMapperMetadata metadata, boolean throwsException) { + boolean addSuccess = mapperSet.add( + metadata.getSourceClassName().reflectionName() + "To" + metadata.getTargetClassName().reflectionName()); + if (throwsException) { + + if (!addSuccess) { + throw new DuplicateMapperException("An exception occurred to generate " + metadata.mapperName() + + ", check the mapping configuration for " + + metadata.getSourceClassName().reflectionName() + " or " + + metadata.getTargetClassName().reflectionName()); + } } + return addSuccess; } private List buildFieldMappingMetadata(final TypeElement autoMapperEle) { @@ -785,15 +879,13 @@ public class AutoMapperProcessor extends AbstractProcessor { if (ele.getKind() != ElementKind.FIELD && ele.getKind() != ElementKind.METHOD) { continue; } - AutoMapping autoMapping = ele.getAnnotation(AutoMapping.class); - if (autoMapping != null) { - list.add(buildAutoMappingMetadata(autoMapping, ele)); + AutoMappingGem autoMappingGem = AutoMappingGem.instanceOn(ele); + if (autoMappingGem != null && autoMappingGem.isValid()) { + list.add(buildAutoMappingMetadata(autoMappingGem, ele)); } - final AutoMappings autoMappings = ele.getAnnotation(AutoMappings.class); - if (autoMappings != null) { - for (AutoMapping autoMappingEle : autoMappings.value()) { - list.add(buildAutoMappingMetadata(autoMappingEle, ele)); - } + AutoMappingsGem autoMappingsGem = AutoMappingsGem.instanceOn(ele); + if (autoMappingsGem != null && autoMappingsGem.isValid()) { + autoMappingsGem.value().get().forEach(a -> list.add(buildAutoMappingMetadata(a, ele))); } } @@ -804,8 +896,8 @@ public class AutoMapperProcessor extends AbstractProcessor { return list; } - private AutoMappingMetadata buildAutoMappingMetadata(AutoMapping autoMapping, Element ele) { - ClassName targetClass = transToClassName(autoMapping::targetClass); + private AutoMappingMetadata buildAutoMappingMetadata(AutoMappingGem autoMappingGem, Element ele) { + ClassName targetClass = transToClassName(autoMappingGem.targetClass().get()); if (targetClass == null) { return null; } @@ -817,27 +909,32 @@ public class AutoMapperProcessor extends AbstractProcessor { elementName = ObjectUtils.defaultIfNull(StrUtil.getGeneralField(elementName), elementName); } - if (StrUtil.isNotEmpty(autoMapping.source())) { - metadata.setSource(autoMapping.source()); + if (StrUtil.isNotEmpty(autoMappingGem.source().get())) { + metadata.setSource(autoMappingGem.source().get()); } else { metadata.setSource(elementName); } - if (StrUtil.isNotEmpty(autoMapping.target())) { - metadata.setTarget(autoMapping.target()); + if (StrUtil.isNotEmpty(autoMappingGem.target().get())) { + metadata.setTarget(autoMappingGem.target().get()); } else { metadata.setTarget(elementName); } metadata.setTargetClass(targetClass); - metadata.setDefaultValue(autoMapping.defaultValue()); - metadata.setIgnore(autoMapping.ignore()); - metadata.setExpression(autoMapping.expression()); - metadata.setDefaultExpression(autoMapping.defaultExpression()); - metadata.setConditionExpression(autoMapping.conditionExpression()); - metadata.setDateFormat(autoMapping.dateFormat()); - metadata.setNumberFormat(autoMapping.numberFormat()); - metadata.setQualifiedByName(autoMapping.qualifiedByName()); - metadata.setConditionQualifiedByName(autoMapping.conditionQualifiedByName()); - metadata.setDependsOn(autoMapping.dependsOn()); + metadata.setDefaultValue(autoMappingGem.defaultValue().getValue()); + metadata.setIgnore(autoMappingGem.ignore().getValue()); + metadata.setExpression(autoMappingGem.expression().getValue()); + metadata.setDefaultExpression(autoMappingGem.defaultExpression().getValue()); + metadata.setConditionExpression(autoMappingGem.conditionExpression().getValue()); + metadata.setDateFormat(autoMappingGem.dateFormat().getValue()); + metadata.setNumberFormat(autoMappingGem.numberFormat().getValue()); + metadata.setQualifiedByName(autoMappingGem.qualifiedByName().getValue()); + metadata.setConditionQualifiedByName(autoMappingGem.conditionQualifiedByName().getValue()); + metadata.setDependsOn(autoMappingGem.dependsOn().getValue()); + metadata.setConstant(autoMappingGem.constant().getValue()); + metadata.setQualifiedBy(transToClassNameList(autoMappingGem.qualifiedBy().getValue())); + metadata.setNullValueCheckStrategy(autoMappingGem.nullValueCheckStrategy().getValue()); + metadata.setNullValuePropertyMappingStrategy(autoMappingGem.nullValuePropertyMappingStrategy().getValue()); + metadata.setMappingControl(transToClassName(autoMappingGem.mappingControl().getValue())); return metadata; } @@ -866,6 +963,22 @@ public class AutoMapperProcessor extends AbstractProcessor { .collect(Collectors.toList()); } + private List transToClassNameList(List typeMirrors) { + if (typeMirrors == null) { + return Collections.emptyList(); + } + return typeMirrors.stream() + .map(this::transToClassName) + .collect(Collectors.toList()); + } + + private ClassName transToClassName(TypeMirror typeMirror) { + if (typeMirror == null) { + return null; + } + return (ClassName) ClassName.get(typeMirror); + } + private TypeElement classNameToTypeElement(ClassName className) { String classNameString = className.toString(); return processingEnv.getElementUtils().getTypeElement(classNameString); diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java index f2fba85..ddb68fe 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/AutoMapperProperties.java @@ -1,5 +1,6 @@ package io.github.linpeilie.processor; +import com.squareup.javapoet.ClassName; import io.github.linpeilie.processor.utils.FileUtils; import io.github.linpeilie.processor.utils.IncrementMarkUtils; import org.mapstruct.NullValueMappingStrategy; @@ -12,14 +13,29 @@ public class AutoMapperProperties { private static String componentModel = ContextConstants.ComponentModelConfig.defaultComponentModel; - private static ReportingPolicy unmappedSourcePolicy = ReportingPolicy.IGNORE; + private static String unmappedSourcePolicy; - private static ReportingPolicy unmappedTargetPolicy = ReportingPolicy.IGNORE; + private static String unmappedTargetPolicy; - private static NullValueMappingStrategy nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL; + private static String typeConversionPolicy; - private static NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy = - NullValuePropertyMappingStrategy.SET_TO_NULL; + private static String collectionMappingStrategy; + + private static String nullValueMappingStrategy; + + private static String nullValueIterableMappingStrategy; + + private static String nullValueMapMappingStrategy; + + private static String nullValuePropertyMappingStrategy; + + private static String nullValueCheckStrategy; + + private static ClassName mappingControl; + + private static ClassName unexpectedValueMappingException; + + private static Boolean suppressTimestampInGenerated; private static String buildMethod = "build"; @@ -46,117 +62,145 @@ public class AutoMapperProperties { autoMapMapperConfigClassName = autoMapMapperConfigClassName + "$" + mark; } - /* ******************** getter/setter ******************** */ - - public static String getMapperPackage() { - return mapperPackage; - } - - public static String getAdapterPackage() { - return adapterPackage; - } - - public static void setAdapterPackage(final String adapterPackage) { - AutoMapperProperties.adapterPackage = adapterPackage; - } - - public static String getAdapterClassName() { - return adapterClassName; - } - - public static String getCycleAvoidingAdapterClassName() { - return getAdapterClassName() + "ForCycleAvoiding"; - } - - public static void setAdapterClassName(final String adapterClassName) { - AutoMapperProperties.adapterClassName = adapterClassName; - } - - public static String getMapAdapterClassName() { - return mapAdapterClassName; - } - - public static void setMapAdapterClassName(final String mapAdapterClassName) { - AutoMapperProperties.mapAdapterClassName = mapAdapterClassName; - } - - public static String getConfigPackage() { - return autoConfigPackage; - } - - public static void setAutoConfigPackage(String autoConfigPackage) { - AutoMapperProperties.autoConfigPackage = autoConfigPackage; - } - public static String getConfigClassName() { return autoMapperConfigClassName; } - public static String getCycleAvoidingConfigClassName() { - return getConfigClassName() + "ForCycleAvoiding"; - } - - public static void setAutoMapperConfigClassName(String autoMapperConfigClassName) { - AutoMapperProperties.autoMapperConfigClassName = autoMapperConfigClassName; - } - public static String getMapConfigClassName() { return autoMapMapperConfigClassName; } - public static void setAutoMapMapperConfigClassName(String autoMapMapperConfigClassName) { - AutoMapperProperties.autoMapMapperConfigClassName = autoMapMapperConfigClassName; + public static String getConfigPackage() { + return autoConfigPackage; + } + + public static String getCycleAvoidingAdapterClassName() { + return getAdapterClassName() + "ForCycleAvoiding"; + } + + public static String getCycleAvoidingConfigClassName() { + return getConfigClassName() + "ForCycleAvoiding"; + } + + /* ******************** getter/setter ******************** */ + + public static String getMapperPackage() { + return mapperPackage; + } + + public static void setMapperPackage(String mapperPackage) { + AutoMapperProperties.mapperPackage = mapperPackage; } public static String getComponentModel() { return componentModel; } - public static void setMapperPackage(final String mapperPackage) { - AutoMapperProperties.mapperPackage = mapperPackage; - } - - public static void setComponentModel(final String componentModel) { + public static void setComponentModel(String componentModel) { AutoMapperProperties.componentModel = componentModel; } - public static ReportingPolicy getUnmappedSourcePolicy() { + public static String getUnmappedSourcePolicy() { return unmappedSourcePolicy; } - public static void setUnmappedSourcePolicy(final ReportingPolicy unmappedSourcePolicy) { + public static void setUnmappedSourcePolicy(String unmappedSourcePolicy) { AutoMapperProperties.unmappedSourcePolicy = unmappedSourcePolicy; } - public static ReportingPolicy getUnmappedTargetPolicy() { + public static String getUnmappedTargetPolicy() { return unmappedTargetPolicy; } - public static void setUnmappedTargetPolicy(final ReportingPolicy unmappedTargetPolicy) { + public static void setUnmappedTargetPolicy(String unmappedTargetPolicy) { AutoMapperProperties.unmappedTargetPolicy = unmappedTargetPolicy; } - public static NullValueMappingStrategy getNullValueMappingStrategy() { + public static String getTypeConversionPolicy() { + return typeConversionPolicy; + } + + public static void setTypeConversionPolicy(String typeConversionPolicy) { + AutoMapperProperties.typeConversionPolicy = typeConversionPolicy; + } + + public static String getCollectionMappingStrategy() { + return collectionMappingStrategy; + } + + public static void setCollectionMappingStrategy(String collectionMappingStrategy) { + AutoMapperProperties.collectionMappingStrategy = collectionMappingStrategy; + } + + public static String getNullValueMappingStrategy() { return nullValueMappingStrategy; } - public static void setNullValueMappingStrategy(NullValueMappingStrategy nullValueMappingStrategy) { + public static void setNullValueMappingStrategy(String nullValueMappingStrategy) { AutoMapperProperties.nullValueMappingStrategy = nullValueMappingStrategy; } - public static NullValuePropertyMappingStrategy getNullValuePropertyMappingStrategy() { + public static String getNullValueIterableMappingStrategy() { + return nullValueIterableMappingStrategy; + } + + public static void setNullValueIterableMappingStrategy(String nullValueIterableMappingStrategy) { + AutoMapperProperties.nullValueIterableMappingStrategy = nullValueIterableMappingStrategy; + } + + public static String getNullValueMapMappingStrategy() { + return nullValueMapMappingStrategy; + } + + public static void setNullValueMapMappingStrategy(String nullValueMapMappingStrategy) { + AutoMapperProperties.nullValueMapMappingStrategy = nullValueMapMappingStrategy; + } + + public static String getNullValuePropertyMappingStrategy() { return nullValuePropertyMappingStrategy; } - public static void setNullValuePropertyMappingStrategy(NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy) { + public static void setNullValuePropertyMappingStrategy(String nullValuePropertyMappingStrategy) { AutoMapperProperties.nullValuePropertyMappingStrategy = nullValuePropertyMappingStrategy; } + public static String getNullValueCheckStrategy() { + return nullValueCheckStrategy; + } + + public static void setNullValueCheckStrategy(String nullValueCheckStrategy) { + AutoMapperProperties.nullValueCheckStrategy = nullValueCheckStrategy; + } + + public static ClassName getMappingControl() { + return mappingControl; + } + + public static void setMappingControl(ClassName mappingControl) { + AutoMapperProperties.mappingControl = mappingControl; + } + + public static ClassName getUnexpectedValueMappingException() { + return unexpectedValueMappingException; + } + + public static void setUnexpectedValueMappingException(ClassName unexpectedValueMappingException) { + AutoMapperProperties.unexpectedValueMappingException = unexpectedValueMappingException; + } + + public static Boolean getSuppressTimestampInGenerated() { + return suppressTimestampInGenerated; + } + + public static void setSuppressTimestampInGenerated(Boolean suppressTimestampInGenerated) { + AutoMapperProperties.suppressTimestampInGenerated = suppressTimestampInGenerated; + } + public static String getBuildMethod() { return buildMethod; } - public static void setBuildMethod(final String buildMethod) { + public static void setBuildMethod(String buildMethod) { AutoMapperProperties.buildMethod = buildMethod; } @@ -164,7 +208,55 @@ public class AutoMapperProperties { return disableBuilder; } - public static void setDisableBuilder(final boolean disableBuilder) { + public static void setDisableBuilder(boolean disableBuilder) { AutoMapperProperties.disableBuilder = disableBuilder; } + + public static String getAdapterPackage() { + return adapterPackage; + } + + public static void setAdapterPackage(String adapterPackage) { + AutoMapperProperties.adapterPackage = adapterPackage; + } + + public static String getAdapterClassName() { + return adapterClassName; + } + + public static void setAdapterClassName(String adapterClassName) { + AutoMapperProperties.adapterClassName = adapterClassName; + } + + public static String getMapAdapterClassName() { + return mapAdapterClassName; + } + + public static void setMapAdapterClassName(String mapAdapterClassName) { + AutoMapperProperties.mapAdapterClassName = mapAdapterClassName; + } + + public static String getAutoConfigPackage() { + return autoConfigPackage; + } + + public static void setAutoConfigPackage(String autoConfigPackage) { + AutoMapperProperties.autoConfigPackage = autoConfigPackage; + } + + public static String getAutoMapperConfigClassName() { + return autoMapperConfigClassName; + } + + public static void setAutoMapperConfigClassName(String autoMapperConfigClassName) { + AutoMapperProperties.autoMapperConfigClassName = autoMapperConfigClassName; + } + + public static String getAutoMapMapperConfigClassName() { + return autoMapMapperConfigClassName; + } + + public static void setAutoMapMapperConfigClassName(String autoMapMapperConfigClassName) { + AutoMapperProperties.autoMapMapperConfigClassName = autoMapMapperConfigClassName; + } } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/BuildCollator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/BuildCollator.java index 03c0cb5..8f2f222 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/BuildCollator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/BuildCollator.java @@ -1,5 +1,7 @@ package io.github.linpeilie.processor; +import com.squareup.javapoet.ClassName; +import com.squareup.javapoet.TypeName; import io.github.linpeilie.processor.utils.FileUtils; import io.github.linpeilie.utils.CollectionUtils; import java.io.File; @@ -101,4 +103,13 @@ public class BuildCollator { write(new HashSet<>(lines)); } + public void appendNonexistentTypes(Collection typeNames) { + List lines = loadRecords(); + typeNames.forEach(ele -> { + String classQualifiedName = ele.reflectionName(); + lines.add(classQualifiedName); + }); + write(new HashSet<>(lines)); + } + } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java index ba91cb6..7344696 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ContextConstants.java @@ -1,5 +1,6 @@ package io.github.linpeilie.processor; +import io.github.linpeilie.DefaultMapping; import java.io.File; import org.mapstruct.MappingConstants; @@ -38,6 +39,10 @@ public interface ContextConstants { String className = "Mapper"; } + interface AutoMapping { + String qualifiedClassName = "io.github.linpeilie.annotations.AutoMapping"; + } + interface AutoMapper { String qualifiedClassName = "io.github.linpeilie.annotations.AutoMapper"; } @@ -93,6 +98,7 @@ public interface ContextConstants { String autoMappers = "autoMappers"; String autoMapMappers = "autoMapMappers"; String enumMappers = "enumMappers"; + String uses = "uses"; } interface AutoIncrementFile { @@ -114,4 +120,45 @@ public interface ContextConstants { String className = "DoIgnore"; } + interface MappingControl { + String packageName = "org.mapstruct.control"; + String className = "MappingControl"; + String qualifiedName = packageName + "." + className; + } + + interface NullValueCheckStrategy { + String packageName = "org.mapstruct"; + String className = "NullValueCheckStrategy"; + } + + interface NullValuePropertyMappingStrategy { + String packageName = "org.mapstruct"; + String className = "NullValuePropertyMappingStrategy"; + } + + interface ReportingPolicy { + String packageName = "org.mapstruct"; + String className = "ReportingPolicy"; + } + + interface CollectionMappingStrategy { + String packageName = "org.mapstruct"; + String className = "CollectionMappingStrategy"; + } + + interface NullValueMappingStrategy { + String packageName = "org.mapstruct"; + String className = "NullValueMappingStrategy"; + } + + interface MappingInheritanceStrategy { + String packageName = "org.mapstruct"; + String className = "MappingInheritanceStrategy"; + } + + interface InjectionStrategy { + String packageName = "org.mapstruct"; + String className = "InjectionStrategy"; + } + } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java index 9451c99..577cddf 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/ProcessorOptions.java @@ -1,11 +1,9 @@ package io.github.linpeilie.processor; +import io.github.linpeilie.utils.StrUtil; import java.util.HashMap; import java.util.Map; import java.util.function.Consumer; -import org.mapstruct.NullValueMappingStrategy; -import org.mapstruct.NullValuePropertyMappingStrategy; -import org.mapstruct.ReportingPolicy; public class ProcessorOptions { @@ -19,10 +17,22 @@ public class ProcessorOptions { public static final String UNMAPPED_TARGET_POLICY = "mapstruct.plus.unmappedTargetPolicy"; + public static final String TYPE_CONVERSION_POLICY = "mapstruct.plus.typeConversionPolicy"; + + public static final String COLLECTION_MAPPING_STRATEGY = "mapstruct.plus.collectionMappingStrategy"; + public static final String NULL_VALUE_MAPPING_STRATEGY = "mapstruct.plus.nullValueMappingStrategy"; + public static final String NULL_VALUE_ITERABLE_MAPPING_STRATEGY = "mapstruct.plus.nullValueIterableMappingStrategy"; + + public static final String NULL_VALUE_MAP_MAPPING_STRATEGY = "mapstruct.plus.nullValueMapMappingStrategy"; + public static final String NULL_VALUE_PROPERTY_MAPPING_STRATEGY = "mapstruct.plus.nullValuePropertyMappingStrategy"; + public static final String NULL_VALUE_CHECK_STRATEGY = "mapstruct.plus.nullValueCheckStrategy"; + + public static final String SUPPRESS_TIMESTAMP_IN_GENERATED = "mapstruct.plus.suppressTimestampInGenerated"; + public static final String BUILDER_BUILD_METHOD = "mapstruct.plus.builder.buildMethod"; public static final String BUILDER_DISABLE_BUILDER = "mapstruct.plus.builder.disableBuilder"; @@ -45,14 +55,20 @@ public class ProcessorOptions { consumerMap.put(DEFAULT_COMPONENT_MODEL, AutoMapperProperties::setComponentModel); consumerMap.put(MAPPER_PACKAGE, AutoMapperProperties::setMapperPackage); - consumerMap.put(UNMAPPED_SOURCE_POLICY, value -> AutoMapperProperties.setUnmappedSourcePolicy(ReportingPolicy.valueOf(value))); - consumerMap.put(UNMAPPED_TARGET_POLICY, value -> AutoMapperProperties.setUnmappedTargetPolicy(ReportingPolicy.valueOf(value))); - consumerMap.put(NULL_VALUE_MAPPING_STRATEGY, - value -> AutoMapperProperties.setNullValueMappingStrategy(NullValueMappingStrategy.valueOf(value))); - consumerMap.put(NULL_VALUE_PROPERTY_MAPPING_STRATEGY, - value -> AutoMapperProperties.setNullValuePropertyMappingStrategy( - NullValuePropertyMappingStrategy.valueOf(value) - )); + consumerMap.put(UNMAPPED_SOURCE_POLICY, AutoMapperProperties::setUnmappedSourcePolicy); + consumerMap.put(UNMAPPED_TARGET_POLICY, AutoMapperProperties::setUnmappedTargetPolicy); + consumerMap.put(TYPE_CONVERSION_POLICY, AutoMapperProperties::setTypeConversionPolicy); + consumerMap.put(COLLECTION_MAPPING_STRATEGY, AutoMapperProperties::setCollectionMappingStrategy); + consumerMap.put(NULL_VALUE_MAPPING_STRATEGY, AutoMapperProperties::setNullValueMappingStrategy); + consumerMap.put(NULL_VALUE_ITERABLE_MAPPING_STRATEGY, AutoMapperProperties::setNullValueIterableMappingStrategy); + consumerMap.put(NULL_VALUE_MAP_MAPPING_STRATEGY, AutoMapperProperties::setNullValueMapMappingStrategy); + consumerMap.put(NULL_VALUE_PROPERTY_MAPPING_STRATEGY, AutoMapperProperties::setNullValuePropertyMappingStrategy); + consumerMap.put(NULL_VALUE_CHECK_STRATEGY, AutoMapperProperties::setNullValueCheckStrategy); + consumerMap.put(SUPPRESS_TIMESTAMP_IN_GENERATED, value -> { + if (StrUtil.isNotEmpty(value)) { + AutoMapperProperties.setSuppressTimestampInGenerated(Boolean.parseBoolean(value)); + } + }); consumerMap.put(BUILDER_BUILD_METHOD, AutoMapperProperties::setBuildMethod); consumerMap.put(BUILDER_DISABLE_BUILDER, value -> AutoMapperProperties.setDisableBuilder(Boolean.parseBoolean(value))); diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/gem/GemGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/gem/GemGenerator.java new file mode 100644 index 0000000..d97a5d6 --- /dev/null +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/gem/GemGenerator.java @@ -0,0 +1,22 @@ +package io.github.linpeilie.processor.gem; + +import io.github.linpeilie.annotations.AutoMapper; +import io.github.linpeilie.annotations.AutoMappers; +import io.github.linpeilie.annotations.AutoMapping; +import io.github.linpeilie.annotations.AutoMappings; +import io.github.linpeilie.annotations.MapperConfig; +import io.github.linpeilie.annotations.ReverseAutoMapping; +import io.github.linpeilie.annotations.ReverseAutoMappings; +import org.mapstruct.Builder; +import org.mapstruct.tools.gem.GemDefinition; + +@GemDefinition(AutoMapper.class) +@GemDefinition(AutoMappers.class) +@GemDefinition(AutoMapping.class) +@GemDefinition(AutoMappings.class) +@GemDefinition(MapperConfig.class) +@GemDefinition(ReverseAutoMapping.class) +@GemDefinition(ReverseAutoMappings.class) +@GemDefinition(Builder.class) +public class GemGenerator { +} diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java index 2902e4a..a05d2ac 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/AutoMapperGenerator.java @@ -8,59 +8,87 @@ import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; import com.squareup.javapoet.ParameterizedTypeName; import com.squareup.javapoet.TypeSpec; +import io.github.linpeilie.annotations.AutoMapper; import io.github.linpeilie.processor.ContextConstants; import io.github.linpeilie.processor.metadata.AutoMapperMetadata; import io.github.linpeilie.processor.metadata.AutoMappingMetadata; -import io.github.linpeilie.utils.ArrayUtil; import io.github.linpeilie.utils.CollectionUtils; -import io.github.linpeilie.utils.StrUtil; import java.io.IOException; -import java.io.UncheckedIOException; import java.io.Writer; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; +import sun.reflect.annotation.AnnotationType; + +import static javax.tools.Diagnostic.Kind.ERROR; public class AutoMapperGenerator { public static final String CONVERT_METHOD_NAME = "convert"; - public void write(AutoMapperMetadata metadata, final ProcessingEnvironment processingEnv, Writer writer) { - try { - JavaFile.builder(metadata.mapperPackage(), createTypeSpec(processingEnv, metadata)).build().writeTo(writer); + private static final Map AUTO_MAPPER_INDEX = new HashMap<>(); + + public void write(AutoMapperMetadata metadata, ProcessingEnvironment processingEnv) { + String mapperPackage = metadata.mapperPackage(); + + /* + 当前处理方式,本地使用 IDEA 开发时,当修改 Source/Target 类时,可能还会出现类名冲突的问题, + 当出现该问题时,需要执行 clean 把之前构建的类清掉。 + */ + String mapperName = metadata.mapperName(); + // 同名类时,增加后缀 + Integer index = AUTO_MAPPER_INDEX.getOrDefault(mapperName, 0); + if (index > 0) { + mapperName = mapperName + "__" + index; + } + AUTO_MAPPER_INDEX.put(metadata.mapperName(), ++index); + + try (final Writer writer = processingEnv.getFiler() + .createSourceFile(mapperPackage + "." + mapperName) + .openWriter()) { + JavaFile.builder(metadata.mapperPackage(), createTypeSpec(processingEnv, metadata, mapperName)) + .build() + .writeTo(writer); } catch (IOException e) { - throw new UncheckedIOException(e); + processingEnv.getMessager() + .printMessage(ERROR, + "Error while opening " + metadata.mapperName() + " output file: " + e.getMessage()); } } - private TypeSpec createTypeSpec(ProcessingEnvironment processingEnv, AutoMapperMetadata metadata) { + private TypeSpec createTypeSpec(ProcessingEnvironment processingEnv, + AutoMapperMetadata metadata, + String mapperName) { ParameterizedTypeName converterName = ParameterizedTypeName.get(metadata.getSuperClass(), metadata.getSuperGenerics()); final ClassName targetClassName = metadata.getTargetClassName(); - TypeSpec.Builder builder = TypeSpec.interfaceBuilder(metadata.mapperName()) + TypeSpec.Builder builder = TypeSpec.interfaceBuilder(mapperName) .addSuperinterface(converterName) .addModifiers(Modifier.PUBLIC) .addAnnotation(buildGeneratedMapperAnnotationSpec(metadata)); - final ParameterSpec source = ParameterSpec.builder(metadata.getSourceClassName(), "source").build(); - final ParameterSpec target = ParameterSpec.builder(targetClassName, "target") + ParameterSpec source = ParameterSpec.builder(metadata.getSourceClassName(), "source").build(); + ParameterSpec target = ParameterSpec.builder(targetClassName, "target") .addAnnotation(AnnotationSpec.builder(ClassName.get("org.mapstruct", "MappingTarget")).build()) .build(); - final ParameterSpec context = + ParameterSpec context = ParameterSpec.builder(ClassName.get("io.github.linpeilie", "CycleAvoidingMappingContext"), "context") .addAnnotation(ClassName.get("org.mapstruct", "Context")) .build(); if (metadata.getFieldMappingList() != null && !metadata.getFieldMappingList().isEmpty()) { builder.addMethod(addConvertMethodSpec( - metadata.isCycleAvoiding() ? CollectionUtils.newArrayList(source, context) : Collections.singletonList(source), + metadata.isCycleAvoiding() ? CollectionUtils.newArrayList(source, context) : Collections.singletonList( + source), metadata.getFieldMappingList(), targetClassName, CONVERT_METHOD_NAME)); @@ -126,51 +154,93 @@ public class AutoMapperGenerator { private List buildMappingAnnotations(final List autoMappingMetadataList) { return autoMappingMetadataList.stream().map(autoMappingMetadata -> { final AnnotationSpec.Builder builder = AnnotationSpec.builder(ClassName.get("org.mapstruct", "Mapping")) - .addMember("target", CodeBlock.builder().add("$S", autoMappingMetadata.getTarget()).build()) - .addMember("ignore", CodeBlock.builder().add(String.valueOf(autoMappingMetadata.isIgnore())).build()); - if (StrUtil.isNotEmpty(autoMappingMetadata.getDateFormat())) { + .addMember("target", CodeBlock.builder().add("$S", autoMappingMetadata.getTarget()).build()); + if (autoMappingMetadata.getIgnore() != null) { + builder.addMember("ignore", + CodeBlock.builder().add(String.valueOf(autoMappingMetadata.getIgnore())).build()); + } + if (autoMappingMetadata.getDateFormat() != null) { builder.addMember("dateFormat", CodeBlock.builder().add("$S", autoMappingMetadata.getDateFormat()).build()); } - if (StrUtil.isNotEmpty(autoMappingMetadata.getNumberFormat())) { + if (autoMappingMetadata.getNumberFormat() != null) { builder.addMember("numberFormat", CodeBlock.builder().add("$S", autoMappingMetadata.getNumberFormat()).build()); } - if (StrUtil.isNotEmpty(autoMappingMetadata.getDefaultValue())) { + if (autoMappingMetadata.getDefaultValue() != null) { builder.addMember("defaultValue", CodeBlock.builder().add("$S", autoMappingMetadata.getDefaultValue()).build()); } - if (StrUtil.isNotEmpty(autoMappingMetadata.getExpression())) { + if (autoMappingMetadata.getExpression() != null) { builder.addMember("expression", CodeBlock.builder().add("$S", autoMappingMetadata.getExpression()).build()); + } else if (autoMappingMetadata.getConstant() != null) { + builder.addMember("constant", CodeBlock.builder().add("$S", autoMappingMetadata.getConstant()).build()); } else { builder.addMember("source", CodeBlock.builder().add("$S", autoMappingMetadata.getSource()).build()); } - if (StrUtil.isNotEmpty(autoMappingMetadata.getDefaultExpression())) { + if (autoMappingMetadata.getDefaultExpression() != null) { builder.addMember("defaultExpression", CodeBlock.builder().add("$S", autoMappingMetadata.getDefaultExpression()).build()); } - if (StrUtil.isNotEmpty(autoMappingMetadata.getConditionExpression())) { + if (autoMappingMetadata.getConditionExpression() != null) { builder.addMember("conditionExpression", CodeBlock.builder().add("$S", autoMappingMetadata.getConditionExpression()).build()); } - if (ArrayUtil.isNotEmpty(autoMappingMetadata.getQualifiedByName())) { - builder.addMember("qualifiedByName", CodeBlock.builder().add("$L", - "{" + ArrayUtil.join(autoMappingMetadata.getQualifiedByName(), ",", "\"", "\"") + "}").build()); + if (autoMappingMetadata.getQualifiedByName() != null) { + builder.addMember("qualifiedByName", CodeBlock.builder() + .add("$L", + "{" + CollectionUtils.join(autoMappingMetadata.getQualifiedByName(), ",", "\"", "\"") + "}") + .build()); } - if (ArrayUtil.isNotEmpty(autoMappingMetadata.getConditionQualifiedByName())) { - builder.addMember("conditionQualifiedByName", CodeBlock.builder().add("$L", - "{" + ArrayUtil.join(autoMappingMetadata.getConditionQualifiedByName(), ",", "\"", "\"") + "}").build()); + if (autoMappingMetadata.getConditionQualifiedByName() != null) { + builder.addMember("conditionQualifiedByName", CodeBlock.builder() + .add("$L", + "{" + CollectionUtils.join(autoMappingMetadata.getConditionQualifiedByName(), ",", "\"", "\"") + + "}") + .build()); } - if (ArrayUtil.isNotEmpty(autoMappingMetadata.getDependsOn())) { + if (autoMappingMetadata.getDependsOn() != null) { builder.addMember("dependsOn", CodeBlock.builder().add("$L", - "{" + ArrayUtil.join(autoMappingMetadata.getDependsOn(), ",", "\"", "\"") + "}").build()); + "{" + CollectionUtils.join(autoMappingMetadata.getDependsOn(), ",", "\"", "\"") + "}").build()); } + if (CollectionUtils.isNotEmpty(autoMappingMetadata.getQualifiedBy())) { + CodeBlock.Builder qualifiedCodeBlockBuilder = CodeBlock.builder().add("{"); + for (int i = 0; i < autoMappingMetadata.getQualifiedBy().size(); i++) { + qualifiedCodeBlockBuilder.add("$T.class", autoMappingMetadata.getQualifiedBy().get(i)); + if (i != autoMappingMetadata.getQualifiedBy().size() - 1) { + qualifiedCodeBlockBuilder.add(","); + } + } + qualifiedCodeBlockBuilder.add("}"); + builder.addMember("qualifiedBy", qualifiedCodeBlockBuilder.build()); + } + if (autoMappingMetadata.getNullValueCheckStrategy() != null) { + CodeBlock nullValueCheckStrategyCodeBlock = CodeBlock.builder() + .add("$T.$L", ClassName.get(ContextConstants.NullValueCheckStrategy.packageName, + ContextConstants.NullValueCheckStrategy.className), + autoMappingMetadata.getNullValueCheckStrategy()).build(); + builder.addMember("nullValueCheckStrategy", nullValueCheckStrategyCodeBlock); + } + if (autoMappingMetadata.getNullValuePropertyMappingStrategy() != null) { + CodeBlock nullValuePropertyMappingStrategy = CodeBlock.builder() + .add("$T.$L", ClassName.get(ContextConstants.NullValuePropertyMappingStrategy.packageName, + ContextConstants.NullValuePropertyMappingStrategy.className), + autoMappingMetadata.getNullValuePropertyMappingStrategy()).build(); + builder.addMember("nullValuePropertyMappingStrategy", nullValuePropertyMappingStrategy); + } + if (autoMappingMetadata.getMappingControl() != null) { + builder.addMember("mappingControl", + CodeBlock.builder().add("$T.class", autoMappingMetadata.getMappingControl()).build()); + } + return builder.build(); }).collect(Collectors.toList()); } private AnnotationSpec buildGeneratedMapperAnnotationSpec(AutoMapperMetadata metadata) { + Map autoMapperDefaultValueMap = AnnotationType.getInstance(AutoMapper.class).memberDefaults(); + List usesClassNameList = Optional.ofNullable(metadata.getUsesClassNameList()).orElse(new ArrayList<>()); @@ -208,6 +278,105 @@ public class AutoMapperGenerator { .addMember("config", configCodeBlock) .addMember("uses", usesCodeBlock) .addMember("imports", importsCodeBlock); + + // unmappedSourcePolicy + if (metadata.getUnmappedSourcePolicy() != null + && !autoMapperDefaultValueMap.get("unmappedSourcePolicy").equals(metadata.getUnmappedSourcePolicy())) { + builder.addMember("unmappedSourcePolicy", CodeBlock.builder() + .add("$T.$L", ClassName.get(ContextConstants.ReportingPolicy.packageName, + ContextConstants.ReportingPolicy.className), + metadata.getUnmappedSourcePolicy()) + .build()); + } + + // unmappedTargetPolicy + if (metadata.getUnmappedTargetPolicy() != null + && !autoMapperDefaultValueMap.get("unmappedTargetPolicy").equals(metadata.getUnmappedTargetPolicy())) { + builder.addMember("unmappedTargetPolicy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.ReportingPolicy.packageName, + ContextConstants.ReportingPolicy.className), + metadata.getUnmappedTargetPolicy()) + .build()); + } + + // typeConversionPolicy + if (metadata.getTypeConversionPolicy() != null && + !autoMapperDefaultValueMap.get("typeConversionPolicy").equals(metadata.getTypeConversionPolicy())) { + builder.addMember("typeConversionPolicy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.ReportingPolicy.packageName, + ContextConstants.ReportingPolicy.className), + metadata.getTypeConversionPolicy()) + .build()); + } + + // collectionMappingStrategy + if (metadata.getCollectionMappingStrategy() != null && + !autoMapperDefaultValueMap.get("collectionMappingStrategy") + .equals(metadata.getCollectionMappingStrategy())) { + builder.addMember("collectionMappingStrategy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.CollectionMappingStrategy.packageName, + ContextConstants.CollectionMappingStrategy.className), + metadata.getCollectionMappingStrategy()) + .build()); + } + + // nullValueMappingStrategy + if (metadata.getNullValueMappingStrategy() != null && + !autoMapperDefaultValueMap.get("nullValueMappingStrategy").equals(metadata.getNullValueMappingStrategy())) { + builder.addMember("nullValueMappingStrategy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.NullValueMappingStrategy.packageName, + ContextConstants.NullValueMappingStrategy.className), + metadata.getNullValueMappingStrategy()) + .build()); + } + + // nullValueIterableMappingStrategy + if (metadata.getNullValueIterableMappingStrategy() != null && + !autoMapperDefaultValueMap.get("nullValueIterableMappingStrategy") + .equals(metadata.getNullValueIterableMappingStrategy())) { + builder.addMember("nullValueIterableMappingStrategy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.NullValueMappingStrategy.packageName, + ContextConstants.NullValueMappingStrategy.className), + metadata.getNullValueIterableMappingStrategy()) + .build()); + } + + // nullValuePropertyMappingStrategy + if (metadata.getNullValuePropertyMappingStrategy() != null && + !autoMapperDefaultValueMap.get("nullValuePropertyMappingStrategy") + .equals(metadata.getNullValuePropertyMappingStrategy())) { + builder.addMember("nullValuePropertyMappingStrategy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.NullValuePropertyMappingStrategy.packageName, + ContextConstants.NullValuePropertyMappingStrategy.className), + metadata.getNullValuePropertyMappingStrategy()) + .build()); + } + + // nullValueCheckStrategy + if (metadata.getNullValueCheckStrategy() != null && + !autoMapperDefaultValueMap.get("nullValueCheckStrategy").equals(metadata.getNullValueCheckStrategy())) { + builder.addMember("nullValueCheckStrategy", CodeBlock.builder() + .add("$T.$L", + ClassName.get(ContextConstants.NullValueCheckStrategy.packageName, + ContextConstants.NullValueCheckStrategy.className), + metadata.getNullValueCheckStrategy()) + .build()); + } + + // mappingControl + if (metadata.getMappingControl() != null && + !((Class) autoMapperDefaultValueMap.get("mappingControl")).getName() + .equals(metadata.getMappingControl().reflectionName())) { + builder.addMember("mappingControl", + CodeBlock.builder().add("$T.class", metadata.getMappingControl()).build()); + } + return builder.build(); } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java index 8dc5a9a..4601ada 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/generator/MapperConfigGenerator.java @@ -69,6 +69,22 @@ public class MapperConfigGenerator { builder.addMember("unmappedTargetPolicy", unmappedTargetPolicyCodeBlock); } + // typeConversionPolicy + if (AutoMapperProperties.getTypeConversionPolicy() != null) { + CodeBlock typeConversionCodeBlock = CodeBlock.builder().add("$T.$L", + ClassName.get("org.mapstruct", "ReportingPolicy"), + AutoMapperProperties.getTypeConversionPolicy()).build(); + builder.addMember("typeConversionPolicy", typeConversionCodeBlock); + } + + // collectionMappingStrategy + if (AutoMapperProperties.getCollectionMappingStrategy() != null) { + CodeBlock collectionMappingStrategyCodeBlock = CodeBlock.builder().add("$T.$L", + ClassName.get("org.mapstruct", "CollectionMappingStrategy"), + AutoMapperProperties.getCollectionMappingStrategy()).build(); + builder.addMember("collectionMappingStrategy", collectionMappingStrategyCodeBlock); + } + // nullValueMappingStrategy if (AutoMapperProperties.getNullValueMappingStrategy() != null) { CodeBlock nullValueMappingStrategyCodeBlock = CodeBlock.builder().add("$T.$L", @@ -77,6 +93,22 @@ public class MapperConfigGenerator { builder.addMember("nullValueMappingStrategy", nullValueMappingStrategyCodeBlock); } + // nullValueIterableMappingStrategy + if (AutoMapperProperties.getNullValueIterableMappingStrategy() != null) { + CodeBlock nullValueIterableMappingStrategyCodeBlock = CodeBlock.builder().add("$T.$L", + ClassName.get("org.mapstruct", "NullValueIterableMappingStrategy"), + AutoMapperProperties.getNullValueIterableMappingStrategy()).build(); + builder.addMember("nullValueIterableMappingStrategy", nullValueIterableMappingStrategyCodeBlock); + } + + // nullValueMapMappingStrategy + if (AutoMapperProperties.getNullValueMapMappingStrategy() != null) { + CodeBlock nullValueMapMappingStrategyCodeBlock = CodeBlock.builder().add("$T.$L", + ClassName.get("org.mapstruct", "NullValueMapMappingStrategy"), + AutoMapperProperties.getNullValueMapMappingStrategy()).build(); + builder.addMember("nullValueMapMappingStrategy", nullValueMapMappingStrategyCodeBlock); + } + // nullValuePropertyMappingStrategy if (AutoMapperProperties.getNullValuePropertyMappingStrategy() != null) { CodeBlock nullValuePropertyMappingStrategyCodeBlock = CodeBlock.builder().add("$T.$L", @@ -85,6 +117,34 @@ public class MapperConfigGenerator { builder.addMember("nullValuePropertyMappingStrategy", nullValuePropertyMappingStrategyCodeBlock); } + // nullValueCheckStrategy + if (AutoMapperProperties.getNullValueCheckStrategy() != null) { + CodeBlock nullValueCheckStrategyCodeBlock = CodeBlock.builder().add("$T.$L", + ClassName.get("org.mapstruct", "NullValueCheckStrategy"), + AutoMapperProperties.getNullValueCheckStrategy()).build(); + builder.addMember("nullValueCheckStrategy", nullValueCheckStrategyCodeBlock); + } + + // mappingControl + if (AutoMapperProperties.getMappingControl() != null) { + CodeBlock mappingControlCodeBlock = CodeBlock.builder().add("$T.class", + AutoMapperProperties.getMappingControl()).build(); + builder.addMember("mappingControl", mappingControlCodeBlock); + } + + // unexpectedValueMappingException + if (AutoMapperProperties.getUnexpectedValueMappingException() != null) { + CodeBlock unexpectedValueMappingExceptionCodeBlock = CodeBlock.builder().add("$T.class", + AutoMapperProperties.getUnexpectedValueMappingException()).build(); + builder.addMember("unexpectedValueMappingException", unexpectedValueMappingExceptionCodeBlock); + } + + // suppressTimestampInGenerated + if (AutoMapperProperties.getSuppressTimestampInGenerated() != null) { + builder.addMember("suppressTimestampInGenerated", CodeBlock.builder() + .add(String.valueOf(AutoMapperProperties.getSuppressTimestampInGenerated())).build()); + } + // builder CodeBlock builderCodeBlock = CodeBlock.builder() .add("@$T(buildMethod = $S, disableBuilder = $L)", ClassName.get("org.mapstruct", "Builder"), diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java index bd6f9e5..8cad3f1 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AdapterMethodMetadata.java @@ -1,7 +1,8 @@ package io.github.linpeilie.processor.metadata; import com.squareup.javapoet.ClassName; -import io.github.linpeilie.processor.utils.ClassUtil; +import io.github.linpeilie.utils.ClassUtil; +import io.github.linpeilie.utils.MapperUtils; public class AdapterMethodMetadata extends AbstractAdapterMethodMetadata { @@ -22,7 +23,7 @@ public class AdapterMethodMetadata extends AbstractAdapterMethodMetadata { public String getMethodName() { String source = ClassUtil.simplifyQualifiedName(this.source.toString()); source = source.substring(0, 1).toLowerCase() + source.substring(1); - return source + "To" + target.simpleName(); + return source + "To" + ClassUtil.simplifyQualifiedName(this.target.toString()); } public ClassName getTarget() { diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java index 5438689..36a55ab 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapMapperMetadata.java @@ -1,10 +1,16 @@ package io.github.linpeilie.processor.metadata; +import com.squareup.javapoet.ClassName; import io.github.linpeilie.processor.AutoMapperProperties; import io.github.linpeilie.utils.StrUtil; public class AutoMapMapperMetadata extends AutoMapperMetadata { + public AutoMapMapperMetadata(ClassName sourceClassName, + ClassName targetClassName) { + super(sourceClassName, targetClassName); + } + @Override public String mapperPackage() { return StrUtil.isNotEmpty( diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java index 30ace3e..56c669f 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMapperMetadata.java @@ -1,10 +1,24 @@ package io.github.linpeilie.processor.metadata; import com.squareup.javapoet.ClassName; +import io.github.linpeilie.utils.MapperUtils; +import io.github.linpeilie.utils.StrUtil; import java.util.List; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.SubclassExhaustiveStrategy; public class AutoMapperMetadata extends AbstractMapperMetadata { + public AutoMapperMetadata(ClassName sourceClassName, ClassName targetClassName) { + this.sourceClassName = sourceClassName; + this.targetClassName = targetClassName; + this.mapperName = MapperUtils.getMapperClassName(sourceClassName.reflectionName(), targetClassName.reflectionName()); + } + + private String mapperName; + + private String mapperNameSuffix; + private ClassName targetClassName; private List usesClassNameList; @@ -27,8 +41,52 @@ public class AutoMapperMetadata extends AbstractMapperMetadata { private boolean cycleAvoiding; + private String unmappedSourcePolicy; + + private String unmappedTargetPolicy; + + private String typeConversionPolicy; + + private String collectionMappingStrategy; + + private String nullValueMappingStrategy; + + private String nullValueIterableMappingStrategy; + + private NullValueMappingStrategy nullValueMapMappingStrategy; + + private String nullValuePropertyMappingStrategy; + + private String nullValueCheckStrategy; + + private SubclassExhaustiveStrategy subclassExhaustiveStrategy; + + private ClassName mappingControl; + + public String qualifiedMapperName() { + return mapperPackage() + "." + mapperName(); + } + + /*************** getter/setter ***************/ + public String mapperName() { - return sourceClassName.simpleName() + "To" + targetClassName.simpleName() + "Mapper"; + return StrUtil.isNotEmpty(this.mapperNameSuffix) ? this.mapperName + this.mapperNameSuffix : this.mapperName; + } + + public void setMapperName(String mapperName) { + this.mapperName = mapperName; + } + + public String getMapperName() { + return mapperName; + } + + public String getMapperNameSuffix() { + return mapperNameSuffix; + } + + public void setMapperNameSuffix(String mapperNameSuffix) { + this.mapperNameSuffix = mapperNameSuffix; } public ClassName getTargetClassName() { @@ -121,4 +179,92 @@ public class AutoMapperMetadata extends AbstractMapperMetadata { public void setCycleAvoiding(boolean cycleAvoiding) { this.cycleAvoiding = cycleAvoiding; } + + public String getUnmappedSourcePolicy() { + return unmappedSourcePolicy; + } + + public void setUnmappedSourcePolicy(String unmappedSourcePolicy) { + this.unmappedSourcePolicy = unmappedSourcePolicy; + } + + public String getUnmappedTargetPolicy() { + return unmappedTargetPolicy; + } + + public void setUnmappedTargetPolicy(String unmappedTargetPolicy) { + this.unmappedTargetPolicy = unmappedTargetPolicy; + } + + public String getTypeConversionPolicy() { + return typeConversionPolicy; + } + + public void setTypeConversionPolicy(String typeConversionPolicy) { + this.typeConversionPolicy = typeConversionPolicy; + } + + public String getCollectionMappingStrategy() { + return collectionMappingStrategy; + } + + public void setCollectionMappingStrategy(String collectionMappingStrategy) { + this.collectionMappingStrategy = collectionMappingStrategy; + } + + public String getNullValueMappingStrategy() { + return nullValueMappingStrategy; + } + + public void setNullValueMappingStrategy(String nullValueMappingStrategy) { + this.nullValueMappingStrategy = nullValueMappingStrategy; + } + + public String getNullValueIterableMappingStrategy() { + return nullValueIterableMappingStrategy; + } + + public void setNullValueIterableMappingStrategy(String nullValueIterableMappingStrategy) { + this.nullValueIterableMappingStrategy = nullValueIterableMappingStrategy; + } + + public NullValueMappingStrategy getNullValueMapMappingStrategy() { + return nullValueMapMappingStrategy; + } + + public void setNullValueMapMappingStrategy(NullValueMappingStrategy nullValueMapMappingStrategy) { + this.nullValueMapMappingStrategy = nullValueMapMappingStrategy; + } + + public String getNullValuePropertyMappingStrategy() { + return nullValuePropertyMappingStrategy; + } + + public void setNullValuePropertyMappingStrategy(String nullValuePropertyMappingStrategy) { + this.nullValuePropertyMappingStrategy = nullValuePropertyMappingStrategy; + } + + public String getNullValueCheckStrategy() { + return nullValueCheckStrategy; + } + + public void setNullValueCheckStrategy(String nullValueCheckStrategy) { + this.nullValueCheckStrategy = nullValueCheckStrategy; + } + + public SubclassExhaustiveStrategy getSubclassExhaustiveStrategy() { + return subclassExhaustiveStrategy; + } + + public void setSubclassExhaustiveStrategy(SubclassExhaustiveStrategy subclassExhaustiveStrategy) { + this.subclassExhaustiveStrategy = subclassExhaustiveStrategy; + } + + public ClassName getMappingControl() { + return mappingControl; + } + + public void setMappingControl(ClassName mappingControl) { + this.mappingControl = mappingControl; + } } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java index dbf8944..a36ff4b 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java +++ b/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/metadata/AutoMappingMetadata.java @@ -1,34 +1,48 @@ package io.github.linpeilie.processor.metadata; import com.squareup.javapoet.ClassName; +import io.github.linpeilie.processor.ContextConstants; +import java.util.ArrayList; +import java.util.List; public class AutoMappingMetadata { private ClassName targetClass; - private String target = ""; + private String target; - private String source = ""; + private String source; - private String dateFormat = ""; + private String dateFormat; - private String numberFormat = ""; + private String numberFormat; - private String expression = ""; + private String expression; - private String defaultExpression = ""; + private String defaultExpression; - private String conditionExpression = ""; + private String conditionExpression; - private boolean ignore = false; + private Boolean ignore; - private String defaultValue = ""; + private String defaultValue; - String[] qualifiedByName = {}; + private List qualifiedByName; - String[] conditionQualifiedByName = {}; + private List conditionQualifiedByName; - String[] dependsOn = {}; + private List dependsOn; + + private String constant; + + private List qualifiedBy; + + private String nullValueCheckStrategy; + + private String nullValuePropertyMappingStrategy; + + private ClassName mappingControl; + /*********** getter/setter ************/ public ClassName getTargetClass() { return targetClass; @@ -78,11 +92,7 @@ public class AutoMappingMetadata { this.expression = expression; } - public boolean isIgnore() { - return ignore; - } - - public void setIgnore(final boolean ignore) { + public void setIgnore(final Boolean ignore) { this.ignore = ignore; } @@ -110,27 +120,71 @@ public class AutoMappingMetadata { this.conditionExpression = conditionExpression; } - public String[] getQualifiedByName() { + public String getConstant() { + return constant; + } + + public void setConstant(String constant) { + this.constant = constant; + } + + public List getQualifiedBy() { + return qualifiedBy; + } + + public void setQualifiedBy(List qualifiedBy) { + this.qualifiedBy = qualifiedBy; + } + + public Boolean getIgnore() { + return ignore; + } + + public List getQualifiedByName() { return qualifiedByName; } - public void setQualifiedByName(String[] qualifiedByName) { + public void setQualifiedByName(List qualifiedByName) { this.qualifiedByName = qualifiedByName; } - public String[] getConditionQualifiedByName() { + public List getConditionQualifiedByName() { return conditionQualifiedByName; } - public void setConditionQualifiedByName(String[] conditionQualifiedByName) { + public void setConditionQualifiedByName(List conditionQualifiedByName) { this.conditionQualifiedByName = conditionQualifiedByName; } - public String[] getDependsOn() { + public List getDependsOn() { return dependsOn; } - public void setDependsOn(String[] dependsOn) { + public void setDependsOn(List dependsOn) { this.dependsOn = dependsOn; } + + public String getNullValueCheckStrategy() { + return nullValueCheckStrategy; + } + + public void setNullValueCheckStrategy(String nullValueCheckStrategy) { + this.nullValueCheckStrategy = nullValueCheckStrategy; + } + + public String getNullValuePropertyMappingStrategy() { + return nullValuePropertyMappingStrategy; + } + + public void setNullValuePropertyMappingStrategy(String nullValuePropertyMappingStrategy) { + this.nullValuePropertyMappingStrategy = nullValuePropertyMappingStrategy; + } + + public ClassName getMappingControl() { + return mappingControl; + } + + public void setMappingControl(ClassName mappingControl) { + this.mappingControl = mappingControl; + } } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java b/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java index bf2d043..c1a7937 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/DefaultConverterFactory.java @@ -1,6 +1,7 @@ package io.github.linpeilie; import io.github.linpeilie.annotations.MapperConfig; +import io.github.linpeilie.utils.MapperUtils; import java.io.File; import java.io.IOException; import java.net.URL; @@ -80,7 +81,7 @@ public class DefaultConverterFactory extends AbstractCachedConverterFactory { } private String getMapperClassName(Class source, Class target) { - return source.getSimpleName() + "To" + target.getSimpleName() + "Mapper"; + return MapperUtils.getMapperClassName(source.getName(), target.getName()); } private String getMapMapperClassName(Class source) { diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapper.java b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapper.java index fc2b90c..bafe7cc 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapper.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapper.java @@ -1,9 +1,22 @@ package io.github.linpeilie.annotations; +import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.mapstruct.BeanMapping; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.IterableMapping; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.control.MappingControl; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; /** * @author linpl @@ -25,6 +38,16 @@ public @interface AutoMapper { */ boolean convertGenerate() default true; + /** + * 生成的 Mapper 接口名称 + */ + String mapperName() default ""; + + /** + * 生成的 Mapper 接口名称后缀,生成的反向转换接口同时生效 + */ + String mapperNameSuffix() default ""; + /** * 是否生成反向转换的接口 * @@ -42,4 +65,114 @@ public @interface AutoMapper { */ boolean cycleAvoiding() default false; + /** + * How unmapped properties of the source type of a mapping should be + * reported. The method overrides an unmappedSourcePolicy set in a central + * configuration + * + * @since 1.4.1 + * + * @return The reporting policy for unmapped source properties. + */ + ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE; + + /** + * How unmapped properties of the target type of a mapping should be + * reported. The method overrides an unmappedTargetPolicy set in a central + * configuration + * + * @since 1.4.1 + * + * @return The reporting policy for unmapped target properties. + */ + ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN; + + /** + * How lossy (narrowing) conversion, for instance long to integer should be + * reported. The method overrides an typeConversionPolicy set in a central + * configuration + * + * @since 1.4.1 + * + * @return The reporting policy for unmapped target properties. + */ + ReportingPolicy typeConversionPolicy() default ReportingPolicy.IGNORE; + + /** + * The strategy to be applied when propagating the value of collection-typed properties. By default, only JavaBeans + * accessor methods (setters or getters) will be used, but it is also possible to invoke a corresponding adder + * method for each element of the source collection (e.g. {@code orderDto.addOrderLine()}). + *

+ * Any setting given for this attribute will take precedence over {@link org.mapstruct.MapperConfig#collectionMappingStrategy()}, + * if present. + * + * @since 1.4.1 + * + * @return The strategy applied when propagating the value of collection-typed properties. + */ + CollectionMappingStrategy collectionMappingStrategy() default CollectionMappingStrategy.ACCESSOR_ONLY; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to the methods of this mapper. + * If no strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} will be + * applied, using {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapper. + */ + NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to an {@link IterableMapping} of + * this mapper. If unset, the strategy set with {@link #nullValueMappingStrategy()} will be applied. If neither + * strategy is configured, the strategy given via {@link MapperConfig#nullValueIterableMappingStrategy()} will be + * applied, using {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source value to an {@link IterableMapping} of + * this mapper. + */ + NullValueMappingStrategy nullValueIterableMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + + /** + * The strategy to be applied when a source bean property is {@code null} or not present. If no strategy is + * configured, the strategy given via {@link MapperConfig#nullValuePropertyMappingStrategy()} will be applied, + * {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() default + NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link MapperConfig}, {@link BeanMapping} or {@link Mapping}. + * + * @since 1.4.1 + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4.1 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + + } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapping.java b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapping.java index 1a84fcf..79ca278 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapping.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/AutoMapping.java @@ -1,12 +1,22 @@ package io.github.linpeilie.annotations; import io.github.linpeilie.DefaultMapping; +import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.mapstruct.BeanMapping; import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; import org.mapstruct.Named; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.Qualifier; +import org.mapstruct.control.MappingControl; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; @Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.CLASS) @@ -28,6 +38,11 @@ public @interface AutoMapping { String numberFormat() default ""; + /** + * @since 1.4.1 + */ + String constant() default ""; + String expression() default ""; String defaultExpression() default ""; @@ -42,6 +57,25 @@ public @interface AutoMapping { */ String defaultValue() default ""; + /** + * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple + * mapping methods (hand written or generated) qualify and thus would result in an 'Ambiguous mapping methods found' + * error. A qualifier is a custom annotation and can be placed on a hand written mapper class or a method. + *

+ * Note that {@link #defaultValue()} usage will also be converted using this qualifier. + * + * qualifier 可以置顶限定符来帮助选择合适的转换方法。qualifier 是一个自定义的注解,可以标注在 mapper 类或者方法上。 + *

+ * Note that {@link #defaultValue()} usage will also be converted using this qualifier. + *

+ * + * @since 1.4.1 + * + * @return the qualifiers + * @see Qualifier + */ + Class[] qualifiedBy() default { }; + /** * String-based form of qualifiers; When looking for a suitable mapping method for a given property, MapStruct will * only consider those methods carrying directly or indirectly (i.e. on the class-level) a {@link Named} annotation @@ -53,9 +87,10 @@ public @interface AutoMapping { *

* Note that {@link #defaultValue()} usage will also be converted using this qualifier. * + * @since 1.4.0 + * * @return One or more qualifier name(s) * @see Named - * @since 1.4.0 */ String[] qualifiedByName() default {}; @@ -72,11 +107,11 @@ public @interface AutoMapping { * number of qualifiers as no custom annotation types are needed. *

* + * @since 1.4.0 * * @return One or more qualifier name(s) * @see #qualifiedByName() * @see Named - * @since 1.4.0 */ String[] conditionQualifiedByName() default {}; @@ -87,9 +122,52 @@ public @interface AutoMapping { *

* An error will be raised in case a cycle in the dependency relationships is detected. * - * @return the dependencies of the mapped property * @since 1.4.0 + * + * @return the dependencies of the mapped property */ String[] dependsOn() default {}; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link org.mapstruct.MapperConfig}, {@link Mapper} or {@link BeanMapping}. + * + * @since 1.4.1 + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * The strategy to be applied when the source property is {@code null} or not present. If no strategy is configured, + * the strategy given via {@link MapperConfig#nullValuePropertyMappingStrategy()}, + * {@link BeanMapping#nullValuePropertyMappingStrategy()} or + * {@link Mapper#nullValuePropertyMappingStrategy()} will be applied. + * + * {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() + default NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4.1 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + + } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/MapperConfig.java b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/MapperConfig.java index 9b5cd79..0c53bfa 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/MapperConfig.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/MapperConfig.java @@ -1,13 +1,24 @@ package io.github.linpeilie.annotations; +import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.mapstruct.BeanMapping; import org.mapstruct.Builder; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.IterableMapping; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; import org.mapstruct.NullValueMappingStrategy; import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.ReportingPolicy; +import org.mapstruct.control.MappingControl; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; /** * 在一个类或者接口上添加该注释,作为自动生成 Mapper 的配置类。在一个模块中,只能有一个有该注释的类。 @@ -38,18 +49,119 @@ public @interface MapperConfig { */ ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.IGNORE; + /** + * How lossy (narrowing) conversion, for instance: long to integer should be + * reported. + * + * @since 1.4.1 + * + * @return The reporting policy for type conversion. + */ + ReportingPolicy typeConversionPolicy() default ReportingPolicy.IGNORE; + + /** + * The strategy to be applied when propagating the value of collection-typed properties. By default, only JavaBeans + * accessor methods (setters or getters) will be used, but it is also possible to invoke a corresponding adder + * method for each element of the source collection (e.g. {@code orderDto.addOrderLine()}). + * + * @since 1.4.1 + * + * @return The strategy applied when propagating the value of collection-typed properties. + */ + CollectionMappingStrategy collectionMappingStrategy() default CollectionMappingStrategy.ACCESSOR_ONLY; + /** * 空对象的映射策略,默认返回 null * @return {@link NullValueMappingStrategy} */ NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + /** + * The strategy to be applied when {@code null} is passed as source argument value to an {@link IterableMapping}. + * If no strategy is configured, the strategy given via {@link #nullValueMappingStrategy()} will be applied, using + * {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source value to an {@link IterableMapping}. + */ + NullValueMappingStrategy nullValueIterableMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to a {@link MapMapping}. + * If no strategy is configured, the strategy given via {@link #nullValueMappingStrategy()} will be applied, using + * {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source value to a {@link MapMapping}. + */ + NullValueMappingStrategy nullValueMapMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + /** * 当属性值为 null 时应对的策略,默认设置为 null * @return {@link NullValuePropertyMappingStrategy} */ NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() default NullValuePropertyMappingStrategy.SET_TO_NULL; + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link Mapper}, {@link BeanMapping} or {@link Mapping}. + * + * @since 1.4.1 + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4.1 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class 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. + *
  • + *
+ * + * @since 1.4.1 + * + * @return the exception that should be used in the generated code + */ + Class unexpectedValueMappingException() default IllegalArgumentException.class; + + /** + * Flag indicating whether the addition of a time stamp in the {@code @Generated} annotation should be suppressed. + * i.e. not be added. + * + * The method overrides the flag set through an annotation processor option. + * + * @since 1.4.1 + * + * @return whether the addition of a timestamp should be suppressed + */ + boolean suppressTimestampInGenerated() default false; + /** * 构造者模式配置,由于 mapstruct 和 lombok 和 builder 一起使用时,会丢失父类属性,这里默认改为关闭 * @return {@link Builder} diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ReverseAutoMapping.java b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ReverseAutoMapping.java index f913226..4883055 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ReverseAutoMapping.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/annotations/ReverseAutoMapping.java @@ -1,12 +1,22 @@ package io.github.linpeilie.annotations; import io.github.linpeilie.DefaultMapping; +import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.mapstruct.BeanMapping; import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; import org.mapstruct.Named; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.Qualifier; +import org.mapstruct.control.MappingControl; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; /** * 由目标类生成当前类的配置 @@ -27,33 +37,25 @@ import org.mapstruct.Named; @Retention(RetentionPolicy.CLASS) public @interface ReverseAutoMapping { + Class targetClass() default DefaultMapping.class; /** * 来源,默认取当前字段名称 - *
  • 可以是当前类中的属性名
  • - *
  • 也可以是属性名.属性名,例如:address.city.name
- * 这里的来源,指的是目标类中的字段信息 - * - * @return 目标类中的属性 + * - 可以是当前类中的属性名 + * - 也可以是属性名.属性名,例如:address.city.name + * @return 当前类中的属性 */ String source() default ""; - /** - * 目标属性,默认取当前字段名称 - *
    - *
  • 可以是当前类中的属性名
  • - *
  • 也可以是属性名.属性名,例如:address.city.name
  • - *
- * - * @return 当前类中的属性 - */ String target() default ""; String dateFormat() default ""; String numberFormat() default ""; + String constant() default ""; + String expression() default ""; String defaultExpression() default ""; @@ -64,11 +66,29 @@ public @interface ReverseAutoMapping { /** * 默认值 - * - * @return 当来源属性为null时,所设置的默认值 + * @return 当源属性为null时,设置的默认值 */ String defaultValue() default ""; + /** + * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple + * mapping methods (hand written or generated) qualify and thus would result in an 'Ambiguous mapping methods found' + * error. A qualifier is a custom annotation and can be placed on a hand written mapper class or a method. + *

+ * Note that {@link #defaultValue()} usage will also be converted using this qualifier. + * + * qualifier 可以置顶限定符来帮助选择合适的转换方法。qualifier 是一个自定义的注解,可以标注在 mapper 类或者方法上。 + *

+ * Note that {@link #defaultValue()} usage will also be converted using this qualifier. + *

+ * + * @since 1.4.1 + * + * @return the qualifiers + * @see Qualifier + */ + Class[] qualifiedBy() default { }; + /** * String-based form of qualifiers; When looking for a suitable mapping method for a given property, MapStruct will * only consider those methods carrying directly or indirectly (i.e. on the class-level) a {@link Named} annotation @@ -80,9 +100,10 @@ public @interface ReverseAutoMapping { *

* Note that {@link #defaultValue()} usage will also be converted using this qualifier. * + * @since 1.4.0 + * * @return One or more qualifier name(s) * @see Named - * @since 1.4.0 */ String[] qualifiedByName() default {}; @@ -99,11 +120,11 @@ public @interface ReverseAutoMapping { * number of qualifiers as no custom annotation types are needed. *

* + * @since 1.4.0 * * @return One or more qualifier name(s) * @see #qualifiedByName() * @see Named - * @since 1.4.0 */ String[] conditionQualifiedByName() default {}; @@ -114,9 +135,51 @@ public @interface ReverseAutoMapping { *

* An error will be raised in case a cycle in the dependency relationships is detected. * - * @return the dependencies of the mapped property * @since 1.4.0 + * + * @return the dependencies of the mapped property */ String[] dependsOn() default {}; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link org.mapstruct.MapperConfig}, {@link Mapper} or {@link BeanMapping}. + * + * @since 1.4.1 + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * The strategy to be applied when the source property is {@code null} or not present. If no strategy is configured, + * the strategy given via {@link MapperConfig#nullValuePropertyMappingStrategy()}, + * {@link BeanMapping#nullValuePropertyMappingStrategy()} or + * {@link Mapper#nullValuePropertyMappingStrategy()} will be applied. + * + * {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.4.1 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() + default NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4.1 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + } diff --git a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/utils/ClassUtil.java b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/ClassUtil.java similarity index 84% rename from mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/utils/ClassUtil.java rename to mapstruct-plus/src/main/java/io/github/linpeilie/utils/ClassUtil.java index 7aa0d2b..80085fb 100644 --- a/mapstruct-plus-processor/src/main/java/io/github/linpeilie/processor/utils/ClassUtil.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/ClassUtil.java @@ -1,4 +1,4 @@ -package io.github.linpeilie.processor.utils; +package io.github.linpeilie.utils; public class ClassUtil { @@ -9,6 +9,9 @@ public class ClassUtil { */ public static String simplifyQualifiedName(String qualifiedName) { String[] arr = qualifiedName.split("\\."); + if (arr.length == 1) { + return arr[0]; + } StringBuilder sb = new StringBuilder(); for (int i = 0; i < arr.length; i++) { if (i == arr.length - 1) { diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java index 857c0f1..711d4fb 100644 --- a/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/CollectionUtils.java @@ -6,6 +6,7 @@ import java.util.Collection; import java.util.Collections; import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; public class CollectionUtils { @@ -26,4 +27,11 @@ public class CollectionUtils { return arrayList; } + public static String join(List list, CharSequence delimiter, String prefix, String suffix) { + if (list == null) { + return null; + } + return list.stream().map(str -> prefix + str + suffix).collect(Collectors.joining(delimiter)); + } + } diff --git a/mapstruct-plus/src/main/java/io/github/linpeilie/utils/MapperUtils.java b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/MapperUtils.java new file mode 100644 index 0000000..d0d4be2 --- /dev/null +++ b/mapstruct-plus/src/main/java/io/github/linpeilie/utils/MapperUtils.java @@ -0,0 +1,14 @@ +package io.github.linpeilie.utils; + +public class MapperUtils { + + public static String getMapperClassName(String sourceQualifiedClassName, String targetQualifiedClassName) { + String[] sourceQualifiedClassNames = sourceQualifiedClassName.split("\\."); + String[] targetQualifiedClassNames = targetQualifiedClassName.split("\\."); + String mapperClassName = sourceQualifiedClassNames[sourceQualifiedClassNames.length - 1] + + "To" + + targetQualifiedClassNames[targetQualifiedClassNames.length - 1]; + return mapperClassName.substring(0, 1).toUpperCase() + mapperClassName.substring(1) + "Mapper"; + } + +} diff --git a/pom.xml b/pom.xml index d15eda1..d0425cf 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ 8 UTF-8 1.5.5.Final + 1.0.0.Alpha3 5.8.26 https://github.com/linpeilie/mapstruct-plus.git @@ -69,6 +70,11 @@ hutool-core ${hutool.version} + + org.mapstruct.tools.gem + gem-api + ${gem.version} +