diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java index a76d8e48f..149209172 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtility.java @@ -123,14 +123,14 @@ public final class RSQLUtility { * be null * @param database * in use - * + * * @return an specification which can be used with JPA * @throws RSQLParameterUnsupportedFieldException * if a field in the RSQL string is used but not provided by the * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException * if the RSQL syntax is wrong - * + * */ public static & FieldNameProvider, T> Specification parse(final String rsql, final Class fieldNameProvider, final VirtualPropertyReplacer virtualPropertyReplacer, @@ -374,10 +374,9 @@ public final class RSQLUtility { * dot notated field path * @return the Path for a field */ - private Path getFieldPath(final A enumField, final String finalProperty) { return (Path) getFieldPath(root, getSubAttributesFrom(finalProperty), enumField.isMap(), - this::getJoinFieldPath); + this::getJoinFieldPath).orElseThrow(() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null)); } private Path getJoinFieldPath(final Path fieldPath, final String fieldNameSplit) { @@ -398,18 +397,17 @@ public final class RSQLUtility { return fieldPath; } - private static Path getFieldPath(final Root root, final String[] split, final boolean isMapKeyField, - final BiFunction, String, Path> joinFieldPathProvider) { + private static Optional> getFieldPath(final Root root, final String[] split, final boolean isMapKeyField, + final BiFunction, String, Path> joinFieldPathProvider) { Path fieldPath = null; for (int i = 0; i < split.length; i++) { - if (isMapKeyField && i == (split.length - 1)) { - return fieldPath; + if (!(isMapKeyField && i == (split.length - 1))) { + final String fieldNameSplit = split[i]; + fieldPath = (fieldPath != null) ? fieldPath.get(fieldNameSplit) : root.get(fieldNameSplit); + fieldPath = joinFieldPathProvider.apply(fieldPath, fieldNameSplit); } - final String fieldNameSplit = split[i]; - fieldPath = (fieldPath != null) ? fieldPath.get(fieldNameSplit) : root.get(fieldNameSplit); - fieldPath = joinFieldPathProvider.apply(fieldPath, fieldNameSplit); } - return fieldPath; + return Optional.ofNullable(fieldPath); } @Override @@ -800,9 +798,9 @@ public final class RSQLUtility { } private static Path getInnerFieldPath(final Root subqueryRoot, final String[] split, - final boolean isMapKeyField) { + final boolean isMapKeyField) { return getFieldPath(subqueryRoot, split, isMapKeyField, - (fieldPath, fieldNameSplit) -> getInnerJoinFieldPath(subqueryRoot, fieldPath, fieldNameSplit)); + (fieldPath, fieldNameSplit) -> getInnerJoinFieldPath(subqueryRoot, fieldPath, fieldNameSplit)).orElseThrow(() -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null)); } private static Path getInnerJoinFieldPath(final Root subqueryRoot, final Path fieldPath, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java index d9d814eb8..f122db806 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLUtilityTest.java @@ -239,7 +239,9 @@ public class RSQLUtilityTest { when(baseSoftwareModuleRootMock.get(anyString())).thenReturn(baseSoftwareModuleRootMock); when(baseSoftwareModuleRootMock.getJavaType()).thenReturn((Class) SoftwareModule.class); - when(subqueryRootMock.get(anyString())).thenReturn(mock(Path.class)); + final Path pathMock = mock(Path.class); + when(pathMock.get(anyString())).thenReturn(pathMock); + when(subqueryRootMock.get(anyString())).thenReturn(pathMock); when(criteriaBuilderMock.and(any(), any())).thenReturn(mock(Predicate.class));