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);
