You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2022/04/07 14:44:59 UTC
[isis] branch master updated: ISIS-2994: make ValueFacet a first class citizen in ObjectSpecification
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/master by this push:
new da29590512 ISIS-2994: make ValueFacet a first class citizen in ObjectSpecification
da29590512 is described below
commit da295905128702d2e55d193e0e742018be3636ac
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Apr 7 16:44:51 2022 +0200
ISIS-2994: make ValueFacet a first class citizen in ObjectSpecification
- provides consistent ObjectSpecification.isValue()
---
.../isis/core/metamodel/facetapi/FacetHolder.java | 24 ----------------
...ionOrAnyMatchingValueSemanticsFacetFactory.java | 21 ++++++++++++--
.../interactions/managed/ActionInteraction.java | 4 +--
.../interactions/managed/_BindingUtil.java | 9 +++---
.../identify/ObjectBookmarker_builtinHandlers.java | 5 ++--
.../isis/core/metamodel/spec/ManagedObject.java | 3 +-
.../core/metamodel/spec/ObjectSpecification.java | 26 ++++--------------
.../metamodel/spec/feature/ObjectAssociation.java | 5 ++--
.../specimpl/dflt/ObjectSpecificationDefault.java | 29 +++++++++++++++++---
.../apache/isis/core/metamodel/util/Facets.java | 32 ++++++++++++----------
.../core/metamodel/util/snapshot/XmlSnapshot.java | 5 ++--
.../testspec/ObjectSpecificationStub.java | 6 ++++
.../domainobjects/ObjectAndActionInvocation.java | 2 +-
.../domainobjects/ObjectPropertyReprRenderer.java | 2 +-
.../domainobjects/ScalarValueReprRenderer.java | 3 +-
.../JsonValueEncoderTest_asAdapter.java | 8 ++++++
.../converter/ConverterBasedOnValueSemantics.java | 4 +--
.../entity/EntityComponentFactoryAbstract.java | 10 ++-----
.../scalars/image/JavaAwtImagePanelFactory.java | 14 ++++++----
.../components/scalars/image/WicketImageUtil.java | 5 ++--
.../value/fallback/ValueFallbackPanelFactory.java | 7 +++--
21 files changed, 116 insertions(+), 108 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java
index b0c24f3c96..fdf625b0ef 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolder.java
@@ -23,10 +23,7 @@ import java.util.function.Predicate;
import java.util.stream.Stream;
import org.apache.isis.applib.Identifier;
-import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
-import org.apache.isis.commons.collections.Can;
import org.apache.isis.core.metamodel.context.HasMetaModelContext;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import lombok.NonNull;
import lombok.val;
@@ -68,27 +65,6 @@ public interface FacetHolder extends HasMetaModelContext {
return lookupFacet(facetType, facet->!facet.getPrecedence().isFallback());
}
- // -- VALUE SEMANTICS LOOKUP
-
- //TODO support qualified selection honoring (@Qualifier) ... all the logic is in ValueFacet
- default boolean hasValueSemantics(
- final @NonNull Class<?> requiredType) {
- return lookupFacet(ValueFacet.class).stream()
- .map(ValueFacet::getAllValueSemantics)
- .flatMap(Can<ValueSemanticsProvider<?>>::stream)
- .anyMatch(valueSemantics->requiredType.isAssignableFrom(valueSemantics.getClass()));
- }
-
- //TODO support qualified selection honoring (@Qualifier) ... all the logic is in ValueFacet
- default <T> Stream<T> streamValueSemantics(
- final @NonNull Class<T> requiredType) {
- return lookupFacet(ValueFacet.class).stream()
- .map(ValueFacet::getAllValueSemantics)
- .flatMap(Can<ValueSemanticsProvider<?>>::stream)
- .filter(valueSemantics->requiredType.isAssignableFrom(valueSemantics.getClass()))
- .map(requiredType::cast);
- }
-
// -- CONTAINS
/**
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/annotcfg/ValueFacetForValueAnnotationOrAnyMatchingValueSemanticsFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/annotcfg/ValueFacetForValueAnnotationOrAnyMatchingValueSemanticsFacetFactory.java
index 8bd3d4fe27..e54a230f80 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/annotcfg/ValueFacetForValueAnnotationOrAnyMatchingValueSemanticsFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/value/annotcfg/ValueFacetForValueAnnotationOrAnyMatchingValueSemanticsFacetFactory.java
@@ -25,6 +25,7 @@ import org.apache.isis.applib.annotation.Value;
import org.apache.isis.applib.id.LogicalType;
import org.apache.isis.applib.value.semantics.ValueSemanticsProvider;
import org.apache.isis.applib.value.semantics.ValueSemanticsResolver;
+import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
@@ -39,8 +40,10 @@ import org.apache.isis.core.metamodel.facets.object.title.parser.TitleFacetFromV
import org.apache.isis.core.metamodel.facets.object.value.ImmutableFacetViaValueSemantics;
import org.apache.isis.core.metamodel.facets.object.value.MaxLengthFacetFromValueFacet;
import org.apache.isis.core.metamodel.facets.object.value.TypicalLengthFacetFromValueFacet;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.facets.object.value.vsp.ValueFacetUsingSemanticsProvider;
import org.apache.isis.core.metamodel.facets.value.annotation.LogicalTypeFacetForValueAnnotation;
+import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
import lombok.AccessLevel;
import lombok.Getter;
@@ -94,12 +97,14 @@ extends FacetFactoryAbstract {
val identifier = Identifier.classIdentifier(logicalType);
- addAllFacetsForValueSemantics(identifier, valueClass, facetHolder, valueIfAny);
+ val valueFacetIfAny = addAllFacetsForValueSemantics(identifier, valueClass, facetHolder, valueIfAny);
+
+ emitValueFacetProcessed(facetHolder, _Casts.uncheckedCast(valueFacetIfAny));
}
// -- HELPER
- private <T> void addAllFacetsForValueSemantics(
+ private <T> Optional<ValueFacet<T>> addAllFacetsForValueSemantics(
final Identifier identifier,
final Class<T> valueClass,
final FacetHolder holder,
@@ -112,7 +117,8 @@ extends FacetFactoryAbstract {
+ "the type was found to be annotated with @Value", valueClass);
// fall through, so gets a ValueFacet
} else {
- return;
+ // don't install a ValueFacet
+ return Optional.empty();
}
} else {
log.debug("found {} ValueSemanticsProvider(s) for value type {}", semanticsProviders.size(), valueClass);
@@ -128,6 +134,15 @@ extends FacetFactoryAbstract {
addFacetIfPresent(MaxLengthFacetFromValueFacet.create(valueFacet, holder));
addFacetIfPresent(DefaultedFacetFromValueFacet.create(valueFacet, holder));
+ return Optional.of(valueFacet);
+ }
+
+ // optimization
+ private void emitValueFacetProcessed(
+ final FacetHolder holder,
+ final Optional<ValueFacet> valueFacetIfAny) {
+ _Casts.castTo(ObjectSpecificationDefault.class, holder)
+ .ifPresent(receiver->receiver.onValueFacetProcessed(valueFacetIfAny));
}
// -- DEPENDENCIES
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
index 750c55d0d8..2d3a25bd78 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/ActionInteraction.java
@@ -203,7 +203,7 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
val elementType = prop.getElementType();
val valueFacet = elementType.isValue()
- ? (ValueFacet<?>) elementType.getFacet(ValueFacet.class)
+ ? (ValueFacet<?>) elementType.valueFacet().orElse(null)
: null;
if(valueFacet!=null
@@ -242,7 +242,7 @@ extends MemberInteraction<ManagedAction, ActionInteraction> {
val elementType = param.getMetaModel().getElementType();
val valueFacet = elementType.isValue()
- ? (ValueFacet<?>) elementType.getFacet(ValueFacet.class)
+ ? (ValueFacet<?>) elementType.valueFacet().orElse(null)
: null;
if(valueFacet!=null
&& valueFacet.isCompositeValueType()
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
index 2fd24dcf5d..3a983255b4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/interactions/managed/_BindingUtil.java
@@ -27,7 +27,6 @@ import org.apache.isis.commons.internal.binding._BindableAbstract;
import org.apache.isis.commons.internal.binding._Bindables;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.facetapi.FeatureType;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ManagedObjects;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -63,7 +62,7 @@ class _BindingUtil {
val spec = prop.getElementType();
// value types should have associated parsers/formatters via value semantics
- return spec.lookupFacet(ValueFacet.class)
+ return spec.valueFacet()
.map(valueFacet->{
val eitherRendererOrParser = format.requiresRenderer()
? Either.<Renderer, Parser>left(valueFacet.selectRendererForPropertyElseFallback(prop))
@@ -92,7 +91,7 @@ class _BindingUtil {
val spec = param.getElementType();
// value types should have associated parsers/formatters via value semantics
- return spec.lookupFacet(ValueFacet.class)
+ return spec.valueFacet()
.map(valueFacet->{
val eitherRendererOrParser = format.requiresRenderer()
? Either.<Renderer, Parser>left(valueFacet.selectRendererForParameterElseFallback(param))
@@ -114,7 +113,7 @@ class _BindingUtil {
boolean hasParser(final @NonNull OneToOneAssociation prop) {
return prop.getElementType()
- .lookupFacet(ValueFacet.class)
+ .valueFacet()
.map(valueFacet->valueFacet.selectRendererForProperty(prop).isPresent())
.orElse(false);
}
@@ -123,7 +122,7 @@ class _BindingUtil {
return isNonScalarParam(param)
? false
: param.getElementType()
- .lookupFacet(ValueFacet.class)
+ .valueFacet()
.map(valueFacet->valueFacet.selectRendererForParameter(param).isPresent())
.orElse(false);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
index d6d2a01382..7236fb567f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/objectmanager/identify/ObjectBookmarker_builtinHandlers.java
@@ -30,7 +30,6 @@ import org.apache.isis.commons.internal.debug._Debug;
import org.apache.isis.commons.internal.debug.xray.XrayUi;
import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.objectmanager.identify.ObjectBookmarker.Handler;
import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -133,7 +132,7 @@ class ObjectBookmarker_builtinHandlers {
@Override
public boolean isHandling(final ManagedObject managedObject) {
- return managedObject.getSpecification().containsFacet(ValueFacet.class);
+ return managedObject.getSpecification().isValue();
}
@SneakyThrows
@@ -145,7 +144,7 @@ class ObjectBookmarker_builtinHandlers {
return Bookmark.forLogicalTypeAndIdentifier(spec.getLogicalType(), "{}");
}
- val valueFacet = spec.getFacet(ValueFacet.class);
+ val valueFacet = spec.valueFacet().orElse(null);
ValueSemanticsProvider<Object> composer = (ValueSemanticsProvider) valueFacet.selectDefaultSemantics()
.orElseThrow(()->_Exceptions.illegalArgument(
"Cannot create a bookmark for the value type %s, "
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
index a4e34f2443..d57199aa03 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ManagedObject.java
@@ -35,7 +35,6 @@ import org.apache.isis.commons.internal.exceptions._Exceptions;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.objectmanager.ObjectManager;
import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
@@ -157,7 +156,7 @@ public interface ManagedObject {
}
val spec = getSpecification();
- val valueFacet = spec.getFacet(ValueFacet.class);
+ val valueFacet = spec.valueFacet().orElse(null);
if(valueFacet==null) {
return String.format("missing ValueFacet %s", spec.getCorrespondingClass());
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
index 13b501de40..109cccd6dd 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/ObjectSpecification.java
@@ -32,7 +32,6 @@ import org.springframework.lang.Nullable;
import org.apache.isis.applib.exceptions.UnrecoverableException;
import org.apache.isis.applib.id.HasLogicalType;
import org.apache.isis.applib.services.metamodel.BeanSort;
-import org.apache.isis.applib.value.semantics.Parser;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Streams;
import org.apache.isis.commons.internal.exceptions._Exceptions;
@@ -59,7 +58,6 @@ import org.apache.isis.core.metamodel.facets.object.parented.ParentedCollectionF
import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacetAbstract;
import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
import org.apache.isis.core.metamodel.interactions.InteractionContext;
import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
@@ -69,7 +67,6 @@ import org.apache.isis.core.metamodel.objectmanager.create.ObjectCreator;
import org.apache.isis.core.metamodel.spec.feature.MixedIn;
import org.apache.isis.core.metamodel.spec.feature.ObjectActionContainer;
import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationContainer;
-import org.apache.isis.core.metamodel.spec.feature.ObjectFeature;
import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
import org.apache.isis.core.metamodel.specloader.specimpl.MixedInMember;
@@ -353,7 +350,7 @@ extends
*/
default boolean isValue() {
return getBeanSort().isValue()
- || containsFacet(ValueFacet.class);
+ || valueFacet().isPresent();
}
/**
@@ -560,7 +557,7 @@ extends
}
default String fqcn() {
- return getCorrespondingClass().getName();
+ return getCorrespondingClass().getName();
}
default Stream<ObjectSpecification> streamTypeHierarchy() {
@@ -571,21 +568,8 @@ extends
// -- VALUE SEMANTICS SUPPORT
- @SuppressWarnings("unchecked")
- default Optional<Parser<?>> selectParser(final ObjectFeature objFeature) {
- return lookupFacet(ValueFacet.class)
- .flatMap(valueFacet->valueFacet.selectParserForFeature(objFeature));
- }
-
- default Parser<?> selectParserElseFallback(final ObjectFeature objFeature) {
- return lookupFacet(ValueFacet.class)
- .map(valueFacet->
- valueFacet.selectParserForFeatureElseFallback(objFeature))
- .orElseGet(()->ValueFacetAbstract.fallbackParser(
- getLogicalType(),
- objFeature.getFeatureIdentifier()));
- }
-
-
+ /** introduced for lookup optimization / allow memoization */
+ @SuppressWarnings("rawtypes")
+ Optional<ValueFacet> valueFacet();
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
index fb1603f672..4d94e0e04f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAssociation.java
@@ -34,7 +34,6 @@ import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.facets.WhereValueFacet;
import org.apache.isis.core.metamodel.facets.all.hide.HiddenFacet;
import org.apache.isis.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderComparator;
import org.apache.isis.core.metamodel.spec.ManagedObject;
@@ -132,8 +131,8 @@ public interface ObjectAssociation extends ObjectMember, CurrentHolder {
assoc -> assoc.isOneToOneAssociation();
public static final Predicate<ObjectAssociation> REFERENCE_PROPERTIES =
- assoc -> assoc.isOneToOneAssociation() &&
- !assoc.getElementType().containsNonFallbackFacet(ValueFacet.class);
+ assoc -> assoc.isOneToOneAssociation()
+ && !assoc.getElementType().isValue();
public static final Predicate<ObjectAssociation> COLLECTIONS =
assoc -> assoc.isOneToManyAssociation();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
index a24f3842b8..dff41e973d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/dflt/ObjectSpecificationDefault.java
@@ -141,7 +141,7 @@ implements FacetHolder {
addNamedFacetIfRequired();
// go no further if a value
- if(this.containsFacet(ValueFacet.class)) {
+ if(this.isValue()) {
if (log.isDebugEnabled()) {
log.debug("skipping type hierarchy introspection for value type {}", getFullIdentifier());
}
@@ -180,7 +180,7 @@ implements FacetHolder {
@Override
protected void introspectMembers() {
- if(this.containsFacet(ValueFacet.class)) {
+ if(this.isValue()) {
if (log.isDebugEnabled()) {
log.debug("skipping full introspection for value type {}", getFullIdentifier());
}
@@ -354,7 +354,8 @@ implements FacetHolder {
// -- ELEMENT SPECIFICATION
- private final _Lazy<Optional<ObjectSpecification>> elementSpecification = _Lazy.of(this::lookupElementSpecification);
+ private final _Lazy<Optional<ObjectSpecification>> elementSpecification =
+ _Lazy.of(this::lookupElementSpecification);
@Override
public Optional<ObjectSpecification> getElementSpecification() {
@@ -362,7 +363,7 @@ implements FacetHolder {
}
private Optional<ObjectSpecification> lookupElementSpecification() {
- return Optional.ofNullable(getFacet(TypeOfFacet.class))
+ return lookupFacet(TypeOfFacet.class)
.map(typeOfFacet -> ElementSpecificationProvider.of(typeOfFacet).getElementType());
}
@@ -377,5 +378,25 @@ implements FacetHolder {
.streamPropertiesForColumnRendering(this, memberIdentifier, parentObject);
}
+ // -- VALUE FACET OPTIMIZATION (MEMOIZATION)
+
+ // not thread-safe, but seems ok for caching
+ @SuppressWarnings("rawtypes")
+ private Optional<ValueFacet> valueFacetMemoized = null;
+
+ @SuppressWarnings("rawtypes")
+ public void onValueFacetProcessed(final Optional<ValueFacet> valueFacetIfAny) {
+ valueFacetMemoized = valueFacetIfAny;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public Optional<ValueFacet> valueFacet() {
+ return valueFacetMemoized != null
+ ? valueFacetMemoized
+ : lookupFacet(ValueFacet.class);
+ }
+
+ // --
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java
index 752ae0ef2b..a21a6c9a3f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/Facets.java
@@ -330,13 +330,9 @@ public final class Facets {
// -- VALUE FACET
- public boolean valueIsPresent(final ObjectSpecification objectSpec) {
- return objectSpec.containsFacet(ValueFacet.class);
- }
-
public static Predicate<ObjectSpecification> valueTypeMatches(final Predicate<Class<?>> typeMatcher) {
return spec->
- spec.lookupFacet(ValueFacet.class)
+ spec.valueFacet()
.map(ValueFacet::getLogicalType)
.map(LogicalType::getCorrespondingClass)
.map(typeMatcher::test)
@@ -349,8 +345,7 @@ public final class Facets {
final ParameterNegotiationModel parameterNegotiationModel,
final int paramIndex) {
val objectSpec = param.getElementType();
- //if(!objectSpec.isValue()) return Optional.empty(); // optimization
- return objectSpec.lookupFacet(ValueFacet.class)
+ return objectSpec.valueFacet()
.<ObjectAction>flatMap(valueFacet->
valueFacet.selectCompositeValueMixinForParameter(
parameterNegotiationModel,paramIndex));
@@ -361,8 +356,7 @@ public final class Facets {
final ObjectFeature prop,
final ManagedProperty managedProperty) {
val objectSpec = prop.getElementType();
- //if(!objectSpec.isValue()) return Optional.empty(); // optimization
- return objectSpec.lookupFacet(ValueFacet.class)
+ return objectSpec.valueFacet()
.<ObjectAction>flatMap(valueFacet->
valueFacet.selectCompositeValueMixinForProperty(managedProperty));
}
@@ -370,26 +364,36 @@ public final class Facets {
@SuppressWarnings("unchecked")
public <X> Stream<X> valueStreamSemantics(
final ObjectSpecification objectSpec, final Class<X> requiredType) {
- //if(!objectSpec.isValue()) return Stream.empty(); // optimization
- return objectSpec.lookupFacet(ValueFacet.class)
+ return objectSpec.valueFacet()
.map(valueFacet->valueFacet.streamValueSemantics(requiredType))
.orElseGet(Stream::empty);
}
+ @SuppressWarnings("unchecked")
+ public <X> boolean valueHasSemantics(
+ final ObjectSpecification objectSpec, final Class<X> requiredType) {
+ return objectSpec.valueFacet()
+ .map(valueFacet->valueFacet.streamValueSemantics(requiredType)
+ .findFirst()
+ .isPresent())
+ .orElse(false);
+ }
+
@SuppressWarnings("unchecked")
public <X> Optional<ValueSemanticsProvider<X>> valueDefaultSemantics(
final ObjectSpecification objectSpec,
final Class<X> requiredType) {
- return objectSpec.lookupFacet(ValueFacet.class)
+ return objectSpec.valueFacet()
.filter(valueFacet->requiredType.isAssignableFrom(valueFacet.getValueClass()))
- .flatMap(ValueFacet::selectDefaultSemantics);
+ .flatMap(ValueFacet::selectDefaultSemantics)
+ .map(_Casts::uncheckedCast);
}
@SuppressWarnings("unchecked")
public <X> Optional<ValueSerializer<X>> valueSerializer(
final ObjectSpecification objectSpec,
final Class<X> requiredType) {
- return objectSpec.lookupFacet(ValueFacet.class)
+ return objectSpec.valueFacet()
.filter(valueFacet->requiredType.isAssignableFrom(valueFacet.getValueClass()))
.map(valueFacet->(ValueSerializer<X>)valueFacet);
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
index ea2f5a25f1..19a670ceff 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/util/snapshot/XmlSnapshot.java
@@ -46,7 +46,6 @@ import org.apache.isis.commons.internal.collections._Maps;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
import org.apache.isis.core.metamodel.facetapi.FacetUtil;
import org.apache.isis.core.metamodel.facets.collections.CollectionFacet;
-import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.facets.object.value.ValueSerializer.Format;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ManagedObjects;
@@ -678,7 +677,7 @@ public class XmlSnapshot implements Snapshot {
Element xsdFieldElement = null;
- if (field.getElementType().containsFacet(ValueFacet.class)) {
+ if (field.getElementType().isValue()) {
if (log.isDebugEnabled()) {
log.debug("objectToElement(NO): {} is value", log("field", fieldName));
}
@@ -709,7 +708,7 @@ public class XmlSnapshot implements Snapshot {
// return encoded string, else title.
String valueStr;
- val valueFacet = fieldNos.getFacet(ValueFacet.class);
+ val valueFacet = fieldNos.valueFacet().orElse(null);
if (valueFacet != null) {
valueStr = valueFacet.toEncodedString(Format.JSON, value.getPojo());
} else {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
index 166437661a..0de46cd282 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/testspec/ObjectSpecificationStub.java
@@ -30,6 +30,7 @@ import org.apache.isis.applib.id.LogicalType;
import org.apache.isis.applib.services.metamodel.BeanSort;
import org.apache.isis.commons.collections.Can;
import org.apache.isis.commons.collections.ImmutableEnumSet;
+import org.apache.isis.commons.internal.base._Casts;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.core.metamodel.consent.Consent;
import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
@@ -44,6 +45,7 @@ import org.apache.isis.core.metamodel.facets.object.icon.ObjectIcon;
import org.apache.isis.core.metamodel.facets.object.immutable.ImmutableFacet;
import org.apache.isis.core.metamodel.facets.object.logicaltype.LogicalTypeFacet;
import org.apache.isis.core.metamodel.facets.object.title.TitleRenderRequest;
+import org.apache.isis.core.metamodel.facets.object.value.ValueFacet;
import org.apache.isis.core.metamodel.interactions.ObjectTitleContext;
import org.apache.isis.core.metamodel.interactions.ObjectValidityContext;
import org.apache.isis.core.metamodel.spec.ActionScope;
@@ -392,5 +394,9 @@ implements ObjectSpecification {
.noneMatch(where -> where.includes(whereContext)));
}
+ @Override
+ public Optional<ValueFacet> valueFacet() {
+ return _Casts.uncheckedCast(lookupFacet(ValueFacet.class));
+ }
}
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
index 50bd73f2dc..3689a29786 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectAndActionInvocation.java
@@ -132,7 +132,7 @@ public class ObjectAndActionInvocation {
//TODO[2449] need to check whether that strategy holds consistently
private static boolean isScalarValue(final @NonNull ObjectSpecification spec) {
- return Facets.valueIsPresent(spec);
+ return spec.isValue();
}
private static boolean isVector(final @NonNull ObjectSpecification spec) {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
index 2de8f6ceb2..dab4e5d671 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ObjectPropertyReprRenderer.java
@@ -90,7 +90,7 @@ extends AbstractObjectMemberReprRenderer<OneToOneAssociation> {
val spec = valueAdapter.getSpecification();
- if (Facets.valueIsPresent(spec)) {
+ if (spec.isValue()) {
String format = null;
final Class<?> valueType = spec.getCorrespondingClass();
if(valueType == java.math.BigDecimal.class) {
diff --git a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
index 83b6e4444f..cec006c73e 100644
--- a/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
+++ b/viewers/restfulobjects/rendering/src/main/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/ScalarValueReprRenderer.java
@@ -22,7 +22,6 @@ import javax.ws.rs.core.MediaType;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.util.Facets;
import org.apache.isis.viewer.restfulobjects.applib.JsonRepresentation;
import org.apache.isis.viewer.restfulobjects.applib.Rel;
import org.apache.isis.viewer.restfulobjects.rendering.IResourceContext;
@@ -56,7 +55,7 @@ extends ReprRendererAbstract<ManagedObject> {
@Override
public ScalarValueReprRenderer with(final ManagedObject objectAdapter) {
- if (!Facets.valueIsPresent(objectAdapter.getSpecification())) {
+ if (!objectAdapter.getSpecification().isValue()) {
throw ReprRendererException.create("Not an (encodable) value", objectAdapter.titleString());
}
String format = null; // TODO
diff --git a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
index 99d2f4881d..c2d8ed0ef1 100644
--- a/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
+++ b/viewers/restfulobjects/rendering/src/test/java/org/apache/isis/viewer/restfulobjects/rendering/domainobjects/JsonValueEncoderTest_asAdapter.java
@@ -383,6 +383,10 @@ public class JsonValueEncoderTest_asAdapter {
private void allowingObjectSpecHasValue(final Class<?> valueClass) {
context.checking(new Expectations() {
{
+
+ allowing(mockObjectSpec).valueFacet();
+ will(returnValue(Optional.of(mockValueFacet)));
+
allowing(mockObjectSpec).getFacet(ValueFacet.class);
will(returnValue(mockValueFacet));
@@ -399,6 +403,10 @@ public class JsonValueEncoderTest_asAdapter {
private <T extends Facet> void allowingObjectSpecHas(final Class<T> facetClass, final T facet) {
context.checking(new Expectations() {
{
+
+ allowing(mockObjectSpec).valueFacet();
+ will(returnValue(Optional.ofNullable(facet)));
+
allowing(mockObjectSpec).getFacet(facetClass);
will(returnValue(facet));
diff --git a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java
index 30e62fcd23..2fd6bd668b 100644
--- a/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java
+++ b/viewers/wicket/model/src/main/java/org/apache/isis/viewer/wicket/model/converter/ConverterBasedOnValueSemantics.java
@@ -150,12 +150,12 @@ implements
private ValueFacet<T> valueFacet() {
val feature = feature();
val valueFacet = feature.getElementType()
- .lookupFacet(ValueFacet.class)
+ .valueFacet()
.orElseThrow(()->_Exceptions.noSuchElement(
"Value type Property or Parameter %s is missing a ValueFacet",
feature.getFeatureIdentifier()));
- return valueFacet;
+ return (ValueFacet<T>) valueFacet;
}
// -- DEPENDENCIES
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityComponentFactoryAbstract.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityComponentFactoryAbstract.java
index 22834311d9..05f93c4e3c 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityComponentFactoryAbstract.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/entity/EntityComponentFactoryAbstract.java
@@ -21,8 +21,6 @@ package org.apache.isis.viewer.wicket.ui.components.entity;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.util.Facets;
import org.apache.isis.viewer.common.model.components.ComponentType;
import org.apache.isis.viewer.wicket.model.models.EntityModel;
import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
@@ -68,11 +66,9 @@ public abstract class EntityComponentFactoryAbstract extends ComponentFactoryAbs
if (adapter == null) {
// is ok;
}
- final ObjectSpecification specification = entityModel.getTypeOfSpecification();
- final boolean isScalar = specification.isScalar();
-
- final boolean isValue = Facets.valueIsPresent(specification);
- if (isScalar && !isValue) {
+ val spec = entityModel.getTypeOfSpecification();
+ if (spec.isScalar()
+ && !spec.isValue()) {
return doAppliesTo(entityModel);
}
return ApplicationAdvice.DOES_NOT_APPLY;
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanelFactory.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanelFactory.java
index 5490b74095..98b293fbc7 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanelFactory.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/JavaAwtImagePanelFactory.java
@@ -21,12 +21,14 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.image;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.util.Facets;
import org.apache.isis.core.metamodel.valuesemantics.ImageValueSemantics;
import org.apache.isis.viewer.common.model.components.ComponentType;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.ComponentFactoryAbstract;
+import lombok.val;
+
public class JavaAwtImagePanelFactory extends ComponentFactoryAbstract {
private static final long serialVersionUID = 1L;
@@ -40,15 +42,15 @@ public class JavaAwtImagePanelFactory extends ComponentFactoryAbstract {
if (!(model instanceof ScalarModel)) {
return ApplicationAdvice.DOES_NOT_APPLY;
}
- final ScalarModel scalarModel = (ScalarModel) model;
- final ObjectSpecification specification = scalarModel.getScalarTypeSpec();
- return appliesIf(specification != null
- && specification.hasValueSemantics(ImageValueSemantics.class));
+ val scalarModel = (ScalarModel) model;
+ val typeSpec = scalarModel.getScalarTypeSpec();
+ return appliesIf(typeSpec != null
+ && Facets.valueHasSemantics(typeSpec, ImageValueSemantics.class));
}
@Override
public Component createComponent(final String id, final IModel<?> model) {
- final ScalarModel scalarModel = (ScalarModel) model;
+ val scalarModel = (ScalarModel) model;
return new JavaAwtImagePanel(id, scalarModel);
}
}
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/WicketImageUtil.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/WicketImageUtil.java
index 0e54e42a49..11f75c0965 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/WicketImageUtil.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/image/WicketImageUtil.java
@@ -31,6 +31,7 @@ import org.apache.isis.applib.value.Blob;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.core.metamodel.spec.ManagedObject;
import org.apache.isis.core.metamodel.spec.ManagedObjects;
+import org.apache.isis.core.metamodel.util.Facets;
import org.apache.isis.core.metamodel.valuesemantics.ImageValueSemantics;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
@@ -82,9 +83,9 @@ public class WicketImageUtil {
return Optional.empty();
}
- val spec = model.getScalarTypeSpec();
+ val typeSpec = model.getScalarTypeSpec();
- return spec.streamValueSemantics(ImageValueSemantics.class)
+ return Facets.valueStreamSemantics(typeSpec, ImageValueSemantics.class)
.map(imageValueSemantics->imageValueSemantics.getImage(adapter).orElse(null))
.filter(_NullSafe::isPresent)
.map(buffImg->asWicketImage(id, buffImg).orElse(null))
diff --git a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/fallback/ValueFallbackPanelFactory.java b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/fallback/ValueFallbackPanelFactory.java
index 5598601e0b..338fcbf671 100644
--- a/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/fallback/ValueFallbackPanelFactory.java
+++ b/viewers/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/scalars/value/fallback/ValueFallbackPanelFactory.java
@@ -21,11 +21,12 @@ package org.apache.isis.viewer.wicket.ui.components.scalars.value.fallback;
import org.apache.wicket.Component;
import org.apache.wicket.model.IModel;
-import org.apache.isis.core.metamodel.util.Facets;
import org.apache.isis.viewer.wicket.model.models.ScalarModel;
import org.apache.isis.viewer.wicket.ui.ComponentFactory;
import org.apache.isis.viewer.wicket.ui.components.scalars.ComponentFactoryScalarAbstract;
+import lombok.val;
+
/**
* {@link ComponentFactory} for the {@link ValueFallbackPanel}.
*/
@@ -43,8 +44,8 @@ extends ComponentFactoryScalarAbstract {
if (!(model instanceof ScalarModel)) {
return ApplicationAdvice.DOES_NOT_APPLY;
}
- final ScalarModel scalarModel = (ScalarModel) model;
- if(!Facets.valueIsPresent(scalarModel.getScalarTypeSpec())) {
+ val scalarModel = (ScalarModel) model;
+ if(!scalarModel.getScalarTypeSpec().isValue()) {
return ApplicationAdvice.DOES_NOT_APPLY;
}
final boolean hasChoices = scalarModel.hasChoices();