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/21 16:57:16 UTC
[isis] branch master updated: ISIS-2158: introduces a new
DomainObject nature (experimental)
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 a751eaa ISIS-2158: introduces a new DomainObject nature (experimental)
a751eaa is described below
commit a751eaa6e632daeb5892d3d2ebef05af38a18178
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Jan 21 17:57:04 2020 +0100
ISIS-2158: introduces a new DomainObject nature (experimental)
- Nature.BEAN to enable an object's lifecycle to entirely be managed by
Spring
---
.../org/apache/isis/applib/annotation/Nature.java | 11 ++-
.../core/config/beans/IsisBeanTypeRegistry.java | 96 ++++++++++++++--------
...atableObjectFacetForDomainObjectAnnotation.java | 1 +
.../specloader/SpecificationLoaderDefault.java | 3 +-
.../demoapp/dom/events/DemoEventSubscriber.java | 7 +-
5 files changed, 81 insertions(+), 37 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 fcb6fc1..df64918 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
@@ -103,10 +103,17 @@ public enum Nature {
VIEW_MODEL,
/**
- * An object that acts as a mix-in to some other object, contributing behaviour and/or derived state based on the
+ * An object that acts as a mix-in to some other object, contributing behavior and/or derived state based on the
* domain object.
*
* @see Mixin
*/
- MIXIN
+ MIXIN,
+
+ /**
+ * An object that is entirely managed by the underlying IoC container.
+ * @apiNote EXPERIMENTAL
+ */
+ BEAN,
+
}
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 6d63f0d..973e458 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
@@ -46,6 +46,7 @@ import static org.apache.isis.core.commons.internal.reflection._Annotations.find
import lombok.Getter;
import lombok.NoArgsConstructor;
+import lombok.Value;
import lombok.val;
import lombok.extern.log4j.Log4j2;
@@ -112,18 +113,15 @@ public final class IsisBeanTypeRegistry implements IsisComponentScanInterceptor,
val type = typeMeta.getUnderlyingClass();
- if(findNearestAnnotation(type, DomainObject.class).isPresent() ||
- findNearestAnnotation(type, ViewModel.class).isPresent() ||
- findNearestAnnotation(type, Mixin.class).isPresent() ||
- findNearestAnnotation(type, Vetoed.class).isPresent()) {
-
- typeMeta.setInjectable(false); // reject
-
- } else {
- typeMeta.setBeanNameOverride(extractObjectType(type).orElse(null));
+ val classification = quickClassify(type);
+
+ val delegated = classification.isDelegateLifecycleManagement();
+ typeMeta.setInjectable(delegated);
+ if(delegated) {
+ typeMeta.setBeanNameOverride(classification.getExplicitObjectType());
}
- val beanSort = quickClassify(type);
+ val beanSort = classification.getBeanSort();
if(beanSort.isToBeIntrospected()) {
addIntrospectableType(beanSort, typeMeta);
@@ -194,82 +192,114 @@ public final class IsisBeanTypeRegistry implements IsisComponentScanInterceptor,
}
}
- public BeanSort quickClassify(Class<?> type) {
+ @Value(staticConstructor = "of")
+ public static class BeanClassification {
+
+ BeanSort beanSort;
+ String explicitObjectType;
+ boolean delegateLifecycleManagement;
+
+ public static BeanClassification delegated(BeanSort beanSort, String explicitObjectType) {
+ return of(beanSort, explicitObjectType, true);
+ }
+
+ public static BeanClassification delegated(BeanSort beanSort) {
+ return delegated(beanSort, null);
+ }
+
+ public static BeanClassification selfManaged(BeanSort beanSort, String explicitObjectType) {
+ return of(beanSort, explicitObjectType, false);
+ }
+
+ public static BeanClassification selfManaged(BeanSort beanSort) {
+ return selfManaged(beanSort, null);
+ }
+
+ }
+
+ public BeanClassification quickClassify(Class<?> type) {
requires(type, "type");
if(findNearestAnnotation(type, Vetoed.class).isPresent()) {
- return BeanSort.UNKNOWN; // reject
+ return BeanClassification.selfManaged(BeanSort.UNKNOWN); // reject
}
val aDomainService = findNearestAnnotation(type, DomainService.class);
if(aDomainService.isPresent()) {
- return BeanSort.MANAGED_BEAN_CONTRIBUTING;
+ return BeanClassification
+ .delegated(BeanSort.MANAGED_BEAN_CONTRIBUTING, objectType(aDomainService.get()));
}
//this takes precedence over whatever @DomainObject has to say
if(_Reflect.containsAnnotation(type, "javax.jdo.annotations.PersistenceCapable")) {
- return BeanSort.ENTITY;
+ return BeanClassification.selfManaged(BeanSort.ENTITY);
}
if(findNearestAnnotation(type, Mixin.class).isPresent()) {
- return BeanSort.MIXIN;
+ return BeanClassification.selfManaged(BeanSort.MIXIN);
}
if(findNearestAnnotation(type, ViewModel.class).isPresent()) {
- return BeanSort.VIEW_MODEL;
+ return BeanClassification.selfManaged(BeanSort.VIEW_MODEL);
}
if(org.apache.isis.applib.ViewModel.class.isAssignableFrom(type)) {
- return BeanSort.VIEW_MODEL;
+ return BeanClassification.selfManaged(BeanSort.VIEW_MODEL);
}
val aDomainObject = findNearestAnnotation(type, DomainObject.class).orElse(null);
if(aDomainObject!=null) {
switch (aDomainObject.nature()) {
+ case BEAN:
+ return BeanClassification.delegated(BeanSort.MANAGED_BEAN_CONTRIBUTING, objectType(aDomainObject));
case MIXIN:
- return BeanSort.MIXIN;
+ return BeanClassification.selfManaged(BeanSort.MIXIN);
case JDO_ENTITY:
- return BeanSort.ENTITY;
+ return BeanClassification.selfManaged(BeanSort.ENTITY);
case EXTERNAL_ENTITY:
case INMEMORY_ENTITY:
case VIEW_MODEL:
case NOT_SPECIFIED:
- return BeanSort.VIEW_MODEL; //because object is not associated with a persistence context unless discovered above
+ //because object is not associated with a persistence context unless discovered above
+ return BeanClassification.selfManaged(BeanSort.VIEW_MODEL);
}
}
if(findNearestAnnotation(type, Component.class).isPresent()) {
- return BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING;
+ return BeanClassification.delegated(BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING);
}
if(Collection.class.isAssignableFrom(type)) {
- return BeanSort.COLLECTION;
+ return BeanClassification.selfManaged(BeanSort.COLLECTION);
}
if(Serializable.class.isAssignableFrom(type)) {
- return BeanSort.VALUE;
+ return BeanClassification.delegated(BeanSort.VALUE);
}
- return BeanSort.UNKNOWN;
+ return BeanClassification.delegated(BeanSort.UNKNOWN);
}
- private Optional<String> extractObjectType(Class<?> type) {
-
- val aDomainService = _Reflect.getAnnotation(type, DomainService.class);
+ private String objectType(DomainService aDomainService) {
if(aDomainService!=null) {
val objectType = aDomainService.objectType();
if(_Strings.isNotEmpty(objectType)) {
- return Optional.of(objectType);
+ return objectType;
}
- return Optional.empty(); // stop processing
}
-
- return Optional.empty();
-
+ return null;
}
-
+ private String objectType(DomainObject aDomainObject) {
+ if(aDomainObject!=null) {
+ val objectType = aDomainObject.objectType();
+ if(_Strings.isNotEmpty(objectType)) {
+ return objectType;
+ }
+ }
+ return null;
+ }
}
\ No newline at end of file
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 764e0de..d1d0c3b 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
@@ -41,6 +41,7 @@ extends RecreatableObjectFacetDeclarativeInitializingAbstract {
.map(nature -> {
switch (nature) {
case NOT_SPECIFIED:
+ case BEAN:
case JDO_ENTITY:
case MIXIN:
// not a recreatable object, so no facet
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 494d43c..6ff6be8 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
@@ -448,7 +448,8 @@ public class SpecificationLoaderDefault implements SpecificationLoader {
&& isisConfiguration.getCore().getMetaModel().getIntrospector().isLockAfterFullIntrospection()) {
val typeRegistry = isisBeanTypeRegistryHolder.getIsisBeanTypeRegistry();
- val sort = typeRegistry.quickClassify(cls);
+ val category = typeRegistry.quickClassify(cls);
+ val sort = category.getBeanSort();
// ISIS-2256:
// throw _Exceptions.illegalState(
diff --git a/examples/demo/src/main/java/demoapp/dom/events/DemoEventSubscriber.java b/examples/demo/src/main/java/demoapp/dom/events/DemoEventSubscriber.java
index d16c0a9..a24e314 100644
--- a/examples/demo/src/main/java/demoapp/dom/events/DemoEventSubscriber.java
+++ b/examples/demo/src/main/java/demoapp/dom/events/DemoEventSubscriber.java
@@ -22,6 +22,7 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.annotation.Import;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@@ -34,6 +35,7 @@ import org.apache.isis.applib.services.wrapper.WrapperFactory;
import lombok.val;
import lombok.extern.log4j.Log4j2;
+import demoapp.dom.events.DemoEventSubscriber.EventLogWriter;
import demoapp.dom.events.EventsDemo.UiButtonEvent;
import static demoapp.utils.DemoUtils.emphasize;
@@ -41,6 +43,9 @@ import static demoapp.utils.DemoUtils.emphasize;
@Service
@Named("demoapp.eventSubscriber")
@Qualifier("demo")
+@Import({
+ EventLogWriter.class
+})
@Log4j2
public class DemoEventSubscriber {
@@ -60,7 +65,7 @@ public class DemoEventSubscriber {
}
@DomainObject(
- nature = Nature.INMEMORY_ENTITY,
+ nature = Nature.BEAN,
objectType = "demoapp.eventLogWriter")
public static class EventLogWriter {