{"id":23902714,"url":"https://github.com/mtumilowicz/model-mapper","last_synced_at":"2025-02-23T10:44:27.140Z","repository":{"id":110878681,"uuid":"138919924","full_name":"mtumilowicz/model-mapper","owner":"mtumilowicz","description":"Exploring basic features of ModelMapper.","archived":false,"fork":false,"pushed_at":"2018-09-12T17:04:40.000Z","size":12,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-04T22:49:57.459Z","etag":null,"topics":["mapping","mapping-tools","modelmapper","modelmapping"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mtumilowicz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-06-27T18:39:44.000Z","updated_at":"2023-09-08T17:42:13.000Z","dependencies_parsed_at":"2023-03-13T13:47:22.036Z","dependency_job_id":null,"html_url":"https://github.com/mtumilowicz/model-mapper","commit_stats":{"total_commits":18,"total_committers":1,"mean_commits":18.0,"dds":0.0,"last_synced_commit":"e0305333679bb36a71e1952e5acf7f1790ed561d"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fmodel-mapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fmodel-mapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fmodel-mapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mtumilowicz%2Fmodel-mapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mtumilowicz","download_url":"https://codeload.github.com/mtumilowicz/model-mapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240304564,"owners_count":19780312,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mapping","mapping-tools","modelmapper","modelmapping"],"created_at":"2025-01-04T22:50:06.520Z","updated_at":"2025-02-23T10:44:27.087Z","avatar_url":"https://github.com/mtumilowicz.png","language":"Java","readme":"[![Build Status](https://travis-ci.com/mtumilowicz/model-mapper.svg?branch=master)](https://travis-ci.com/mtumilowicz/model-mapper)\n\n# model-mapper\nThe main goal of this project is to explore basic features of\n`ModelMapper`.\n\n_References_: [Manual](http://modelmapper.org/user-manual/)  \n_References_: [java doc](http://modelmapper.org/javadoc/)  \n_References_: [How it works](http://modelmapper.org/user-manual/how-it-works/)  \n_References_: [Configuration](http://modelmapper.org/user-manual/configuration/)\n\n# technologies used\n```\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.modelmapper\u003c/groupId\u003e\n    \u003cartifactId\u003emodelmapper\u003c/artifactId\u003e\n    \u003cversion\u003e2.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n# preface\nApplications often consist of similar but different object models, \nwhere the data in two models may be similar but the structure and \nconcerns of the models are different. Object mapping makes it easy \nto convert one model to another, allowing separate models to remain \nsegregated.\n\n# description\nThe goal of ModelMapper is to make object mapping easy, \nby automatically determining how one object model maps to another, \nbased on conventions.\n\nModel Mapper is:\n* **Intelligent** - it analyzes your object model to intelligently \ndetermine how data should be mapped.\n\n* **Convention Based** - it uses conventions to determine \nhow properties and values are mapped to each other. \nWhat is more - users can create custom conventions.\n\n* **Extensible** - it supports integration with any type of data model.\n\n# defaults\n* **Access level**: public - eligible for matching are only public \nmethods and fields.\n* **Field matching**: disabled - only methods are eligible for matching.\n* **Naming convention**: JavaBeans.\n* **Name transformer**: JavaBeans.\n* **Name tokenizer**: Camel Case.\n* **Matching strategy**: Standard, which means that:\n    * all destination properties be matched and \n    all source property names have at least one token matched,\n    * tokens can be matched in any order.\n    \n# matching process\n* **Eligibility** - only source methods with zero parameters and a \nnon-void return type are eligible, and destination methods with one \nparameter and a void return type are eligible.\n\n* **Transformation** - if you have a source object with a \n`getPerson` method and a destination object with a `setPerson` method, \nin order for these to be matched, a `NameTransformer` is used to \ntransform the method names to `person`.\n\n* **Tokenization** - After transformation, `NameTokenizers` are used to \ntokenize class and property names for matching.\n\n* **Matching** - match is based on properties' names and class \nname tokens.\n\n* **Handling Ambiguity** -  it is possible that multiple source \nproperties may match the same destination property. \nWhen this occurs, the matching engine attempts to resolve the \nambiguity by finding the closest match among the duplicates.\nIf the ambiguity cannot be resolved, a \n`ConfigurationException` is thrown.\n\n# manual\nAssume that we have two classes `Person` and `PersonDto` and relations:\n* exact 1 - 1 matching between fields\n    ```\n    TypeMap\u003cPerson, PersonDto\u003e personToDto = new ModelMapper().createTypeMap(Person.class, PersonDto.class);\n    \n    Person person = ...\n    \n    PersonDto personDto = personToDto.map(person);    \n    ```\n    \n* some fields differs at names (`name -\u003e firstName`)\n    ```\n    TypeMap\u003cPerson, PersonDto\u003e personToDto = new ModelMapper().createTypeMap(Person.class, PersonDto.class)\n            .addMapping(Person::getName, PersonDto::setFirstName);\n    \n    Person person = ...\n    \n    PersonDto personDto = personToDto.map(person);\n    ```\n    \n* mapping `Person` property's fields to dto fields \n(`address.street -\u003e street`)\n    ```\n    TypeMap\u003cPerson, PersonDto\u003e personToDto = new ModelMapper().createTypeMap(Person.class, PersonDto.class)\n            .addMapping(x -\u003e x.getAddress().getCity(), PersonDto::setCity)\n            .addMapping(x -\u003e x.getAddress().getStreet(), PersonDto::setStreet);\n    \n    Person person = ...\n    \n    PersonDto personDto = personToDto.map(person);\n    ```\n    \n    Note that this approach is null safe - if `person.address` is null \n    mapping will not occur.\n    \n* mapping fields of `Person` to `PersonDto` property's fields (`email -\u003e contact.email`)\n    * `Contact` has no-arg constructor\n        ```\n        TypeMap\u003cPerson, PersonDto\u003e personToDto = new ModelMapper().createTypeMap(Person.class, PersonDto.class)\n                .\u003cString\u003eaddMapping(Person::getEmail, (x, y) -\u003e x.getContact().setEmail(y))\n                .\u003cString\u003eaddMapping(Person::getPhone, (x, y) -\u003e x.getContact().setPhone(y));\n        \n        Person person = ...\n        \n        PersonDto personDto = personToDto.map(person);\n        ```\n    \n    * `Contact` does not have no-arg constructor\n        ```\n        TypeMap\u003cPerson, PersonDto\u003e personToDto = new ModelMapper().createTypeMap(Person.class, PersonDto.class);\n        personToDto.addMappings(\n                new PropertyMap\u003cPerson, PersonDto\u003e() {\n                    @Override\n                    protected void configure() {\n                        using(ctx -\u003e new Contact(\n                                ((Person) ctx.getSource()).getEmail(),\n                                ((Person) ctx.getSource()).getPhone())\n                        ).map(source, destination.getContact());\n                    }\n                });\n        \n        Person person = ...\n        \n        PersonDto personDto = personToDto.map(person);\n        ```\n    * mapping fields that need conversion\n        ```\n        Converter\u003cLocalDate, String\u003e dateOfBirthConverter = \n                context -\u003e context.getSource().format(DateTimeFormatter.ISO_DATE);\n        \n        TypeMap\u003cPerson, PersonDto\u003e personToDto = new ModelMapper().createTypeMap(Person.class, PersonDto.class);\n        \n        personToDto.addMappings(mapper -\u003e \n                mapper.using(dateOfBirthConverter).map(Person::getDateOfBirth, PersonDto::setDateOfBirth));\n\n        Person person = ...\n        \n        PersonDto dto = personToDto.map(person);      \n        ```\n# test cases\nAll above features are tested in `PersonToPersonDto`.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtumilowicz%2Fmodel-mapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmtumilowicz%2Fmodel-mapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmtumilowicz%2Fmodel-mapper/lists"}