Skip to content

Commit 245cb4b

Browse files
authored
Merge pull request #453 from AuthMe/443-introduce-collection-property
#443 Create CollectionProperty parent type
2 parents 89d1f7e + b3a2322 commit 245cb4b

File tree

8 files changed

+193
-46
lines changed

8 files changed

+193
-46
lines changed
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package ch.jalu.configme.properties;
2+
3+
import ch.jalu.configme.properties.types.CollectionPropertyType;
4+
import ch.jalu.configme.properties.types.PropertyType;
5+
import org.jetbrains.annotations.NotNull;
6+
7+
import java.util.Arrays;
8+
import java.util.Collection;
9+
import java.util.stream.Collector;
10+
11+
/**
12+
* General {@link Collection} property. Used as common parent type for all collection properties.
13+
*
14+
* @param <E> the type of the entries in the collection
15+
* @param <C> the concrete collection type
16+
* @see ListProperty
17+
* @see SetProperty
18+
*/
19+
public class CollectionProperty<E, C extends Collection<E>> extends TypeBasedProperty<C> {
20+
21+
/**
22+
* Constructor.
23+
*
24+
* @param path the path of the property
25+
* @param collectionType the property type
26+
* @param defaultValue the default value of the property
27+
*/
28+
public CollectionProperty(@NotNull String path, @NotNull PropertyType<C> collectionType, @NotNull C defaultValue) {
29+
super(path, collectionType, defaultValue);
30+
}
31+
32+
/**
33+
* Constructs a new collection property based on the given entry type and collector.
34+
*
35+
* @param path the path of the property
36+
* @param entryType the collection type
37+
* @param collector the collection type
38+
* @param defaultValue the default value
39+
* @param <E> the type of the entries in the collection
40+
* @param <C> the concrete collection type
41+
* @return a new collection property
42+
*/
43+
public static <E, C extends Collection<E>> @NotNull Property<C> of(@NotNull String path,
44+
@NotNull PropertyType<E> entryType,
45+
@NotNull Collector<E, ?, C> collector,
46+
@NotNull C defaultValue) {
47+
CollectionPropertyType<E, C> collectionPropertyType = CollectionPropertyType.of(entryType, collector);
48+
return new CollectionProperty<>(path, collectionPropertyType, defaultValue);
49+
}
50+
51+
/**
52+
* Constructs a new collection property based on the given entry type and collector.
53+
*
54+
* @param path the path of the property
55+
* @param entryType the collection type
56+
* @param collector the collection type
57+
* @param defaultValueEntries the entries that make up the default value
58+
* @param <E> the type of the entries in the collection
59+
* @param <C> the concrete collection type
60+
* @return a new collection property
61+
*/
62+
@SafeVarargs
63+
public static <E, C extends Collection<E>> @NotNull Property<C> of(@NotNull String path,
64+
@NotNull PropertyType<E> entryType,
65+
@NotNull Collector<E, ?, C> collector,
66+
E @NotNull ... defaultValueEntries) {
67+
CollectionPropertyType<E, C> collectionPropertyType = CollectionPropertyType.of(entryType, collector);
68+
C defaultValue = Arrays.stream(defaultValueEntries).collect(collector);
69+
return new CollectionProperty<>(path, collectionPropertyType, defaultValue);
70+
}
71+
}

src/main/java/ch/jalu/configme/properties/EnumSetProperty.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,25 @@
55

66
import java.util.Arrays;
77
import java.util.EnumSet;
8-
import java.util.Set;
98

109
/**
11-
* EnumSet property.
10+
* EnumSet property. The property's values are mutable and in declaration order of the enum.
1211
*
1312
* @param <E> the enum type
1413
*/
15-
public class EnumSetProperty<E extends Enum<E>> extends SetProperty<E> {
14+
public class EnumSetProperty<E extends Enum<E>> extends CollectionProperty<E, EnumSet<E>> {
1615

1716
public EnumSetProperty(@NotNull String path, @NotNull Class<E> enumClass, @NotNull EnumSet<E> defaultValue) {
18-
super(new EnumSetPropertyType(enumClass), path, defaultValue);
17+
super(path, new EnumSetPropertyType<>(enumClass), defaultValue);
1918
}
2019

21-
public EnumSetProperty(@NotNull String path, @NotNull Class<E> enumClass, @NotNull E @NotNull... defaultValue) {
22-
super(new EnumSetPropertyType(enumClass), path, newEnumSet(enumClass, defaultValue));
20+
@SafeVarargs
21+
public EnumSetProperty(@NotNull String path, @NotNull Class<E> enumClass, @NotNull E @NotNull ... defaultValue) {
22+
super(path, new EnumSetPropertyType<>(enumClass), newEnumSet(enumClass, defaultValue));
2323
}
2424

25-
private static <E extends Enum<E>> @NotNull Set<E> newEnumSet(@NotNull Class<E> enumClass,
26-
E @NotNull [] defaultValue) {
25+
private static <E extends Enum<E>> @NotNull EnumSet<E> newEnumSet(@NotNull Class<E> enumClass,
26+
E @NotNull [] defaultValue) {
2727
EnumSet<E> enumSet = EnumSet.noneOf(enumClass);
2828
enumSet.addAll(Arrays.asList(defaultValue));
2929
return enumSet;

src/main/java/ch/jalu/configme/properties/ListProperty.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* @param <E> the type of the elements in the list
1515
*/
16-
public class ListProperty<E> extends TypeBasedProperty<List<E>> {
16+
public class ListProperty<E> extends CollectionProperty<E, List<E>> {
1717

1818
/**
1919
* Constructor.

src/main/java/ch/jalu/configme/properties/SetProperty.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
*
1818
* @param <E> the type of the elements in the set
1919
*/
20-
public class SetProperty<E> extends TypeBasedProperty<Set<E>> {
20+
public class SetProperty<E> extends CollectionProperty<E, Set<E>> {
2121

2222
/**
2323
* Constructor.

src/main/java/ch/jalu/configme/properties/StringSetProperty.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class StringSetProperty extends SetProperty<String> {
1717
* @param path the path of the property
1818
* @param defaultValue the values that make up the entries of the default set
1919
*/
20-
public StringSetProperty(@NotNull String path, @NotNull String @NotNull... defaultValue) {
20+
public StringSetProperty(@NotNull String path, @NotNull String @NotNull ... defaultValue) {
2121
super(path, StringType.STRING, defaultValue);
2222
}
2323

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package ch.jalu.configme.properties;
2+
3+
import ch.jalu.configme.properties.convertresult.PropertyValue;
4+
import ch.jalu.configme.properties.types.CollectionPropertyType;
5+
import ch.jalu.configme.properties.types.NumberType;
6+
import ch.jalu.configme.resource.PropertyReader;
7+
import org.junit.jupiter.api.Test;
8+
import org.junit.jupiter.api.extension.ExtendWith;
9+
import org.mockito.Mock;
10+
import org.mockito.junit.jupiter.MockitoExtension;
11+
12+
import java.util.Arrays;
13+
import java.util.Collections;
14+
import java.util.List;
15+
import java.util.TreeSet;
16+
import java.util.Vector;
17+
import java.util.stream.Collectors;
18+
19+
import static ch.jalu.configme.TestUtils.isErrorValueOf;
20+
import static ch.jalu.configme.TestUtils.isValidValueOf;
21+
import static org.hamcrest.MatcherAssert.assertThat;
22+
import static org.hamcrest.Matchers.contains;
23+
import static org.hamcrest.Matchers.empty;
24+
import static org.hamcrest.Matchers.equalTo;
25+
import static org.hamcrest.Matchers.instanceOf;
26+
import static org.mockito.BDDMockito.given;
27+
28+
/**
29+
* Test for {@link CollectionProperty}.
30+
*/
31+
@ExtendWith(MockitoExtension.class)
32+
class CollectionPropertyTest {
33+
34+
@Mock
35+
private PropertyReader reader;
36+
37+
@Test
38+
void shouldUseGivenPropertyType() {
39+
// given
40+
CollectionPropertyType<Double, TreeSet<Double>> treeSetType =
41+
CollectionPropertyType.of(NumberType.DOUBLE, Collectors.toCollection(TreeSet::new));
42+
Property<TreeSet<Double>> sortedValuesProperty =
43+
new CollectionProperty<>("values", treeSetType, new TreeSet<>());
44+
given(reader.getObject("values")).willReturn(Arrays.asList(16, 9, 4));
45+
46+
// when
47+
PropertyValue<TreeSet<Double>> value = sortedValuesProperty.determineValue(reader);
48+
49+
// then
50+
assertThat(value.isValidInResource(), equalTo(true));
51+
assertThat(value.getValue(), instanceOf(TreeSet.class));
52+
assertThat(value.getValue(), contains(4.0, 9.0, 16.0));
53+
}
54+
55+
@Test
56+
void shouldCreatePropertyWithEntryTypeAndCollector() {
57+
// given
58+
Property<Vector<Double>> valuesProperty = CollectionProperty.of(
59+
"values",
60+
NumberType.DOUBLE,
61+
Collectors.toCollection(Vector::new),
62+
new Vector<>(Arrays.asList(3.0, 4.0)));
63+
given(reader.getObject("values")).willReturn(Arrays.asList(1.0, 2.5, 4.0));
64+
65+
// when
66+
PropertyValue<Vector<Double>> value = valuesProperty.determineValue(reader);
67+
68+
// then
69+
assertThat(valuesProperty.getPath(), equalTo("values"));
70+
assertThat(valuesProperty.getDefaultValue(), instanceOf(Vector.class));
71+
assertThat(valuesProperty.getDefaultValue(), contains(3.0, 4.0));
72+
73+
assertThat(value.isValidInResource(), equalTo(true));
74+
assertThat(value.getValue(), instanceOf(Vector.class));
75+
assertThat(value.getValue(), contains(1.0, 2.5, 4.0));
76+
}
77+
78+
@Test
79+
void shouldCreatePropertyWithEntryTypeAndCollectorAndVarargsDefaultValue() {
80+
// given
81+
Property<List<Long>> property1 = CollectionProperty.of("p1", NumberType.LONG, Collectors.toList());
82+
Property<List<Long>> property2 = CollectionProperty.of("p2", NumberType.LONG, Collectors.toList(), 4L, 6L);
83+
given(reader.getObject("p1")).willReturn("invalid");
84+
given(reader.getObject("p2")).willReturn(Arrays.asList("1", "2"));
85+
86+
// when
87+
PropertyValue<List<Long>> value1 = property1.determineValue(reader);
88+
PropertyValue<List<Long>> value2 = property2.determineValue(reader);
89+
90+
// then
91+
assertThat(property1.getDefaultValue(), empty());
92+
assertThat(property2.getDefaultValue(), contains(4L, 6L));
93+
assertThat(value1, isErrorValueOf(Collections.emptyList())); // default value
94+
assertThat(value2, isValidValueOf(Arrays.asList(1L, 2L)));
95+
}
96+
}

src/test/java/ch/jalu/configme/properties/EnumSetPropertyTest.java

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import org.mockito.junit.jupiter.MockitoExtension;
99

1010
import java.util.EnumSet;
11-
import java.util.Set;
1211

1312
import static ch.jalu.configme.TestUtils.isErrorValueOf;
1413
import static org.hamcrest.MatcherAssert.assertThat;
14+
import static org.hamcrest.Matchers.contains;
1515
import static org.mockito.BDDMockito.given;
1616

1717
/**
@@ -27,13 +27,11 @@ class EnumSetPropertyTest {
2727
void shouldReturnEnumSetDefaultValue() {
2828
// given
2929
EnumSet<TestEnum> set = EnumSet.of(TestEnum.ENTRY_A);
30-
EnumSetProperty<TestEnum> property =
31-
new EnumSetProperty<>("enum.path", TestEnum.class, set);
32-
given(reader.getObject(property.getPath()))
33-
.willReturn(null);
30+
EnumSetProperty<TestEnum> property = new EnumSetProperty<>("enum.path", TestEnum.class, set);
31+
given(reader.getObject(property.getPath())).willReturn(null);
3432

3533
// when
36-
PropertyValue<Set<TestEnum>> result = property.determineValue(reader);
34+
PropertyValue<EnumSet<TestEnum>> result = property.determineValue(reader);
3735

3836
// then
3937
assertThat(result, isErrorValueOf(EnumSet.of(TestEnum.ENTRY_A)));
@@ -43,15 +41,13 @@ void shouldReturnEnumSetDefaultValue() {
4341
void shouldReturnEnumSetDefaultValueFromArray() {
4442
// given
4543
EnumSetProperty<TestEnum> property =
46-
new EnumSetProperty<>("enum.path", TestEnum.class, new TestEnum[]{TestEnum.ENTRY_B, TestEnum.ENTRY_C});
47-
given(reader.getObject(property.getPath()))
48-
.willReturn(null);
44+
new EnumSetProperty<>("enum.path", TestEnum.class, TestEnum.ENTRY_B, TestEnum.ENTRY_C);
4945

5046
// when
51-
PropertyValue<Set<TestEnum>> result = property.determineValue(reader);
47+
EnumSet<TestEnum> defaultValue = property.getDefaultValue();
5248

5349
// then
54-
assertThat(result, isErrorValueOf(EnumSet.of(TestEnum.ENTRY_B, TestEnum.ENTRY_C)));
50+
assertThat(defaultValue, contains(TestEnum.ENTRY_B, TestEnum.ENTRY_C));
5551
}
5652

5753
private enum TestEnum {

src/test/java/ch/jalu/configme/resource/YamlSetPropertyExportTest.java

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import ch.jalu.configme.TestUtils;
44
import ch.jalu.configme.configurationdata.ConfigurationData;
55
import ch.jalu.configme.configurationdata.ConfigurationDataBuilder;
6-
import ch.jalu.configme.properties.BaseProperty;
7-
import ch.jalu.configme.properties.Property;
8-
import ch.jalu.configme.properties.convertresult.ConvertErrorRecorder;
6+
import ch.jalu.configme.properties.EnumSetProperty;
97
import ch.jalu.configme.samples.TestEnum;
108
import org.jetbrains.annotations.NotNull;
119
import org.junit.jupiter.api.BeforeEach;
@@ -15,14 +13,11 @@
1513
import java.io.IOException;
1614
import java.nio.file.Files;
1715
import java.nio.file.Path;
18-
import java.util.Arrays;
19-
import java.util.Collections;
16+
import java.util.EnumSet;
2017
import java.util.LinkedHashSet;
21-
import java.util.List;
2218
import java.util.Set;
2319
import java.util.stream.Collectors;
2420

25-
import static ch.jalu.configme.TestUtils.transform;
2621
import static java.util.Collections.singletonList;
2722
import static org.hamcrest.MatcherAssert.assertThat;
2823
import static org.hamcrest.Matchers.contains;
@@ -48,9 +43,9 @@ void copyConfigFile() {
4843
void shouldLoadAndExportProperly() throws IOException {
4944
// given
5045
PropertyResource resource = new YamlFileResource(configFile);
51-
Property<Set<TestEnum>> setProperty = new EnumSetProperty("sample.ratio.fields", Collections.emptySet());
46+
EnumSetProperty<TestEnum> setProperty = new ExportToSetProperty("sample.ratio.fields");
5247
ConfigurationData configurationData = ConfigurationDataBuilder.createConfiguration(singletonList(setProperty));
53-
configurationData.setValue(setProperty, new LinkedHashSet<>(Arrays.asList(TestEnum.FIRST, TestEnum.SECOND, TestEnum.THIRD)));
48+
configurationData.setValue(setProperty, EnumSet.of(TestEnum.FIRST, TestEnum.SECOND, TestEnum.THIRD));
5449

5550
// when
5651
resource.exportProperties(configurationData);
@@ -68,25 +63,14 @@ void shouldLoadAndExportProperly() throws IOException {
6863
" - THIRD"));
6964
}
7065

71-
private static final class EnumSetProperty extends BaseProperty<Set<TestEnum>> {
66+
private static final class ExportToSetProperty extends EnumSetProperty<TestEnum> {
7267

73-
EnumSetProperty(String path, Set<TestEnum> defaultValue) {
74-
super(path, defaultValue);
68+
ExportToSetProperty(String path) {
69+
super(path, TestEnum.class, EnumSet.noneOf(TestEnum.class));
7570
}
7671

7772
@Override
78-
protected Set<TestEnum> getFromReader(@NotNull PropertyReader reader,
79-
@NotNull ConvertErrorRecorder errorRecorder) {
80-
List<?> list = reader.getList(getPath());
81-
if (list == null) {
82-
return null;
83-
}
84-
return new LinkedHashSet<>(
85-
transform(list, v -> TestEnum.valueOf(v.toString())));
86-
}
87-
88-
@Override
89-
public Set<String> toExportValue(@NotNull Set<TestEnum> value) {
73+
public Set<String> toExportValue(@NotNull EnumSet<TestEnum> value) {
9074
return value.stream()
9175
.map(Enum::name)
9276
.collect(Collectors.toCollection(LinkedHashSet::new));

0 commit comments

Comments
 (0)