Skip to content

AfonsoMatElias/converter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

96 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Converter v1.4.1

Introduction

Converter is a Library used to convert/map an object to another, in a simple way without doing making to many steps to achieve the object conversion.

This Mapper Lib inspired in C# AutoMapper Library.

Usage

  // Converter Instance
  IConverter converter = new Converter();

  // Entities
  Product model = new Product();

  // Mapping
  ProductDto dto = converter.map(model).to(ProductDto.class);

Creating Mapping for each class type

We can also create mapping configuration for each class type, and add global options if needed. The options can be added on Mapping Configuration Creation or after, it depends to you.

  • Mapping Configuration Creation
  // Converter Instance
  IConverter converter = new Converter();

  converter.createMap(Category.class, CategoryDto.class);

  converter.createMap(Product.class, ProductDto.class, (options) -> {
    
    options.beforeMap((src, dst) -> {
      // TODO: something nice 🤩 before the object is mapped
    });

    options.afterMap((src, dst) -> {
      // TODO: something nice 🤩 after the object is mapped
    });

  });
  • After Mapping Configuration Creation, this way we can chain them
  // Converter Instance
  IConverter converter = new Converter();

  converter.createMap(Category.class, CategoryDto.class);

  converter.createMap(Product.class, ProductDto.class)
    .beforeMap((src, dst) -> {
      // TODO: something nice 🤩 before the object is mapped
    })
    .afterMap((src, dst) -> {
      // TODO: something nice 🤩 after the object is mapped
    });
  • If you also want to add reverse mapping for the entities, we use reverseMap to achieve that
  // Converter Instance
  IConverter converter = new Converter();

  converter.createMap(Category.class, CategoryDto.class)
    .reverseMap();
  • We can also mutate or transform a value types
  // Converter Instance
  IConverter converter = new Converter();

  converter.addTransform(String.class, String[].class, (source) -> {

      String[] arrayOfStringValue = source.split(";");

      return arrayOfStringValue;
  });
  • Using forMember method we can target a member and modify it value, and skipMember to avoid member mapping
  // Converter Instance
  IConverter converter = new Converter();

  converter.createMap(User.class, UserDto.class)
    .forMember("name", (src) -> {
      return " Sr(a)." + src.getName();
    })
    .forMember(UserDto::setUsername, (src) -> {
      return "@" + src.getUsername();
    })
    .forMember("role", (src, member) -> {
      
      // Adding extra mapping while mapping the member
      // Getting just one record from the list and mapping
      // From: List<Role> to: Role
      UserRoleDto role = member.map(src.getRoles().get(0)).to(UserRoleDto.class);

      return role;
    })
    .skipMember("password");
  • We can also use skipTypes to avoid certain type mapping
  // Converter Instance
  IConverter converter = new Converter();

  // We can use name of the Class
  converter.skipTypes("Float");

  // Or, we can use the Class Type
  converter.skipTypes(String.class);

  // Entities
  Product model = new Product();

  // Mapping
  ProductDto dto = converter.map(model).to(ProductDto.class, (options) -> {
    options.skipTypes(Integer.class);
  });

Note: When creating forMember map expression with inner mapping, always use memberMapping from the second argument of the expresion: .forMember("field", (src, memberMapping) -> { }). We cannot use the main converter instance because whenever converter.map({}) is called, it creates a new instance of MappingProcessor, ignoring the previous configuration.

  • Converting and modifying
  // Converter Instance
  IConverter converter = new Converter();

  // Entities
  Product model = new Product();

  // Mapping
  ProductDto dto = converter.map(model).to(ProductDto.class, (options) -> {
     options.beforeMap((src, dst) -> {
      // TODO: something nice 🤩 before the object is mapped
    });

    options.afterMap((src, dst) -> {
      // TODO: something nice 🤩 after the object is mapped
    });
  });
  • Mapping or Extracting values from another object
  // Converter Instance
  IConverter converter = new Converter();

  // Entities
  Product dbModel = new Product();
  dbModel.setName("Coca Cola");
  dbModel.setPrice(0.5f);

  // Mapping
  ProductDto dtoModel = new ProductDto();
  dtoModel.setName("Sprite");
  dtoModel.setPrice(1f);

  Product dbModelMapped = converter.map(dbModel).from(dtoModel);

  // Has the same memory address
  Boolean isEquals = dbModel == dbModelMapped;  
  • Making a copy of an Object with different memory address
  // Converter Instance
  IConverter converter = new Converter();

  // Entities
  Product model = new Product();
  model.setName("Coca Cola");
  model.setPrice(0.5f);

  Product copy = converter.map(model).to();

  // Has the different memory address
  Boolean isEquals = dbModel == dbModelMapped;  

Note: We can also apply modifiers, like: .to((options) -> { })

  • Members can be skipped while extracting values from another object using mapping actions
  // Converter Instance
  IConverter converter = new Converter();

  // Entities
  Product dbModel = new Product();
  dbModel.setName("Coca Cola");
  dbModel.setPrice(0.5f);

  // Mapping
  ProductDto dtoModel = new ProductDto();
  dtoModel.setName("Sprite");
  dtoModel.setPrice(1f);

  Product dbModelMapped = converter.map(dbModel).from(dtoModel, (options) -> {
    options.skipMembers("price");

    // Note: We advice to use this one
    // The other one target every property having the same name even in their child
    // options.skipMembers(Product.class.getDeclaredField("price"));
  });
  • Converting and modifying a list
  // Converter Instance
  IConverter converter = new Converter();

  // Entities
  Product model1 = new Product("Coca Cola");
  Product model2 = new Product("Sprite");

  List<Product> models = Arrays.asList(model1, model2);

  // Mapping
  List<ProductDto> dto = converter.map(models).to(ProductDto.class, (options) -> {
    options.beforeMap((src, dst) -> {
      // TODO: something nice 🤩 before the object is mapped
      // src -> List<Product>
      // dst -> List<ProductDto> <null>
    });

    options.afterMap((src, dst) -> {
      // TODO: something nice 🤩 after the object is mapped
      // src -> List<Product>
      // dst -> List<ProductDto>
    });
    
    options.beforeEachMap((src, dst) -> {
      // TODO: something nice 🤩 before the object is mapped
      // src -> item: Product
      // dst -> item: ProductDto <null>
    });

    options.afterEachMap((src, dst) -> {
      // TODO: something nice 🤩 after the object is mapped
      // src -> item: Product
      // dst -> item: ProductDto
    });
  });

Using Spring Boot

If you use SpringBoot and want to use Dependency Injection, you can create a converter config file and assign it as @Component:

  @Component
  public class ConverterConfig extends Converter {
    public ConverterConfig() {
      
      createMap(Product.class, ProductDto.class);

      createMap(User.class, UserDto.class)
        .skipMember("password");

    }

    @Bean @Primary
    public Converter autowire() throws InstantiationException, IllegalAccessException {
      // This method is used to give the possibility to 
      // instantiate the class using @Autowired annotation
      return this; 
    }
  }
  • Injecting in the controller via DI
  @Component
  public class ProductController {
    @Autowired
    IConverter converter;
    
    @Autowired
    ProductService service;

    @GetMapping(produces = "application/json", value = "/{id}")
    public ProductDto getOne(@PathVariable("id") Long id) {
      
      Product product = service.findById(id);

      ProductDto productDto = converter.map(product).to(ProductDto.class);

      return productDto;
    }

    @GetMapping(produces = "application/json")
    public List<ProductDto> getAll() {

      List<Product> products = service.findAll();
      
      List<ProductDto> productDtos = converter.map(products).to(ProductDto.class);

      return productDtos;
    }
  }

How to import into a maven project

To load the dependency to you a Maven project, you can follow these steps:

1. Add the following repository to your pom.xml file:

  <repositories>
    <repository>
      <id>jitpack.io</id>
      <url>https://jitpack.io</url>
    </repository>
  </repositories>

2. Add the dependency to your pom.xml file:

  <dependencies>
    ...
    
    <dependency>
      <groupId>io.github.afonsomatelias</groupId>
      <artifactId>converter</artifactId>
      <version>[tag]</version>
    </dependency>

  </dependencies>

Note: Converter tags begins with v[number]. Example: v.1.1

3. Save the pom.xml file.

4. Download and Install the dependency.

  mvn clean install

5. You can now use the Converter in your Maven project.