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

ahuber pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/causeway.git


The following commit(s) were added to refs/heads/main by this push:
     new 97cdf03ae3e CAUSEWAY-3859: Java record refactoring (part 19)
97cdf03ae3e is described below

commit 97cdf03ae3e063260ba968daacc14418bac3e10f
Author: Andi Huber <[email protected]>
AuthorDate: Wed Feb 19 11:46:06 2025 +0100

    CAUSEWAY-3859: Java record refactoring (part 19)
    
    - consolidate compare algorithms, remove unused code
---
 .../core/metamodel/layout/DeweyOrderSet.java       |  20 ++--
 .../MemberIdentifierComparator.java                |  43 ---------
 .../memberorderfacet/MemberOrderComparator.java    |  81 -----------------
 .../OrderSetGroupNameComparator.java               |  54 -----------
 .../object/{MMHintUtils.java => MmHintUtils.java}  |   2 +-
 .../core/metamodel/object/MmSortUtils.java         | 101 +++++++++++++++++++--
 .../memento/ObjectMementoSingular.java             |   4 +-
 .../grid/bootstrap/GridSystemServiceBootstrap.java |   4 +-
 .../grid/bootstrap/_UnreferencedSequenceUtil.java  |   4 +-
 .../core/metamodel/spec/feature/ObjectAction.java  |   6 +-
 .../metamodel/spec/feature/ObjectAssociation.java  |  47 ----------
 .../core/metamodel/spec/feature/ObjectMember.java  |  50 +---------
 .../memberorder/DeweyOrderComparatorTest.java      |  10 +-
 13 files changed, 120 insertions(+), 306 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/DeweyOrderSet.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/DeweyOrderSet.java
index 21bbdcae238..dcbb0ec513c 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/DeweyOrderSet.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/DeweyOrderSet.java
@@ -35,8 +35,7 @@
 import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
 import org.apache.causeway.core.metamodel.facets.FacetedMethod;
 import 
org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
-import 
org.apache.causeway.core.metamodel.layout.memberorderfacet.MemberIdentifierComparator;
-import 
org.apache.causeway.core.metamodel.layout.memberorderfacet.MemberOrderComparator;
+import org.apache.causeway.core.metamodel.object.MmSortUtils;
 
 /**
  * Represents a nested hierarchy of ordered members.
@@ -76,7 +75,7 @@ public class DeweyOrderSet implements 
Comparable<DeweyOrderSet>, Iterable<Object
     public static DeweyOrderSet createOrderSet(final Stream<? extends 
FacetHolder> identifiedHolders) {
 
         final SortedMap<String, SortedSet<FacetHolder>> sortedMembersByGroup = 
_Maps.newTreeMap();
-        final SortedSet<FacetHolder> nonAnnotatedGroup = _Sets.newTreeSet(new 
MemberIdentifierComparator());
+        final SortedSet<FacetHolder> nonAnnotatedGroup = 
_Sets.newTreeSet(MmSortUtils::memberIdentifierCompare);
 
         // spin over all the members and put them into a Map of SortedSets
         // any non-annotated members go into additional nonAnnotatedGroup set.
@@ -150,24 +149,19 @@ private static void ensureParentFor(final 
SortedMap<String,DeweyOrderSet> orderS
     /**
      * Gets the SortedSet with the specified group from the supplied Map of
      * SortedSets.
-     *
      * <p>
-     * If there is no such SortedSet, creates.
-     *
-     * @param sortedMembersByGroup
-     * @param groupName
-     * @return
+     * If there is no such SortedSet, creates one.
      */
     private static SortedSet<FacetHolder> getSortedSet(final SortedMap<String, 
SortedSet<FacetHolder>> sortedMembersByGroup, final String groupName) {
         SortedSet<FacetHolder> sortedMembersForGroup = 
sortedMembersByGroup.get(groupName);
         if (sortedMembersForGroup == null) {
-            sortedMembersForGroup = new TreeSet<FacetHolder>(new 
MemberOrderComparator(true));
+            sortedMembersForGroup = new TreeSet<FacetHolder>((a, 
b)->MmSortUtils.compareMemberOrder(true, a, b));
             sortedMembersByGroup.put(groupName, sortedMembersForGroup);
         }
         return sortedMembersForGroup;
     }
 
-    // 
/////////////////////////////////////////////////////////////////////////
+    // --
 
     private final List<Object> elements = _Lists.newArrayList();
     private final String groupFullName;
@@ -182,7 +176,7 @@ private static SortedSet<FacetHolder> getSortedSet(final 
SortedMap<String, Sorte
      */
     protected SortedSet<DeweyOrderSet> childOrderSets = new 
TreeSet<DeweyOrderSet>();
 
-    // 
/////////////////////////////////////////////////////////////////////////
+    // --
 
     private DeweyOrderSet(final String groupFullName) {
         this.groupFullName = groupFullName;
@@ -191,7 +185,7 @@ private DeweyOrderSet(final String groupFullName) {
         groupPath = deriveGroupPath(groupFullName);
     }
 
-    // ///////////////// Group Name etc ////////////////////
+    // -- Group Name etc
 
     /**
      * Last component of the comma-separated group name supplied in the
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/MemberIdentifierComparator.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/MemberIdentifierComparator.java
deleted file mode 100644
index 91a4b271f08..00000000000
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/MemberIdentifierComparator.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.core.metamodel.layout.memberorderfacet;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.apache.causeway.applib.Identifier;
-import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
-import org.apache.causeway.core.metamodel.facets.FacetedMethod;
-
-/**
- * Compares {@link FacetedMethod}) by {@link FacetedMethod#getIdentifier()}
- *
- */
-public class MemberIdentifierComparator implements Comparator<FacetHolder>, 
Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    @Override
-    public int compare(final FacetHolder o1, final FacetHolder o2) {
-        final Identifier identifier1 = o1.getFeatureIdentifier();
-        final Identifier identifier2 = o2.getFeatureIdentifier();
-        return identifier1.compareTo(identifier2);
-    }
-
-}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/MemberOrderComparator.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/MemberOrderComparator.java
deleted file mode 100644
index 8f04d0257a6..00000000000
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/MemberOrderComparator.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.core.metamodel.layout.memberorderfacet;
-
-import java.util.Comparator;
-
-import org.apache.causeway.commons.internal.exceptions._Exceptions;
-import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
-import org.apache.causeway.core.metamodel.facets.FacetedMethod;
-import 
org.apache.causeway.core.metamodel.facets.members.layout.order.LayoutOrderFacet;
-import org.apache.causeway.core.metamodel.layout.DeweyOrderSet;
-import org.apache.causeway.core.metamodel.spec.feature.ObjectMember;
-
-/**
- * Compares by {@link ObjectMember}(s) obtained based on their {@link 
LayoutOrderFacet}.
- *
- * <p>
- * Will also compare {@link DeweyOrderSet}s; these are put after any
- * {@link FacetedMethod}s. If there is more than one DeweyOrderSet then these 
are
- * compared by an {@link OrderSetGroupNameComparator}.
- *
- * <p>
- * If there is no annotation on either member, then will compare the members by
- * name instead.
- *
- * <p>
- * Can specify if requires that members are in the same (group) name.
- */
-public class MemberOrderComparator implements Comparator<Object> {
-
-    private final Comparator<FacetHolder> memberComparator;
-    private final MemberIdentifierComparator memberIdentifierComparator = new 
MemberIdentifierComparator();
-    private final OrderSetGroupNameComparator orderSetComparator = new 
OrderSetGroupNameComparator(true);
-
-    public MemberOrderComparator(final boolean ensureGroupIsSame) {
-        memberComparator = 
ObjectMember.Comparators.byMemberOrderSequence(ensureGroupIsSame);
-    }
-
-    @Override
-    public int compare(final Object o1, final Object o2) {
-        if (o1 instanceof FacetHolder && o2 instanceof FacetHolder) {
-            var m1 = (FacetHolder) o1;
-            var m2 = (FacetHolder) o2;
-            final int memberOrderComparison = memberComparator.compare(m1, m2);
-            if(memberOrderComparison != 0) {
-                return memberOrderComparison;
-            }
-            return memberIdentifierComparator.compare(m1, m2);
-        }
-        if (o1 instanceof DeweyOrderSet && o2 instanceof DeweyOrderSet) {
-            return orderSetComparator.compare((DeweyOrderSet) o1, 
(DeweyOrderSet) o2);
-        }
-        if (o1 instanceof FacetHolder && o2 instanceof DeweyOrderSet) {
-            return -1; // members before OrderSets.
-        }
-        if (o1 instanceof DeweyOrderSet && o2 instanceof FacetHolder) {
-            return +1; // members before OrderSets.
-        }
-        throw _Exceptions.illegalArgument(
-                "can only compare IdentifiedHolders and DeweyOrderSets, got: 
%s, %s",
-                o1==null ? null : o1.getClass().getName(),
-                o2==null ? null : o2.getClass().getName());
-    }
-
-}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/OrderSetGroupNameComparator.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/OrderSetGroupNameComparator.java
deleted file mode 100644
index c92d94b263c..00000000000
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/layout/memberorderfacet/OrderSetGroupNameComparator.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.causeway.core.metamodel.layout.memberorderfacet;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.apache.causeway.core.metamodel.layout.DeweyOrderSet;
-
-/**
- * Compares by (simple) group name of each {@link DeweyOrderSet}.
- *
- * <p>
- * Note that it only makes sense to use this comparator for {@link 
DeweyOrderSet}s
- * that are known to have the same parent {@link DeweyOrderSet}s.
- */
-public class OrderSetGroupNameComparator implements Comparator<DeweyOrderSet>, 
Serializable {
-
-    private static final long serialVersionUID = 1L;
-
-    public OrderSetGroupNameComparator(final boolean ensureInSameGroupPath) {
-        this.ensureInSameGroupPath = ensureInSameGroupPath;
-    }
-
-    private final boolean ensureInSameGroupPath;
-
-    @Override
-    public int compare(final DeweyOrderSet o1, final DeweyOrderSet o2) {
-        if (ensureInSameGroupPath && 
!o1.getGroupPath().equals(o2.getGroupPath())) {
-            throw new IllegalArgumentException("OrderSets being compared do 
not have the same group path");
-        }
-
-        final String groupName1 = o1.getGroupName();
-        final String groupName2 = o2.getGroupName();
-
-        return groupName1.compareTo(groupName2);
-    }
-}
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MMHintUtils.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmHintUtils.java
similarity index 98%
rename from 
core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MMHintUtils.java
rename to 
core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmHintUtils.java
index 0a1fb6338eb..dddd5a7bdd1 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MMHintUtils.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmHintUtils.java
@@ -27,7 +27,7 @@
 import lombok.experimental.UtilityClass;
 
 @UtilityClass
-public class MMHintUtils {
+public class MmHintUtils {
 
     public String hintId(final @Nullable ManagedObject adapter) {
         if(ManagedObjects.isNullOrUnspecifiedOrEmpty(adapter)) return null;
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmSortUtils.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmSortUtils.java
index 22115eeaf8c..868fadf43ad 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmSortUtils.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/object/MmSortUtils.java
@@ -23,9 +23,19 @@
 
 import org.jspecify.annotations.Nullable;
 
+import org.apache.causeway.applib.Identifier;
 import org.apache.causeway.commons.internal.base._Objects;
+import org.apache.causeway.commons.internal.base._Strings;
+import org.apache.causeway.commons.internal.compare._Comparators;
+import org.apache.causeway.commons.internal.exceptions._Exceptions;
 import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
+import org.apache.causeway.core.metamodel.facets.FacetedMethod;
+import 
org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
+import 
org.apache.causeway.core.metamodel.facets.members.layout.order.LayoutOrderFacet;
+import org.apache.causeway.core.metamodel.layout.DeweyOrderSet;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.causeway.core.metamodel.spec.feature.ObjectMember;
 
 import lombok.experimental.UtilityClass;
 
@@ -56,12 +66,9 @@ public int compare(final @Nullable ManagedObject p, final 
@Nullable ManagedObjec
     // -- PREDEFINED COMPARATOR
 
     final Comparator<ManagedObject> NATURAL_NULL_FIRST = (a, b) -> {
-
         var aPojo = MmUnwrapUtils.single(a);
         var bPojo = MmUnwrapUtils.single(b);
-        if(Objects.equals(aPojo, bPojo)) {
-            return 0;
-        }
+        if(Objects.equals(aPojo, bPojo)) return 0;
         if((aPojo==null
                 || aPojo instanceof Comparable)
             && (bPojo==null
@@ -69,11 +76,91 @@ public int compare(final @Nullable ManagedObject p, final 
@Nullable ManagedObjec
             return _Objects.compareNullsFirst((Comparable<?>)aPojo, 
(Comparable<?>)bPojo);
         }
         final int hashCompare = Integer.compare(Objects.hashCode(aPojo), 
Objects.hashCode(bPojo));
-        if(hashCompare!=0) {
-            return hashCompare;
-        }
+        if(hashCompare!=0) return hashCompare;
         //XXX on hash-collision we return an arbitrary non-equal relation 
(unspecified behavior)
         return -1;
     };
 
+    public int memberIdentifierCompare(final FacetHolder o1, final FacetHolder 
o2) {
+        final Identifier identifier1 = o1.getFeatureIdentifier();
+        final Identifier identifier2 = o2.getFeatureIdentifier();
+        return identifier1.compareTo(identifier2);
+    }
+
+    /**
+     * Compares by (simple) group name of each {@link DeweyOrderSet}.
+     * <p>
+     * Note that it only makes sense to use this comparator for {@link 
DeweyOrderSet}s
+     * that are known to have the same parent {@link DeweyOrderSet}s.
+     */
+    public int compareDeweyOrderSet(final boolean assertInSameGroupPath, final 
DeweyOrderSet o1, final DeweyOrderSet o2) {
+        if (assertInSameGroupPath
+                && !o1.getGroupPath().equals(o2.getGroupPath())) {
+            throw new IllegalArgumentException("OrderSets being compared do 
not have the same group path");
+        }
+        final String groupName1 = o1.getGroupName();
+        final String groupName2 = o2.getGroupName();
+        return groupName1.compareTo(groupName2);
+    }
+
+    /**
+     * Compares by {@link ObjectMember}(s) obtained based on their {@link 
LayoutOrderFacet}.
+     * <p>
+     * Will also compare {@link DeweyOrderSet}s; these are put after any
+     * {@link FacetedMethod}s. If there is more than one DeweyOrderSet then 
these are
+     * compared by {@link #compareDeweyOrderSet(boolean, DeweyOrderSet, 
DeweyOrderSet)}.
+     * <p>
+     * If there is no annotation on either member, then will compare the 
members by
+     * name instead.
+     * <p>
+     * Can specify if requires that members are in the same (group) name.
+     */
+    public int compareMemberOrder(final boolean assertInSameGroupPath, final 
Object o1, final Object o2) {
+        if (o1 instanceof FacetHolder fh1
+            && o2 instanceof FacetHolder fh2) {
+            final int memberOrderComparison = 
compareMemberOrderSequence(assertInSameGroupPath, fh1, fh2);
+            return memberOrderComparison != 0
+                ? memberOrderComparison
+                : memberIdentifierCompare(fh1, fh2);
+        }
+        if (o1 instanceof DeweyOrderSet dos1
+            && o2 instanceof DeweyOrderSet dos2) {
+            return compareDeweyOrderSet(assertInSameGroupPath, dos1, dos2);
+        }
+        if (o1 instanceof FacetHolder && o2 instanceof DeweyOrderSet) return 
-1; // members before OrderSets.
+        if (o1 instanceof DeweyOrderSet && o2 instanceof FacetHolder) return 
+1; // members before OrderSets.
+
+        throw _Exceptions.illegalArgument(
+                "can only compare IdentifiedHolders and DeweyOrderSets, got: 
%s, %s",
+                o1==null ? null : o1.getClass().getName(),
+                o2==null ? null : o2.getClass().getName());
+    }
+
+    public int compareMemberOrderSequence(final boolean assertInSameGroup, 
final FacetHolder m1, final FacetHolder m2) {
+        var orderFacet1 = m1==null ? null : 
m1.getFacet(LayoutOrderFacet.class);
+        var orderFacet2 = m2==null ? null : 
m2.getFacet(LayoutOrderFacet.class);
+
+        if (orderFacet1 == null && orderFacet2 == null) return 0;
+        if (orderFacet1 == null && orderFacet2 != null) return +1; // 
annotated before non-annotated
+        if (orderFacet1 != null && orderFacet2 == null) return -1; // 
annotated before non-annotated
+
+        if(assertInSameGroup) {
+            var groupFacet1 = m1.getFacet(LayoutGroupFacet.class);
+            var groupFacet2 = m2.getFacet(LayoutGroupFacet.class);
+            var groupId1 = _Strings.nullToEmpty(groupFacet1==null ? null : 
groupFacet1.getGroupId());
+            var groupId2 = _Strings.nullToEmpty(groupFacet2==null ? null : 
groupFacet2.getGroupId());
+
+            if(!Objects.equals(groupId1, groupId2)) {
+                throw _Exceptions.illegalArgument(
+                        "Not in same fieldSetId1 when comparing: '%s', '%s'",
+                        groupId1,
+                        groupId2);
+            }
+        }
+
+        return _Comparators.deweyOrderCompare(
+                orderFacet1.getSequence(),
+                orderFacet2.getSequence());
+    }
+
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
index 6cfe39c68c3..cf7feaa837a 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/objectmanager/memento/ObjectMementoSingular.java
@@ -21,7 +21,7 @@
 import org.apache.causeway.applib.id.LogicalType;
 import org.apache.causeway.applib.services.bookmark.Bookmark;
 import org.apache.causeway.commons.internal.assertions._Assert;
-import org.apache.causeway.core.metamodel.object.MMHintUtils;
+import org.apache.causeway.core.metamodel.object.MmHintUtils;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.object.MmTitleUtils;
 
@@ -50,7 +50,7 @@ static ObjectMementoSingular create(final @NonNull 
ManagedObject adapter) {
 
         return new ObjectMementoSingular(
                 adapter.getLogicalType(),
-                MMHintUtils.bookmarkElseFail(adapter),
+                MmHintUtils.bookmarkElseFail(adapter),
                 MmTitleUtils.titleOf(adapter));
     }
 
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
index 310d1d4329f..40e907e7881 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/GridSystemServiceBootstrap.java
@@ -327,7 +327,7 @@ protected boolean validateAndNormalize(
                         associationIds.stream()
                         .map(oneToOneAssociationById::get)
                         .filter(_NullSafe::isPresent)
-                        
.sorted(ObjectMember.Comparators.byMemberOrderSequence(false))
+                        .sorted(ObjectMember.byMemberOrderSequence(false))
                         .map(ObjectAssociation::getId)
                         .collect(Collectors.toList());
 
@@ -406,7 +406,7 @@ protected boolean validateAndNormalize(
         final List<ObjectAction> sortedPossiblyMissingActions =
                 _Lists.map(possiblyMissingActionIds, objectActionById::get);
 
-        
sortedPossiblyMissingActions.sort(ObjectMember.Comparators.byMemberOrderSequence(false));
+        
sortedPossiblyMissingActions.sort(ObjectMember.byMemberOrderSequence(false));
 
         final List<String> sortedPossiblyMissingActionIds =
                 _Lists.map(sortedPossiblyMissingActions, ObjectMember::getId);
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/_UnreferencedSequenceUtil.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/_UnreferencedSequenceUtil.java
index 8a4d7ef8c73..937771e64da 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/_UnreferencedSequenceUtil.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/grid/bootstrap/_UnreferencedSequenceUtil.java
@@ -48,7 +48,7 @@ List<String> sortProperties(
                     .sorted()
                     .collect(Collectors.toList())
                 : propertyStream
-                    
.sorted(ObjectMember.Comparators.byMemberOrderSequence(false))
+                    .sorted(ObjectMember.byMemberOrderSequence(false))
                     .map(ObjectAssociation::getId)
                     .collect(Collectors.toList());
     }
@@ -64,7 +64,7 @@ List<String> sortCollections(
                     .sorted()
                     .collect(Collectors.toList())
                 : collectionStream
-                    
.sorted(ObjectMember.Comparators.byMemberOrderSequence(false))
+                    .sorted(ObjectMember.byMemberOrderSequence(false))
                     .map(ObjectAssociation::getId)
                     .collect(Collectors.toList());
     }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
index b65f7af09fb..107cc59e69c 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAction.java
@@ -24,6 +24,8 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.jspecify.annotations.NonNull;
+
 import org.apache.causeway.applib.annotation.ActionLayout;
 import org.apache.causeway.applib.annotation.PromptStyle;
 import org.apache.causeway.applib.annotation.SemanticsOf;
@@ -56,8 +58,6 @@
 
 import static org.apache.causeway.commons.internal.base._NullSafe.stream;
 
-import org.jspecify.annotations.NonNull;
-
 public interface ObjectAction extends ObjectMember {
 
     /**
@@ -386,7 +386,7 @@ public static Stream<ObjectAction> findForAssociation(
 
             return spec.streamRuntimeActions(MixedIn.INCLUDED)
             .filter(Predicates.isSameLayoutGroupAs(association))
-            .sorted(Comparators.byMemberOrderSequence(false));
+            .sorted(ObjectMember.byMemberOrderSequence(false));
         }
 
         public static PromptStyle promptStyleFor(final ObjectAction 
objectAction) {
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java
index 46db565179f..55204ee56d3 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectAssociation.java
@@ -18,8 +18,6 @@
  */
 package org.apache.causeway.core.metamodel.spec.feature;
 
-import java.util.List;
-import java.util.Map;
 import java.util.function.Predicate;
 
 import org.jspecify.annotations.Nullable;
@@ -28,15 +26,10 @@
 import org.apache.causeway.applib.annotation.Where;
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.commons.functional.Either;
-import org.apache.causeway.commons.internal.base._Strings;
-import org.apache.causeway.commons.internal.collections._Lists;
-import org.apache.causeway.commons.internal.collections._Maps;
 import org.apache.causeway.commons.internal.functions._Predicates;
 import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
 import org.apache.causeway.core.metamodel.facets.WhereValueFacet;
 import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet;
-import 
org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
-import 
org.apache.causeway.core.metamodel.layout.memberorderfacet.MemberOrderComparator;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.util.Facets;
@@ -212,44 +205,4 @@ private static boolean equivalent(final 
ObjectSpecification parentSpec, final Ob
         }
     }
 
-    // -- UTIL
-
-    @Domain.Exclude
-    public static class Util {
-        private Util(){}
-
-        public static final String LAYOUT_DEFAULT_GROUP = "General";
-
-        public static Map<String, List<ObjectAssociation>> 
groupByMemberOrderName(
-                final List<ObjectAssociation> associations) {
-            Map<String, List<ObjectAssociation>> associationsByGroup = 
_Maps.newHashMap();
-            for(ObjectAssociation association: associations) {
-                addAssociationIntoGroup(associationsByGroup, association);
-            }
-            for (Map.Entry<String, List<ObjectAssociation>> objectAssociations 
: associationsByGroup.entrySet()) {
-                objectAssociations.getValue().sort(new 
MemberOrderComparator(true));
-            }
-            return associationsByGroup;
-        }
-
-        private static void addAssociationIntoGroup(
-                final Map<String, List<ObjectAssociation>> associationsByGroup,
-                final ObjectAssociation association) {
-
-            var layoutGroupFacet = 
association.getFacet(LayoutGroupFacet.class);
-            if(layoutGroupFacet != null) {
-                var fieldSetId = layoutGroupFacet.getGroupId();
-                if(_Strings.isNotEmpty(fieldSetId)) {
-                    getFrom(associationsByGroup, fieldSetId).add(association);
-                    return;
-                }
-            }
-            getFrom(associationsByGroup, 
LAYOUT_DEFAULT_GROUP).add(association);
-        }
-
-        private static List<ObjectAssociation> getFrom(final Map<String, 
List<ObjectAssociation>> associationsByGroup, final String groupName) {
-            return associationsByGroup.computeIfAbsent(groupName, k -> 
_Lists.newArrayList());
-        }
-    }
-
 }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java
index b23c6687747..d463c5c656d 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/feature/ObjectMember.java
@@ -20,7 +20,6 @@
 
 import java.util.Comparator;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Optional;
 import java.util.OptionalInt;
 import java.util.stream.Stream;
@@ -30,10 +29,7 @@
 import org.apache.causeway.applib.annotation.Where;
 import org.apache.causeway.commons.internal.base._Casts;
 import org.apache.causeway.commons.internal.base._NullSafe;
-import org.apache.causeway.commons.internal.base._Strings;
 import org.apache.causeway.commons.internal.collections._Maps;
-import org.apache.causeway.commons.internal.compare._Comparators;
-import org.apache.causeway.commons.internal.exceptions._Exceptions;
 import org.apache.causeway.commons.internal.factory._InstanceUtil;
 import org.apache.causeway.core.metamodel.consent.Consent;
 import org.apache.causeway.core.metamodel.consent.InteractionInitiatedBy;
@@ -41,11 +37,10 @@
 import org.apache.causeway.core.metamodel.facetapi.FacetUtil;
 import org.apache.causeway.core.metamodel.facets.all.hide.HiddenFacet;
 import 
org.apache.causeway.core.metamodel.facets.collections.sortedby.SortedByFacet;
-import 
org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacet;
-import 
org.apache.causeway.core.metamodel.facets.members.layout.order.LayoutOrderFacet;
 import org.apache.causeway.core.metamodel.facets.object.paged.PagedFacet;
 import 
org.apache.causeway.core.metamodel.facets.object.tabledec.TableDecoratorFacet;
 import org.apache.causeway.core.metamodel.object.ManagedObject;
+import org.apache.causeway.core.metamodel.object.MmSortUtils;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.util.Facets;
 
@@ -294,47 +289,8 @@ default Optional<Comparator<ManagedObject>> 
getElementComparator(){
 
     // -- COMPARATORS
 
-    public static class Comparators {
-
-        public static <T extends FacetHolder> Comparator<T> 
byMemberOrderSequence(
-                final boolean ensureInSameGroup) {
-
-            return (m1, m2) -> {
-
-                var orderFacet1 = m1==null ? null : 
m1.getFacet(LayoutOrderFacet.class);
-                var orderFacet2 = m2==null ? null : 
m2.getFacet(LayoutOrderFacet.class);
-
-                if (orderFacet1 == null && orderFacet2 == null) {
-                    return 0;
-                }
-                if (orderFacet1 == null && orderFacet2 != null) {
-                    return +1; // annotated before non-annotated
-                }
-                if (orderFacet1 != null && orderFacet2 == null) {
-                    return -1; // annotated before non-annotated
-                }
-
-                if (ensureInSameGroup) {
-
-                    var groupFacet1 = m1.getFacet(LayoutGroupFacet.class);
-                    var groupFacet2 = m2.getFacet(LayoutGroupFacet.class);
-                    var groupId1 = _Strings.nullToEmpty(groupFacet1==null ? 
null : groupFacet1.getGroupId());
-                    var groupId2 = _Strings.nullToEmpty(groupFacet2==null ? 
null : groupFacet2.getGroupId());
-
-                    if(!Objects.equals(groupId1, groupId2)) {
-                        throw _Exceptions.illegalArgument(
-                                "Not in same fieldSetId1 when comparing: '%s', 
'%s'",
-                                groupId1,
-                                groupId2);
-                    }
-                }
-
-                return _Comparators.deweyOrderCompare(
-                        orderFacet1.getSequence(),
-                        orderFacet2.getSequence());
-            };
-        }
-
+    public static <T extends FacetHolder> Comparator<T> 
byMemberOrderSequence(final boolean assertInSameGroup) {
+        return (m1, m2) -> 
MmSortUtils.compareMemberOrderSequence(assertInSameGroup, m1, m2);
     }
 
 }
diff --git 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/ordering/memberorder/DeweyOrderComparatorTest.java
 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/ordering/memberorder/DeweyOrderComparatorTest.java
index e6a5e469185..db6e50e2c68 100644
--- 
a/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/ordering/memberorder/DeweyOrderComparatorTest.java
+++ 
b/core/metamodel/src/test/java/org/apache/causeway/core/metamodel/facets/ordering/memberorder/DeweyOrderComparatorTest.java
@@ -18,6 +18,8 @@
  */
 package org.apache.causeway.core.metamodel.facets.ordering.memberorder;
 
+import java.util.Comparator;
+
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mock;
@@ -34,11 +36,11 @@
 import 
org.apache.causeway.core.metamodel.facets.members.layout.group.GroupIdAndName;
 import 
org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacetAbstract;
 import 
org.apache.causeway.core.metamodel.facets.members.layout.order.LayoutOrderFacetAbstract;
-import 
org.apache.causeway.core.metamodel.layout.memberorderfacet.MemberOrderComparator;
+import org.apache.causeway.core.metamodel.object.MmSortUtils;
 
 class DeweyOrderComparatorTest  {
 
-    private MemberOrderComparator comparator, laxComparator;
+    private Comparator<Object> comparator, laxComparator;
 
     static class Customer {
         private String abc;
@@ -59,8 +61,8 @@ public String getAbc() {
        @BeforeEach
     protected void setUp() {
         _Context.clear();
-        comparator = new MemberOrderComparator(true);
-        laxComparator = new MemberOrderComparator(false);
+        comparator = (a, b)->MmSortUtils.compareMemberOrder(true, a, b);
+        laxComparator = (a, b)->MmSortUtils.compareMemberOrder(false, a, b);
     }
 
        @Test


Reply via email to