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

ahuber pushed a commit to branch 3965-fix.hierarchy.introspect
in repository https://gitbox.apache.org/repos/asf/causeway.git

commit 833af072f96cd6a30105d703add43b5b6263586b
Author: andi-huber <[email protected]>
AuthorDate: Mon Feb 9 14:42:53 2026 +0100

    CAUSEWAY-3965: removes sub-type handling (never used)
    
    Task-Url: https://issues.apache.org/jira/browse/CAUSEWAY-3965
---
 .../services/metamodel/DomainMemberDefault.java    |  20 +--
 .../causeway/core/metamodel/spec/Hierarchical.java |  17 ---
 .../metamodel/spec/ObjectSpecificationRecord.java  |   6 -
 .../spec/impl/ObjectSpecificationDefault.java      | 151 ++++-----------------
 .../metamodel/MetaModelServiceDefaultTest.java     |   2 -
 5 files changed, 36 insertions(+), 160 deletions(-)

diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java
index 1042dfc5284..c1cc1d478eb 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/services/metamodel/DomainMemberDefault.java
@@ -22,7 +22,6 @@
 import java.util.Comparator;
 import java.util.SortedSet;
 import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
 import jakarta.xml.bind.annotation.XmlAccessorType;
@@ -47,7 +46,6 @@
 import 
org.apache.causeway.core.metamodel.facets.properties.defaults.PropertyDefaultFacet;
 import 
org.apache.causeway.core.metamodel.facets.properties.validating.PropertyValidateFacet;
 import org.apache.causeway.core.metamodel.services.devutils.MemberType;
-import org.apache.causeway.core.metamodel.spec.Hierarchical;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.spec.feature.MixedInMember;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
@@ -90,19 +88,15 @@ public class DomainMemberDefault implements DomainMember {
 
     @XmlElement @Override
     public String getClassType() {
-
-        var isService = Stream.concat(
-                    Stream.of(spec),
-                    spec.subclasses(Hierarchical.Depth.DIRECT).stream())
-                .anyMatch(ObjectSpecification::isInjectable);
-
-        return isService
+        return spec.isAbstract()
+                       ? "0 Abstract"
+                       : spec.isInjectable()
                     ? "2 Service"
                     : spec.isValue()
-                            ? "3 Value"
-                            : spec.isPlural()
-                                    ? "4 Collection"
-                                    : "1 Object";
+                        ? "3 Value"
+                        : spec.isPlural()
+                            ? "4 Collection"
+                            : "1 Object";
     }
 
     @XmlElement @Override
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/Hierarchical.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/Hierarchical.java
index 613a5963259..b37787476e2 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/Hierarchical.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/Hierarchical.java
@@ -22,12 +22,6 @@
 
 public interface Hierarchical {
 
-    /**
-     * Returns true if the <tt>subclasses()</tt> method will return an array of
-     * one or more elements (ie, not an empty array).
-     */
-    boolean hasSubclasses();
-
     /**
      * Get the set of specifications for all the interfaces that the class
      * represented by this specification implements.
@@ -50,17 +44,6 @@ public interface Hierarchical {
      */
     boolean isOfTypeResolvePrimitive(ObjectSpecification other);
 
-    public static enum Depth {
-        DIRECT,
-        TRANSITIVE
-    }
-
-    /**
-     * Get the set of specifications for the subclasses of the class
-     * represented by this specification
-     */
-    Can<ObjectSpecification> subclasses(Depth depth);
-
     /**
      * Get the specification for this specification's class's superclass.
      */
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecificationRecord.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecificationRecord.java
index fd9943a7c31..fd6e163ee81 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecificationRecord.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/ObjectSpecificationRecord.java
@@ -62,9 +62,6 @@ public record ObjectSpecificationRecord(
 
     // -- HIERARCHICAL
 
-    @Override public boolean hasSubclasses() {
-        return hierarchical.hasSubclasses();
-    }
     @Override public Can<ObjectSpecification> interfaces() {
         return hierarchical.interfaces();
     }
@@ -74,9 +71,6 @@ public record ObjectSpecificationRecord(
     @Override public boolean isOfTypeResolvePrimitive(final 
ObjectSpecification other) {
         return hierarchical.isOfTypeResolvePrimitive(other);
     }
-    @Override public Can<ObjectSpecification> subclasses(final Depth depth) {
-        return hierarchical.subclasses(depth);
-    }
     @Override public ObjectSpecification superclass() {
         return hierarchical.superclass();
     }
diff --git 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
index 6cd28f22706..9a031b5a4e9 100644
--- 
a/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
+++ 
b/core/metamodel/src/main/java/org/apache/causeway/core/metamodel/spec/impl/ObjectSpecificationDefault.java
@@ -207,33 +207,8 @@ protected void introspectTypeHierarchy() {
             return;
         }
 
-        // superclass
-        final Class<?> superclass = getCorrespondingClass().getSuperclass();
-        loadSpecOfSuperclass(superclass);
-
-        // walk superinterfaces
-
-        //
-        // REVIEW: the processing here isn't quite the same as with
-        // superclasses, in that with superclasses the superclass adds this 
type as its
-        // subclass, whereas here this type defines itself as the subtype.
-        //
-        // it'd be nice to push the responsibility for adding subclasses to
-        // the interface type... needs some tests around it, though, before
-        // making that refactoring.
-        //
-        final Class<?>[] interfaceTypes = 
getCorrespondingClass().getInterfaces();
-        final List<ObjectSpecification> interfaceSpecList = 
_Lists.newArrayList();
-        for (var interfaceType : interfaceTypes) {
-            var interfaceSubstitute = 
classSubstitutorRegistry.getSubstitution(interfaceType);
-            if (interfaceSubstitute.isReplace()) {
-                var interfaceSpec = 
specLoaderInternal().loadSpecification(interfaceSubstitute.replacement());
-                interfaceSpecList.add(interfaceSpec);
-            }
-        }
-
-        updateAsSubclassTo(interfaceSpecList);
-        updateInterfaces(interfaceSpecList);
+        loadSpecOfSuperclass(getCorrespondingClass().getSuperclass());
+        //TODO loadSpecOfInterfaces(getCorrespondingClass().getInterfaces());
     }
 
     private void introspectMembers() {
@@ -433,33 +408,6 @@ public boolean isDomainService() {
     // MERGED FROM FORMER ObjectSpecificationAbstract
     
//-----------------------------------------------------------------------------------------------------------------
 
-    /**
-     * @implNote thread-safe
-     */
-    private static class Subclasses {
-
-        // List performs better compared to a Set, when the number of elements 
is low
-        private Can<ObjectSpecification> classes = Can.empty();
-
-        public void addSubclass(final ObjectSpecification subclass) {
-            synchronized(classes) {
-                classes = classes.addUnique(subclass);
-            }
-        }
-
-        public boolean hasSubclasses() {
-            synchronized(classes) {
-                return classes.isNotEmpty();
-            }
-        }
-
-        public Can<ObjectSpecification> snapshot() {
-            synchronized(classes) {
-                return classes;
-            }
-        }
-    }
-
     // -- FIELDS
 
     private final PostProcessor postProcessor;
@@ -498,9 +446,9 @@ public Can<ObjectSpecification> snapshot() {
     private final _Lazy<Can<ObjectSpecification>> unmodifiableInterfaces =
             _Lazy.threadSafe(()->Can.ofCollection(interfaces));
 
-    private final Subclasses directSubclasses = new Subclasses();
+    //private final Subclasses directSubclasses = new Subclasses();
     // built lazily
-    private Subclasses transitiveSubclasses;
+    //private Subclasses transitiveSubclasses;
 
     private final Class<?> correspondingClass;
     private final String fullName;
@@ -645,42 +593,39 @@ private boolean isLessThan(final IntrospectionState upTo) 
{
     }
 
     protected void loadSpecOfSuperclass(final Class<?> superclass) {
-        if (superclass == null) {
+        if (superclass == null)
             return;
-        }
-        superclassSpec = specLoaderInternal().loadSpecification(superclass);
-        if (superclassSpec != null) {
-            if (log.isDebugEnabled()) {
-                log.debug("  Superclass {}", superclass.getName());
-            }
-            updateAsSubclassTo(superclassSpec);
+        
+        this.superclassSpec = 
specLoaderInternal().loadSpecification(superclass);
+        if (superclassSpec != null 
+                       && log.isDebugEnabled()) {
+            log.debug("  Superclass {}", superclass.getName());
         }
     }
-
-    protected void updateInterfaces(final List<ObjectSpecification> 
interfaces) {
+    
+    protected void loadSpecOfInterfaces(final Class<?>[] interfaces) {
+        final List<ObjectSpecification> interfaceSpecList = 
_Lists.newArrayList();
+        for (final Class<?> interfaceType : interfaces) {
+            var substitution = 
classSubstitutorRegistry.getSubstitution(interfaceType);
+            var interfaceToAdd = substitution.isReplace()
+                       ? substitution.replacement()
+                               : substitution.isNeverIntrospect()
+                                       ? null
+                                       : interfaceType;
+            if(interfaceToAdd==null)
+               continue;
+            var interfaceSpec = 
specLoaderInternal().loadSpecification(interfaceToAdd);
+            if(interfaceSpec==null)
+               continue;
+            interfaceSpecList.add(interfaceSpec);
+        }
         synchronized(unmodifiableInterfaces) {
             this.interfaces.clear();
-            this.interfaces.addAll(interfaces);
+            this.interfaces.addAll(interfaceSpecList);
             unmodifiableInterfaces.clear();
         }
     }
 
-    private void updateAsSubclassTo(final ObjectSpecification supertypeSpec) {
-        // API
-        var introspectableSpec = (ObjectSpecificationDefault) supertypeSpec;
-        introspectableSpec.updateSubclasses(this);
-    }
-
-    protected void updateAsSubclassTo(final List<ObjectSpecification> 
supertypeSpecs) {
-        for (final ObjectSpecification supertypeSpec : supertypeSpecs) {
-            updateAsSubclassTo(supertypeSpec);
-        }
-    }
-
-    private void updateSubclasses(final ObjectSpecification subclass) {
-        this.directSubclasses.addSubclass(subclass);
-    }
-
     protected final void replaceAssociations(final Stream<ObjectAssociation> 
associations) {
         var orderedAssociations = 
_MemberSortingUtils.sortAssociationsIntoList(associations);
         synchronized (unmodifiableAssociations) {
@@ -943,7 +888,7 @@ public ObjectTitleContext createTitleInteractionContext(
                 interactionMethod);
     }
 
-    // -- SUPERCLASS, INTERFACES, SUBCLASSES, IS-ABSTRACT
+    // -- INHERITED
 
     @Override
     public ObjectSpecification superclass() {
@@ -955,44 +900,6 @@ public Can<ObjectSpecification> interfaces() {
         return unmodifiableInterfaces.get();
     }
 
-    @Override
-    public Can<ObjectSpecification> subclasses(final Depth depth) {
-        if (depth == Depth.DIRECT) {
-            return directSubclasses.snapshot();
-        }
-
-        // depth == Depth.TRANSITIVE)
-        if (transitiveSubclasses == null) {
-            transitiveSubclasses = transitiveSubclasses();
-        }
-
-        return transitiveSubclasses.snapshot();
-    }
-
-    private synchronized Subclasses transitiveSubclasses() {
-        final Subclasses appendTo = new Subclasses();
-        appendSubclasses(this, appendTo);
-        transitiveSubclasses = appendTo;
-        return transitiveSubclasses;
-    }
-
-    private void appendSubclasses(
-            final ObjectSpecification objectSpecification,
-            final Subclasses appendTo) {
-
-        var directSubclasses = objectSpecification.subclasses(Depth.DIRECT);
-        for (ObjectSpecification subclass : directSubclasses) {
-            appendTo.addSubclass(subclass);
-            appendSubclasses(subclass, appendTo);
-        }
-
-    }
-
-    @Override
-    public boolean hasSubclasses() {
-        return directSubclasses.hasSubclasses();
-    }
-
     // -- ASSOCIATIONS
 
     @Override
diff --git 
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
 
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
index f1f572f4ba0..1a4aa3f38af 100644
--- 
a/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
+++ 
b/core/mmtest/src/test/java/org/apache/causeway/core/metamodel/services/metamodel/MetaModelServiceDefaultTest.java
@@ -44,7 +44,6 @@
 import org.apache.causeway.commons.collections.Can;
 import org.apache.causeway.core.metamodel.facets.FacetedMethod;
 import org.apache.causeway.core.metamodel.id.TypeIdentifierTestFactory;
-import org.apache.causeway.core.metamodel.spec.Hierarchical;
 import org.apache.causeway.core.metamodel.spec.ObjectSpecification;
 import org.apache.causeway.core.metamodel.spec.feature.ObjectAction;
 import org.apache.causeway.core.metamodel.spec.impl._JUnitSupport;
@@ -74,7 +73,6 @@ void setUp() throws Exception {
         mockSpec = Mockito.mock(ObjectSpecification.class);
         Mockito.when(mockSpec.getFullIdentifier()).thenReturn("mocked");
         Mockito.when(mockSpec.logicalTypeName()).thenReturn("logicalType");
-        
Mockito.when(mockSpec.subclasses(Hierarchical.Depth.DIRECT)).thenReturn(Can.empty());
         Mockito.when(mockSpec.isInjectable()).thenReturn(true);
 
         action = _JUnitSupport.actionForMethod(mockFacetedMethod);

Reply via email to