You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/12/13 06:13:55 UTC

[isis] 05/13: ISIS-2050: extends IntrospectionState with additional states for type vs member introspection; inlining methods to simplify

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

danhaywood pushed a commit to branch ISIS-2050
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 34a56c1a1e958ae32ab4a2ea3e59422b973b7010
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Dec 12 23:52:54 2018 +0100

    ISIS-2050: extends IntrospectionState with additional states for type vs member introspection; inlining methods to simplify
    
    ... with the aim of exposing the IntrospectionState upTo so can pass through and honour the phases.
    
    Removed the guards in introspectTypeHierarchy, don't think they are needed any more since only ever called from its caller which checks the introspectionState anyway
---
 .../metamodel/specloader/SpecificationLoader.java  | 69 ++++++++--------------
 .../specloader/specimpl/IntrospectionState.java    | 16 ++++-
 .../specimpl/ObjectSpecificationAbstract.java      | 30 +++++++---
 .../specimpl/dflt/ObjectSpecificationDefault.java  | 23 ++------
 .../ObjectSpecificationOnStandaloneList.java       |  2 +-
 .../IntrospectionState_comparable_Test.java        | 20 +++----
 6 files changed, 78 insertions(+), 82 deletions(-)

diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index 6c5632c..843851a 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@ -240,7 +240,7 @@ public class SpecificationLoader implements ApplicationScopedComponent {
                 public Object call() {
 
                     final ObjectSpecificationAbstract specSpi = (ObjectSpecificationAbstract) specification;
-                    specSpi.introspectUpTo(IntrospectionState.INTROSPECTED);
+                    specSpi.introspectUpTo(IntrospectionState.FULLY_INTROSPECTED);
 
                     return null;
                 }
@@ -395,7 +395,7 @@ public class SpecificationLoader implements ApplicationScopedComponent {
 
         try {
             final Class<?> cls = loadBuiltIn(className);
-            return internalLoadSpecification(cls);
+            return internalLoadSpecification(cls, null, IntrospectionState.FULLY_INTROSPECTED);
         } catch (final ClassNotFoundException e) {
             final ObjectSpecification spec = cache.get(className);
             if (spec == null) {
@@ -410,7 +410,7 @@ public class SpecificationLoader implements ApplicationScopedComponent {
      */
     @Programmatic
     public ObjectSpecification loadSpecification(final Class<?> type) {
-        final ObjectSpecification spec = internalLoadSpecification(type);
+        final ObjectSpecification spec = internalLoadSpecification(type, null, IntrospectionState.FULLY_INTROSPECTED);
         if(spec == null) {
             return null;
         }
@@ -427,61 +427,43 @@ public class SpecificationLoader implements ApplicationScopedComponent {
         return spec;
     }
 
-    private ObjectSpecification internalLoadSpecification(final Class<?> type) {
-        return internalLoadSpecification(type, null, IntrospectionState.INTROSPECTED);
-    }
-
     private ObjectSpecification internalLoadSpecification(
             final Class<?> type,
             final NatureOfService natureFallback,
             final IntrospectionState upTo) {
 
         final Class<?> substitutedType = classSubstitutor.getClass(type);
-        return substitutedType != null
-                ? loadSpecificationForSubstitutedClass(substitutedType, natureFallback, upTo)
-                : null;
-    }
-
-    private ObjectSpecification loadSpecificationForSubstitutedClass(
-            final Class<?> type,
-            final NatureOfService natureFallback,
-            final IntrospectionState upTo) {
-        Assert.assertNotNull(type);
+        if (substitutedType == null) {
+            return null;
+        }
+        Assert.assertNotNull(substitutedType);
 
-        final String typeName = type.getName();
-        final ObjectSpecification spec = cache.get(typeName);
+        final String typeName = substitutedType.getName();
+        ObjectSpecification spec = cache.get(typeName);
         if (spec != null) {
             return spec;
         }
 
-        return loadSpecificationForSubstitutedClassSynchronized(type, natureFallback, upTo);
-    }
-
-
-    private synchronized ObjectSpecification loadSpecificationForSubstitutedClassSynchronized(
-            final Class<?> type,
-            final NatureOfService natureOfServiceFallback,
-            final IntrospectionState upTo) {
+        synchronized (this) {
+            // inside the synchronized block
+            spec = cache.get(typeName);
+            if (spec != null) {
+                return spec;
+            }
 
-        final String typeName = type.getName();
-        final ObjectSpecification spec = cache.get(typeName);
-        if (spec != null) {
-            // because caller isn't synchronized.
-            return spec;
-        }
+            final ObjectSpecification specification = createSpecification(substitutedType, natureFallback);
 
-        final ObjectSpecification specification = createSpecification(type, natureOfServiceFallback);
+            // put into the cache prior to introspecting, to prevent
+            // infinite loops
+            cache.cache(typeName, specification);
 
-        // put into the cache prior to introspecting, to prevent
-        // infinite loops
-        cache.cache(typeName, specification);
+            if (state == State.INTROSPECTING) {
+                final ObjectSpecificationAbstract specSpi = (ObjectSpecificationAbstract) specification;
+                specSpi.introspectUpTo(upTo);
+            }
 
-        if (state == State.INTROSPECTING) {
-            final ObjectSpecificationAbstract specSpi = (ObjectSpecificationAbstract) specification;
-            specSpi.introspectUpTo(upTo);
+            return specification;
         }
-
-        return specification;
     }
 
     /**
@@ -493,7 +475,8 @@ public class SpecificationLoader implements ApplicationScopedComponent {
         boolean anyLoadedAsNull = false;
         for (final Class<?> typeToLoad : typesToLoad) {
             if (typeToLoad != typeToIgnore) {
-                final ObjectSpecification objectSpecification = internalLoadSpecification(typeToLoad);
+                final ObjectSpecification objectSpecification = internalLoadSpecification(typeToLoad, null,
+                        IntrospectionState.FULLY_INTROSPECTED);
                 final boolean loadedAsNull = (objectSpecification == null);
                 anyLoadedAsNull = loadedAsNull || anyLoadedAsNull;
             }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState.java
index 83c91c4..869e2d1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState.java
@@ -21,13 +21,23 @@ public enum IntrospectionState implements Comparable<IntrospectionState> {
      * ObjectSpecIdFacet only.
      */
     NOT_INTROSPECTED,
+
+    /**
+     * Interim stage, to avoid infinite loops while on way to being {@link #PARTIALLY_INTROSPECTED}
+     */
+    TYPE_BEING_INTROSPECTED,
+    /**
+     * Type has been introspected (but not its members).
+     */
+    PARTIALLY_INTROSPECTED,
+
     /**
-     * Interim stage, to avoid infinite loops while on way to being {@link #INTROSPECTED}
+     * Interim stage, to avoid infinite loops while on way to being {@link #FULLY_INTROSPECTED}
      */
-    BEING_INTROSPECTED,
+    MEMBERS_BEING_INTROSPECTED,
     /**
      * Fully introspected... class and also its members.
      */
-    INTROSPECTED
+    FULLY_INTROSPECTED
 
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
index f4a8f89..068ffed 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectSpecificationAbstract.java
@@ -247,7 +247,7 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
     }
 
     protected boolean isNotIntrospected() {
-        return !(introspectionState == IntrospectionState.INTROSPECTED);
+        return !(introspectionState == IntrospectionState.FULLY_INTROSPECTED);
     }
 
     //endregion
@@ -268,24 +268,38 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
     public void introspectUpTo(final IntrospectionState upTo) {
 
         while(this.introspectionState.compareTo(upTo) < 0) {
+
             switch (introspectionState) {
             case NOT_INTROSPECTED:
 
                 // set to avoid infinite loops
-                this.introspectionState = IntrospectionState.BEING_INTROSPECTED;
+                this.introspectionState = IntrospectionState.TYPE_BEING_INTROSPECTED;
                 try {
                     introspectTypeHierarchy();
                     updateFromFacetValues();
-
-                    introspectMembers();
-                    this.introspectionState = IntrospectionState.INTROSPECTED;
+                    this.introspectionState = IntrospectionState.PARTIALLY_INTROSPECTED;
                 } catch(Exception ex) {
                     this.introspectionState = IntrospectionState.NOT_INTROSPECTED;
                     throw ex;
                 }
                 break;
-            case BEING_INTROSPECTED:
-            case INTROSPECTED:
+            case TYPE_BEING_INTROSPECTED:
+                // nothing to do
+                break;
+            case PARTIALLY_INTROSPECTED:
+                // set to avoid infinite loops
+                this.introspectionState = IntrospectionState.MEMBERS_BEING_INTROSPECTED;
+                try {
+                    introspectMembers();
+                    this.introspectionState = IntrospectionState.FULLY_INTROSPECTED;
+                } catch(Exception ex) {
+                    this.introspectionState = IntrospectionState.PARTIALLY_INTROSPECTED;
+                    throw ex;
+                }
+                break;
+            case MEMBERS_BEING_INTROSPECTED:
+                // nothing to do
+            case FULLY_INTROSPECTED:
                 // nothing to do
                 break;
             }
@@ -296,7 +310,7 @@ public abstract class ObjectSpecificationAbstract extends FacetHolderImpl implem
     protected abstract void introspectMembers();
 
 
-    protected void updateSuperclass(final Class<?> superclass) {
+    protected void loadSpecOfSuperclass(final Class<?> superclass) {
         if (superclass == null) {
             return;
         }
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 1c98335..3fb3efb 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
@@ -113,15 +113,10 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
     @Override
     protected void introspectTypeHierarchy() {
 
-        metadataProperties = null;
-        if(isNotIntrospected()) {
-            metadataProperties = facetedMethodsBuilder.introspectClass();
-        }
+        metadataProperties = facetedMethodsBuilder.introspectClass();
 
         // name
-        if(isNotIntrospected()) {
-            addNamedFacetAndPluralFacetIfRequired();
-        }
+        addNamedFacetAndPluralFacetIfRequired();
 
         // go no further if a value
         if(this.containsFacet(ValueFacet.class)) {
@@ -132,10 +127,8 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
         }
 
         // superclass
-        if(isNotIntrospected()) {
-            final Class<?> superclass = getCorrespondingClass().getSuperclass();
-            updateSuperclass(superclass);
-        }
+        final Class<?> superclass = getCorrespondingClass().getSuperclass();
+        loadSpecOfSuperclass(superclass);
 
         // walk superinterfaces
 
@@ -158,12 +151,8 @@ public class ObjectSpecificationDefault extends ObjectSpecificationAbstract impl
             }
         }
 
-        if(isNotIntrospected()) {
-            updateAsSubclassTo(interfaceSpecList);
-        }
-        if(isNotIntrospected()) {
-            updateInterfaces(interfaceSpecList);
-        }
+        updateAsSubclassTo(interfaceSpecList);
+        updateInterfaces(interfaceSpecList);
 
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/ObjectSpecificationOnStandaloneList.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/ObjectSpecificationOnStandaloneList.java
index 63a432c..977a2a0 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/ObjectSpecificationOnStandaloneList.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/standalonelist/ObjectSpecificationOnStandaloneList.java
@@ -67,7 +67,7 @@ public class ObjectSpecificationOnStandaloneList extends ObjectSpecificationAbst
 
     @Override
     protected void introspectTypeHierarchy() {
-        updateSuperclass(Object.class);
+        loadSpecOfSuperclass(Object.class);
 
         addFacet(new CollectionFacetOnStandaloneList(this));
         addFacet(new TypeOfFacetDefaultToObject(this, getSpecificationLoader()) {
diff --git a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState_comparable_Test.java b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState_comparable_Test.java
index eefda8e..91ec216 100644
--- a/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState_comparable_Test.java
+++ b/core/metamodel/src/test/java/org/apache/isis/core/metamodel/specloader/specimpl/IntrospectionState_comparable_Test.java
@@ -5,8 +5,8 @@ import org.hamcrest.Matcher;
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.Test;
 
-import static org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState.BEING_INTROSPECTED;
-import static org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState.INTROSPECTED;
+import static org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState.MEMBERS_BEING_INTROSPECTED;
+import static org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState.FULLY_INTROSPECTED;
 import static org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState.NOT_INTROSPECTED;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
@@ -16,16 +16,16 @@ public class IntrospectionState_comparable_Test {
     @Test
     public void all_of_em() throws Exception {
         assertComparison(NOT_INTROSPECTED, NOT_INTROSPECTED, equal());
-        assertComparison(NOT_INTROSPECTED, BEING_INTROSPECTED, negative());
-        assertComparison(NOT_INTROSPECTED, INTROSPECTED, negative());
+        assertComparison(NOT_INTROSPECTED, MEMBERS_BEING_INTROSPECTED, negative());
+        assertComparison(NOT_INTROSPECTED, FULLY_INTROSPECTED, negative());
 
-        assertComparison(BEING_INTROSPECTED, NOT_INTROSPECTED, positive());
-        assertComparison(BEING_INTROSPECTED, BEING_INTROSPECTED, equal());
-        assertComparison(BEING_INTROSPECTED, INTROSPECTED, negative());
+        assertComparison(MEMBERS_BEING_INTROSPECTED, NOT_INTROSPECTED, positive());
+        assertComparison(MEMBERS_BEING_INTROSPECTED, MEMBERS_BEING_INTROSPECTED, equal());
+        assertComparison(MEMBERS_BEING_INTROSPECTED, FULLY_INTROSPECTED, negative());
 
-        assertComparison(INTROSPECTED, NOT_INTROSPECTED, positive());
-        assertComparison(INTROSPECTED, BEING_INTROSPECTED, positive());
-        assertComparison(INTROSPECTED, INTROSPECTED, equal());
+        assertComparison(FULLY_INTROSPECTED, NOT_INTROSPECTED, positive());
+        assertComparison(FULLY_INTROSPECTED, MEMBERS_BEING_INTROSPECTED, positive());
+        assertComparison(FULLY_INTROSPECTED, FULLY_INTROSPECTED, equal());
     }
 
     private Matcher<Integer> equal() {