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/17 09:16:51 UTC
[isis] branch master updated: ISIS-2681: don't use MetaModelService
internally for LogicalType resolution
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 20065eb ISIS-2681: don't use MetaModelService internally for LogicalType resolution
20065eb is described below
commit 20065eb0489caaa80189bf0c715bf34d7f98ba86
Author: ahuber@apache.org <ah...@luna>
AuthorDate: Mon May 17 11:16:35 2021 +0200
ISIS-2681: don't use MetaModelService internally for LogicalType
resolution
---
.../services/metamodel/MetaModelService.java | 4 +-
.../DomainObjectAnnotationFacetFactory.java | 29 ++-----------
.../objectspecid/ObjectTypeFacetAbstract.java | 3 +-
.../specloader/LogicalTypeResolverDefault.java | 48 ++++++++--------------
.../runtimeservices/jaxb/JaxbServiceDefault.java | 14 +++----
.../TableColumnVisibilityServiceForSecman.java | 10 ++---
6 files changed, 37 insertions(+), 71 deletions(-)
diff --git a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
index 1e0fae5..ca8b540 100644
--- a/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
+++ b/api/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
@@ -43,7 +43,9 @@ public interface MetaModelService {
/**
* Provides a lookup by objectType of a domain class' object type, as defined by
* {@link DomainObject#objectType()} (or any other mechanism that corresponds to Isis'
- * <code>ObjectTypeFacet</code>).
+ * <code>ObjectTypeFacet</code>). Will return an empty result if there is no
+ * such non-abstract class registered.
+ * (interfaces and abstract types are never added to the lookup table).
*/
Optional<LogicalType> lookupLogicalTypeByName(final String objectType);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index 054bf58..a864ee9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@ -496,17 +496,15 @@ implements
@Override
public void validate(ObjectSpecification objSpec) {
- // Allow members of a type hierarchy including interfaces to share the same
- // @DomainObject(objectType=...)
+ // @DomainObject(objectType=...) must be unique among non-abstract types
// Eg. having an ApplicationUser interface and a concrete ApplicationUser (JDO)
// that have the same @DomainObject(objectType=...) should be allowed.
- // The only constraint that applies, is that there cannot be multiple bookmark-able
+ // A hard constraint that applies, is that there cannot be multiple bookmark-able
// types that share the same @DomainObject(objectType=...).
// This must be guaranteed by MM validation.
// - see also LogicalTypeResolver.register(...)
- if(objSpec.isManagedBean()
- || objSpec.isAbstract()) {
+ if(objSpec.isAbstract()) {
return;
}
collidingSpecsByLogicalTypeName.putElement(objSpec.getLogicalTypeName(), objSpec);
@@ -535,27 +533,8 @@ implements
collidingSpecsByLogicalTypeName.clear();
}
- // detect whether specs (of concrete type) belong to more than one type hierarchy
private boolean isObjectTypeCollision(final List<ObjectSpecification> specs) {
- if(specs.size()<=1) {
- return false;
- }
- // algorithm: check all non-first against the first
-
- val first = specs.get(0);
-
- val shareSameTypeHierarchy = specs.stream()
- .skip(1)
- .allMatch(next->shareSameTypeHierarchy(first, next));
-
- return !shareSameTypeHierarchy;
- }
-
- private boolean shareSameTypeHierarchy(
- final @NonNull ObjectSpecification a, final @NonNull ObjectSpecification b) {
- return a.equals(b)
- || a.getCorrespondingClass().isAssignableFrom(b.getCorrespondingClass())
- || b.getCorrespondingClass().isAssignableFrom(a.getCorrespondingClass());
+ return specs.size()>1;
}
private String asCsv(final List<ObjectSpecification> specList) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectTypeFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectTypeFacetAbstract.java
index b3f97fe..9f0dd27 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectTypeFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/objectspecid/ObjectTypeFacetAbstract.java
@@ -57,6 +57,7 @@ implements ObjectTypeFacet {
@Override
public void appendAttributesTo(final Map<String, Object> attributeMap) {
super.appendAttributesTo(attributeMap);
- attributeMap.put("logicalType", logicalType.getLogicalTypeName());
+ attributeMap.put("logicalTypeName", logicalType.getLogicalTypeName());
+ attributeMap.put("logicalTypeCorrespondingClass", logicalType.getCorrespondingClass().getName());
}
}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java
index 7e70f0e..2bb67e1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/LogicalTypeResolverDefault.java
@@ -53,7 +53,23 @@ class LogicalTypeResolverDefault implements LogicalTypeResolver {
if(!spec.isAbstract()
&& hasUsableObjectTypeFacet(spec)) {
- logicalTypeByName.merge(spec.getLogicalTypeName(), spec.getLogicalType(), this::mostSpecializedOfConcrete);
+ val key = spec.getLogicalTypeName();
+
+ val previousMapping = logicalTypeByName.put(key, spec.getLogicalType());
+
+ if(previousMapping!=null) {
+
+ val msg = String.format("Overriding existing mapping\n"
+ + "%s -> %s,\n"
+ + "with\n "
+ + "%s -> %s\n "
+ + "This will result in the meta-model validation to fail.",
+ key, previousMapping.getCorrespondingClass(),
+ key, spec.getCorrespondingClass());
+
+ log.warn(msg);
+
+ }
}
}
@@ -65,34 +81,4 @@ class LogicalTypeResolverDefault implements LogicalTypeResolver {
return spec.containsNonFallbackFacet(ObjectTypeFacet.class);
}
- private LogicalType mostSpecializedOfConcrete(final @NonNull LogicalType a, final @NonNull LogicalType b) {
- if(a.equals(b)) {
- return a;
- }
- if(a.getCorrespondingClass().isAssignableFrom(b.getCorrespondingClass())) {
- return b;
- }
- if(b.getCorrespondingClass().isAssignableFrom(a.getCorrespondingClass())) {
- return a;
- }
-
- val key = a.getLogicalTypeName();
-
- val msg = String.format("Failed to register mapping\n"
- + "%s -> %s,\n"
- + "because there was already a mapping\n "
- + "%s -> %s.\n"
- + "Meta-model validation should detect this and fail, if not - that's a bug.",
- key,
- b.getCorrespondingClass(),
- key,
- a.getCorrespondingClass());
-
- log.warn(msg);
-
- // do not fail fast, but clear the entry and let MM validation fail later on
- return null;
- }
-
-
}
diff --git a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/jaxb/JaxbServiceDefault.java b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/jaxb/JaxbServiceDefault.java
index 5837e6d..5775bff 100644
--- a/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/jaxb/JaxbServiceDefault.java
+++ b/core/runtimeservices/src/main/java/org/apache/isis/core/runtimeservices/jaxb/JaxbServiceDefault.java
@@ -22,7 +22,6 @@ import java.util.Map;
import javax.inject.Inject;
import javax.inject.Named;
-import javax.inject.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
@@ -36,13 +35,13 @@ import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
import org.apache.isis.applib.domain.DomainObjectList;
-import org.apache.isis.applib.id.LogicalType;
import org.apache.isis.applib.jaxb.PersistentEntitiesAdapter;
import org.apache.isis.applib.jaxb.PersistentEntityAdapter;
import org.apache.isis.applib.services.inject.ServiceInjector;
import org.apache.isis.applib.services.jaxb.JaxbService.Simple;
-import org.apache.isis.applib.services.metamodel.MetaModelService;
import org.apache.isis.commons.internal.resources._Xml;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
@@ -58,8 +57,7 @@ import lombok.val;
public class JaxbServiceDefault extends Simple {
private final ServiceInjector serviceInjector;
- /*circular dependency, so use provider*/
- private final Provider<MetaModelService> metaModelServiceProvider;
+ private final SpecificationLoader specificationLoader;
@Override @SneakyThrows
protected JAXBContext jaxbContextForObject(final @NonNull Object domainObject) {
@@ -67,9 +65,9 @@ public class JaxbServiceDefault extends Simple {
val domainClass = domainObject.getClass();
val domainObjectList = (DomainObjectList) domainObject;
try {
- val elementType = metaModelServiceProvider.get()
- .lookupLogicalTypeByName(domainObjectList.getElementObjectType())
- .map(LogicalType::getCorrespondingClass)
+ val elementType = specificationLoader
+ .specForLogicalTypeName(domainObjectList.getElementObjectType())
+ .map(ObjectSpecification::getCorrespondingClass)
.orElse(null);
if (elementType!=null
&& elementType.getAnnotation(XmlJavaTypeAdapter.class) == null) {
diff --git a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/spiimpl/TableColumnVisibilityServiceForSecman.java b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/spiimpl/TableColumnVisibilityServiceForSecman.java
index 3b0597e..9443584 100644
--- a/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/spiimpl/TableColumnVisibilityServiceForSecman.java
+++ b/extensions/security/secman/model/src/main/java/org/apache/isis/extensions/secman/model/spiimpl/TableColumnVisibilityServiceForSecman.java
@@ -8,10 +8,10 @@ import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.apache.isis.applib.annotation.OrderPrecedence;
-import org.apache.isis.applib.id.LogicalType;
import org.apache.isis.applib.services.appfeat.ApplicationFeatureId;
-import org.apache.isis.applib.services.metamodel.MetaModelService;
import org.apache.isis.applib.services.tablecol.TableColumnVisibilityService;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
import org.apache.isis.extensions.secman.api.permission.dom.ApplicationPermissionMode;
import org.apache.isis.extensions.secman.api.user.menu.MeService;
@@ -26,15 +26,15 @@ import lombok.val;
public class TableColumnVisibilityServiceForSecman implements TableColumnVisibilityService {
final MeService meService;
- final MetaModelService metaModelService;
+ final SpecificationLoader specificationLoader;
@Override
public boolean hides(Class<?> elementType, String memberId) {
val me = meService.me();
val permissionSet = me.getPermissionSet();
- final boolean granted = metaModelService.lookupLogicalTypeByClass(elementType)
- .map(LogicalType::getLogicalTypeName)
+ final boolean granted = specificationLoader.specForType(elementType)
+ .map(ObjectSpecification::getLogicalTypeName)
.map(objectType->{
val featureId = ApplicationFeatureId.newMember(objectType, memberId);
return permissionSet.evaluate(featureId, ApplicationPermissionMode.VIEWING).isGranted();