This is an automated email from the ASF dual-hosted git repository. ahuber pushed a commit to branch 3014-enum_title_not_honored in repository https://gitbox.apache.org/repos/asf/causeway.git
commit ac4377199b138bf2a1882854397270aa693dffd6 Author: andi-huber <[email protected]> AuthorDate: Sat Feb 11 08:48:14 2023 +0100 CAUSEWAY-3014: refactors EnumValueSemanticsAbstract - delegate title concerns to the MMTitleUtil --- .../_testing/MetaModelContext_forTesting.java | 3 +- .../specloader/SpecificationLoaderDefault.java | 2 +- .../valuesemantics/EnumValueSemanticsAbstract.java | 74 +++++++++------------- .../valuetypes/ValueSemanticsResolverDefault.java | 4 ++ .../java/demoapp/dom/_infra/samples/DemoEnum.java | 11 ++-- 5 files changed, 42 insertions(+), 52 deletions(-) diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java index 3d292eb612..fd0030bfcd 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/_testing/MetaModelContext_forTesting.java @@ -314,7 +314,8 @@ implements MetaModelContext { private ValueSemanticsResolver valueSemanticsResolver; private ValueSemanticsResolver getValueSemanticsResolver(){ if(valueSemanticsResolver==null) { - valueSemanticsResolver = new ValueSemanticsResolverDefault(valueSemantics, getTranslationService()); + valueSemanticsResolver = new ValueSemanticsResolverDefault(valueSemantics, + getTranslationService(), this::getSpecificationLoader); } return valueSemanticsResolver; } diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java index 2fb788992f..e40e3c6fde 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/specloader/SpecificationLoaderDefault.java @@ -197,7 +197,7 @@ implements val instance = new SpecificationLoaderDefault( programmingModel, causewayConfiguration, causewaySystemEnvironment, serviceRegistry, causewayBeanTypeClassifier, causewayBeanTypeRegistry, - ()->new ValueSemanticsResolverDefault(List.of(), null), + ()->new ValueSemanticsResolverDefault(List.of(), null, null), classSubstitutorRegistry); instance.metaModelContext = serviceRegistry.lookupServiceElseFail(MetaModelContext.class); diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuesemantics/EnumValueSemanticsAbstract.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuesemantics/EnumValueSemanticsAbstract.java index c6e42afcaf..6b38e7071c 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuesemantics/EnumValueSemanticsAbstract.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuesemantics/EnumValueSemanticsAbstract.java @@ -18,13 +18,14 @@ */ package org.apache.causeway.core.metamodel.valuesemantics; -import java.lang.reflect.Method; +import java.util.Optional; import java.util.function.UnaryOperator; import java.util.stream.Stream; +import javax.inject.Provider; + import org.apache.causeway.applib.annotation.Introspection.IntrospectionPolicy; import org.apache.causeway.applib.exceptions.recoverable.TextEntryParseException; -import org.apache.causeway.applib.services.i18n.TranslatableString; import org.apache.causeway.applib.services.i18n.TranslationContext; import org.apache.causeway.applib.services.i18n.TranslationService; import org.apache.causeway.applib.util.Enums; @@ -37,9 +38,10 @@ import org.apache.causeway.applib.value.semantics.ValueSemanticsProvider; import org.apache.causeway.commons.collections.Can; import org.apache.causeway.commons.internal.base._Strings; import org.apache.causeway.commons.internal.exceptions._Exceptions; -import org.apache.causeway.core.config.progmodel.ProgrammingModelConstants.ObjectSupportMethod; -import org.apache.causeway.core.metamodel.commons.CanonicalInvoker; -import org.apache.causeway.core.metamodel.methods.MethodFinder; +import org.apache.causeway.core.metamodel.object.ManagedObject; +import org.apache.causeway.core.metamodel.object.MmTitleUtil; +import org.apache.causeway.core.metamodel.spec.ObjectSpecification; +import org.apache.causeway.core.metamodel.specloader.SpecificationLoader; import org.apache.causeway.schema.common.v2.EnumDto; import org.apache.causeway.schema.common.v2.ValueType; import org.apache.causeway.schema.common.v2.ValueWithTypeDto; @@ -56,20 +58,30 @@ implements Renderer<T> { private final TranslationService translationService; - private final Method titleMethod; + private final Provider<SpecificationLoader> specificationLoaderProvider; @Getter(onMethod_ = {@Override}) private final Class<T> correspondingClass; @Getter(onMethod_ = {@Override}) @Accessors(fluent = true) private final int maxLength; + @Getter(lazy=true) + private final ObjectSpecification enumSpec = + Optional.ofNullable(specificationLoaderProvider) + .map(provider->provider.get()) + .flatMap(specLoader->specLoader.specForType(correspondingClass)) + .orElse(null); + + @Override public ValueType getSchemaValueType() { return ValueType.ENUM; } public static <T extends Enum<T>> EnumValueSemanticsAbstract<T> create( + final Provider<SpecificationLoader> specificationLoaderProvider, final TranslationService translationService, final IntrospectionPolicy introspectionPolicy, final Class<T> correspondingClass) { return new EnumValueSemanticsAbstract<>( + specificationLoaderProvider, translationService, introspectionPolicy, correspondingClass){}; @@ -78,6 +90,7 @@ implements // -- CONSTRUCTION protected EnumValueSemanticsAbstract( + final Provider<SpecificationLoader> specificationLoaderProvider, final TranslationService translationService, final IntrospectionPolicy introspectionPolicy, final Class<T> correspondingClass) { @@ -86,21 +99,7 @@ implements this.translationService = translationService; this.correspondingClass = correspondingClass; this.maxLength = maxLengthFor(correspondingClass); - - val supportMethodEnum = ObjectSupportMethod.TITLE; - - titleMethod = - - MethodFinder - .objectSupport( - correspondingClass, - supportMethodEnum.getMethodNames(), - introspectionPolicy) - .withReturnTypeAnyOf(supportMethodEnum.getReturnTypeCategory().getReturnTypes()) - .streamMethodsMatchingSignature(MethodFinder.NO_ARG) - .findFirst() - .orElse(null); - + this.specificationLoaderProvider = specificationLoaderProvider; } // -- DEFAULTS PROVIDER @@ -150,31 +149,16 @@ implements return renderHtml(value, v->friendlyName(context, v)); } - private String friendlyName(final Context context, final T object) { - if (titleMethod != null) { - // sadness: same as in TranslationFactory - val translationContext = TranslationContext.forMethod(titleMethod); - - try { - final Object returnValue = CanonicalInvoker.invoke(titleMethod, object); - if(returnValue instanceof String) { - return (String) returnValue; - } - if(returnValue instanceof TranslatableString) { - final TranslatableString ts = (TranslatableString) returnValue; - return ts.translate(translationService, translationContext); - } - return null; - } catch (final RuntimeException ex) { - // fall through - } - } + private String friendlyName(final Context context, final T objectAsEnum) { + + val friendlyNameOfEnum = Optional.ofNullable(this.getEnumSpec()) + .map(enumSpec->ManagedObject.value(enumSpec, objectAsEnum)) + .map(MmTitleUtil::titleOf) + .orElseGet(()->Enums.getFriendlyNameOf(objectAsEnum.name())); - // simply translate the enum constant's name - val objectAsEnum = object; - val translationContext = TranslationContext.forEnum(objectAsEnum); - final String friendlyNameOfEnum = Enums.getFriendlyNameOf(objectAsEnum.name()); - return translationService.translate(translationContext, friendlyNameOfEnum); + return Optional.ofNullable(translationService) + .map(ts->ts.translate(TranslationContext.forEnum(objectAsEnum), friendlyNameOfEnum)) + .orElse(friendlyNameOfEnum); } // -- PARSER diff --git a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/ValueSemanticsResolverDefault.java b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/ValueSemanticsResolverDefault.java index eeca20ae8b..802fb6c9d4 100644 --- a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/ValueSemanticsResolverDefault.java +++ b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/valuetypes/ValueSemanticsResolverDefault.java @@ -24,6 +24,7 @@ import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Named; +import javax.inject.Provider; import org.springframework.stereotype.Service; import org.springframework.util.ClassUtils; @@ -39,6 +40,7 @@ import org.apache.causeway.commons.internal.base._Casts; import org.apache.causeway.commons.internal.base._NullSafe; import org.apache.causeway.commons.internal.collections._Maps; import org.apache.causeway.core.metamodel.CausewayModuleCoreMetamodel; +import org.apache.causeway.core.metamodel.specloader.SpecificationLoader; import org.apache.causeway.core.metamodel.valuesemantics.EnumValueSemanticsAbstract; import lombok.NonNull; @@ -54,6 +56,7 @@ implements ValueSemanticsResolver { // managed by Spring private final List<ValueSemanticsProvider<?>> valueSemanticsProviders; private final TranslationService translationService; + private final Provider<SpecificationLoader> specificationLoaderProvider; @Override public boolean hasValueSemantics(final Class<?> valueType) { @@ -109,6 +112,7 @@ implements ValueSemanticsResolver { return enumSemantics.computeIfAbsent(enumType, t-> EnumValueSemanticsAbstract .create( + null, //specificationLoader.specForType(enumType).orElse(null), translationService, // in order to simplify matters, we just assume this for enums IntrospectionPolicy.ENCAPSULATION_ENABLED, diff --git a/examples/demo/domain/src/main/java/demoapp/dom/_infra/samples/DemoEnum.java b/examples/demo/domain/src/main/java/demoapp/dom/_infra/samples/DemoEnum.java index baaa47ddb2..2594500a15 100644 --- a/examples/demo/domain/src/main/java/demoapp/dom/_infra/samples/DemoEnum.java +++ b/examples/demo/domain/src/main/java/demoapp/dom/_infra/samples/DemoEnum.java @@ -18,8 +18,8 @@ */ package demoapp.dom._infra.samples; -import org.apache.causeway.applib.annotation.Title; -import org.apache.causeway.commons.internal.base._Strings; +import org.apache.causeway.applib.annotation.ObjectSupport; +import org.apache.causeway.applib.util.Enums; import lombok.RequiredArgsConstructor; @@ -32,11 +32,12 @@ public enum DemoEnum { final String symbol; - @Title - public String getTitle() { + //@Title + @ObjectSupport + public String title() { return String.format("%s %s", symbol, - _Strings.asNaturalName2.apply(name())); + Enums.getFriendlyNameOf(name())); } }
