📦📦📦❗️❗️ This page is under construction ❗️❗️📦📦📦
Table of Contents
- Prerequisites
- Let's code!
- How does it work?
- Multiple mappings from/to the same type
- Mappings of multiple classes and complex objects
- Mapping collections and arrays
- Configuration
- Customize the mapping
- Logging
- Spring
- In the future
- Download
- Javadoc
- License
The library is written in Java 8 with no external dependencies needed!
Just before looking to the first example, there is a little consideration to do: all destination classes of a mapping should have at least the empty public constructor, otherwise the Mapper
will not be able to create a new instance to return. If the class cannot have such a constructor, see section "Customize the mapping" to find an alternative!
Now let's do some mappings!
Step 1
the first step is to create a Mapper
instance that will contains all our wanted mappings:
Mapper mapper = new Mapper();
Step 2
once we have a mapper
, we can define the mapping we want. To do that specify a Source
class and a Destination
class:
mapper.add(Source.class, Destination.class); // create a mapping between Source and Destination types
Step 3
Once we have created a mapper
and defined some mappings inside it (here from Source
to Destination
), we can map our objects:
Source src = /*creation of a Source istance*/;
Destination dest = mapper.map(src); // mapping src object into Destination type
Full code
Mapper mapper = new Mapper();
mapper.add(Source.class, Destination.class);
Source src = /*creation of a Source istance*/;
Destination dest = mapper.map(src);
And that's all!
When the Mapper
is build, it search automatically the field in the source type and in the destination type that are called with the same name and are of the same type (or if the source field can be assigned to the destination field).
But what happens if the needed mapping is between two variables with differents names, for example String name
in the Source
class and String user_name
in the Destination
class? There are different ways to do it, but the simplest is the following:
use the @AliasNames
annotation to the name
field passing the destination field name. For example:
public class Source {
// ...
@AliasNames("user_name")
private String name;
// ...
}
We can also put the annotation to the destination field @AliasNames("name")
, the result will be the same, or to both field (the same name inside the annotation): @AliasNames("friend_name")
For more customize mappings, see the "Customize the mapping" section.
In the Mapper
, the identifier of a given mapping is the pair Source-Destination classes, so we can easily add all the mapping we want.
First we add two different mapping from the Source
class.
Mapper mapper = new Mapper();
mapper.add(Source.class, Destination1.class);
mapper.add(Source.class, Destination2.class);
To map a source
instance, we can do as following:
Source src = /*creation of a Source istance*/;
Destination1 dest = mapper.map(src,Destination1.class);
In this case we have to specify the destination class otherwise the mapper
will not able to determine the destination type of the required mapping! If the Source
class has only one mapping, the destination class is not mandatory (mapper.map(src)
).
First we add two different mapping to the Destination
class.
Mapper mapper = new Mapper();
mapper.add(Source1.class, Destination.class);
mapper.add(Source2.class, Destination.class);
Now we have a known situation (one source class for one destination class) and we already know how to manage it!
Source1 src1 = /*creation of a Source1 istance*/;
Source2 src2 = /*creation of a Source2 istance*/;
Destination dest1 = mapper.map(src1);
Destination dest2 = mapper.map(src2);
The example above shows the basic case of a Mapper
with only one effective mapping inside. It's not rare to want to convert different object or complex object that have not only simple field such that String
, int
or similar, but also complex variables like ComplexSourceObject
.
The solution is simply: add more mappings to the mapper
.
For example the Source
and Destination
classes contains a complex object as below:
public class Source {
// ...
private ComplexSourceObject obj;
// ...
}
public class Destination {
// ...
private ComplexDestinationObject obj;
// ...
}
Our example code become:
Mapper mapper = new Mapper();
mapper.add(Source.class, Destination.class);
mapper.add(ComplexSourceObject.class, ComplexDestinationObject.class);
Source src = /*creation of a Source istance*/;
Destination dest = mapper.map(src);
If the field to be mapped is a Collection
or an array, the same logic of our previous examples still works. The default mapping will be created if both the field in the source class and the destination type are:
- collection of the same type, or the source collection can be assign to the destination filed, and the inner type is the same or the source inner type is assignable to the destination inner type;
- arrays witch inner type is the same or the source inner type is assignable to the destination inner type
For the collection, we often defined a field with an interface type (List
or Set
for example) that are not instanziable. To make the mapping work correclty, we can use the annotation CollectionType
to specify the type of the sub-collection to be instantiate for the destination field:
public class Source {
// ...
@CollectionType(ArrayList.class)
private List<String> name;
// ...
}
For more customize mappings, see the "Customize the mapping" section.
// TODO add description of the available configurations
So far we only saw how to create default mapping, but rarely is the mapping we want at the end: this library allow using 20.162 different ways to create a custom mapping!
// TODO
The library used to log is slf4j
(Simple Logging Facade for Java, http://www.slf4j.org/) and this allows you to use the logger library you prefer.
The following libraries worked successfully:
- SLF4J Simple
- JUL (java.util.logging)
- logback
- log4j
// TODO
The Mapper
class is annotated with @Component
, so you can create a bean to autowired a Mapper
instance to use inside your Spring project.
// TODO
- support for generic in custom types
With Maven:
First add a new repository inside your pom.xml
<repositories>
<repository>
<id>mvn-repo</id>
<url>https://github.com/eschoysman/repository/raw/mvn-repo</url>
</repository>
</repositories>
Next add the dependency to the artifact
<dependency>
<groupId>io.github.eschoysman</groupId>
<artifactId>mapper</artifactId>
<version>[1.0.0,)</version>
</dependency>
Without Maven:
You can download the jar to include into you project here.
You can find the full javadoc updated to the last version here.
The code in this project is licensed under MIT License.
[]: #