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:22 UTC
[causeway] 01/01: CAUSEWAY-3014: refactors EnumValueSemanticsAbstract
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()));
}
}