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 2021/05/04 19:08:58 UTC
[isis] branch master updated: ISIS-2641: MM: fix abstract type
detection
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 35298a3 ISIS-2641: MM: fix abstract type detection
35298a3 is described below
commit 35298a360bb839d12eb18b4f28b6506b417c01a6
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue May 4 21:07:57 2021 +0200
ISIS-2641: MM: fix abstract type detection
also adding tests
---
.../config/beans/IsisBeanTypeClassifierImpl.java | 35 ++++++-----
.../specloader/specimpl/FacetedMethodsBuilder.java | 6 --
.../DomainModelTest_usingGoodDomain.java | 69 ++++++++++++++++++----
...TypeInterface.java => ElementTypeAbstract.java} | 21 ++++++-
.../testdomain/model/good/ElementTypeConcrete.java | 5 +-
.../model/good/ElementTypeInterface.java | 18 +++++-
.../testdomain/model/good/ProperElementTypeVm.java | 9 +++
7 files changed, 127 insertions(+), 36 deletions(-)
diff --git a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java
index acf91ff..4e2e72e 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/beans/IsisBeanTypeClassifierImpl.java
@@ -55,10 +55,30 @@ implements IsisBeanTypeClassifier {
@Override
public BeanClassification classify(final @NonNull Class<?> type) {
+ // handle arbitrary types ...
+
if(type.isPrimitive()) {
return BeanClassification.delegated(BeanSort.VALUE);
}
+ if(Collection.class.isAssignableFrom(type)
+ || Can.class.isAssignableFrom(type)
+ || type.isArray()) {
+ return BeanClassification.selfManaged(BeanSort.COLLECTION);
+ }
+
+ if(type.isInterface()
+ // modifier predicate must be called after testing for non-scalar type above,
+ // otherwise we'd get false positives
+ || Modifier.isAbstract(type.getModifiers())) {
+
+ // apiNote: abstract types and interfaces cannot be vetoed
+ // and should also never be identified as ENTITY, VIEWMODEL or MIXIN
+ return BeanClassification.delegated(BeanSort.ABSTRACT);
+ }
+
+ // handle actual bean types ...
+
if(findNearestAnnotation(type, Vetoed.class).isPresent()
|| findNearestAnnotation(type, Programmatic.class).isPresent()) {
return BeanClassification.selfManaged(BeanSort.VETOED); // reject
@@ -71,7 +91,7 @@ implements IsisBeanTypeClassifier {
&& !profiles.stream().anyMatch(this::isProfileActive)) {
return BeanClassification.selfManaged(BeanSort.VETOED); // reject
}
-
+
val aDomainService = findNearestAnnotation(type, DomainService.class);
if(aDomainService.isPresent()) {
return BeanClassification
@@ -142,19 +162,6 @@ implements IsisBeanTypeClassifier {
return BeanClassification.delegated(BeanSort.MANAGED_BEAN_NOT_CONTRIBUTING);
}
- if(Collection.class.isAssignableFrom(type)
- || Can.class.isAssignableFrom(type)
- || type.isArray()) {
- return BeanClassification.selfManaged(BeanSort.COLLECTION);
- }
-
- if(type.isInterface()
- // modifier predicate must be called after testing for non-scalar type above,
- // otherwise we'd get false positives
- || Modifier.isAbstract(type.getModifiers())) {
- return BeanClassification.delegated(BeanSort.ABSTRACT);
- }
-
if(Serializable.class.isAssignableFrom(type)) {
return BeanClassification.delegated(BeanSort.VALUE);
}
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 34a63d7..f5959e4 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
@@ -38,7 +38,6 @@ import org.apache.isis.applib.exceptions.unrecoverable.MetaModelException;
import org.apache.isis.commons.internal.base._NullSafe;
import org.apache.isis.commons.internal.collections._Lists;
import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.commons.internal.debug._Probe;
import org.apache.isis.commons.internal.reflection._Annotations;
import org.apache.isis.core.metamodel.commons.CanBeVoid;
import org.apache.isis.core.metamodel.commons.MethodUtil;
@@ -229,11 +228,6 @@ public class FacetedMethodsBuilder {
TypeExtractor.streamMethodReturn(associationCandidateMethods)
.filter(typeToLoad->typeToLoad!=introspectedClass)
- .peek(typeToLoad->{
- if(getClassName().contains("ProperElementTypeVm")) {
- _Probe.errOut("load %s", typeToLoad);
- }
- })
.forEach(typeToLoad->specLoader.loadSpecification(typeToLoad, IntrospectionState.TYPE_INTROSPECTED));
// now create FacetedMethods for collections and for properties
diff --git a/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java b/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
index 34934b1..bcabb68 100644
--- a/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
+++ b/regressiontests/stable-domainmodel/src/test/java/org/apache/isis/testdomain/domainmodel/DomainModelTest_usingGoodDomain.java
@@ -45,12 +45,14 @@ import org.apache.isis.core.metamodel.facetapi.FacetHolder;
import org.apache.isis.core.metamodel.facets.members.publish.execution.ExecutionPublishingFacet;
import org.apache.isis.core.metamodel.facets.object.icon.IconFacet;
import org.apache.isis.core.metamodel.facets.object.title.TitleFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.MixedIn;
import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.core.metamodel.specloader.specimpl.IntrospectionState;
import org.apache.isis.schema.metamodel.v2.DomainClassDto;
import org.apache.isis.testdomain.conf.Configuration_headless;
import org.apache.isis.testdomain.model.good.Configuration_usingValidDomain;
+import org.apache.isis.testdomain.model.good.ElementTypeAbstract;
import org.apache.isis.testdomain.model.good.ElementTypeConcrete;
import org.apache.isis.testdomain.model.good.ElementTypeInterface;
import org.apache.isis.testdomain.model.good.ProperElementTypeVm;
@@ -278,7 +280,9 @@ class DomainModelTest_usingGoodDomain {
}
@Test
- void elementTypes_shouldBeIntrospected_whenNotConcrete() {
+ void elementTypes_shouldBeIntrospected_whenDiscoveredViaGenerics_usingNoWildcards() {
+
+ // when using generic type (no wild-cards)
val vmSpec = specificationLoader.loadSpecification(ProperElementTypeVm.class,
IntrospectionState.FULLY_INTROSPECTED);
@@ -288,32 +292,75 @@ class DomainModelTest_usingGoodDomain {
assertEquals(ElementTypeConcrete.class, concreteCollSpec.getCorrespondingClass());
assertEquals(BeanSort.VIEW_MODEL, concreteCollSpec.getBeanSort());
+ assertHasAction(concreteCollSpec, "abstractAction");
+ assertHasAction(concreteCollSpec, "interfaceAction");
+ assertHasProperty(concreteCollSpec, "abstractProp");
+ assertHasProperty(concreteCollSpec, "interfaceProp");
val interfaceColl = vmSpec.getCollectionElseFail("interfaceColl");
val interfaceCollSpec = interfaceColl.getSpecification();
assertEquals(ElementTypeInterface.class, interfaceCollSpec.getCorrespondingClass());
assertEquals(BeanSort.ABSTRACT, interfaceCollSpec.getBeanSort());
+ assertHasAction(interfaceCollSpec, "interfaceAction");
+ assertHasProperty(interfaceCollSpec, "interfaceProp");
+
+ val abstractColl = vmSpec.getCollectionElseFail("abstractColl");
+ val abstractCollSpec = abstractColl.getSpecification();
+
+ assertEquals(ElementTypeAbstract.class, abstractCollSpec.getCorrespondingClass());
+ assertEquals(BeanSort.ABSTRACT, abstractCollSpec.getBeanSort());
+ assertHasAction(abstractCollSpec, "abstractAction");
+ assertHasProperty(abstractCollSpec, "abstractProp");
+
+ }
+
+ @Test
+ void elementTypes_shouldBeIntrospected_whenDiscoveredViaGenerics_usingWildcards() {
+
+ // when using generic type (w/ wild-cards)
+
+ val vmSpec = specificationLoader.loadSpecification(ProperElementTypeVm.class,
+ IntrospectionState.FULLY_INTROSPECTED);
- // when using generic type wild-cards
+ val concreteColl = vmSpec.getCollectionElseFail("concreteColl2");
+ val concreteCollSpec = concreteColl.getSpecification();
- val concreteColl2 = vmSpec.getCollectionElseFail("concreteColl2");
- val concreteCollSpec2 = concreteColl2.getSpecification();
+ assertEquals(ElementTypeConcrete.class, concreteCollSpec.getCorrespondingClass());
+ assertEquals(BeanSort.VIEW_MODEL, concreteCollSpec.getBeanSort());
+ assertHasAction(concreteCollSpec, "abstractAction");
+ assertHasAction(concreteCollSpec, "interfaceAction");
+ assertHasProperty(concreteCollSpec, "abstractProp");
+ assertHasProperty(concreteCollSpec, "interfaceProp");
- assertEquals(ElementTypeConcrete.class, concreteCollSpec2.getCorrespondingClass());
- assertEquals(BeanSort.VIEW_MODEL, concreteCollSpec2.getBeanSort());
+ val interfaceColl = vmSpec.getCollectionElseFail("interfaceColl2");
+ val interfaceCollSpec = interfaceColl.getSpecification();
- val interfaceColl2 = vmSpec.getCollectionElseFail("interfaceColl2");
- val interfaceCollSpec2 = interfaceColl2.getSpecification();
+ assertEquals(ElementTypeInterface.class, interfaceCollSpec.getCorrespondingClass());
+ assertEquals(BeanSort.ABSTRACT, interfaceCollSpec.getBeanSort());
+ assertHasAction(interfaceCollSpec, "interfaceAction");
+ assertHasProperty(interfaceCollSpec, "interfaceProp");
- assertEquals(ElementTypeInterface.class, interfaceCollSpec2.getCorrespondingClass());
- assertEquals(BeanSort.ABSTRACT, interfaceCollSpec2.getBeanSort());
+ val abstractColl = vmSpec.getCollectionElseFail("abstractColl2");
+ val abstractCollSpec = abstractColl.getSpecification();
+
+ assertEquals(ElementTypeAbstract.class, abstractCollSpec.getCorrespondingClass());
+ assertEquals(BeanSort.ABSTRACT, abstractCollSpec.getBeanSort());
+ assertHasAction(abstractCollSpec, "abstractAction");
+ assertHasProperty(abstractCollSpec, "abstractProp");
- // TODO for the abstract case, we also want to see any members and the title-facet
}
// -- HELPER
+ private void assertHasProperty(ObjectSpecification spec, String propertyId) {
+ spec.getPropertyElseFail(propertyId);
+ }
+
+ private void assertHasAction(ObjectSpecification spec, String actionId) {
+ spec.getActionElseFail(actionId);
+ }
+
private void assertHasPublishedActionFacet(FacetHolder facetHolder) {
val facet = facetHolder.getFacet(ExecutionPublishingFacet.class);
assertNotNull(facet);
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeAbstract.java
similarity index 65%
copy from regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java
copy to regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeAbstract.java
index 8d0d788..9e588ad 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeAbstract.java
@@ -18,10 +18,25 @@
*/
package org.apache.isis.testdomain.model.good;
-public interface ElementTypeInterface {
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.Property;
- default String title() {
- return "aTitle";
+import lombok.Getter;
+import lombok.Setter;
+
+public abstract class ElementTypeAbstract {
+
+ public String title() {
+ return "AbstractTitle";
}
+ @Action
+ public void abstractAction(String p0, String p1) {
+ // no-op, just testing meta-data
+ }
+
+ @Property
+ @Getter @Setter
+ private String abstractProp = "abstractProp";
+
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeConcrete.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeConcrete.java
index aebf26b..c0c558c 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeConcrete.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeConcrete.java
@@ -21,6 +21,9 @@ package org.apache.isis.testdomain.model.good;
import org.apache.isis.applib.annotation.DomainObject;
@DomainObject(objectType = "isis.testdomain.ElementTypeConcrete")
-public class ElementTypeConcrete implements ElementTypeInterface {
+public class ElementTypeConcrete
+extends ElementTypeAbstract
+implements ElementTypeInterface {
+
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java
index 8d0d788..8c612f8 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ElementTypeInterface.java
@@ -18,10 +18,26 @@
*/
package org.apache.isis.testdomain.model.good;
+import org.apache.isis.applib.annotation.Action;
+import org.apache.isis.applib.annotation.Property;
+
public interface ElementTypeInterface {
default String title() {
- return "aTitle";
+ return "InterfaceTitle";
+ }
+
+ @Action
+ default void interfaceAction(String p0, String p1) {
+ // no-op, just testing meta-data
+ }
+
+ @Property
+ default String getInterfaceProp() {
+ return "InterfaceProp";
+ }
+ default void setInterfaceProp(String prop) {
+ // no-op, just testing meta-data
}
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ProperElementTypeVm.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ProperElementTypeVm.java
index afd6990..e5db5aa 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ProperElementTypeVm.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/model/good/ProperElementTypeVm.java
@@ -27,6 +27,9 @@ import org.apache.isis.applib.annotation.Nature;
import lombok.Getter;
import lombok.Setter;
+/**
+ * @see <a href="https://issues.apache.org/jira/browse/ISIS-2499">ISIS-2499</a>
+ */
@DomainObject(nature = Nature.VIEW_MODEL)
public class ProperElementTypeVm {
@@ -34,12 +37,18 @@ public class ProperElementTypeVm {
@Getter @Setter private List<ElementTypeInterface> interfaceColl;
@Collection
+ @Getter @Setter private List<ElementTypeAbstract> abstractColl;
+
+ @Collection
@Getter @Setter private List<ElementTypeConcrete> concreteColl;
@Collection
@Getter @Setter private List<? extends ElementTypeInterface> interfaceColl2;
@Collection
+ @Getter @Setter private List<? extends ElementTypeAbstract> abstractColl2;
+
+ @Collection
@Getter @Setter private List<? extends ElementTypeConcrete> concreteColl2;
}