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

commit 11fa35fbb4f360a64b481f8ad5335f7f9626a574
Author: Andi Huber <[email protected]>
AuthorDate: Tue Sep 1 11:47:59 2020 +0200

    ISIS-2332: new DomainObject.nature: JPA_ENTITY
    
    also when spec-loading initially, use the immutable BeanSort from quick
    classification (as determined during class scanning)
---
 .../org/apache/isis/applib/annotation/Nature.java  | 16 +++++++
 .../core/config/beans/IsisBeanTypeRegistry.java    |  1 +
 ...atableObjectFacetForDomainObjectAnnotation.java |  1 +
 .../specloader/SpecificationLoaderDefault.java     | 54 ++++++++++++++++++----
 .../specimpl/ObjectSpecificationAbstract.java      | 26 +++++------
 .../specimpl/dflt/ObjectSpecificationDefault.java  |  4 +-
 .../bootstrapping/JpaBootstrappingTest.java        | 11 +++++
 .../isis/testdomain/jpa/entities/JpaBook.java      |  2 +
 .../isis/testdomain/jpa/entities/JpaInventory.java |  2 +
 .../isis/testdomain/jpa/entities/JpaProduct.java   |  4 +-
 .../testdomain/jpa/entities/JpaProductComment.java |  4 +-
 11 files changed, 101 insertions(+), 24 deletions(-)

diff --git 
a/api/applib/src/main/java/org/apache/isis/applib/annotation/Nature.java 
b/api/applib/src/main/java/org/apache/isis/applib/annotation/Nature.java
index b044747..8ac77a7 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/annotation/Nature.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/annotation/Nature.java
@@ -55,6 +55,22 @@ public enum Nature {
      */
     // tag::refguide[]
     JDO_ENTITY,
+    
+    // end::refguide[]
+    /**
+     * A domain entity whose persistence is managed internally by Isis, using 
JPA as the persistence implementation.
+     * Domain entities are considered to be part of the domain model layer.
+     *
+     * <p>
+     *     Domain entities are considered to be part of the domain model layer.
+     * </p>
+     *
+     * <p>
+     *    Currently implies no additional semantics other than documentation.
+     * </p>
+     */
+    // tag::refguide[]
+    JPA_ENTITY,
 
     // end::refguide[]
     /**
diff --git 
a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistry.java
 
b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistry.java
index f37a595..bbc12e8 100644
--- 
a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistry.java
+++ 
b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeRegistry.java
@@ -273,6 +273,7 @@ public final class IsisBeanTypeRegistry implements 
IsisComponentScanInterceptor,
             case MIXIN:
                 return BeanClassification.selfManaged(BeanSort.MIXIN);
             case JDO_ENTITY:
+            case JPA_ENTITY:
                 return BeanClassification.selfManaged(BeanSort.ENTITY);
             case EXTERNAL_ENTITY:
             case INMEMORY_ENTITY:
diff --git 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
index d1d0c3b..1b41056 100644
--- 
a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
+++ 
b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
@@ -43,6 +43,7 @@ extends RecreatableObjectFacetDeclarativeInitializingAbstract 
{
                     case NOT_SPECIFIED:
                     case BEAN:
                     case JDO_ENTITY:
+                    case JPA_ENTITY:
                     case MIXIN:
                         // not a recreatable object, so no facet
                         return null;
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 14d9046..b46a3b2 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
@@ -38,6 +38,7 @@ import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Service;
 
 import org.apache.isis.applib.annotation.OrderPrecedence;
+import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.core.commons.internal.assertions._Assert;
 import org.apache.isis.core.commons.internal.base._Blackhole;
@@ -75,6 +76,7 @@ import 
org.apache.isis.core.metamodel.valuetypes.ValueTypeRegistry;
 import static org.apache.isis.core.commons.internal.base._With.requires;
 
 import lombok.Getter;
+import lombok.NonNull;
 import lombok.Setter;
 import lombok.val;
 import lombok.extern.log4j.Log4j2;
@@ -237,9 +239,9 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
         .forEach(entry->{
 
             val type = entry.getKey();
-            val sort = entry.getValue(); 
-
-            val spec = loadSpecification(type, 
IntrospectionState.NOT_INTROSPECTED);
+            val sort = entry.getValue();
+            
+            val spec = primeSpecification(type, sort);
             if(spec==null) {
                 typeRegistry.veto(type);
                 return;
@@ -286,7 +288,7 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
             setMetamodelFullyIntrospected(true);
         }
     }
-    
+
     @Override
     public ValidationFailures getValidationResult() {
         return validationResult.get();
@@ -363,9 +365,44 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
         return true;
     }
 
+    
+    //TODO[ISIS-2332] when the cache is cleared, sort information get's lost
+    //instead better integrate the isis bean type registry with the spec 
loading
+    @Nullable
+    private ObjectSpecification primeSpecification(
+            final @Nullable Class<?> type,
+            final @NonNull BeanSort sort) {
+        
+        if(type==null) {
+            return null;
+        }
+
+        val substitute = classSubstitutorRegistry.getSubstitution(type);
+        if (substitute.isNeverIntrospect()) {
+            return null; // never inspect
+        }
+        
+        val substitutedType = substitute.apply(type);
+        
+        val typeName = substitutedType.getName();
+        
+        final ObjectSpecification cachedSpec;
+        
+        // we try not to block on long running code ... 
'spec.introspectUpTo(upTo);'
+        synchronized (cache) {
+            cachedSpec = cache.computeIfAbsent(typeName, 
__->createSpecification(substitutedType, sort));
+        }
+
+        cachedSpec.introspectUpTo(IntrospectionState.NOT_INTROSPECTED);
+
+        return cachedSpec;
+        
+    }
+    
+    
     @Override @Nullable
     public ObjectSpecification loadSpecification(
-            @Nullable final Class<?> type, 
+            final @Nullable Class<?> type,
             final IntrospectionState upTo) {
 
         if(type==null) {
@@ -387,7 +424,7 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
         
         // we try not to block on long running code ... 
'spec.introspectUpTo(upTo);'
         synchronized (cache) {
-            cachedSpec = cache.computeIfAbsent(typeName, 
__->createSpecification(substitutedType));
+            cachedSpec = cache.computeIfAbsent(typeName, 
__->createSpecification(substitutedType, BeanSort.UNKNOWN));
         }
 
         cachedSpec.introspectUpTo(upTo);
@@ -507,7 +544,7 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
     /**
      * Creates the appropriate type of {@link ObjectSpecification}.
      */
-    private ObjectSpecification createSpecification(final Class<?> cls) {
+    private ObjectSpecification createSpecification(final Class<?> cls, final 
BeanSort beanSort) {
 
         guardAgainstMetamodelLockedAfterFullIntrospection(cls);
 
@@ -518,6 +555,7 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
         val managedBeanNameIfAny = typeRegistry.getManagedBeanNameForType(cls);
         val objectSpec = new ObjectSpecificationDefault(
                         cls,
+                        beanSort,
                         metaModelContext,
                         facetProcessor,
                         managedBeanNameIfAny.orElse(null),
@@ -548,7 +586,7 @@ public class SpecificationLoaderDefault implements 
SpecificationLoader {
         .forEach(spec -> {
             try {
                 spec.introspectUpTo(upTo);
-            } catch (Throwable ex) {
+            } catch (Throwable ex) {    
                 log.error(ex);
                 throw ex;
             }
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 a8fe145..74609ea 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
@@ -95,7 +95,7 @@ import lombok.val;
 import lombok.extern.log4j.Log4j2;
 
 @EqualsAndHashCode(of = "correspondingClass", callSuper = false)
[email protected](of = {"correspondingClass", "fullName", "managedObjectSort"})
[email protected](of = {"correspondingClass", "fullName", "beanSort"})
 @Log4j2 
 public abstract class ObjectSpecificationAbstract 
 extends FacetHolderImpl 
@@ -206,12 +206,14 @@ implements ObjectSpecification {
     public ObjectSpecificationAbstract(
             final Class<?> introspectedClass,
             final String shortName,
+            final BeanSort beanSort,
             final FacetProcessor facetProcessor,
             final PostProcessor postProcessor) {
 
         this.correspondingClass = introspectedClass;
         this.fullName = introspectedClass.getName();
         this.shortName = shortName;
+        this.beanSort = beanSort;
 
         this.isAbstract = ClassExtensions.isAbstract(introspectedClass);
 
@@ -876,19 +878,17 @@ implements ObjectSpecification {
         return new ObjectValidityContext(targetAdapter, getIdentifier(), 
interactionInitiatedBy);
     }
 
-    private BeanSort managedObjectSort;
+    //@Setter(AccessLevel.PROTECTED)
+    @Getter
+    private final BeanSort beanSort;
 
-    @Override
-    public BeanSort getBeanSort() {
-        if(managedObjectSort==null) {
-            setManagedObjectSort(sortOf(this));
-        }
-        return managedObjectSort;
-    }
-
-    protected void setManagedObjectSort(BeanSort managedObjectSort) {
-        this.managedObjectSort = managedObjectSort;
-    }
+//    @Override
+//    public BeanSort getBeanSort() {
+//        if(beanSort==null) {
+//            setBeanSort(sortOf(this));
+//        }
+//        return beanSort;
+//    }
 
 
     // -- convenience isXxx (looked up from facets)
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 d985165..9ccfeed 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
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
 
 import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.services.metamodel.BeanSort;
 import org.apache.isis.core.commons.collections.Can;
 import org.apache.isis.core.commons.internal.base._Lazy;
 import org.apache.isis.core.commons.internal.collections._Lists;
@@ -100,13 +101,14 @@ public class ObjectSpecificationDefault extends 
ObjectSpecificationAbstract impl
 
     public ObjectSpecificationDefault(
             final Class<?> correspondingClass,
+            final BeanSort beanSort,
             final MetaModelContext metaModelContext,
             final FacetProcessor facetProcessor,
             final String nameIfIsManagedBean,
             final PostProcessor postProcessor,
             final ClassSubstitutorRegistry classSubstitutorRegistry) {
         
-        super(correspondingClass, determineShortName(correspondingClass), 
facetProcessor, postProcessor);
+        super(correspondingClass, determineShortName(correspondingClass), 
beanSort, facetProcessor, postProcessor);
 
         setMetaModelContext(metaModelContext);
 
diff --git 
a/examples/smoketests/incubating/src/test/java/org/apache/isis/testdomain/bootstrapping/JpaBootstrappingTest.java
 
b/examples/smoketests/incubating/src/test/java/org/apache/isis/testdomain/bootstrapping/JpaBootstrappingTest.java
index 155868e..79ad201 100644
--- 
a/examples/smoketests/incubating/src/test/java/org/apache/isis/testdomain/bootstrapping/JpaBootstrappingTest.java
+++ 
b/examples/smoketests/incubating/src/test/java/org/apache/isis/testdomain/bootstrapping/JpaBootstrappingTest.java
@@ -43,6 +43,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.isis.applib.services.repository.RepositoryService;
 import org.apache.isis.core.config.presets.IsisPresets;
+import org.apache.isis.core.metamodel.facets.object.entity.EntityFacet;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.iactn.IsisInteractionFactory;
 import org.apache.isis.testdomain.Incubating;
 import org.apache.isis.testdomain.Smoketest;
@@ -67,6 +69,7 @@ class JpaBootstrappingTest /*extends 
IsisIntegrationTestAbstract*/ {
     @Inject private Optional<PlatformTransactionManager> 
platformTransactionManager; 
     @Inject private RepositoryService repository;
     @Inject private IsisInteractionFactory isisInteractionFactory;
+    @Inject private SpecificationLoader specLoader;
     //@Inject private TransactionService transactionService;
 
     @BeforeAll
@@ -106,6 +109,14 @@ class JpaBootstrappingTest /*extends 
IsisIntegrationTestAbstract*/ {
         assertTrue(platformTransactionManager.isPresent());
     }
     
+    @Test @Order(0) 
+    void jpaEntities_shouldBeRecognisedAsSuch() {
+        val spec = specLoader.loadSpecification(JpaProduct.class);
+        assertTrue(spec.isEntity());
+        assertNotNull(spec.getFacet(EntityFacet.class));
+    }
+    
+    
     @Test @Order(1) @Rollback(false) 
     void sampleInventoryShouldBeSetUp() {
         
diff --git 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaBook.java
 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaBook.java
index ceccbc8..9db0b9a 100644
--- 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaBook.java
+++ 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaBook.java
@@ -23,6 +23,7 @@ import javax.persistence.Entity;
 
 import org.apache.isis.applib.annotation.Auditing;
 import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.annotation.Publishing;
 
@@ -37,6 +38,7 @@ import lombok.ToString;
 //@Discriminator(value="Book")
 @DomainObject(
         objectType = "testdomain.jpa.Book",
+        nature = Nature.JPA_ENTITY, //TODO[ISIS-2332] should not be required, 
when using JPA quick classify SPI 
         publishing=Publishing.ENABLED, 
         auditing = Auditing.ENABLED)
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
diff --git 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaInventory.java
 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaInventory.java
index 543e14a..8d49f05 100644
--- 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaInventory.java
+++ 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaInventory.java
@@ -26,6 +26,7 @@ import javax.persistence.Entity;
 import org.apache.isis.applib.annotation.Auditing;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.DomainObjectLayout;
+import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.Property;
 
 import lombok.AccessLevel;
@@ -41,6 +42,7 @@ import lombok.ToString;
 //@Version(strategy= VersionStrategy.DATE_TIME, column="version")
 @DomainObject(
         objectType = "testdomain.jdo.Inventory",
+        nature = Nature.JPA_ENTITY, //TODO[ISIS-2332] should not be required, 
when using JPA quick classify SPI
         auditing = Auditing.ENABLED)
 @DomainObjectLayout()  // causes UI events to be triggered
 @NoArgsConstructor(access = AccessLevel.PROTECTED) 
diff --git 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProduct.java
 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProduct.java
index 6cc0461..ec03682 100644
--- 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProduct.java
+++ 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProduct.java
@@ -30,6 +30,7 @@ import javax.persistence.Id;
 import org.apache.isis.applib.annotation.Collection;
 import org.apache.isis.applib.annotation.DomainObject;
 import org.apache.isis.applib.annotation.Editing;
+import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.Property;
 
 import lombok.AccessLevel;
@@ -44,7 +45,8 @@ import lombok.ToString;
 //@Inheritance(strategy=InheritanceStrategy.NEW_TABLE)
 //@Discriminator(strategy=DiscriminatorStrategy.VALUE_MAP, value="Product")
 @DomainObject(
-        objectType = "testdomain.jpa.Product"
+        objectType = "testdomain.jpa.Product",
+        nature = Nature.JPA_ENTITY //TODO[ISIS-2332] should not be required, 
when using JPA quick classify SPI
         )
 @NoArgsConstructor(access = AccessLevel.PROTECTED)
 @AllArgsConstructor(access = AccessLevel.PROTECTED) 
diff --git 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
index bf3afbb..24634ac 100644
--- 
a/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
+++ 
b/examples/smoketests/stable/src/main/java/org/apache/isis/testdomain/jpa/entities/JpaProductComment.java
@@ -27,6 +27,7 @@ import javax.persistence.GenerationType;
 import javax.persistence.Id;
 
 import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.Nature;
 import org.apache.isis.applib.annotation.Property;
 import org.apache.isis.applib.mixins.timestamp.Timestampable;
 
@@ -35,7 +36,8 @@ import lombok.Setter;
 
 @Entity
 @DomainObject(
-        objectType = "testdomain.jpa.ProductComment")
+        objectType = "testdomain.jpa.ProductComment",
+        nature = Nature.JPA_ENTITY) //TODO[ISIS-2332] should not be required, 
when using JPA quick classify SPI
 public class JpaProductComment implements Timestampable {
 
     @Id

Reply via email to