diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 33e7f6f..6c1f23b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -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
diff --git a/pom.xml b/pom.xml
index e16189d..0ea8480 100644
--- a/pom.xml
+++ b/pom.xml
@@ -16,7 +16,7 @@
17
17
- 3.1.1
+ 3.2.6
7.7.0
diff --git a/src/main/java/org/modelmapper/record/RecordConstructorInjector.java b/src/main/java/org/modelmapper/record/RecordConstructorInjector.java
new file mode 100644
index 0000000..1f78777
--- /dev/null
+++ b/src/main/java/org/modelmapper/record/RecordConstructorInjector.java
@@ -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 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);
+ }
+}
diff --git a/src/main/java/org/modelmapper/record/RecordModule.java b/src/main/java/org/modelmapper/record/RecordModule.java
index ed3f3b0..03da7dc 100644
--- a/src/main/java/org/modelmapper/record/RecordModule.java
+++ b/src/main/java/org/modelmapper/record/RecordModule.java
@@ -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());
}
}
diff --git a/src/test/java/org/modelmapper/record/RecordConstructorInjectorTest.java b/src/test/java/org/modelmapper/record/RecordConstructorInjectorTest.java
new file mode 100644
index 0000000..f4ec7a7
--- /dev/null
+++ b/src/test/java/org/modelmapper/record/RecordConstructorInjectorTest.java
@@ -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");
+ }
+}
\ No newline at end of file