diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java index 7eca3566a..58f1682e4 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java @@ -18,7 +18,7 @@ import java.util.List; * Sort and search fields for actions. */ @Getter -public enum ActionFields implements FieldNameProvider, FieldValueConverter { +public enum ActionFields implements RsqlQueryField, FieldValueConverter { ID("id"), STATUS("active"), @@ -26,29 +26,29 @@ public enum ActionFields implements FieldNameProvider, FieldValueConverter subEntityAttributes; - ActionFields(final String fieldName) { - this.fieldName = fieldName; + ActionFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = Collections.emptyList(); } - ActionFields(final String fieldName, final String... subEntityAttributes) { - this.fieldName = fieldName; + ActionFields(final String jpaEntityFieldName, final String... subEntityAttributes) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = List.of(subEntityAttributes); } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionStatusFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionStatusFields.java index 6f79dbd5b..93dae2849 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionStatusFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionStatusFields.java @@ -15,14 +15,14 @@ import lombok.Getter; * Sort and search fields for action status. */ @Getter -public enum ActionStatusFields implements FieldNameProvider { +public enum ActionStatusFields implements RsqlQueryField { ID("id"), REPORTEDAT("createdAt"); - private final String fieldName; + private final String jpaEntityFieldName; - ActionStatusFields(final String fieldName) { - this.fieldName = fieldName; + ActionStatusFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetFields.java index 54bdf0c8b..00dfc8652 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetFields.java @@ -22,7 +22,7 @@ import java.util.Optional; * REST API e.g. for sorting etc. */ @Getter -public enum DistributionSetFields implements FieldNameProvider { +public enum DistributionSetFields implements RsqlQueryField { ID("id"), TYPE("type.key"), @@ -32,29 +32,29 @@ public enum DistributionSetFields implements FieldNameProvider { LASTMODIFIEDAT("lastModifiedAt"), VERSION("version"), COMPLETE("complete"), - MODULE("modules", SoftwareModuleFields.ID.getFieldName(), SoftwareModuleFields.NAME.getFieldName()), + MODULE("modules", SoftwareModuleFields.ID.getJpaEntityFieldName(), SoftwareModuleFields.NAME.getJpaEntityFieldName()), TAG("tags.name"), METADATA("metadata", new SimpleImmutableEntry<>("key", "value")), VALID("valid"); - private final String fieldName; + private final String jpaEntityFieldName; private final Entry subEntityMapTuple; private final List subEntityAttributes; - DistributionSetFields(final String fieldName) { - this(fieldName, null, Collections.emptyList()); + DistributionSetFields(final String jpaEntityFieldName) { + this(jpaEntityFieldName, null, Collections.emptyList()); } - DistributionSetFields(final String fieldName, final String... subEntityAttributes) { - this(fieldName, null, List.of(subEntityAttributes)); + DistributionSetFields(final String jpaEntityFieldName, final String... subEntityAttributes) { + this(jpaEntityFieldName, null, List.of(subEntityAttributes)); } - DistributionSetFields(final String fieldName, final Entry subEntityMapTuple) { - this(fieldName, subEntityMapTuple, Collections.emptyList()); + DistributionSetFields(final String jpaEntityFieldName, final Entry subEntityMapTuple) { + this(jpaEntityFieldName, subEntityMapTuple, Collections.emptyList()); } - DistributionSetFields(final String fieldName, final Entry subEntityMapTuple, List subEntityAttributes) { - this.fieldName = fieldName; + DistributionSetFields(final String jpaEntityFieldName, final Entry subEntityMapTuple, List subEntityAttributes) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityMapTuple = subEntityMapTuple; this.subEntityAttributes = subEntityAttributes; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataFields.java index 2aca1ae88..d46adb2e2 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetMetadataFields.java @@ -15,19 +15,19 @@ import lombok.Getter; * Sort fields for DistributionSetMetadata. */ @Getter -public enum DistributionSetMetadataFields implements FieldNameProvider { +public enum DistributionSetMetadataFields implements RsqlQueryField { KEY("key"), VALUE("value"); - private final String fieldName; + private final String jpaEntityFieldName; - DistributionSetMetadataFields(final String fieldName) { - this.fieldName = fieldName; + DistributionSetMetadataFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } @Override public String identifierFieldName() { - return KEY.getFieldName(); + return KEY.getJpaEntityFieldName(); } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagFields.java index 2f8286023..c40321666 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTagFields.java @@ -21,25 +21,25 @@ import java.util.List; * filtering over distribution set fields also. */ @Getter -public enum DistributionSetTagFields implements FieldNameProvider { +public enum DistributionSetTagFields implements RsqlQueryField { - ID(TagFields.ID.getFieldName()), - NAME(TagFields.NAME.getFieldName()), - DESCRIPTION(TagFields.DESCRIPTION.getFieldName()), - COLOUR(TagFields.COLOUR.getFieldName()), + ID(TagFields.ID.getJpaEntityFieldName()), + NAME(TagFields.NAME.getJpaEntityFieldName()), + DESCRIPTION(TagFields.DESCRIPTION.getJpaEntityFieldName()), + COLOUR(TagFields.COLOUR.getJpaEntityFieldName()), DISTRIBUTIONSET("assignedToDistributionSet", - DistributionSetFields.ID.getFieldName(), DistributionSetFields.NAME.getFieldName()); + DistributionSetFields.ID.getJpaEntityFieldName(), DistributionSetFields.NAME.getJpaEntityFieldName()); - private final String fieldName; + private final String jpaEntityFieldName; private final List subEntityAttributes; - DistributionSetTagFields(final String fieldName) { - this.fieldName = fieldName; + DistributionSetTagFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = Collections.emptyList(); } - DistributionSetTagFields(final String fieldName, final String... subEntityAttributes) { - this.fieldName = fieldName; + DistributionSetTagFields(final String jpaEntityFieldName, final String... subEntityAttributes) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = List.of(subEntityAttributes); } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeFields.java index c3e5f568a..fdc3daa52 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/DistributionSetTypeFields.java @@ -16,16 +16,16 @@ import lombok.Getter; * the REST API e.g. for sorting etc. */ @Getter -public enum DistributionSetTypeFields implements FieldNameProvider { +public enum DistributionSetTypeFields implements RsqlQueryField { ID("id"), KEY("key"), NAME("name"), DESCRIPTION("description"); - private final String fieldName; + private final String jpaEntityFieldName; - DistributionSetTypeFields(final String fieldName) { - this.fieldName = fieldName; + DistributionSetTypeFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutFields.java index e6ed9ef1f..4c5157e29 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutFields.java @@ -18,26 +18,26 @@ import java.util.List; * Describing the fields of the Rollout model which can be used in the REST API e.g. for sorting etc. */ @Getter -public enum RolloutFields implements FieldNameProvider { +public enum RolloutFields implements RsqlQueryField { ID("id"), NAME("name"), DESCRIPTION("description"), STATUS("status"), - DISTRIBUTIONSET("distributionSet", DistributionSetFields.ID.getFieldName(), - DistributionSetFields.NAME.getFieldName(), DistributionSetFields.VERSION.getFieldName(), - DistributionSetFields.TYPE.getFieldName()); + DISTRIBUTIONSET("distributionSet", DistributionSetFields.ID.getJpaEntityFieldName(), + DistributionSetFields.NAME.getJpaEntityFieldName(), DistributionSetFields.VERSION.getJpaEntityFieldName(), + DistributionSetFields.TYPE.getJpaEntityFieldName()); - private final String fieldName; + private final String jpaEntityFieldName; private final List subEntityAttributes; - RolloutFields(final String fieldName) { - this.fieldName = fieldName; + RolloutFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = Collections.emptyList(); } - RolloutFields(final String fieldName, final String... subEntityAttributes) { - this.fieldName = fieldName; + RolloutFields(final String jpaEntityFieldName, final String... subEntityAttributes) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = List.of(subEntityAttributes); } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupFields.java index 5b433e250..37582557a 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RolloutGroupFields.java @@ -15,15 +15,15 @@ import lombok.Getter; * Describing the fields of the RolloutGroup model which can be used in the REST API e.g. for sorting etc. */ @Getter -public enum RolloutGroupFields implements FieldNameProvider { +public enum RolloutGroupFields implements RsqlQueryField { ID("id"), NAME("name"), DESCRIPTION("description"); - private final String fieldName; + private final String jpaEntityFieldName; - RolloutGroupFields(final String fieldName) { - this.fieldName = fieldName; + RolloutGroupFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RsqlQueryField.java similarity index 88% rename from hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RsqlQueryField.java index 9cdcf4c0b..a454b5e8f 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/RsqlQueryField.java @@ -15,15 +15,13 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Optional; +import jakarta.validation.constraints.NotNull; import org.springframework.util.ObjectUtils; /** - * An interface for declaring the name of the field described in the database - * which is used as string representation of the field, e.g. for sorting the - * fields over REST. + * An RSQL query field interface extended by all the fields that could be used in RSQL queries. */ -@FunctionalInterface -public interface FieldNameProvider { +public interface RsqlQueryField { /** * Separator for the sub attributes @@ -32,10 +30,10 @@ public interface FieldNameProvider { String SUB_ATTRIBUTE_SPLIT_REGEX = "\\" + SUB_ATTRIBUTE_SEPARATOR; /** - * @return the string representation of the underlying persistence field - * name e.g. in case of sorting. Never {@code null}. + * @return the string representation of the underlying persistence field name e.g. in case of sorting. */ - String getFieldName(); + @NotNull + String getJpaEntityFieldName(); /** * Returns the sub attributes @@ -48,7 +46,7 @@ public interface FieldNameProvider { final String[] subAttributes = propertyFieldName.split(SUB_ATTRIBUTE_SPLIT_REGEX, 2); // [0] field name | [1] key name (could miss, e.g. for target attributes) final String mapKeyName = subAttributes.length == 2 ? subAttributes[1] : null; - return ObjectUtils.isEmpty(mapKeyName) ? new String[] { getFieldName() } : new String[] { getFieldName(), mapKeyName }; + return ObjectUtils.isEmpty(mapKeyName) ? new String[] { getJpaEntityFieldName() } : new String[] { getJpaEntityFieldName(), mapKeyName }; } else { return propertyFieldName.split(SUB_ATTRIBUTE_SPLIT_REGEX); } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleFields.java index f119266a3..34c9c5261 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleFields.java @@ -19,7 +19,7 @@ import java.util.Optional; * Describing the fields of the SoftwareModule model which can be used in the REST API e.g. for sorting etc. */ @Getter -public enum SoftwareModuleFields implements FieldNameProvider { +public enum SoftwareModuleFields implements RsqlQueryField { ID("id"), TYPE("type.key"), @@ -28,15 +28,15 @@ public enum SoftwareModuleFields implements FieldNameProvider { VERSION("version"), METADATA("metadata", new SimpleImmutableEntry<>("key", "value")); - private final String fieldName; + private final String jpaEntityFieldName; private Entry subEntityMapTuple; - SoftwareModuleFields(final String fieldName) { - this(fieldName, null); + SoftwareModuleFields(final String jpaEntityFieldName) { + this(jpaEntityFieldName, null); } - SoftwareModuleFields(final String fieldName, final Entry subEntityMapTuple) { - this.fieldName = fieldName; + SoftwareModuleFields(final String jpaEntityFieldName, final Entry subEntityMapTuple) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityMapTuple = subEntityMapTuple; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataFields.java index 85229ce87..89951601e 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleMetadataFields.java @@ -15,20 +15,20 @@ import lombok.Getter; * Sort fields for SoftwareModuleMetadata. */ @Getter -public enum SoftwareModuleMetadataFields implements FieldNameProvider { +public enum SoftwareModuleMetadataFields implements RsqlQueryField { KEY("key"), VALUE("value"), TARGETVISIBLE("targetVisible"); - private final String fieldName; + private final String jpaEntityFieldName; - SoftwareModuleMetadataFields(final String fieldName) { - this.fieldName = fieldName; + SoftwareModuleMetadataFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } @Override public String identifierFieldName() { - return KEY.getFieldName(); + return KEY.getJpaEntityFieldName(); } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java index 699c8c5ae..29852bd1d 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java @@ -15,7 +15,7 @@ import lombok.Getter; * Describing the fields of the SoftwareModuleType model which can be used in the REST API e.g. for sorting etc. */ @Getter -public enum SoftwareModuleTypeFields implements FieldNameProvider { +public enum SoftwareModuleTypeFields implements RsqlQueryField { ID("id"), KEY("key"), @@ -23,9 +23,9 @@ public enum SoftwareModuleTypeFields implements FieldNameProvider { DESCRIPTION("description"), MAXASSIGNMENTS("maxAssignments"); - private final String fieldName; + private final String jpaEntityFieldName; - SoftwareModuleTypeFields(final String fieldName) { - this.fieldName = fieldName; + SoftwareModuleTypeFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TagFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TagFields.java index ec394ba59..028e679a5 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TagFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TagFields.java @@ -15,16 +15,16 @@ import lombok.Getter; * Describing the fields of the Tag model which can be used in the REST API e.g. for sorting etc. */ @Getter -public enum TagFields implements FieldNameProvider { +public enum TagFields implements RsqlQueryField { ID("id"), NAME("name"), DESCRIPTION("description"), COLOUR("colour"); - private final String fieldName; + private final String jpaEntityFieldName; - TagFields(final String fieldName) { - this.fieldName = fieldName; + TagFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java index 23d4966d5..72e36657d 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFields.java @@ -22,7 +22,7 @@ import java.util.Optional; * e.g. for sorting etc. */ @Getter -public enum TargetFields implements FieldNameProvider { +public enum TargetFields implements RsqlQueryField { ID("controllerId"), NAME("name"), @@ -38,26 +38,26 @@ public enum TargetFields implements FieldNameProvider { TAG("tags.name"), LASTCONTROLLERREQUESTAT("lastTargetQuery"), METADATA("metadata", new SimpleImmutableEntry<>("key", "value")), - TARGETTYPE("targetType", TargetTypeFields.KEY.getFieldName(), TargetTypeFields.NAME.getFieldName()); + TARGETTYPE("targetType", TargetTypeFields.KEY.getJpaEntityFieldName(), TargetTypeFields.NAME.getJpaEntityFieldName()); - private final String fieldName; + private final String jpaEntityFieldName; private final List subEntityAttributes; private final Entry subEntityMapTuple; - TargetFields(final String fieldName) { - this(fieldName, Collections.emptyList(), null); + TargetFields(final String jpaEntityFieldName) { + this(jpaEntityFieldName, Collections.emptyList(), null); } - TargetFields(final String fieldName, final String... subEntityAttributes) { - this(fieldName, List.of(subEntityAttributes), null); + TargetFields(final String jpaEntityFieldName, final String... subEntityAttributes) { + this(jpaEntityFieldName, List.of(subEntityAttributes), null); } - TargetFields(final String fieldName, final Entry subEntityMapTuple) { - this(fieldName, Collections.emptyList(), subEntityMapTuple); + TargetFields(final String jpaEntityFieldName, final Entry subEntityMapTuple) { + this(jpaEntityFieldName, Collections.emptyList(), subEntityMapTuple); } - TargetFields(final String fieldName, final List subEntityAttributes, final Entry subEntityMapTuple) { - this.fieldName = fieldName; + TargetFields(final String jpaEntityFieldName, final List subEntityAttributes, final Entry subEntityMapTuple) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = subEntityAttributes; this.subEntityMapTuple = subEntityMapTuple; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryFields.java index c90323bd4..c07d81dab 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetFilterQueryFields.java @@ -18,25 +18,25 @@ import java.util.List; * Describing the fields of the Target model which can be used in the REST API e.g. for sorting etc. */ @Getter -public enum TargetFilterQueryFields implements FieldNameProvider { +public enum TargetFilterQueryFields implements RsqlQueryField { ID("id"), NAME("name"), AUTOASSIGNDISTRIBUTIONSET("autoAssignDistributionSet", "name", "version"); - private final String fieldName; + private final String jpaEntityFieldName; private List subEntityAttributes; - TargetFilterQueryFields(final String fieldName) { - this(fieldName, Collections.emptyList()); + TargetFilterQueryFields(final String jpaEntityFieldName) { + this(jpaEntityFieldName, Collections.emptyList()); } - TargetFilterQueryFields(final String fieldName, final String... subEntityAttribues) { - this(fieldName, List.of(subEntityAttribues)); + TargetFilterQueryFields(final String jpaEntityFieldName, final String... subEntityAttribues) { + this(jpaEntityFieldName, List.of(subEntityAttribues)); } - TargetFilterQueryFields(final String fieldName, final List subEntityAttribues) { - this.fieldName = fieldName; + TargetFilterQueryFields(final String jpaEntityFieldName, final List subEntityAttribues) { + this.jpaEntityFieldName = jpaEntityFieldName; this.subEntityAttributes = subEntityAttribues; } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetMetadataFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetMetadataFields.java index a487ddbcf..f9bb7ae65 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetMetadataFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetMetadataFields.java @@ -15,19 +15,19 @@ import lombok.Getter; * Sort fields for TargetMetadata. */ @Getter -public enum TargetMetadataFields implements FieldNameProvider { +public enum TargetMetadataFields implements RsqlQueryField { KEY("key"), VALUE("value"); - private final String fieldName; + private final String jpaEntityFieldName; - TargetMetadataFields(final String fieldName) { - this.fieldName = fieldName; + TargetMetadataFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } @Override public String identifierFieldName() { - return KEY.getFieldName(); + return KEY.getJpaEntityFieldName(); } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTagFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTagFields.java index 79da07972..efc3887e3 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTagFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTagFields.java @@ -16,16 +16,16 @@ import lombok.Getter; * Additionally, here were added fields for Target in order filtering over target fields also. */ @Getter -public enum TargetTagFields implements FieldNameProvider { +public enum TargetTagFields implements RsqlQueryField { - ID(TagFields.ID.getFieldName()), - NAME(TagFields.NAME.getFieldName()), - DESCRIPTION(TagFields.DESCRIPTION.getFieldName()), - COLOUR(TagFields.COLOUR.getFieldName()); + ID(TagFields.ID.getJpaEntityFieldName()), + NAME(TagFields.NAME.getJpaEntityFieldName()), + DESCRIPTION(TagFields.DESCRIPTION.getJpaEntityFieldName()), + COLOUR(TagFields.COLOUR.getJpaEntityFieldName()); - private final String fieldName; + private final String jpaEntityFieldName; - TargetTagFields(final String fieldName) { - this.fieldName = fieldName; + TargetTagFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTypeFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTypeFields.java index 090486c26..403e9b758 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTypeFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/TargetTypeFields.java @@ -15,16 +15,16 @@ import lombok.Getter; * Describing the fields of the TargetType model which can be used in the REST API */ @Getter -public enum TargetTypeFields implements FieldNameProvider { +public enum TargetTypeFields implements RsqlQueryField { ID("id"), KEY("key"), NAME("name"), DESCRIPTION("description"); - private final String fieldName; + private final String jpaEntityFieldName; - TargetTypeFields(final String fieldName) { - this.fieldName = fieldName; + TargetTypeFields(final String jpaEntityFieldName) { + this.jpaEntityFieldName = jpaEntityFieldName; } } diff --git a/hawkbit-core/src/test/java/org/eclipse/hawkbit/repository/FileNameFieldsTest.java b/hawkbit-core/src/test/java/org/eclipse/hawkbit/repository/FileNameFieldsTest.java index 3c964ed7e..bc48eed88 100644 --- a/hawkbit-core/src/test/java/org/eclipse/hawkbit/repository/FileNameFieldsTest.java +++ b/hawkbit-core/src/test/java/org/eclipse/hawkbit/repository/FileNameFieldsTest.java @@ -27,16 +27,16 @@ public class FileNameFieldsTest { public void repositoryManagementMethodsArePreAuthorizedAnnotated() { final String packageName = getClass().getPackage().getName(); try (final ScanResult scanResult = new ClassGraph().acceptPackages(packageName).scan()) { - final List> matchingClasses = scanResult.getAllClasses() + final List> matchingClasses = scanResult.getAllClasses() .stream() - .filter(classInPackage -> classInPackage.implementsInterface(FieldNameProvider.class)) + .filter(classInPackage -> classInPackage.implementsInterface(RsqlQueryField.class)) .map(ClassInfo::loadClass) - .map(clazz -> (Class) clazz) + .map(clazz -> (Class) clazz) .toList(); assertThat(matchingClasses).isNotEmpty(); matchingClasses.forEach(providerClass -> { assertThat(providerClass.getEnumConstants()).isNotEmpty(); - for (final FieldNameProvider provider : providerClass.getEnumConstants()) { + for (final RsqlQueryField provider : providerClass.getEnumConstants()) { if (provider.isMap() && !provider.getSubEntityAttributes().isEmpty()) { throw new UnsupportedOperationException( "Currently sub-entity attributes for maps are not supported, alternatively you could use the key/value tuple, defined by SimpleImmutableEntry class"); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/RsqlVisitorFactory.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/RsqlVisitorFactory.java index 49958124e..c2d8640f9 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/RsqlVisitorFactory.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/rsql/RsqlVisitorFactory.java @@ -9,7 +9,7 @@ */ package org.eclipse.hawkbit.repository.rsql; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import cz.jirutka.rsql.parser.ast.Node; import cz.jirutka.rsql.parser.ast.RSQLVisitor; @@ -23,16 +23,16 @@ public interface RsqlVisitorFactory { /** * Provides a {@link RSQLVisitor} instance for validating RSQL queries based - * on the given {@link FieldNameProvider}. + * on the given {@link RsqlQueryField}. * * @param - * The type of the {@link FieldNameProvider}. + * The type of the {@link RsqlQueryField}. * @param fieldNameProvider * providing accessing to the relevant field names. * * @return An {@link RSQLVisitor} to validate the {@link Node}s of an RSQL * query. */ - & FieldNameProvider> RSQLVisitor validationRsqlVisitor(Class fieldNameProvider); + & RsqlQueryField> RSQLVisitor validationRsqlVisitor(Class fieldNameProvider); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractRSQLVisitor.java similarity index 55% rename from hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java rename to hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractRSQLVisitor.java index d3c02456b..80c5a5b21 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractFieldNameRSQLVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/AbstractRSQLVisitor.java @@ -15,70 +15,83 @@ import java.util.stream.Collectors; import jakarta.validation.constraints.NotNull; +import lombok.Value; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import cz.jirutka.rsql.parser.ast.ComparisonNode; @Slf4j -public abstract class AbstractFieldNameRSQLVisitor & FieldNameProvider> { +public abstract class AbstractRSQLVisitor & RsqlQueryField> { private final Class fieldNameProvider; - protected AbstractFieldNameRSQLVisitor(final Class fieldNameProvider) { + @Value + public class RsqlField { + + A enumValue; + String[] subAttributes; + + private RsqlField(final A enumValue, final String[] subAttributes) { + this.enumValue = enumValue; + this.subAttributes = subAttributes; + } + } + + protected AbstractRSQLVisitor(final Class fieldNameProvider) { this.fieldNameProvider = fieldNameProvider; } - protected A getFieldEnumByName(final ComparisonNode node) { - final String[] graph = node.getSelector().split(FieldNameProvider.SUB_ATTRIBUTE_SPLIT_REGEX); + protected RsqlField getRsqlField(final ComparisonNode node) { + final String[] graph = node.getSelector().split(RsqlQueryField.SUB_ATTRIBUTE_SPLIT_REGEX); final String enumName = graph.length == 0 ? node.getSelector() : graph[0]; log.debug("get field identifier by name {} of enum type {}", enumName, fieldNameProvider); + try { - return Enum.valueOf(fieldNameProvider, enumName.toUpperCase()); + final A enumValue = Enum.valueOf(fieldNameProvider, enumName.toUpperCase()); + final String[] subAttributes = enumValue.getSubAttributes(node.getSelector()); + + // validate + if (enumValue.isMap()) { + // enum.key + if (subAttributes.length != 2) { + throw new RSQLParameterUnsupportedFieldException( + "The syntax of the given map search parameter field {" + node.getSelector() + "} is wrong. Syntax is: ."); + } + } else { + // sub entity need minimum 1 dot + if (!enumValue.getSubEntityAttributes().isEmpty() && subAttributes.length < 2) { + throw createRSQLParameterUnsupportedException(node, null); + } + } + + // build property and validate sub attributes + final StringBuilder fieldNameBuilder = new StringBuilder(enumValue.getJpaEntityFieldName()); + for (int i = 1; i < subAttributes.length; i++) { + final String propertyField = getFormattedSubEntityAttribute(enumValue, subAttributes[i]); + + if (!enumValue.containsSubEntityAttribute(propertyField)) { + if (i != subAttributes.length - 1 || !enumValue.isMap()) { + throw createRSQLParameterUnsupportedException(node, null); + } // otherwise - the key of map is not in the sub entity attributes + } + + fieldNameBuilder.append(RsqlQueryField.SUB_ATTRIBUTE_SEPARATOR).append(propertyField); + } + + return new RsqlField(enumValue, enumValue.getSubAttributes(fieldNameBuilder.toString())); } catch (final IllegalArgumentException e) { throw createRSQLParameterUnsupportedException(node, e); } } - protected String getAndValidatePropertyFieldName(final A propertyEnum, final ComparisonNode node) { - final String[] subAttributes = propertyEnum.getSubAttributes(node.getSelector()); - - if (propertyEnum.isMap()) { - // enum.key - if (subAttributes.length != 2) { - throw new RSQLParameterUnsupportedFieldException( - "The syntax of the given map search parameter field {" + node.getSelector() + "} is wrong. Syntax is: ."); - } - } else { - // sub entity need minimum 1 dot - if (!propertyEnum.getSubEntityAttributes().isEmpty() && subAttributes.length < 2) { - throw createRSQLParameterUnsupportedException(node, null); - } - } - - final StringBuilder fieldNameBuilder = new StringBuilder(propertyEnum.getFieldName()); - for (int i = 1; i < subAttributes.length; i++) { - final String propertyField = getFormattedSubEntityAttribute(propertyEnum, subAttributes[i]); - - if (!propertyEnum.containsSubEntityAttribute(propertyField)) { - if (i != subAttributes.length - 1 || !propertyEnum.isMap()) { - throw createRSQLParameterUnsupportedException(node, null); - } // otherwise - the key of map is not in the sub entity attributes - } - - fieldNameBuilder.append(FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR).append(propertyField); - } - - return fieldNameBuilder.toString(); - } - /** * @param node current processing node * @param rootException in case there is a cause otherwise {@code null} * @return Exception with prepared message extracted from the comparison node. */ - protected RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException( + private RSQLParameterUnsupportedFieldException createRSQLParameterUnsupportedException( @NotNull final ComparisonNode node, final Exception rootException) { return new RSQLParameterUnsupportedFieldException(String.format( @@ -97,7 +110,7 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName .filter(enumField -> enumField.getSubEntityAttributes().isEmpty()).map(enumField -> { final String enumFieldName = enumField.name().toLowerCase(); if (enumField.isMap()) { - return enumFieldName + FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR + "keyName"; + return enumFieldName + RsqlQueryField.SUB_ATTRIBUTE_SEPARATOR + "keyName"; } else { return enumFieldName; } @@ -107,7 +120,7 @@ public abstract class AbstractFieldNameRSQLVisitor & FieldName .filter(enumField -> !enumField.getSubEntityAttributes().isEmpty()).flatMap(enumField -> { final List subEntity = enumField .getSubEntityAttributes().stream().map(fieldName -> enumField.name().toLowerCase() - + FieldNameProvider.SUB_ATTRIBUTE_SEPARATOR + fieldName) + + RsqlQueryField.SUB_ATTRIBUTE_SEPARATOR + fieldName) .toList(); return subEntity.stream(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/DefaultRsqlVisitorFactory.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/DefaultRsqlVisitorFactory.java index 2b5fe47a2..de78323e5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/DefaultRsqlVisitorFactory.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/DefaultRsqlVisitorFactory.java @@ -9,19 +9,19 @@ */ package org.eclipse.hawkbit.repository.jpa.rsql; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.rsql.RsqlVisitorFactory; import cz.jirutka.rsql.parser.ast.RSQLVisitor; /** * Factory providing {@link RSQLVisitor} instances which validate the nodes - * based on a given {@link FieldNameProvider}. + * based on a given {@link RsqlQueryField}. */ public class DefaultRsqlVisitorFactory implements RsqlVisitorFactory { @Override - public & FieldNameProvider> RSQLVisitor validationRsqlVisitor( + public & RsqlQueryField> RSQLVisitor validationRsqlVisitor( final Class fieldNameProvider) { return new FieldValidationRsqlVisitor<>(fieldNameProvider); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/FieldValidationRsqlVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/FieldValidationRsqlVisitor.java index d5fe39eb6..9aabe5bb5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/FieldValidationRsqlVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/FieldValidationRsqlVisitor.java @@ -9,7 +9,7 @@ */ package org.eclipse.hawkbit.repository.jpa.rsql; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import cz.jirutka.rsql.parser.ast.AndNode; import cz.jirutka.rsql.parser.ast.ComparisonNode; @@ -19,19 +19,19 @@ import cz.jirutka.rsql.parser.ast.RSQLVisitor; /** * {@link RSQLVisitor} implementation which validates the nodes (fields) based - * on a given {@link FieldNameProvider} for a given entity type. + * on a given {@link RsqlQueryField} for a given entity type. * * @param - * The type the {@link FieldNameProvider} refers to. + * The type the {@link RsqlQueryField} refers to. */ -public class FieldValidationRsqlVisitor & FieldNameProvider> extends AbstractFieldNameRSQLVisitor +public class FieldValidationRsqlVisitor & RsqlQueryField> extends AbstractRSQLVisitor implements RSQLVisitor { /** * Constructs the visitor and initializes it. * * @param fieldNameProvider - * The {@link FieldNameProvider} to use for validation. + * The {@link RsqlQueryField} to use for validation. */ public FieldValidationRsqlVisitor(final Class fieldNameProvider) { super(fieldNameProvider); @@ -49,8 +49,8 @@ public class FieldValidationRsqlVisitor & FieldNameProvider> e @Override public Void visit(final ComparisonNode node, final String param) { - final A fieldName = getFieldEnumByName(node); - getAndValidatePropertyFieldName(fieldName, node); + // get AND validates + getRsqlField(node); return null; } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java index 9d5b037c7..66b79814f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitor.java @@ -43,7 +43,7 @@ import cz.jirutka.rsql.parser.ast.OrNode; import cz.jirutka.rsql.parser.ast.RSQLVisitor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.math.NumberUtils; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.FieldValueConverter; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; @@ -66,7 +66,7 @@ import org.springframework.util.ObjectUtils; */ @Deprecated(forRemoval = true) @Slf4j -public class JpaQueryRsqlVisitor & FieldNameProvider, T> extends AbstractFieldNameRSQLVisitor +public class JpaQueryRsqlVisitor & RsqlQueryField, T> extends AbstractRSQLVisitor implements RSQLVisitor, String> { public static final Character LIKE_WILDCARD = '*'; @@ -171,13 +171,12 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten * @param enumField * field from a FieldNameProvider to resolve on the persistence * layer - * @param finalProperty - * dot notated field path + * @param rsqlField RSQL field * @return the Path for a field */ @SuppressWarnings("unchecked") - private Path getFieldPath(final A enumField, final String finalProperty) { - return (Path) getFieldPath(root, enumField.getSubAttributes(finalProperty), enumField.isMap(), + private Path getFieldPath(final A enumField, final RsqlField rsqlField) { + return (Path) getFieldPath(root, rsqlField.getSubAttributes(), enumField.isMap(), this::getJoinFieldPath).orElseThrow( () -> new RSQLParameterUnsupportedFieldException("RSQL field path cannot be empty", null)); } @@ -218,20 +217,19 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten // https://jira.sonarsource.com/browse/SONARJAVA-1478 @SuppressWarnings({ "squid:S2095" }) public List visit(final ComparisonNode node, final String param) { - final A fieldName = getFieldEnumByName(node); - final String finalProperty = getAndValidatePropertyFieldName(fieldName, node); + final RsqlField rsqlField = getRsqlField(node); final List values = node.getArguments(); final List transformedValues = new ArrayList<>(); - final Path fieldPath = getFieldPath(fieldName, finalProperty); + final Path fieldPath = getFieldPath(rsqlField.getEnumValue(), rsqlField); for (final String value : values) { - transformedValues.add(convertValueIfNecessary(node, fieldName, value, fieldPath)); + transformedValues.add(convertValueIfNecessary(node, rsqlField.getEnumValue(), value, fieldPath)); } this.joinsNeeded = this.joinsNeeded || areJoinsNeeded(node); - return mapToPredicate(node, fieldPath, node.getArguments(), transformedValues, fieldName, finalProperty); + return mapToPredicate(node, fieldPath, node.getArguments(), transformedValues, rsqlField); } private static boolean areJoinsNeeded(final ComparisonNode node) { @@ -307,8 +305,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten } private List mapToPredicate(final ComparisonNode node, final Path fieldPath, - final List values, final List transformedValues, final A enumField, - final String finalProperty) { + final List values, final List transformedValues, final RsqlField rsqlField) { String value = values.get(0); // if lookup is available, replace macros ... @@ -316,16 +313,16 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten value = virtualPropertyReplacer.replace(value); } - final Predicate mapPredicate = mapToMapPredicate(node, fieldPath, enumField); + final Predicate mapPredicate = mapToMapPredicate(node, fieldPath, rsqlField.getEnumValue()); - final Predicate valuePredicate = addOperatorPredicate(node, getMapValueFieldPath(enumField, fieldPath), - transformedValues, value, finalProperty, enumField); + final Predicate valuePredicate = addOperatorPredicate(node, getMapValueFieldPath(rsqlField.getEnumValue(), fieldPath), + transformedValues, value, rsqlField); return toSingleList(mapPredicate != null ? cb.and(mapPredicate, valuePredicate) : valuePredicate); } private Predicate addOperatorPredicate(final ComparisonNode node, final Path fieldPath, - final List transformedValues, final String value, final String finalProperty, final A enumField) { + final List transformedValues, final String value, final RsqlField rsqlField) { // only 'equal' and 'notEqual' can handle transformed value like // enums. The JPA API cannot handle object types for greaterThan etc @@ -337,7 +334,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten case "==": return getEqualToPredicate(transformedValue, fieldPath); case "!=": - return getNotEqualToPredicate(transformedValue, fieldPath, finalProperty, enumField); + return getNotEqualToPredicate(transformedValue, fieldPath, rsqlField); case "=gt=": return cb.greaterThan(pathOfString(fieldPath), value); case "=ge=": @@ -349,7 +346,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten case "=in=": return in(pathOfString(fieldPath), transformedValues); case "=out=": - return getOutPredicate(transformedValues, finalProperty, enumField, fieldPath); + return getOutPredicate(transformedValues, rsqlField, fieldPath); default: throw new RSQLParameterSyntaxException( "operator symbol {" + operator + "} is either not supported or not implemented"); @@ -357,18 +354,18 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten } private Predicate getOutPredicate( - final List transformedValues, final String finalProperty, - final A enumField, final Path fieldPath) { - final String[] fieldNames = enumField.getSubAttributes(finalProperty); + final List transformedValues, + final RsqlField rsqlField, final Path fieldPath) { + final String[] fieldNames = rsqlField.getSubAttributes(); - if (isSimpleField(fieldNames, enumField.isMap())) { + if (isSimpleField(fieldNames, rsqlField.getEnumValue().isMap())) { final Path pathOfString = pathOfString(fieldPath); return cb.or(cb.isNull(pathOfString), cb.not(in(pathOfString, transformedValues))); } clearOuterJoinsIfNotNeeded(); - return toNotExistsSubQueryPredicate(fieldNames, enumField, expressionToCompare -> in(expressionToCompare, transformedValues)); + return toNotExistsSubQueryPredicate(fieldNames, rsqlField.getEnumValue(), expressionToCompare -> in(expressionToCompare, transformedValues)); } private Path getMapValueFieldPath(final A enumField, final Path fieldPath) { @@ -422,7 +419,7 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten } private Predicate getNotEqualToPredicate(final Object transformedValue, final Path fieldPath, - final String finalProperty, final A enumField) { + final RsqlField rsqlField) { if (transformedValue == null) { return cb.isNotNull(pathOfString(fieldPath)); @@ -433,9 +430,9 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten return cb.and(cb.isNotNull(pathOfString(fieldPath)), cb.notEqual(pathOfString(fieldPath), "")); } - final String[] fieldNames = enumField.getSubAttributes(finalProperty); + final String[] fieldNames = rsqlField.getSubAttributes(); - if (isSimpleField(fieldNames, enumField.isMap())) { + if (isSimpleField(fieldNames, rsqlField.getEnumValue().isMap())) { if (isPattern(transformedValueStr)) { // a pattern, use like return cb.or(cb.isNull(pathOfString(fieldPath)), notLike(pathOfString(fieldPath), toSQL(transformedValueStr))); } else { @@ -446,9 +443,9 @@ public class JpaQueryRsqlVisitor & FieldNameProvider, T> exten clearOuterJoinsIfNotNeeded(); if (isPattern(transformedValueStr)) { // a pattern, use like - return toNotExistsSubQueryPredicate(fieldNames, enumField, expressionToCompare -> like(expressionToCompare, toSQL(transformedValueStr))); + return toNotExistsSubQueryPredicate(fieldNames, rsqlField.getEnumValue(), expressionToCompare -> like(expressionToCompare, toSQL(transformedValueStr))); } else { - return toNotExistsSubQueryPredicate(fieldNames, enumField, expressionToCompare -> equal(expressionToCompare, transformedValueStr)); + return toNotExistsSubQueryPredicate(fieldNames, rsqlField.getEnumValue(), expressionToCompare -> equal(expressionToCompare, transformedValueStr)); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitorG2.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitorG2.java index 82834f2c0..d6ca46454 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitorG2.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rsql/JpaQueryRsqlVisitorG2.java @@ -39,7 +39,7 @@ import jakarta.persistence.metamodel.SingularAttribute; import jakarta.persistence.metamodel.Type; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.math.NumberUtils; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.FieldValueConverter; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; @@ -57,8 +57,8 @@ import org.springframework.util.ObjectUtils; * @param the entity type referenced by the root */ @Slf4j -public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> - extends AbstractFieldNameRSQLVisitor implements RSQLVisitor, String> { +public class JpaQueryRsqlVisitorG2 & RsqlQueryField, T> + extends AbstractRSQLVisitor implements RSQLVisitor, String> { public static final Character LIKE_WILDCARD = '*'; private static final char ESCAPE_CHAR = '\\'; @@ -110,31 +110,30 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> @Override public List visit(final ComparisonNode node, final String param) { - final A fieldName = getFieldEnumByName(node); - final String finalProperty = getAndValidatePropertyFieldName(fieldName, node); + final RsqlField rsqlField = getRsqlField(node); final List values = node.getArguments(); final List transformedValues = new ArrayList<>(); - final Path fieldPath = getFieldPath(root, fieldName.getSubAttributes(finalProperty), fieldName.isMap()); + final Path fieldPath = getFieldPath(root, rsqlField); for (final String value : values) { - transformedValues.add(convertValueIfNecessary(node, fieldName, fieldPath, value)); + transformedValues.add(convertValueIfNecessary(node, rsqlField.getEnumValue(), fieldPath, value)); } this.joinsNeeded = this.joinsNeeded || areJoinsNeeded(node); - return mapToPredicate(node, fieldName, finalProperty, fieldPath, node.getArguments(), transformedValues); + return mapToPredicate(node, rsqlField, fieldPath, node.getArguments(), transformedValues); } - private List mapToPredicate(final ComparisonNode node, final A enumField, final String finalProperty, + private List mapToPredicate(final ComparisonNode node, final RsqlField rsqlField, final Path fieldPath, final List values, final List transformedValues) { // if lookup is available, replace macros ... final String value = virtualPropertyReplacer == null ? values.get(0) : virtualPropertyReplacer.replace(values.get(0)); - final Predicate mapPredicate = mapToMapPredicate(node, enumField, fieldPath); - final Predicate valuePredicate = addOperatorPredicate(node, enumField, finalProperty, - getValueFieldPath(enumField, fieldPath), transformedValues, value); + final Predicate mapPredicate = mapToMapPredicate(node, rsqlField.getEnumValue(), fieldPath); + final Predicate valuePredicate = addOperatorPredicate(node, rsqlField, + getValueFieldPath(rsqlField.getEnumValue(), fieldPath), transformedValues, value); return Collections.singletonList(mapPredicate != null ? cb.and(mapPredicate, valuePredicate) : valuePredicate); } @@ -165,7 +164,7 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> "SimpleImmutableEntry are allowed. Neither of those could be found!")); return equal(fieldPath.get(keyFieldName), keyValue); } - private Predicate addOperatorPredicate(final ComparisonNode node, final A enumField, final String finalProperty, + private Predicate addOperatorPredicate(final ComparisonNode node, final RsqlField rsqlField, final Path fieldPath, final List transformedValues, final String value) { // only 'equal' and 'notEqual' can handle transformed value like enums. // The JPA API cannot handle object types for greaterThan etc. methods. @@ -173,13 +172,13 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> final String operator = node.getOperator().getSymbol(); return switch (operator) { case "==" -> getEqualToPredicate(fieldPath, transformedValue); - case "!=" -> getNotEqualToPredicate(enumField, finalProperty, fieldPath, transformedValue); + case "!=" -> getNotEqualToPredicate(rsqlField, fieldPath, transformedValue); case "=gt=" -> cb.greaterThan(pathOfString(fieldPath), value); case "=ge=" -> cb.greaterThanOrEqualTo(pathOfString(fieldPath), value); case "=lt=" -> cb.lessThan(pathOfString(fieldPath), value); case "=le=" -> cb.lessThanOrEqualTo(pathOfString(fieldPath), value); case "=in=" -> in(pathOfString(fieldPath), transformedValues); - case "=out=" -> getOutPredicate(enumField, finalProperty, fieldPath, transformedValues); + case "=out=" -> getOutPredicate(rsqlField, fieldPath, transformedValues); default -> throw new RSQLParameterSyntaxException( "Operator symbol {" + operator + "} is either not supported or not implemented"); }; @@ -204,7 +203,7 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> return cb.equal(fieldPath, transformedValue); } - private Predicate getNotEqualToPredicate(final A enumField, final String finalProperty, + private Predicate getNotEqualToPredicate(final RsqlField rsqlField, final Path fieldPath, final Object transformedValue) { if (transformedValue == null) { return cb.isNotNull(fieldPath); @@ -215,9 +214,9 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> return cb.and(cb.isNotNull(fieldPath), cb.notEqual(pathOfString(fieldPath), "")); } - final String[] fieldNames = enumField.getSubAttributes(finalProperty); + final String[] fieldNames = rsqlField.getSubAttributes(); - if (isSimpleField(fieldNames, enumField.isMap())) { + if (isSimpleField(fieldNames, rsqlField.getEnumValue().isMap())) { if (isPattern(transformedValueStr)) { // a pattern, use like return cb.or(cb.isNull(fieldPath), notLike(pathOfString(fieldPath), toSQL(transformedValueStr))); } else { @@ -226,7 +225,7 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> } clearJoinsIfNotNeeded(); - return toNotExistsSubQueryPredicate(enumField, fieldNames, expressionToCompare -> + return toNotExistsSubQueryPredicate(rsqlField, expressionToCompare -> isPattern(transformedValueStr) ? // a pattern, use like like(expressionToCompare, toSQL(transformedValueStr)) : equal(expressionToCompare, transformedValueStr)); @@ -235,23 +234,22 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> return toNullOrNotEqualPredicate(fieldPath, transformedValue); } - private Predicate getOutPredicate(final A enumField, final String finalProperty, final Path fieldPath, + private Predicate getOutPredicate(final RsqlField rsqlField, final Path fieldPath, final List transformedValues) { - final String[] fieldNames = enumField.getSubAttributes(finalProperty); + final String[] subAttributes = rsqlField.getSubAttributes(); - if (isSimpleField(fieldNames, enumField.isMap())) { + if (isSimpleField(subAttributes, rsqlField.getEnumValue().isMap())) { return cb.or(cb.isNull(fieldPath), cb.not(in(pathOfString(fieldPath), transformedValues))); } clearJoinsIfNotNeeded(); - return toNotExistsSubQueryPredicate(enumField, fieldNames, - expressionToCompare -> in(expressionToCompare, transformedValues)); + return toNotExistsSubQueryPredicate(rsqlField, expressionToCompare -> in(expressionToCompare, transformedValues)); } - private Path getFieldPath( - final Root root, final String[] split, final boolean isMapKeyField) { + private Path getFieldPath(final Root root, final RsqlField rsqlField) { + final String[] split = rsqlField.getSubAttributes(); Path fieldPath = null; - for (int i = 0, end = isMapKeyField ? split.length - 1 : split.length; i < end; i++) { + for (int i = 0, end = rsqlField.getEnumValue().isMap() ? split.length - 1 : split.length; i < end; i++) { final String fieldNameSplit = split[i]; fieldPath = fieldPath == null ? getPath(root, fieldNameSplit) : fieldPath.get(fieldNameSplit); } @@ -360,14 +358,14 @@ public class JpaQueryRsqlVisitorG2 & FieldNameProvider, T> } @SuppressWarnings({ "unchecked", "rawtypes" }) - private Predicate toNotExistsSubQueryPredicate(final A enumField, final String[] fieldNames, final Function, Predicate> subQueryPredicateProvider) { + private Predicate toNotExistsSubQueryPredicate(final RsqlField rsqlField, final Function, Predicate> subQueryPredicateProvider) { final Class javaType = root.getJavaType(); final Subquery subquery = query.subquery(javaType); final Root subqueryRoot = subquery.from(javaType); - final Predicate equalPredicate = cb.equal(root.get(enumField.identifierFieldName()), - subqueryRoot.get(enumField.identifierFieldName())); - final Expression expressionToCompare = getExpressionToCompare(enumField, - getFieldPath(subqueryRoot, fieldNames, enumField.isMap())); + final Predicate equalPredicate = cb.equal(root.get(rsqlField.getEnumValue().identifierFieldName()), + subqueryRoot.get(rsqlField.getEnumValue().identifierFieldName())); + final Expression expressionToCompare = getExpressionToCompare(rsqlField.getEnumValue(), + getFieldPath(subqueryRoot, rsqlField)); final Predicate subQueryPredicate = subQueryPredicateProvider.apply(expressionToCompare); subquery.select(subqueryRoot).where(cb.and(equalPredicate, subQueryPredicate)); return cb.not(cb.exists(subquery)); 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 2d8bb6e3b..799d97e3c 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 @@ -22,7 +22,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.text.StrLookup; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.rsql.RsqlConfigHolder; @@ -82,7 +82,7 @@ public final class RSQLUtility { * given RSQL query. * * @param rsql the rsql query to be parsed - * @param fieldNameProvider the enum class type which implements the {@link FieldNameProvider} + * @param fieldNameProvider the enum class type which implements the {@link RsqlQueryField} * @param virtualPropertyReplacer holds the logic how the known macros have to be resolved; may be null * @param database database in use * @@ -91,7 +91,7 @@ public final class RSQLUtility { * given {@code fieldNameProvider} * @throws RSQLParameterSyntaxException if the RSQL syntax is wrong */ - public static & FieldNameProvider, T> Specification buildRsqlSpecification( + public static & RsqlQueryField, T> Specification buildRsqlSpecification( final String rsql, final Class fieldNameProvider, final VirtualPropertyReplacer virtualPropertyReplacer, final Database database) { return new RSQLSpecification<>(rsql, fieldNameProvider, virtualPropertyReplacer, database); @@ -106,7 +106,7 @@ public final class RSQLUtility { * @throws RSQLParserException if RSQL syntax is invalid * @throws RSQLParameterUnsupportedFieldException if RSQL key is not allowed */ - public static & FieldNameProvider> void validateRsqlFor( + public static & RsqlQueryField> void validateRsqlFor( final String rsql, final Class fieldNameProvider) { final RSQLVisitor visitor = RsqlConfigHolder.getInstance().getRsqlVisitorFactory().validationRsqlVisitor(fieldNameProvider); @@ -127,7 +127,7 @@ public final class RSQLUtility { } } - private static final class RSQLSpecification & FieldNameProvider, T> implements Specification { + private static final class RSQLSpecification & RsqlQueryField, T> implements Specification { @Serial private static final long serialVersionUID = 1L; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java index 52c627780..473b1954a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java @@ -1196,7 +1196,7 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { + "from target/controller. Expected behaviour is that in case of OK finished update the target will go to " + "IN_SYNC status and installed DS is set to the assigned DS entry.") void assignDistributionSetAndAddFinishedActionStatus() { - final PageRequest pageRequest = PageRequest.of(0, 100, Direction.ASC, ActionStatusFields.ID.getFieldName()); + final PageRequest pageRequest = PageRequest.of(0, 100, Direction.ASC, ActionStatusFields.ID.getJpaEntityFieldName()); final DeploymentResult deployResWithDsA = prepareComplexRepo("undep-A-T", 2, "dep-A-T", 4, 1, "dsA"); final DeploymentResult deployResWithDsB = prepareComplexRepo("undep-B-T", 3, "dep-B-T", 5, 1, "dsB"); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQL.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQL.java index b81c3fd6b..29855b9ca 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQL.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQL.java @@ -19,7 +19,7 @@ import jakarta.persistence.criteria.CriteriaBuilder; import jakarta.persistence.criteria.CriteriaQuery; import jakarta.persistence.criteria.Predicate; import jakarta.persistence.criteria.Root; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.rsql.RsqlConfigHolder; import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer; import org.eclipse.persistence.config.PersistenceUnitProperties; @@ -39,11 +39,11 @@ public class RSQLToSQL { this.entityManager = entityManager; } - public & FieldNameProvider> String toSQL(final Class domainClass, final Class fieldsClass, final String rsql, final boolean legacyRsqlVisitor) { + public & RsqlQueryField> String toSQL(final Class domainClass, final Class fieldsClass, final String rsql, final boolean legacyRsqlVisitor) { return createDbQuery(domainClass, fieldsClass, rsql, legacyRsqlVisitor).getSQLString(); } - public & FieldNameProvider> DatabaseQuery createDbQuery(final Class domainClass, final Class fieldsClass, final String rsql, final boolean legacyRsqlVisitor) { + public & RsqlQueryField> DatabaseQuery createDbQuery(final Class domainClass, final Class fieldsClass, final String rsql, final boolean legacyRsqlVisitor) { final CriteriaQuery query = createQuery(domainClass, fieldsClass, rsql, legacyRsqlVisitor); final TypedQuery typedQuery = entityManager.createQuery(query); // executes the query - otherwise the SQL string is not generated @@ -52,7 +52,7 @@ public class RSQLToSQL { return typedQuery.unwrap(JpaQuery.class).getDatabaseQuery(); } - private & FieldNameProvider> CriteriaQuery createQuery(final Class domainClass, final Class fieldsClass, final String rsql, final boolean legacyRsqlVisitor) { + private & RsqlQueryField> CriteriaQuery createQuery(final Class domainClass, final Class fieldsClass, final String rsql, final boolean legacyRsqlVisitor) { final CriteriaQuery query = entityManager.getCriteriaBuilder().createQuery(domainClass); final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); return query.where( @@ -65,7 +65,7 @@ public class RSQLToSQL { ); } - private & FieldNameProvider> Predicate toPredicate( + private & RsqlQueryField> Predicate toPredicate( final String rsql, final Class fieldsClass, final VirtualPropertyReplacer virtualPropertyReplacer, final Root root, final CriteriaQuery query, final CriteriaBuilder cb, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQLTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQLTest.java index fe11cb88c..b07f76c72 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQLTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLToSQLTest.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.repository.jpa.rsql; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; @@ -52,7 +52,7 @@ public class RSQLToSQLTest { print(JpaTarget.class, TargetFields.class, "(tag!=TAG1 or tag !=TAG2)"); } - private & FieldNameProvider> void print(final Class domainClass, final Class fieldsClass, final String rsql) { + private & RsqlQueryField> void print(final Class domainClass, final Class fieldsClass, final String rsql) { System.out.println(rsql); System.out.println("\tlegacy:\n" + "\t\t" + rsqlToSQL.toSQL(domainClass, fieldsClass, rsql, true)); 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 c004d89c6..44da7ae64 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 @@ -38,7 +38,7 @@ import jakarta.persistence.metamodel.EntityType; import jakarta.persistence.metamodel.SingularAttribute; import jakarta.persistence.metamodel.Type; import org.eclipse.hawkbit.repository.DistributionSetFields; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.repository.SoftwareModuleFields; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; @@ -554,7 +554,7 @@ public class RSQLUtilityTest { return (Path) path; } - private enum TestFieldEnum implements FieldNameProvider { + private enum TestFieldEnum implements RsqlQueryField { TESTFIELD("testfield"), TESTFIELD_WITH_SUB_ENTITIES("testfieldWithSubEntities", "subentity11", "subentity22"); private final String fieldName; @@ -570,7 +570,7 @@ public class RSQLUtilityTest { } @Override - public String getFieldName() { + public String getJpaEntityFieldName() { return this.fieldName; } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index 1e2005479..e2c63eca9 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -82,7 +82,7 @@ public final class MgmtTargetMapper { .withRel(MgmtRestConstants.TARGET_V1_ATTRIBUTES).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionHistory(response.getControllerId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, - ActionFields.ID.getFieldName() + ":" + SortDirection.DESC, null)) + ActionFields.ID.getJpaEntityFieldName() + ":" + SortDirection.DESC, null)) .withRel(MgmtRestConstants.TARGET_V1_ACTIONS).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getMetadata(response.getControllerId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, @@ -316,7 +316,7 @@ public final class MgmtTargetMapper { result.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionStatusList(controllerId, action.getId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, - ActionStatusFields.ID.getFieldName() + ":" + SortDirection.DESC)) + ActionStatusFields.ID.getJpaEntityFieldName() + ":" + SortDirection.DESC)) .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS).expand()); final Rollout rollout = action.getRollout(); diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java index 862dfa0cb..2809db5cf 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/PagingUtility.java @@ -58,7 +58,7 @@ public final class PagingUtility { static Sort sanitizeTargetSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TargetFields.CONTROLLERID.getFieldName()); + return Sort.by(Direction.ASC, TargetFields.CONTROLLERID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(TargetFields.class, sortParam)); } @@ -66,7 +66,7 @@ public final class PagingUtility { static Sort sanitizeTargetTypeSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TargetTypeFields.ID.getFieldName()); + return Sort.by(Direction.ASC, TargetTypeFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(TargetTypeFields.class, sortParam)); } @@ -74,7 +74,7 @@ public final class PagingUtility { static Sort sanitizeTagSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TagFields.ID.getFieldName()); + return Sort.by(Direction.ASC, TagFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(TagFields.class, sortParam)); } @@ -82,7 +82,7 @@ public final class PagingUtility { static Sort sanitizeTargetFilterQuerySortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, TargetFilterQueryFields.ID.getFieldName()); + return Sort.by(Direction.ASC, TargetFilterQueryFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(TargetFilterQueryFields.class, sortParam)); } @@ -90,7 +90,7 @@ public final class PagingUtility { static Sort sanitizeSoftwareModuleSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, SoftwareModuleFields.ID.getFieldName()); + return Sort.by(Direction.ASC, SoftwareModuleFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(SoftwareModuleFields.class, sortParam)); } @@ -98,7 +98,7 @@ public final class PagingUtility { static Sort sanitizeSoftwareModuleTypeSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, SoftwareModuleTypeFields.ID.getFieldName()); + return Sort.by(Direction.ASC, SoftwareModuleTypeFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(SoftwareModuleTypeFields.class, sortParam)); } @@ -106,7 +106,7 @@ public final class PagingUtility { static Sort sanitizeDistributionSetSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, DistributionSetFields.ID.getFieldName()); + return Sort.by(Direction.ASC, DistributionSetFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(DistributionSetFields.class, sortParam)); } @@ -114,7 +114,7 @@ public final class PagingUtility { static Sort sanitizeDistributionSetTypeSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, DistributionSetTypeFields.ID.getFieldName()); + return Sort.by(Direction.ASC, DistributionSetTypeFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(DistributionSetTypeFields.class, sortParam)); } @@ -123,7 +123,7 @@ public final class PagingUtility { if (sortParam == null) { // default sort is DESC in case of action to match behavior // of management UI (last entry on top) - return Sort.by(Direction.DESC, ActionFields.ID.getFieldName()); + return Sort.by(Direction.DESC, ActionFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(ActionFields.class, sortParam)); } @@ -132,7 +132,7 @@ public final class PagingUtility { if (sortParam == null) { // default sort is DESC in case of action status to match behavior // of management UI (last entry on top) - return Sort.by(Direction.DESC, ActionStatusFields.ID.getFieldName()); + return Sort.by(Direction.DESC, ActionStatusFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(ActionStatusFields.class, sortParam)); } @@ -140,7 +140,7 @@ public final class PagingUtility { static Sort sanitizeDistributionSetMetadataSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, DistributionSetMetadataFields.KEY.getFieldName()); + return Sort.by(Direction.ASC, DistributionSetMetadataFields.KEY.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(DistributionSetMetadataFields.class, sortParam)); } @@ -148,7 +148,7 @@ public final class PagingUtility { static Sort sanitizeSoftwareModuleMetadataSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, SoftwareModuleMetadataFields.KEY.getFieldName()); + return Sort.by(Direction.ASC, SoftwareModuleMetadataFields.KEY.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(SoftwareModuleMetadataFields.class, sortParam)); } @@ -156,7 +156,7 @@ public final class PagingUtility { static Sort sanitizeRolloutSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, RolloutFields.ID.getFieldName()); + return Sort.by(Direction.ASC, RolloutFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(RolloutFields.class, sortParam)); } @@ -164,7 +164,7 @@ public final class PagingUtility { static Sort sanitizeRolloutGroupSortParam(final String sortParam) { if (sortParam == null) { // default - return Sort.by(Direction.ASC, RolloutGroupFields.ID.getFieldName()); + return Sort.by(Direction.ASC, RolloutGroupFields.ID.getJpaEntityFieldName()); } return Sort.by(SortUtility.parse(RolloutGroupFields.class, sortParam)); } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index ea42bfbfa..d36a71c29 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -155,7 +155,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { assertThat(actions).hasSize(2); updateActionStatus(actions.get(0), Status.FINISHED, null, "test"); - final PageRequest pageRequest = PageRequest.of(0, 1000, Direction.ASC, ActionFields.ID.getFieldName()); + final PageRequest pageRequest = PageRequest.of(0, 1000, Direction.ASC, ActionFields.ID.getJpaEntityFieldName()); final Action action = deploymentManagement.findActionsByTarget(knownTargetId, pageRequest).getContent().get(0); final ActionStatus status = deploymentManagement.findActionStatusByAction(PAGE, action.getId()).getContent() diff --git a/hawkbit-rest/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/SortUtility.java b/hawkbit-rest/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/SortUtility.java index f3c2718df..06be0abfd 100644 --- a/hawkbit-rest/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/SortUtility.java +++ b/hawkbit-rest/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/SortUtility.java @@ -13,7 +13,7 @@ import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; -import org.eclipse.hawkbit.repository.FieldNameProvider; +import org.eclipse.hawkbit.repository.RsqlQueryField; import org.eclipse.hawkbit.rest.exception.SortParameterSyntaxErrorException; import org.eclipse.hawkbit.rest.exception.SortParameterUnsupportedDirectionException; import org.eclipse.hawkbit.rest.exception.SortParameterUnsupportedFieldException; @@ -53,11 +53,11 @@ public final class SortUtility { * should be related to. * @param * the type of the enumeration which must be derived from - * {@link FieldNameProvider} + * {@link RsqlQueryField} * @param sortString * the string representation of the query parameters. Might be * {@code null} or an empty string. - * @return a list which holds the {@link FieldNameProvider} and the specific + * @return a list which holds the {@link RsqlQueryField} and the specific * {@link Direction} for them as a tuple. Never {@code null}. In * case of no sorting parameters an empty map will be returned. * @throws SortParameterSyntaxErrorException @@ -67,7 +67,7 @@ public final class SortUtility { * @throws SortParameterUnsupportedDirectionException * if the given direction is not "ASC" or "DESC" */ - public static & FieldNameProvider> List parse(final Class enumType, + public static & RsqlQueryField> List parse(final Class enumType, final String sortString) throws SortParameterSyntaxErrorException { final List parsedSortings = new ArrayList<>(); // scan the sort tuples e.g. field:direction @@ -84,7 +84,7 @@ public final class SortUtility { final T identifier = getAttributeIdentifierByName(enumType, fieldName); final Direction sortDirection = getDirection(sortDirectionStr); - parsedSortings.add(new Order(sortDirection, identifier.getFieldName())); + parsedSortings.add(new Order(sortDirection, identifier.getJpaEntityFieldName())); } else { throw new SortParameterSyntaxErrorException(); } @@ -103,12 +103,12 @@ public final class SortUtility { * the name of the enum * @param * the type of the enumeration which must be derived from - * {@link FieldNameProvider} + * {@link RsqlQueryField} * @return the corresponding enum * @throws SortParameterUnsupportedFieldException * if there is no matching enum for the specified name */ - private static & FieldNameProvider> T getAttributeIdentifierByName(final Class enumType, + private static & RsqlQueryField> T getAttributeIdentifierByName(final Class enumType, final String name) { try { return Enum.valueOf(enumType, name.toUpperCase());