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/11/30 14:33:00 UTC
[isis] branch master updated: ISIS-2903: fixes mm-validation logic for annotation @XmlJavaTypeAdapter
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 b39f584 ISIS-2903: fixes mm-validation logic for annotation @XmlJavaTypeAdapter
b39f584 is described below
commit b39f58407695b1e7b8157a9968a55477ae53d3ca
Author: Andi Huber <ah...@apache.org>
AuthorDate: Tue Nov 30 15:30:01 2021 +0100
ISIS-2903: fixes mm-validation logic for annotation @XmlJavaTypeAdapter
- fixes [Demo] Nature Stateful Refs Entity, such that can now click on
the title
- however, choices, when removing a child, are broken (detached
entities)
---
.../metamodel/facets/jaxb/JaxbFacetFactory.java | 142 ++++++++++-----------
.../jaxbrefentity/StatefulVmJaxbRefsEntity.java | 7 +-
.../domainmodel/jdo/DomainModelTest.java | 3 +
.../isis/testdomain/jpa/JpaInventoryJaxbVm.java | 18 +++
4 files changed, 97 insertions(+), 73 deletions(-)
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java
index 3d49dbb..a8a53c4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/jaxb/JaxbFacetFactory.java
@@ -47,12 +47,13 @@ import org.apache.isis.core.metamodel.facets.properties.update.modify.PropertySe
import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
import org.apache.isis.core.metamodel.spec.ObjectSpecification;
import org.apache.isis.core.metamodel.spec.feature.MixedIn;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
import org.apache.isis.core.metamodel.specloader.validator.ValidationFailure;
import static org.apache.isis.commons.internal.reflection._Reflect.Filter.isPublic;
import static org.apache.isis.commons.internal.reflection._Reflect.Filter.paramCount;
+import lombok.RequiredArgsConstructor;
import lombok.val;
/**
@@ -149,7 +150,7 @@ implements MetaModelRefiner {
public void refineProgrammingModel(final ProgrammingModel programmingModel) {
final List<TypeValidator> typeValidators = getTypeValidators(getConfiguration());
- final List<PropertyValidator> propertyValidators = getPropertyValidators(getConfiguration());
+ final List<AssociationValidator> associationValidators = getAssociationValidators(getConfiguration());
programmingModel.addVisitingValidatorSkipManagedBeans(objectSpec->{
@@ -167,15 +168,15 @@ implements MetaModelRefiner {
typeValidator.validate(objectSpec);
}
- final Stream<OneToOneAssociation> properties = objectSpec
- .streamProperties(MixedIn.EXCLUDED);
+ final Stream<ObjectAssociation> associations = objectSpec
+ .streamAssociations(MixedIn.EXCLUDED);
- properties
+ associations
// ignore derived
- .filter(property->property.containsNonFallbackFacet(PropertySetterFacet.class))
- .forEach(property->{
- for (final PropertyValidator adapterValidator : propertyValidators) {
- adapterValidator.validate(objectSpec, property);
+ .filter(association->association.containsNonFallbackFacet(PropertySetterFacet.class))
+ .forEach(association->{
+ for (final AssociationValidator adapterValidator : associationValidators) {
+ adapterValidator.validate(objectSpec, association);
}
});
@@ -198,24 +199,24 @@ implements MetaModelRefiner {
return typeValidators;
}
- private List<PropertyValidator> getPropertyValidators(final IsisConfiguration configuration) {
- final List<PropertyValidator> propertyValidators = _Lists.newArrayList();
+ private List<AssociationValidator> getAssociationValidators(final IsisConfiguration configuration) {
+ final List<AssociationValidator> associationValidators = _Lists.newArrayList();
if(configuration.getCore().getMetaModel().getValidator().getJaxbViewModel().isReferenceTypeAdapter()) {
- propertyValidators.add(new PropertyValidatorForReferenceTypes());
+ associationValidators.add(new PropertyValidatorForReferenceTypes());
}
if(configuration.getCore().getMetaModel().getValidator().getJaxbViewModel().isDateTimeTypeAdapter()) {
- propertyValidators.add(new PropertyValidatorForDateTypes(java.sql.Timestamp.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(ZonedDateTime.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(OffsetDateTime.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(LocalDate.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(LocalDateTime.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(LocalTime.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(org.joda.time.DateTime.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(org.joda.time.LocalDate.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(org.joda.time.LocalDateTime.class));
- propertyValidators.add(new PropertyValidatorForDateTypes(org.joda.time.LocalTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(java.sql.Timestamp.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(ZonedDateTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(OffsetDateTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(LocalDate.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(LocalDateTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(LocalTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(org.joda.time.DateTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(org.joda.time.LocalDate.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(org.joda.time.LocalDateTime.class));
+ associationValidators.add(new PropertyValidatorForDateTypes(org.joda.time.LocalTime.class));
}
- return propertyValidators;
+ return associationValidators;
}
private static abstract class TypeValidator {
@@ -223,78 +224,77 @@ implements MetaModelRefiner {
}
- private static abstract class PropertyValidator {
+ private static abstract class AssociationValidator {
abstract void validate(
ObjectSpecification objectSpec,
- OneToOneAssociation property);
+ ObjectAssociation propertyOrCollection);
}
- private static class PropertyValidatorForReferenceTypes extends PropertyValidator {
+ private static class PropertyValidatorForReferenceTypes extends AssociationValidator {
@Override
void validate(
final ObjectSpecification objectSpec,
- final OneToOneAssociation property) {
+ final ObjectAssociation propertyOrCollection) {
- final ObjectSpecification propertyTypeSpec = property.getElementType();
- if (!propertyTypeSpec.isEntity()) {
- return;
- }
+ val elementTypeSpec = propertyOrCollection.getElementType();
+ if (elementTypeSpec.isEntity()
+ && !propertyOrCollection.containsFacet(XmlJavaTypeAdapterFacet.class)
+ && !propertyOrCollection.containsFacet(XmlTransientFacet.class)) {
- final XmlJavaTypeAdapterFacet xmlJavaTypeAdapterFacet =
- propertyTypeSpec.getFacet(XmlJavaTypeAdapterFacet.class);
- if(xmlJavaTypeAdapterFacet != null) {
- return;
+ val elementType = elementTypeSpec.getCorrespondingClass();
+ ValidationFailure.raiseFormatted(
+ propertyOrCollection,
+ "JAXB view model '%s' %s '%s' is of entity type '%s', "
+ + "but is not annotated with @XmlJavaTypeAdapter. "
+ + "The referenced entity types must be annotated with "
+ + "@XmlJavaTypeAdapter(org.apache.isis.applib.jaxb.%s.class) or equivalent.",
+ objectSpec.getFullIdentifier(),
+ elementTypeSpec.isNotCollection()
+ ? "@Property"
+ : "@Collection",
+ propertyOrCollection.getId(),
+ elementType.getName(),
+ elementTypeSpec.isNotCollection()
+ ? "PersistentEntityAdapter"
+ : "PersistentEntitiesAdapter");
}
- final Class<?> propertyType = propertyTypeSpec.getCorrespondingClass();
- ValidationFailure.raiseFormatted(
- property,
- "JAXB view model '%s' property '%s' is of type '%s' but that type is not annotated with @XmlJavaTypeAdapter. The type must be annotated with @XmlJavaTypeAdapter(org.apache.isis.applib.jaxb.PersistentEntityAdapter.class) or equivalent.",
- objectSpec.getFullIdentifier(),
- property.getId(),
- propertyType.getName());
}
}
- private static class PropertyValidatorForDateTypes extends PropertyValidator {
- private final Class<?> jodaType;
-
- private PropertyValidatorForDateTypes(final Class<?> jodaType) {
- this.jodaType = jodaType;
- }
+ @RequiredArgsConstructor
+ private static class PropertyValidatorForDateTypes extends AssociationValidator {
+ private final Class<?> dateType;
@Override
void validate(
final ObjectSpecification objectSpec,
- final OneToOneAssociation property) {
-
- final ObjectSpecification propertyTypeSpec = property.getElementType();
- final Class<?> propertyType = propertyTypeSpec.getCorrespondingClass();
+ final ObjectAssociation propertyOrCollection) {
- if (!jodaType.isAssignableFrom(propertyType)) {
- return;
- }
+ val elementTypeSpec = propertyOrCollection.getElementType();
+ val elementType = elementTypeSpec.getCorrespondingClass();
+ if (dateType.isAssignableFrom(elementType)
+ && !propertyOrCollection.containsFacet(XmlJavaTypeAdapterFacet.class)
+ && !propertyOrCollection.containsFacet(XmlTransientFacet.class)) {
- final XmlJavaTypeAdapterFacet xmlJavaTypeAdapterFacet = property.getFacet(XmlJavaTypeAdapterFacet.class);
- if (xmlJavaTypeAdapterFacet != null) {
- return;
- }
+ ValidationFailure.raiseFormatted(
+ propertyOrCollection,
+ "JAXB view model '%s' %s '%s' is of type '%s', "
+ + "but is not annotated with @XmlJavaTypeAdapter. "
+ + "The field/method must be annotated with "
+ + "@XmlJavaTypeAdapter(org.apache.isis.schema.utils.jaxbadapters.XxxAdapter.ForJaxb.class) "
+ + "or equivalent, "
+ + "or be ignored by being annotated with @XmlTransient.",
+ objectSpec.getFullIdentifier(),
+ elementTypeSpec.isNotCollection()
+ ? "@Property"
+ : "@Collection",
+ propertyOrCollection.getId(),
+ dateType.getName());
- final XmlTransientFacet xmlTransientFacet =
- property.getFacet(XmlTransientFacet.class);
- if(xmlTransientFacet != null) {
- return;
}
-
- // else
- ValidationFailure.raiseFormatted(
- property,
- "JAXB view model '%s' property '%s' is of type '%s' but is not annotated with @XmlJavaTypeAdapter. The field/method must be annotated with @XmlJavaTypeAdapter(org.apache.isis.schema.utils.jaxbadapters.XxxAdapter.ForJaxb.class) or equivalent, or be ignored by being annotated with @XmlTransient.",
- objectSpec.getFullIdentifier(),
- property.getId(),
- jodaType.getName());
}
}
diff --git a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/nature/viewmodels/jaxbrefentity/StatefulVmJaxbRefsEntity.java b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/nature/viewmodels/jaxbrefentity/StatefulVmJaxbRefsEntity.java
index e8fb467..dedc492 100644
--- a/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/nature/viewmodels/jaxbrefentity/StatefulVmJaxbRefsEntity.java
+++ b/examples/demo/domain/src/main/java/demoapp/dom/domain/objects/DomainObject/nature/viewmodels/jaxbrefentity/StatefulVmJaxbRefsEntity.java
@@ -26,10 +26,10 @@ import javax.inject.Inject;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import org.apache.isis.applib.annotation.Action;
import org.apache.isis.applib.annotation.ActionLayout;
@@ -42,6 +42,8 @@ import org.apache.isis.applib.annotation.ObjectSupport;
import org.apache.isis.applib.annotation.Optionality;
import org.apache.isis.applib.annotation.Property;
import org.apache.isis.applib.annotation.SemanticsOf;
+import org.apache.isis.applib.jaxb.PersistentEntitiesAdapter;
+import org.apache.isis.applib.jaxb.PersistentEntityAdapter;
import lombok.Getter;
import lombok.Setter;
@@ -77,6 +79,7 @@ public class StatefulVmJaxbRefsEntity implements HasAsciiDocDescription {
@Getter @Setter
@Property(editing = Editing.ENABLED, optionality = Optionality.OPTIONAL)
@XmlElement(required = false)
+ @XmlJavaTypeAdapter(PersistentEntityAdapter.class)
private JaxbRefEntity favoriteChild = null;
@Action(semantics = SemanticsOf.IDEMPOTENT)
@@ -132,8 +135,8 @@ public class StatefulVmJaxbRefsEntity implements HasAsciiDocDescription {
//tag::class[]
@Getter @Setter
@Collection
- @XmlElementWrapper(name = "children")
@XmlElement(name = "child")
+ @XmlJavaTypeAdapter(PersistentEntitiesAdapter.class)
private List<JaxbRefEntity> children = new ArrayList<>();
@Action(choicesFrom = "children", semantics = SemanticsOf.NON_IDEMPOTENT)
diff --git a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java
index 010ecea..de7f9e7 100644
--- a/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java
+++ b/regressiontests/stable-persistence-jdo/src/test/java/org/apache/isis/testdomain/domainmodel/jdo/DomainModelTest.java
@@ -73,6 +73,9 @@ class DomainModelTest {
assertFalse(specificationLoader.snapshotSpecifications().isEmpty());
val validateDomainModel = new DomainModelValidator(serviceRegistry);
+
+ validateDomainModel.getFailures().forEach(f->System.err.printf("%s:%s%n", f.getOrigin(), f.getMessage()));
+
validateDomainModel.throwIfInvalid(); // should not throw
}
diff --git a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/JpaInventoryJaxbVm.java b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/JpaInventoryJaxbVm.java
index d4225b0..02e224a 100644
--- a/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/JpaInventoryJaxbVm.java
+++ b/regressiontests/stable/src/main/java/org/apache/isis/testdomain/jpa/JpaInventoryJaxbVm.java
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
package org.apache.isis.testdomain.jpa;
import java.util.ArrayList;