Skip to content

Commit 8ade20b

Browse files
committed
add negative addressing and wrap-around
1 parent 41cc9fa commit 8ade20b

File tree

4 files changed

+58
-15
lines changed

4 files changed

+58
-15
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<modelVersion>4.0.0</modelVersion>
1212
<artifactId>jre-utils</artifactId>
13-
<version>0.3.9</version>
13+
<version>0.3.10</version>
1414
<name>JreUtils</name>
1515
<packaging>jar</packaging>
1616

src/main/java/info/unterrainer/commons/jreutils/FieldParser.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ private <T> T parse(final Object instance, final Class<?> clazz)
4848
if (pathArray.length == 0)
4949
return null;
5050

51-
for (Field field : clazz.getDeclaredFields()) {
51+
for (Field field : clazz.getDeclaredFields())
5252
if (field.isAnnotationPresent(annotation) && field.getName().equals(currentPlain)) {
5353
field.setAccessible(true);
5454
Object fieldInstance = resolveInstanceOf(instance, field);
@@ -57,7 +57,6 @@ private <T> T parse(final Object instance, final Class<?> clazz)
5757
advance();
5858
return parse(fieldInstance, fieldInstance.getClass());
5959
}
60-
}
6160

6261
Class<?> c = clazz.getSuperclass();
6362
while (c != null) {
@@ -69,30 +68,40 @@ private <T> T parse(final Object instance, final Class<?> clazz)
6968
return null;
7069
}
7170

72-
private Object resolveInstanceOf(Object instance, Field field)
71+
private Object resolveInstanceOf(final Object instance, final Field field)
7372
throws IllegalArgumentException, IllegalAccessException {
7473
Object fieldInstance = field.get(instance);
7574
Class<?> currentType = field.getType();
7675
if (currentIndex == null)
77-
return fieldInstance;
76+
currentIndex = 0;
7877

7978
if (List.class.isAssignableFrom(currentType)) {
79+
int size = ((List<?>) fieldInstance).size();
80+
currentIndex = cap(currentIndex, size);
8081
return ((List<?>) fieldInstance).get(currentIndex);
8182
}
8283
if (currentType.isArray()) {
84+
int size = ((Object[]) fieldInstance).length;
85+
currentIndex = cap(currentIndex, size);
8386
return ((Object[]) fieldInstance)[currentIndex];
8487
}
8588
return fieldInstance;
8689
}
8790

88-
private String withoutIndex(String current) {
91+
private int cap(final int index, final int size) {
92+
if (index >= 0)
93+
return index % size;
94+
return index % size + size;
95+
}
96+
97+
private String withoutIndex(final String current) {
8998
int pos = current.indexOf(":");
9099
if (pos == -1)
91100
return current;
92101
return current.substring(0, pos);
93102
}
94103

95-
private Integer index(String current) {
104+
private Integer index(final String current) {
96105
try {
97106
int pos = current.indexOf(":");
98107
if (pos == -1)

src/test/java/info/unterrainer/commons/jreutils/ReflectingTests.java

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ public void TestReadingFields() {
1919
List<String> results = Reflecting.getPathsOf(Test1Class.class, MyType.class, ContainsMyType.class);
2020
assertThat(results).containsAll(List.of("myType", "usedClass.myType"));
2121
}
22-
22+
2323
@Test
2424
public void TestReadingFieldsContainsFieldsInArrays() {
2525
List<String> results = Reflecting.getPathsOf(Test1Class.class, MyType.class, ContainsMyType.class);
2626
assertThat(results).containsAll(List.of("myTypeArray", "usedClassArray.myType"));
2727
}
28-
28+
2929
@Test
3030
public void TestReadingFieldsContainsFieldsInGenericLists() {
3131
List<String> results = Reflecting.getPathsOf(Test1Class.class, MyType.class, ContainsMyType.class);
@@ -52,7 +52,7 @@ public void TestWritingOfFieldInArray() throws IllegalArgumentException, Illegal
5252
assertThat(tc.getMyTypeArray()[1].getName()).isNull();
5353
assertThat(tc.getMyTypeArray()[3].getName()).isEqualTo("gluppy");
5454
}
55-
55+
5656
@Test
5757
public void TestWritingOfFieldInList() throws IllegalArgumentException, IllegalAccessException {
5858
Test1Class tc = new Test1Class();
@@ -64,7 +64,7 @@ public void TestWritingOfFieldInList() throws IllegalArgumentException, IllegalA
6464
assertThat(tc.getMyTypeList().get(1).getName()).isNull();
6565
assertThat(tc.getMyTypeList().get(3).getName()).isEqualTo("gluppy");
6666
}
67-
67+
6868
@Test
6969
public void TestWritingOfFieldInUsedClassInArray() throws IllegalArgumentException, IllegalAccessException {
7070
Test1Class tc = new Test1Class();
@@ -76,7 +76,7 @@ public void TestWritingOfFieldInUsedClassInArray() throws IllegalArgumentExcepti
7676
assertThat(tc.getUsedClassArray()[1].getMyType().getName()).isNull();
7777
assertThat(tc.getUsedClassArray()[2].getMyType().getName()).isEqualTo("gluppy");
7878
}
79-
79+
8080
@Test
8181
public void TestWritingOfFieldInUsedClassInList() throws IllegalArgumentException, IllegalAccessException {
8282
Test1Class tc = new Test1Class();
@@ -88,7 +88,40 @@ public void TestWritingOfFieldInUsedClassInList() throws IllegalArgumentExceptio
8888
assertThat(tc.getUsedClassList().get(1).getMyType().getName()).isNull();
8989
assertThat(tc.getUsedClassList().get(2).getMyType().getName()).isEqualTo("gluppy");
9090
}
91-
91+
92+
@Test
93+
public void TestIndexOfListEmptyReturnsFirstEntry() throws IllegalArgumentException, IllegalAccessException {
94+
Test1Class tc = new Test1Class();
95+
MyType mt = Reflecting.getFieldByPath("usedClassList.myType", tc, ContainsMyType.class);
96+
mt.setName("blubb");
97+
assertThat(tc.getUsedClassList().get(0).getMyType().getName()).isEqualTo("blubb");
98+
}
99+
100+
@Test
101+
public void TestIndexOfListOverflowJustStartsFromBeginning()
102+
throws IllegalArgumentException, IllegalAccessException {
103+
Test1Class tc = new Test1Class();
104+
MyType mt = Reflecting.getFieldByPath("usedClassList:3.myType", tc, ContainsMyType.class);
105+
mt.setName("blubb");
106+
assertThat(tc.getUsedClassList().get(0).getMyType().getName()).isEqualTo("blubb");
107+
}
108+
109+
@Test
110+
public void TestIndexOfListUnderflowJustStartsFromTheEnd() throws IllegalArgumentException, IllegalAccessException {
111+
Test1Class tc = new Test1Class();
112+
MyType mt = Reflecting.getFieldByPath("usedClassList:-1.myType", tc, ContainsMyType.class);
113+
mt.setName("blubb");
114+
assertThat(tc.getUsedClassList().get(2).getMyType().getName()).isEqualTo("blubb");
115+
}
116+
117+
@Test
118+
public void TestIndexOfListNegativeOverflowWrapsAsWell() throws IllegalArgumentException, IllegalAccessException {
119+
Test1Class tc = new Test1Class();
120+
MyType mt = Reflecting.getFieldByPath("usedClassList:-4.myType", tc, ContainsMyType.class);
121+
mt.setName("blubb");
122+
assertThat(tc.getUsedClassList().get(2).getMyType().getName()).isEqualTo("blubb");
123+
}
124+
92125
@Test
93126
public void TestWritingOfFieldInUsedClass() throws IllegalArgumentException, IllegalAccessException {
94127
Test1Class tc = new Test1Class();

src/test/java/info/unterrainer/commons/jreutils/dtos/Test1Class.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ public class Test1Class {
2121
private String className;
2222
@ContainsMyType
2323
private List<Test1OtherClass> usedClassList = List.of(new Test1OtherClass(), new Test1OtherClass(),
24-
new Test1OtherClass(), new Test1OtherClass());
24+
new Test1OtherClass());
2525
@ContainsMyType
2626
private Test1OtherClass[] usedClassArray = List
27-
.of(new Test1OtherClass(), new Test1OtherClass(), new Test1OtherClass()).toArray(new Test1OtherClass[0]);
27+
.of(new Test1OtherClass(), new Test1OtherClass(), new Test1OtherClass())
28+
.toArray(new Test1OtherClass[0]);
2829
@ContainsMyType
2930
private Test1OtherClass usedClass = new Test1OtherClass();
3031
}

0 commit comments

Comments
 (0)