Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ jobs:
with:
java-version: ${{ matrix.java }}
distribution: 'zulu'
cache: 'maven'
- name: Cache local Maven repository
uses: actions/cache@v4
continue-on-error: true
with:
path: ~/.m2/repository
key: cache-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
cache-maven-${{ hashFiles('**/pom.xml') }}
cache-maven-
- name: Build
run: mvn --no-transfer-progress -B clean package
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<modelmapper.version>3.1.1</modelmapper.version>
<modelmapper.version>3.2.6</modelmapper.version>
<testng.version>7.7.0</testng.version>
</properties>
<licenses>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.modelmapper.record;

import java.lang.reflect.Constructor;
import java.lang.reflect.RecordComponent;
import java.util.stream.IntStream;
import org.modelmapper.ConstructorParam;
import org.modelmapper.spi.ConstructorInjector;

import java.util.List;

public class RecordConstructorInjector implements ConstructorInjector {

@Override
public List<ConstructorParam> getParameters(Class<?> type) {
if (!isApplicable(type)) {
throw new IllegalArgumentException(
String.format("Type %s is not a Record type.", type.getName()));
}
Constructor<?> constructor = type.getDeclaredConstructors()[0];
RecordComponent[] components = type.getRecordComponents();
return IntStream.range(0, components.length)
.mapToObj(index -> new ConstructorParam(constructor, index, components[index].getName(),
components[index].getType()))
.toList();
}

@Override
public boolean isApplicable(Class<?> type) {
return Record.class.isAssignableFrom(type);
}
}
2 changes: 2 additions & 0 deletions src/main/java/org/modelmapper/record/RecordModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ public class RecordModule implements Module {
@Override
public void setupModule(ModelMapper modelMapper) {
modelMapper.getConfiguration().addValueReader(new RecordValueReader());
modelMapper.getConfiguration().addConstructorInjector(
new RecordConstructorInjector());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.modelmapper.record;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;

import org.modelmapper.ModelMapper;
import org.modelmapper.config.Configuration.AccessLevel;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

/**
* Tests the mapping of a POJO to a Record.
*/
@Test
public class RecordConstructorInjectorTest {
private ModelMapper modelMapper;

record UserRecord(String userId, String userName) {
}

static class User {
String userId;
String userName;
}

@BeforeMethod
public void setup() {
modelMapper = new ModelMapper()
.registerModule(new RecordModule());
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(AccessLevel.PACKAGE_PRIVATE)
.setMethodAccessLevel(AccessLevel.PACKAGE_PRIVATE);
}

public void shouldMapToRecord() {
User user = new User();
user.userId = "id";
user.userName = "name";

UserRecord record = modelMapper.map(user, UserRecord.class);
assertEquals(record.userId, "id");
assertEquals(record.userName, "name");
}
}