This is an automated email from the ASF dual-hosted git repository. danhaywood pushed a commit to branch v2 in repository https://gitbox.apache.org/repos/asf/causeway-app-petclinic.git
commit c9cefd81d3f08385c9c7783d13ae05c85a614ae0 Author: Dan Haywood <[email protected]> AuthorDate: Sat May 25 16:11:33 2024 +0100 Adds EmailAddressValueSemantics ... that defines how to interact with the EmailAddress --- .../petowner/value/EmailAddressValueSemantics.java | 109 +++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/module-petowner/src/main/java/domainapp/modules/petowner/value/EmailAddressValueSemantics.java b/module-petowner/src/main/java/domainapp/modules/petowner/value/EmailAddressValueSemantics.java new file mode 100644 index 0000000..516d72e --- /dev/null +++ b/module-petowner/src/main/java/domainapp/modules/petowner/value/EmailAddressValueSemantics.java @@ -0,0 +1,109 @@ +package domainapp.modules.petowner.value; + +import lombok.NonNull; + +import java.util.regex.Pattern; + +import javax.inject.Named; + +import org.apache.causeway.applib.services.bookmark.IdStringifier; +import org.apache.causeway.applib.value.semantics.DefaultsProvider; +import org.apache.causeway.applib.value.semantics.Parser; +import org.apache.causeway.applib.value.semantics.Renderer; +import org.apache.causeway.applib.value.semantics.ValueDecomposition; +import org.apache.causeway.applib.value.semantics.ValueSemanticsAbstract; +import org.apache.causeway.commons.internal.base._Strings; + +import org.apache.causeway.schema.common.v2.ValueType; +import org.apache.causeway.schema.common.v2.ValueWithTypeDto; + +import org.springframework.stereotype.Component; + +@Named("demo.EmailAddressValueSemantics") +@Component +public class EmailAddressValueSemantics + extends ValueSemanticsAbstract<EmailAddress> { + + @Override + public Class<EmailAddress> getCorrespondingClass() { + return EmailAddress.class; + } + + @Override + public ValueType getSchemaValueType() { + return ValueType.STRING; + } + + @Override + public ValueDecomposition decompose(final EmailAddress value) { + return decomposeAsNullable(value, EmailAddress::getEmailAddress, ()->null); + } + + @Override + public EmailAddress compose(final ValueDecomposition decomposition) { + return composeFromNullable( + decomposition, ValueWithTypeDto::getString, EmailAddress::of, ()->null); + } + + @Override + public DefaultsProvider<EmailAddress> getDefaultsProvider() { + return () -> EmailAddress.of(""); + } + + @Override + public Renderer<EmailAddress> getRenderer() { + return (context, emailAddress) -> emailAddress == null ? null : emailAddress.getEmailAddress(); + } + + @Override + public Parser<EmailAddress> getParser() { + return new Parser<>() { + // https://stackoverflow.com/a/47181151 + final Pattern REGEX = Pattern.compile("^[\\w-\\+]+(\\.[\\w]+)*@[\\w-]+(\\.[\\w]+)*(\\.[a-zA-Z]{2,})$"); + + @Override + public String parseableTextRepresentation(Context context, EmailAddress value) { + return renderTitle(value, EmailAddress::getEmailAddress); + } + + @Override + public EmailAddress parseTextRepresentation(Context context, String text) { + if(!REGEX.matcher(text).matches()) { + throw new RuntimeException("Invalid email format"); + } + if (_Strings.isEmpty(text)) return null; + return EmailAddress.of(text); + } + + @Override + public int typicalLength() { + return 30; + } + + @Override + public int maxLength() { + return 100; + } + }; + } + + @Override + public IdStringifier<EmailAddress> getIdStringifier() { + return new IdStringifier.EntityAgnostic<>() { + @Override + public Class<EmailAddress> getCorrespondingClass() { + return EmailAddressValueSemantics.this.getCorrespondingClass(); + } + + @Override + public String enstring(@NonNull EmailAddress value) { + return _Strings.base64UrlEncode(value.getEmailAddress()); + } + + @Override + public EmailAddress destring(@NonNull String stringified) { + return EmailAddress.of(_Strings.base64UrlDecode(stringified)); + } + }; + } +}
