You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by ah...@apache.org on 2023/02/11 07:48:21 UTC

[causeway] branch 3014-enum_title_not_honored created (now ac4377199b)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a change to branch 3014-enum_title_not_honored
in repository https://gitbox.apache.org/repos/asf/causeway.git


      at ac4377199b CAUSEWAY-3014: refactors EnumValueSemanticsAbstract

This branch includes the following new commits:

     new ac4377199b CAUSEWAY-3014: refactors EnumValueSemanticsAbstract

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[causeway] 01/01: CAUSEWAY-3014: refactors EnumValueSemanticsAbstract

Posted by ah...@apache.org.
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 <ah...@apache.org>
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()));
     }
 
 }