diff --git a/pom.xml b/pom.xml
index 6d5834ae..46face1a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -58,6 +58,7 @@
1.12.1
5.5.2
+ 3.24.2
7.2
2.0.1.Final
6.0.20.Final
@@ -151,6 +152,12 @@
${junit-jupiter-version}
+
+ org.assertj
+ assertj-core
+ ${assertj-core.version}
+
+
javax.validation
validation-api
diff --git a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/CollectionBuilderUtils.java b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/CollectionBuilderUtils.java
index 775a53ac..9452f48e 100644
--- a/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/CollectionBuilderUtils.java
+++ b/record-builder-processor/src/main/java/io/soabase/recordbuilder/processor/CollectionBuilderUtils.java
@@ -50,10 +50,12 @@ class CollectionBuilderUtils {
private static final Class> mapType = Map.class;
private static final Class> setType = Set.class;
private static final Class> collectionType = Collection.class;
+ private static final Class> collectionsType = Collections.class;
private static final TypeName listTypeName = TypeName.get(listType);
private static final TypeName mapTypeName = TypeName.get(mapType);
private static final TypeName setTypeName = TypeName.get(setType);
private static final TypeName collectionTypeName = TypeName.get(collectionType);
+ private static final TypeName collectionsTypeName = TypeName.get(collectionsType);
private static final TypeVariableName tType = TypeVariableName.get("T");
private static final TypeVariableName kType = TypeVariableName.get("K");
@@ -298,7 +300,13 @@ private String disambiguateGeneratedMethodName(List recordCompo
private MethodSpec buildShimMethod(String name, TypeName mainType, Class> abstractType,
ParameterizedTypeName parameterizedType, TypeVariableName... typeVariables) {
- var code = CodeBlock.of("return (o != null) ? $T.copyOf(o) : $T.of()", mainType, mainType);
+ CodeBlock code;
+ if (mainType.equals(setTypeName)) {
+ code = CodeBlock.of("return (o != null) ? $T.unmodifiableSet(($T) o) : $T.of()", collectionsTypeName, parameterizedType, mainType);
+ } else {
+ code = CodeBlock.of("return (o != null) ? $T.copyOf(o) : $T.of()", mainType, mainType);
+ }
+
TypeName[] wildCardTypeArguments = parameterizedType.typeArguments.stream().map(WildcardTypeName::subtypeOf)
.toList().toArray(new TypeName[0]);
var extendedParameterizedType = ParameterizedTypeName.get(ClassName.get(abstractType), wildCardTypeArguments);
diff --git a/record-builder-test/pom.xml b/record-builder-test/pom.xml
index 9e1907de..90210377 100644
--- a/record-builder-test/pom.xml
+++ b/record-builder-test/pom.xml
@@ -64,6 +64,12 @@
junit-jupiter
test
+
+
+ org.assertj
+ assertj-core
+ test
+
diff --git a/record-builder-test/src/main/java/io/soabase/recordbuilder/test/OrderedSetRecord.java b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/OrderedSetRecord.java
new file mode 100644
index 00000000..da1c713d
--- /dev/null
+++ b/record-builder-test/src/main/java/io/soabase/recordbuilder/test/OrderedSetRecord.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019 The original author or authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.soabase.recordbuilder.test;
+
+import io.soabase.recordbuilder.core.RecordBuilder;
+
+import java.util.Set;
+
+@RecordBuilder
+@RecordBuilder.Options(useImmutableCollections = true)
+record OrderedSetRecord(Set orderedSet) {
+}
diff --git a/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOrderedSetsBuilder.java b/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOrderedSetsBuilder.java
new file mode 100644
index 00000000..caca475e
--- /dev/null
+++ b/record-builder-test/src/test/java/io/soabase/recordbuilder/test/TestOrderedSetsBuilder.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 The original author or authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.soabase.recordbuilder.test;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.LinkedHashSet;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TestOrderedSetsBuilder {
+
+ @Test
+ void shouldKeepOrderInSetIfProvided() {
+ // given
+ var orderedSet = new LinkedHashSet();
+ orderedSet.add("C");
+ orderedSet.add("B");
+ orderedSet.add("A");
+
+ // when
+ var record = OrderedSetRecordBuilder.builder().orderedSet(orderedSet).build();
+
+ // then
+ assertThat(record.orderedSet()).containsExactly("C", "B", "A");
+ }
+}