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 393d2a5a2b ISIS-3049: fully implement FacetHolderLayered
393d2a5a2b is described below
commit 393d2a5a2b5942dc41e6bfba2aec77df15809031
Author: Andi Huber <[email protected]>
AuthorDate: Tue Jun 28 22:08:33 2022 +0200
ISIS-3049: fully implement FacetHolderLayered
- provides a merged view of the local and the shared list of facets
---
.../metamodel/facetapi/FacetHolderAbstract.java | 16 +++---
.../metamodel/facetapi/FacetHolderLayered.java | 57 ++++++++++++++++++----
.../isis/core/metamodel/facetapi/FacetRanking.java | 7 +++
3 files changed, 64 insertions(+), 16 deletions(-)
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
index e53864592f..432e9ecf3e 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderAbstract.java
@@ -70,14 +70,14 @@ implements FacetHolder {
private final Object $lock = new Object();
@Override
- public boolean containsFacet(final Class<? extends Facet> facetType) {
+ public final boolean containsFacet(final Class<? extends Facet> facetType)
{
synchronized($lock) {
return snapshot.get().containsKey(facetType);
}
}
@Override
- public void addFacet(final @NonNull Facet facet) {
+ public final void addFacet(final @NonNull Facet facet) {
synchronized($lock) {
val ranking = rankingByType.computeIfAbsent(facet.facetType(),
FacetRanking::new);
@@ -88,15 +88,17 @@ implements FacetHolder {
}
}
+ //TODO should be made final - however, overridden by
ObjectSpecificationAbstract,
+ // which potentially leads to inconsistent behavior with facet and
facet-ranking streaming
@Override
- public <T extends Facet> T getFacet(final Class<T> facetType) {
+ public /*final*/ <T extends Facet> T getFacet(final Class<T> facetType) {
synchronized($lock) {
return uncheckedCast(snapshot.get().get(facetType));
}
}
@Override
- public Stream<Facet> streamFacets() {
+ public final Stream<Facet> streamFacets() {
synchronized($lock) {
// consumers should play nice and don't take too long (as we have
a lock)
return snapshot.get().values().stream();
@@ -104,7 +106,7 @@ implements FacetHolder {
}
@Override
- public int getFacetCount() {
+ public final int getFacetCount() {
synchronized($lock) {
return snapshot.get().size();
}
@@ -113,12 +115,12 @@ implements FacetHolder {
// -- VALIDATION SUPPORT
@Override
- public Stream<FacetRanking> streamFacetRankings() {
+ public final Stream<FacetRanking> streamFacetRankings() {
return rankingByType.values().stream();
}
@Override
- public Optional<FacetRanking> getFacetRanking(final Class<? extends Facet>
facetType) {
+ public final Optional<FacetRanking> getFacetRanking(final Class<? extends
Facet> facetType) {
return Optional.ofNullable(rankingByType.get(facetType));
}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderLayered.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderLayered.java
index ba0cee8a4c..4549df9b94 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderLayered.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetHolderLayered.java
@@ -18,11 +18,13 @@
*/
package org.apache.isis.core.metamodel.facetapi;
+import java.util.HashSet;
import java.util.Optional;
import java.util.stream.Stream;
import org.apache.isis.applib.Identifier;
import org.apache.isis.applib.services.i18n.TranslationContext;
+import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.core.metamodel.context.MetaModelContext;
import org.apache.isis.core.metamodel.facets.FacetedMethod;
@@ -87,7 +89,7 @@ implements FacetHolder {
return shared.getFacetCount();
}
// cannot simply add up shared and local
- return (int)streamFacets().count();
+ return (int)streamPopulatedFacetTypes().count();
}
@Override
@@ -110,9 +112,11 @@ implements FacetHolder {
if(localFacet.semanticEquals(sharedFacet)) {
return localFacet; // arbitrarily picking one
}
- return localFacet; // have the local win, this is safe for layout.xml
stuff, but not for future use-cases
+ // semantic conflict
+ // have the local win, this is safe for layout.xml stuff, but probably
not for future use-cases
+ return localFacet;
-// // semantic conflict (unfortunately semanticEquals() is not always
implemented yet)
+// unfortunately semanticEquals() is not always implemented yet,
otherwise we could throw ...
// throw _Exceptions.illegalState("conflicting facet semantics between
shared %s and local %s",
// FacetUtil.toString(sharedFacet),
// FacetUtil.toString(localFacet));
@@ -126,20 +130,55 @@ implements FacetHolder {
@Override
public Stream<Facet> streamFacets() {
- //FIXME[ISIS-3049] concat with local
- return shared.streamFacets();
+ // optimization, not strictly required
+ if(local.getFacetCount()==0) {
+ return shared.streamFacets();
+ }
+ return streamPopulatedFacetTypes()
+ .<Facet>map(facetType->getFacet(facetType))
+ .filter(_NullSafe::isPresent);
}
@Override
public Stream<FacetRanking> streamFacetRankings() {
- //FIXME[ISIS-3049] concat with local
- return shared.streamFacetRankings();
+ // optimization, not strictly required
+ if(local.getFacetCount()==0) {
+ return shared.streamFacetRankings();
+ }
+ return streamPopulatedFacetTypes()
+ .map(facetType->getFacetRanking(facetType).orElseThrow());
}
@Override
public Optional<FacetRanking> getFacetRanking(final Class<? extends Facet>
facetType) {
- //FIXME[ISIS-3049] concat with local
- return shared.getFacetRanking(facetType);
+ val localFacetRanking = local.getFacetRanking(facetType);
+ val sharedFacetRanking = shared.getFacetRanking(facetType);
+
+ if(localFacetRanking.isEmpty()) {
+ return sharedFacetRanking;
+ }
+ if(sharedFacetRanking.isEmpty()) {
+ return localFacetRanking;
+ }
+
+ val combinedFacetRanking = new FacetRanking(facetType);
+ // arbitrarily picking order: shared first and local last, such that
if in conflict local wins
+ combinedFacetRanking.addAll(sharedFacetRanking.get());
+ combinedFacetRanking.addAll(localFacetRanking.get());
+
+ return Optional.of(combinedFacetRanking);
+ }
+
+ // -- HELPER
+
+ private Stream<Class<? extends Facet>> streamPopulatedFacetTypes() {
+ val facetTypes = new HashSet<Class<? extends Facet>>();
+ Stream.concat(
+ shared.streamFacets(),
+ local.streamFacets())
+ .map(Facet::facetType)
+ .forEach(facetTypes::add);
+ return facetTypes.stream();
}
}
diff --git
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
index b3bdf31ce6..cc0d8b8e92 100644
---
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
+++
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facetapi/FacetRanking.java
@@ -121,6 +121,11 @@ public final class FacetRanking {
return changesTopRank;
}
+ public void addAll(final @NonNull FacetRanking facetRanking) {
+ facetRanking.facetsByPrecedence.asNavigableMapElseFail()
+ .forEach((k, facets)->facets.forEach(this::add));
+ }
+
/**
* Optionally returns the winning facet, considering the event facet (if
any) and the top rank,
* based on whether there was any added that has given facetType.
@@ -279,4 +284,6 @@ public final class FacetRanking {
}
+
+
}