From e8839c66ed8f3a422ba8d60e1000d27965da670a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9da=20Housni=20Alaoui?= Date: Thu, 28 Mar 2024 11:38:27 +0100 Subject: [PATCH] Add an annotation allowing to explicitly declare if an input is editable or not --- .../springframework/hateoas/InputEdition.java | 41 +++++++++++++++++++ .../hateoas/mediatype/PropertyUtils.java | 6 +++ .../hateoas/mediatype/PropertyUtilsTest.java | 11 +++++ 3 files changed, 58 insertions(+) create mode 100644 src/main/java/org/springframework/hateoas/InputEdition.java diff --git a/src/main/java/org/springframework/hateoas/InputEdition.java b/src/main/java/org/springframework/hateoas/InputEdition.java new file mode 100644 index 000000000..e394b384f --- /dev/null +++ b/src/main/java/org/springframework/hateoas/InputEdition.java @@ -0,0 +1,41 @@ +/* + * Copyright 2024 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.hateoas; + +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.*; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * Annotation to explicitly declare if an input is editable or not. + * + * @author RĂ©da Housni Alaoui + * @since 2.3 + */ +@Documented +@Retention(RUNTIME) +@Target({ FIELD, METHOD, ANNOTATION_TYPE }) +public @interface InputEdition { + + Mode value(); + + enum Mode { + READ_ONLY, READ_WRITE + } +} diff --git a/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java b/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java index a6529923d..883f9b9da 100644 --- a/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java +++ b/src/main/java/org/springframework/hateoas/mediatype/PropertyUtils.java @@ -49,6 +49,7 @@ import org.springframework.hateoas.AffordanceModel.PropertyMetadata; import org.springframework.hateoas.CollectionModel; import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.InputEdition; import org.springframework.hateoas.InputType; import org.springframework.http.HttpEntity; import org.springframework.lang.Nullable; @@ -471,6 +472,11 @@ public boolean isRequired() { @Override public boolean isReadOnly() { + MergedAnnotation inputEditionAnnotation = property.getAnnotation(InputEdition.class); + if (inputEditionAnnotation.isPresent()) { + return inputEditionAnnotation.getEnum("value", InputEdition.Mode.class) == InputEdition.Mode.READ_ONLY; + } + if (!property.hasWriteMethod()) { return true; } diff --git a/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java b/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java index c5670fbd9..c36f6167f 100644 --- a/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java +++ b/src/test/java/org/springframework/hateoas/mediatype/PropertyUtilsTest.java @@ -45,6 +45,7 @@ import org.springframework.hateoas.AffordanceModel.PayloadMetadata; import org.springframework.hateoas.AffordanceModel.PropertyMetadata; import org.springframework.hateoas.EntityModel; +import org.springframework.hateoas.InputEdition; import org.springframework.hateoas.InputType; import org.springframework.hateoas.mediatype.html.HtmlInputType; import org.springframework.hateoas.server.core.MethodParameters; @@ -148,6 +149,14 @@ void considersAccessorAvailablility() { assertThat(getProperty(metadata, "readOnly")) // .map(PropertyMetadata::isReadOnly) // .hasValue(true); + + assertThat(getProperty(metadata, "getterWithInputEditionEnabled")) + .map(PropertyMetadata::isReadOnly) + .hasValue(false); + + assertThat(getProperty(metadata, "setterWithInputEditionDisabled")) + .map(PropertyMetadata::isReadOnly) + .hasValue(true); } @Test @@ -294,6 +303,8 @@ static class MethodExposurePayload { @Getter @Setter String readWrite; @Getter String readOnly; + @Getter @InputEdition(InputEdition.Mode.READ_WRITE) String getterWithInputEditionEnabled; + @Getter @Setter @InputEdition(InputEdition.Mode.READ_ONLY) String setterWithInputEditionDisabled; } @RestController