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 2020/01/18 11:03:35 UTC

[isis] branch master updated: ISIS-2223: improve/re-model ClassSubstitutor interface

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 0ac469d  ISIS-2223: improve/re-model ClassSubstitutor interface
0ac469d is described below

commit 0ac469d57b9a1ac66fff78ca497f424bf3385cd9
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sat Jan 18 12:03:24 2020 +0100

    ISIS-2223: improve/re-model ClassSubstitutor interface
---
 ...jectSpecIdFacetDerivedFromClassNameFactory.java |  9 +--
 .../classsubstitutor/ClassSubstitutor.java         | 91 +++++++++++++++++++++-
 .../classsubstitutor/ClassSubstitutorAbstract.java | 18 ++++-
 .../ClassSubstitutorForCollections.java            | 22 +++---
 .../classsubstitutor/ClassSubstitutorRegistry.java | 47 +++++------
 .../specloader/SpecificationLoaderDefault.java     | 21 +++--
 .../specloader/specimpl/FacetedMethodsBuilder.java |  4 +-
 .../specimpl/dflt/ObjectSpecificationDefault.java  |  6 +-
 .../ClassSubstitutorTest_getClass.java             | 21 +++--
 .../JdoDiscriminatorAnnotationFacetFactory.java    | 16 +++-
 10 files changed, 183 insertions(+), 72 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
index 4134cf2..4d9c8b3 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/classname/ObjectSpecIdFacetDerivedFromClassNameFactory.java
@@ -70,13 +70,12 @@ implements MetaModelRefiner, ObjectSpecIdFacetFactory {
         if(facetHolder.containsNonFallbackFacet(ObjectSpecIdFacet.class)) {
             return;
         }
-        final Class<?> cls = processClassContext.getCls();
-        final Class<?> substitutedClass = classSubstitutorRegistry.getClass(cls);
-        if(substitutedClass == null) {
+        val cls = processClassContext.getCls();
+        val substitute = classSubstitutorRegistry.getSubstitution(cls);
+        if(substitute.isIgnore()) {
             return;
         }
-
-        final ObjectSpecIdFacet objectSpecIdFacet = createObjectSpecIdFacet(facetHolder, substitutedClass);
+        val objectSpecIdFacet = createObjectSpecIdFacet(facetHolder, substitute.replace(cls));
         FacetUtil.addFacet(objectSpecIdFacet);
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutor.java
index 64a2351..a2ce7e5 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutor.java
@@ -19,10 +19,99 @@
 
 package org.apache.isis.core.metamodel.services.classsubstitutor;
 
+import java.io.Serializable;
+
+import javax.annotation.Nullable;
+
+import lombok.NonNull;
+import lombok.Value;
+
 /**
  * Provides capability to translate or ignore classes.
  */
 public interface ClassSubstitutor {
     
-    Class<?> getClass(@lombok.NonNull @org.springframework.lang.NonNull Class<?> cls);
+    /**
+     * Captures 3 possible directives:
+     * <ul>
+     * <li>do not replace the class (NOP)</li>
+     * <li>ignore the class, that is do not introspect ever</li>
+     * <li>replace the class with another (non-null)</li>
+     * </ul> 
+     * @since 2.0
+     */
+    @Value(staticConstructor = "of")
+    static class Substitution implements Serializable {
+        private static final long serialVersionUID = 1L;
+        private static final Substitution NOP = Substitution.of(Type.DO_NOT_REPLACE, null);
+        private static final Substitution IGNORE = Substitution.of(Type.IGNORE_CLASS, null);
+        
+        private static enum Type {
+            DO_NOT_REPLACE,
+            IGNORE_CLASS,
+            REPLACE_WITH_OTHER_CLASS,
+        }
+        
+        @NonNull Type type;        
+        @Nullable Class<?> replacement;
+
+        /**
+         * for framework internal use only, not required for ClassSubstitutor implementations!
+         * (forces a class to be never replaced)
+         */
+        public static Substitution dontReplaceClass() {
+            return NOP;
+        }
+        
+        public static Substitution ignoreClass() {
+            return IGNORE;
+        }
+        
+        public static Substitution replaceClass(@lombok.NonNull @org.springframework.lang.NonNull Class<?> cls) {
+            return of(Type.REPLACE_WITH_OTHER_CLASS, cls);
+        }
+        
+        /**
+         * @return whether to be the replacement be an identity operation (do nothing) 
+         */
+        public boolean isDoNotReplace() {
+            return type == Type.DO_NOT_REPLACE;
+        }
+        
+        /**
+         * @return whether to ignore the class (never introspect)
+         */
+        public boolean isIgnore() {
+            return type == Type.IGNORE_CLASS;
+        }
+
+        /**
+         * @return whether to replace the class with registered replacement
+         */
+        public boolean isReplace() {
+            return type == Type.REPLACE_WITH_OTHER_CLASS;            
+        }
+
+        public Class<?> replace(Class<?> cls) {
+            if(isIgnore()) {
+                return null;
+            }
+            return isReplace() ? getReplacement() : cls;
+        }
+        
+    }
+    
+    // -- INTERFACE
+    
+    /**
+     * @param cls
+     * @return Substitution for given {@code cls} if any
+     * or Substitution.ignore(), when {@code cls} shall be ignored 
+     * @implNote most likely do not return Substitution.dontReplaceClass(), return {@code null} instead
+     * @since 2.0
+     */
+    @Nullable
+    Substitution getSubstitution(@lombok.NonNull @org.springframework.lang.NonNull Class<?> cls);
+     
+    
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java
index 6bcc941..bea06ad 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorAbstract.java
@@ -27,12 +27,24 @@ import org.apache.isis.core.commons.internal.collections._Sets;
 import org.apache.isis.core.metamodel.commons.ClassUtil;
 import org.apache.isis.core.metamodel.specloader.classsubstitutor.ProxyEnhanced;
 
+import lombok.NonNull;
 import lombok.val;
 
 public abstract class ClassSubstitutorAbstract implements ClassSubstitutor {
 
     @Override
-    public Class<?> getClass(final Class<?> cls) {
+    public Substitution getSubstitution(@NonNull Class<?> cls) {
+        val replacement = getReplacement(cls);
+        if(replacement==null) {
+            return Substitution.ignoreClass();
+        }
+        if(cls.equals(replacement)) {
+            return null; // NOP
+        }
+        return Substitution.replaceClass(replacement) ;
+    }
+    
+    private Class<?> getReplacement(final Class<?> cls) {
 
         if(cls == null) {
             return null;
@@ -40,7 +52,7 @@ public abstract class ClassSubstitutorAbstract implements ClassSubstitutor {
 
         if(proxyPackageNamesToSkip.stream()
                 .anyMatch(packageName -> cls.getName().startsWith(packageName))) {
-            return getClass(cls.getSuperclass());
+            return getReplacement(cls.getSuperclass());
         }
 
         if (shouldIgnore(cls)) {
@@ -60,7 +72,7 @@ public abstract class ClassSubstitutorAbstract implements ClassSubstitutor {
         }
         if (ClassUtil.directlyImplements(cls, ProxyEnhanced.class)) {
             // REVIEW: arguably this should now go back to the ClassSubstitorRegistry
-            return getClass(cls.getSuperclass());
+            return getReplacement(cls.getSuperclass());
         }
 
         try {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorForCollections.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorForCollections.java
index f92162c..920e61d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorForCollections.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorForCollections.java
@@ -31,7 +31,8 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.core.metamodel.spec.Container;
+
+import lombok.NonNull;
 
 @Component
 @Named("isisMetaModel.ClassSubstitutorForCollections")
@@ -39,27 +40,22 @@ import org.apache.isis.core.metamodel.spec.Container;
 public class ClassSubstitutorForCollections implements ClassSubstitutor {
 
     @Override
-    public Class<?> getClass(@lombok.NonNull @org.springframework.lang.NonNull Class<?> cls) {
-
-        if(Container.class.isAssignableFrom(cls)) {
-            return Container.class;
-        }
-        // legacy
+    public Substitution getSubstitution(@NonNull Class<?> cls) {
         if(Vector.class.isAssignableFrom(cls)) {
-            return Vector.class;
+            return Substitution.replaceClass(Vector.class);
         }
         if(List.class.isAssignableFrom(cls)) {
-            return List.class;
+            return Substitution.replaceClass(List.class);
         }
         if(SortedSet.class.isAssignableFrom(cls)) {
-            return SortedSet.class;
+            return Substitution.replaceClass(SortedSet.class);
         }
         if(Set.class.isAssignableFrom(cls)) {
-            return Set.class;
+            return Substitution.replaceClass(Set.class);
         }
         if(Collection.class.isAssignableFrom(cls)) {
-            return Collection.class;
+            return Substitution.replaceClass(Collection.class);
         }
-        return cls;
+        return null; // NOP
     }
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorRegistry.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorRegistry.java
index e9ae0f7..c20ba96 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorRegistry.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/classsubstitutor/ClassSubstitutorRegistry.java
@@ -21,8 +21,8 @@ package org.apache.isis.core.metamodel.services.classsubstitutor;
 
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 
+import javax.annotation.Nullable;
 import javax.inject.Inject;
 import javax.inject.Named;
 
@@ -30,7 +30,9 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.core.commons.internal.base._NullSafe;
 import org.apache.isis.core.commons.internal.collections._Maps;
+import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor.Substitution;
 
 /**
  * Aggregates all {@link ClassSubstitutor}s.
@@ -47,34 +49,25 @@ public class ClassSubstitutorRegistry {
         this.classSubstitutors = classSubstitutors;
     }
 
-    private final Map<Class<?>, Optional<Class<?>>> cache = _Maps.newHashMap();
+    private final Map<Class<?>, Substitution> cache = _Maps.newConcurrentHashMap();
 
-    // TODO: it would be preferable to return an Optional here.
-    public Class<?> getClass(final Class<?> originalClass) {
+    public Substitution getSubstitution(@Nullable final Class<?> originalClass) {
         if(originalClass == null) {
-            return null;
+            return Substitution.dontReplaceClass();
         }
-
-        Optional<Class<?>> substitutedClass = cache.get(originalClass);
-
-
-        cacheMiss:
-        //noinspection OptionalAssignedToNull
-        if(substitutedClass == null) {
-            // don't yet know if this class needs to be substituted
-            for (ClassSubstitutor classSubstitutor : classSubstitutors) {
-                final Class<?> substitutedType = classSubstitutor.getClass(originalClass);
-                if(substitutedType != originalClass) {
-                    // one of the substitutors has made a substitution
-                    // (though note, it might have substituted it with null).
-                    substitutedClass = Optional.ofNullable(substitutedType);
-                    break cacheMiss;
-                }
-            }
-            // no substitution
-            substitutedClass = Optional.of(originalClass);
-            cache.put(originalClass, substitutedClass);
-        }
-        return substitutedClass.orElse(null);
+        return cache.computeIfAbsent(originalClass, this::findSubstitutionFor);
+    }
+    
+    // -- HELPER 
+    
+    private Substitution findSubstitutionFor(final Class<?> originalClass) {
+        
+        return classSubstitutors.stream()
+        .map(classSubstitutor->classSubstitutor.getSubstitution(originalClass))
+        .filter(_NullSafe::isPresent)
+        .findFirst()
+        .orElse(Substitution.dontReplaceClass());
+         
     }
+    
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
index ff3d59e..8480b7a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoaderDefault.java
@@ -21,7 +21,6 @@ package org.apache.isis.core.metamodel.specloader;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Objects;
 import java.util.function.Consumer;
 
 import javax.annotation.Nullable;
@@ -53,6 +52,7 @@ import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelService;
 import org.apache.isis.core.metamodel.progmodels.dflt.ProgrammingModelFacetsJava8;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor;
+import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor.Substitution;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorDefault;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorForCollections;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
@@ -356,8 +356,8 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
     public boolean loadSpecifications(Class<?>... domainTypes) {
         // ensure that all types are loadable
         if (Arrays.stream(domainTypes)
-                .map(classSubstitutorRegistry::getClass)
-                .anyMatch(Objects::isNull)) {
+                .map(classSubstitutorRegistry::getSubstitution)
+                .anyMatch(Substitution::isIgnore)) {
             return false;
         }
         Arrays.stream(domainTypes).forEach(this::loadSpecification);
@@ -375,11 +375,13 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
 
         requires(upTo, "upTo");
         
-        val substitutedType = classSubstitutorRegistry.getClass(type);
-        if (substitutedType == null) {
-            return null;
+        val substitute = classSubstitutorRegistry.getSubstitution(type);
+        if (substitute.isIgnore()) {
+            return null; // never inspect
         }
         
+        val substitutedType = substitute.replace(type);
+        
         val typeName = substitutedType.getName();
 
         final ObjectSpecification cachedSpec;
@@ -527,10 +529,13 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
 
     private void invalidateCache(final Class<?> cls) {
 
-        val substitutedType = classSubstitutorRegistry.getClass(cls);
+        val substitute = classSubstitutorRegistry.getSubstitution(cls);
+        if(substitute.isIgnore()) {
+            return;
+        }
 
         ObjectSpecification spec = 
-                loadSpecification(substitutedType, IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
+                loadSpecification(substitute.replace(cls), IntrospectionState.TYPE_AND_MEMBERS_INTROSPECTED);
         
         while(spec != null) {
             val type = spec.getCorrespondingClass();
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index d568250..8ede154 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@ -315,7 +315,7 @@ public class FacetedMethodsBuilder {
             facetedMethod.setType(elementType);
 
             // skip if class substitutor says so.
-            if (classSubstitutorRegistry.getClass(elementType) == null) {
+            if (classSubstitutorRegistry.getSubstitution(elementType).isIgnore()) {
                 continue;
             }
 
@@ -333,7 +333,7 @@ public class FacetedMethodsBuilder {
             final Class<?> returnType = accessorMethod.getReturnType();
 
             // skip if class strategy says so.
-            if (classSubstitutorRegistry.getClass(returnType) == null) {
+            if (classSubstitutorRegistry.getSubstitution(returnType).isIgnore()) {
                 continue;
             }
 
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 db91723..6cc0ba7 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
@@ -163,9 +163,9 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
         final Class<?>[] interfaceTypes = getCorrespondingClass().getInterfaces();
         final List<ObjectSpecification> interfaceSpecList = _Lists.newArrayList();
         for (val interfaceType : interfaceTypes) {
-            val substitutedInterfaceType = classSubstitutorRegistry.getClass(interfaceType);
-            if (substitutedInterfaceType != null) {
-                val interfaceSpec = getSpecificationLoader().loadSpecification(substitutedInterfaceType);
+            val interfaceSubstitute = classSubstitutorRegistry.getSubstitution(interfaceType);
+            if (interfaceSubstitute.isReplace()) {
+                val interfaceSpec = getSpecificationLoader().loadSpecification(interfaceSubstitute.getReplacement());
                 interfaceSpecList.add(interfaceSpec);
             }
         }
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java
index 369660e..39d7418 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/classsubstitutor/ClassSubstitutorTest_getClass.java
@@ -24,16 +24,22 @@ import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 
+import org.apache.isis.core.commons.internal.collections._Lists;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutor;
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorDefault;
+import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
+
+import lombok.val;
 
 public class ClassSubstitutorTest_getClass {
 
     private ClassSubstitutor classSubstitutor;
+    private ClassSubstitutorRegistry classSubstitutorReg;
 
     @Before
     public void setUp() throws Exception {
         classSubstitutor = new ClassSubstitutorDefault();
+        classSubstitutorReg = new ClassSubstitutorRegistry(_Lists.of(classSubstitutor));
     }
 
     public static class SomeDomainObject {
@@ -50,20 +56,23 @@ public class ClassSubstitutorTest_getClass {
 
     @Test
     public void regularDomainObject() throws Exception {
-        Class<?> cls = classSubstitutor.getClass(SomeDomainObject.class);
-        assertEquals(SomeDomainObject.class, cls);
+        val input = SomeDomainObject.class;
+        val replacement = classSubstitutorReg.getSubstitution(input).replace(input);
+        assertEquals(input, replacement);
     }
 
     @Test
     public void someEnum() throws Exception {
-        Class<?> cls = classSubstitutor.getClass(SomeDomainObject.SomeEnum.class);
-        assertEquals(SomeDomainObject.SomeEnum.class, cls);
+        val input = SomeDomainObject.SomeEnum.class;
+        val replacement = classSubstitutorReg.getSubstitution(input).replace(input);
+        assertEquals(input, replacement);
     }
 
     @Test
     public void someAnonymousSubtypeOfEnum() throws Exception {
-        Class<?> cls = classSubstitutor.getClass(SomeDomainObject.SomeEnum.Foo.getClass());
-        assertEquals(SomeDomainObject.SomeEnum.class, cls);
+        val input = SomeDomainObject.SomeEnum.Foo.getClass();
+        val replacement = classSubstitutorReg.getSubstitution(input).replace(input);
+        assertEquals(SomeDomainObject.SomeEnum.class, replacement);
     }
 
 }
diff --git a/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java b/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java
index 9693517..b869dca 100644
--- a/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java
+++ b/persistence/jdo/datanucleus-5/src/main/java/org/apache/isis/persistence/jdo/datanucleus5/metamodel/facets/object/discriminator/JdoDiscriminatorAnnotationFacetFactory.java
@@ -34,6 +34,8 @@ import org.apache.isis.core.metamodel.facets.object.objectspecid.classname.Objec
 import org.apache.isis.core.metamodel.services.classsubstitutor.ClassSubstitutorRegistry;
 import org.apache.isis.persistence.jdo.datanucleus5.metamodel.JdoMetamodelUtil;
 
+import lombok.val;
+
 public class JdoDiscriminatorAnnotationFacetFactory
 extends FacetFactoryAbstract
 implements ObjectSpecIdFacetFactory {
@@ -66,10 +68,16 @@ implements ObjectSpecIdFacetFactory {
             facet = new ObjectSpecIdFacetInferredFromJdoDiscriminatorValueAnnotation(
                     annotationValue, facetHolder);
         } else {
-            final Class<?> substitutedClass = classSubstitutorRegistry.getClass(cls);
-            facet = substitutedClass != null
-                        ? new ObjectSpecIdFacetDerivedFromClassName(substitutedClass.getCanonicalName(), facetHolder)
-                        : null;
+            val substitute = classSubstitutorRegistry.getSubstitution(cls);
+            if(substitute.isIgnore()) {
+                return;
+            }
+                   
+            val substituted = substitute.replace(cls);
+            facet = new ObjectSpecIdFacetDerivedFromClassName(
+                            substituted.getCanonicalName(), 
+                            facetHolder);
+                        
         }
         FacetUtil.addFacet(facet);
     }